├── .editorconfig ├── .github ├── FUNDING.yml └── workflows │ ├── binaries.yml │ └── js.yml ├── .gitignore ├── .mocharc.json ├── README.adoc ├── integration-tests ├── fixtures │ └── repo │ │ ├── index.json │ │ ├── nginx-1.18.0-x86_64-linux │ │ └── nginx-1.19.5-x86_64-linux ├── helpers │ └── index.ts └── index.test.ts ├── nyc.config.js ├── package.json ├── patches ├── nginx-1.24.x-avoid-using-openssl-config.patch └── njs-0.7.12-fix-module-build.patch ├── scripts ├── build-nginx ├── build-njs ├── common.sh ├── fetch-sources ├── generate-index └── parse-mapfile-loaded-libs ├── src ├── downloader.ts ├── index.ts ├── internal │ ├── archName.ts │ ├── cacheDir.ts │ ├── downloadFile.ts │ ├── fetch.ts │ └── utils.ts ├── logger.test.ts ├── logger.ts └── repoIndex.ts ├── tsconfig.build.json ├── tsconfig.json └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | ; http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 2 8 | indent_style = space 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | [scripts/*] 13 | indent_size = 4 14 | indent_style = tab 15 | 16 | [scripts/generate-index] 17 | indent_size = 2 18 | indent_style = space 19 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: jirutka 4 | -------------------------------------------------------------------------------- /.github/workflows/binaries.yml: -------------------------------------------------------------------------------- 1 | name: binaries 2 | on: 3 | push: 4 | # Don't run on version tags (these are used for JS module). 5 | tags-ignore: 6 | - 'v**' 7 | branches: 8 | - '**' 9 | paths: 10 | - .github/workflows/binaries.yml 11 | - patches/* 12 | - scripts/* 13 | pull_request: 14 | schedule: 15 | - cron: '0 0 * * 0' # run each Sunday 16 | 17 | env: 18 | ALPINE_BRANCH: v3.21 19 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 20 | JOBS: 3 21 | CFLAGS: -Os -fomit-frame-pointer -pipe 22 | LINUX_LDFLAGS: -static -Wl,--as-needed -Wl,-Map,linker.map 23 | DARWIN_LDFLAGS: -Wl,-map,linker.map 24 | WIN32_LDFLAGS: -Wl,--as-needed -Wl,-Map,linker.map 25 | # List of extra nginx modules to download. 26 | # NOTE: nginx/njs is not defined here, but directly in the jobs. 27 | NGINX_MODULES: >- 28 | kjdev/nginx-auth-jwt 29 | kjdev/nginx-keyval 30 | vision5/ngx_devel_kit 31 | openresty/echo-nginx-module 32 | openresty/headers-more-nginx-module 33 | openresty/set-misc-nginx-module 34 | # The same as above, but for Windows. 35 | # - kjdev/nginx-auth-jwt, kjdev/nginx-keyval: a bit complicated to build (TODO) 36 | NGINX_MODULES_WIN32: >- 37 | vision5/ngx_devel_kit 38 | openresty/echo-nginx-module 39 | openresty/headers-more-nginx-module 40 | openresty/set-misc-nginx-module 41 | # Don't update binaries with unchanged sources. 42 | SKIP_SAME_SOURCES: true 43 | 44 | jobs: 45 | njs-multi-linux: 46 | name: njs-${{ matrix.NJS_VERSION }}${{ matrix.VARIANT }}-${{ matrix.ARCH }}-linux 47 | runs-on: ubuntu-latest 48 | strategy: 49 | matrix: 50 | NJS_VERSION: 51 | - 0.x.x 52 | VARIANT: 53 | - '-debug' 54 | - '' 55 | ARCH: 56 | - x86_64 57 | - aarch64 58 | - ppc64le 59 | steps: 60 | - name: Checkout master branch 61 | uses: actions/checkout@v4 62 | with: 63 | path: master 64 | 65 | - name: Download and extract njs 66 | run: ./master/scripts/fetch-sources -d . nginx/njs@${{ matrix.NJS_VERSION }} 67 | 68 | - name: Install Alpine ${{ env.ALPINE_BRANCH }} for ${{ matrix.ARCH }} 69 | uses: jirutka/setup-alpine@v1 70 | with: 71 | arch: ${{ matrix.ARCH }} 72 | branch: ${{ env.ALPINE_BRANCH }} 73 | packages: > 74 | build-base 75 | libedit-dev 76 | libedit-static 77 | ncurses-dev 78 | ncurses-static 79 | openssl-dev 80 | openssl-libs-static 81 | pcre-dev 82 | zlib-static 83 | 84 | - name: Build njs 85 | env: 86 | VARIANT: ${{ matrix.VARIANT }} 87 | CFLAGS: ${{ env.CFLAGS }} 88 | LDFLAGS: ${{ env.LINUX_LDFLAGS }} 89 | run: ./master/scripts/build-njs 90 | shell: alpine.sh {0} 91 | 92 | - name: Upload njs binary to artifacts 93 | uses: actions/upload-artifact@v4 94 | with: 95 | name: njs-${{ matrix.NJS_VERSION }}${{ matrix.VARIANT }}-${{ matrix.ARCH }}-linux 96 | path: artifact/* 97 | 98 | njs-x86_64-darwin: 99 | name: njs-${{ matrix.NJS_VERSION }}${{ matrix.VARIANT }}-x86_64-darwin 100 | runs-on: macos-latest 101 | strategy: 102 | matrix: 103 | NJS_VERSION: 104 | - 0.x.x 105 | VARIANT: 106 | - '-debug' 107 | - '' 108 | steps: 109 | - name: Install dependencies 110 | run: brew install gsed jq libedit openssl@3 ncurses pcre zlib 111 | 112 | - name: Checkout master branch 113 | uses: actions/checkout@v4 114 | with: 115 | path: master 116 | 117 | - name: Download and extract njs 118 | run: ./master/scripts/fetch-sources -d . nginx/njs@${{ matrix.NJS_VERSION }} 119 | 120 | # cmake prefers dynamic libs and there's no option to change it, so 121 | # we have to remove them to give it no other option than using static. 122 | - name: Remove dylibs 123 | run: | 124 | rm /opt/homebrew/opt/libedit/lib/*.dylib 125 | rm /opt/homebrew/opt/openssl/lib/*.dylib 126 | rm /opt/homebrew/opt/ncurses/lib/*.dylib 127 | rm /opt/homebrew/opt/pcre/lib/*.dylib 128 | rm /opt/homebrew/opt/zlib/lib/*.dylib 129 | 130 | - name: Build njs 131 | env: 132 | VARIANT: ${{ matrix.VARIANT }} 133 | CFLAGS: ${{ env.CFLAGS }} -I/opt/homebrew/opt/libedit/include -I/opt/homebrew/opt/openssl/include -I/opt/homebrew/opt/ncurses/include -I/opt/homebrew/opt/pcre/include -I/opt/homebrew/opt/zlib/include 134 | LDFLAGS: ${{ env.DARWIN_LDFLAGS }} -L/opt/homebrew/opt/libedit/lib -L/opt/homebrew/opt/openssl/lib -L/opt/homebrew/opt/ncurses/lib -L/opt/homebrew/opt/pcre/lib -L/opt/homebrew/opt/zlib/lib 135 | run: ./master/scripts/build-njs 136 | 137 | - name: Upload njs binary to artifacts 138 | uses: actions/upload-artifact@v4 139 | with: 140 | name: njs-${{ matrix.NJS_VERSION }}${{ matrix.VARIANT }}-x86_64-darwin 141 | path: artifact/* 142 | 143 | nginx-multi-linux: 144 | name: nginx-${{ matrix.NGINX_VERSION }}-${{ matrix.ARCH }}-linux 145 | runs-on: ubuntu-latest 146 | strategy: 147 | matrix: 148 | NGINX_VERSION: 149 | - 1.26.x 150 | - 1.27.x 151 | - 1.28.x 152 | ARCH: 153 | - x86_64 154 | - aarch64 155 | - ppc64le 156 | include: 157 | - NJS_VERSION: 0.x.x 158 | # Pin older njs version for old stable nginx. 159 | - NGINX_VERSION: 1.26.x 160 | NJS_VERSION: 0.8.x 161 | steps: 162 | - name: Checkout master branch 163 | uses: actions/checkout@v4 164 | with: 165 | path: master 166 | 167 | - name: Download and extract nginx 168 | run: ./master/scripts/fetch-sources -d . nginx/nginx@release-${{ matrix.NGINX_VERSION }} 169 | 170 | - name: Download and extract nginx modules 171 | run: ./master/scripts/fetch-sources nginx/njs@${{ matrix.NJS_VERSION }} $NGINX_MODULES 172 | 173 | - name: Install Alpine ${{ env.ALPINE_BRANCH }} for ${{ matrix.ARCH }} 174 | uses: jirutka/setup-alpine@v1 175 | with: 176 | arch: ${{ matrix.ARCH }} 177 | branch: ${{ env.ALPINE_BRANCH }} 178 | packages: > 179 | build-base 180 | jansson-dev 181 | jansson-static 182 | linux-headers 183 | openssl-dev 184 | openssl-libs-static 185 | pcre-dev 186 | zlib-dev 187 | zlib-static 188 | 189 | - name: Build nginx 190 | env: 191 | NGINX_MODULES: nginx/njs ${{ env.NGINX_MODULES }} 192 | CFLAGS: ${{ env.CFLAGS }} 193 | LDFLAGS: ${{ env.LINUX_LDFLAGS }} 194 | run: ./master/scripts/build-nginx 195 | shell: alpine.sh {0} 196 | 197 | - name: Upload nginx binary to artifacts 198 | uses: actions/upload-artifact@v4 199 | with: 200 | name: nginx-${{ matrix.NGINX_VERSION }}-${{ matrix.ARCH }}-linux 201 | path: artifact/* 202 | 203 | nginx-x86_64-darwin: 204 | name: nginx-${{ matrix.NGINX_VERSION }}-x86_64-darwin 205 | runs-on: macos-latest 206 | strategy: 207 | matrix: 208 | NGINX_VERSION: 209 | - 1.26.x 210 | - 1.27.x 211 | - 1.28.x 212 | include: 213 | - NJS_VERSION: 0.x.x 214 | # Pin older njs version for old nginx. 215 | - NGINX_VERSION: 1.26.x 216 | NJS_VERSION: 0.8.x 217 | steps: 218 | - name: Install dependencies 219 | run: brew install gsed jansson jq openssl@3 pcre zlib 220 | 221 | - name: Checkout master branch 222 | uses: actions/checkout@v4 223 | with: 224 | path: master 225 | 226 | - name: Download and extract nginx 227 | run: ./master/scripts/fetch-sources -d . nginx/nginx@release-${{ matrix.NGINX_VERSION }} 228 | 229 | - name: Download and extract nginx modules 230 | run: ./master/scripts/fetch-sources nginx/njs@${{ matrix.NJS_VERSION }} $NGINX_MODULES 231 | 232 | # cmake prefers dynamic libs and there's no option to change it, so 233 | # we have to remove them to give it no other option than using static. 234 | - name: Remove dylibs 235 | run: | 236 | rm /opt/homebrew/opt/jansson/lib/*.dylib 237 | rm /opt/homebrew/opt/openssl/lib/*.dylib 238 | rm /opt/homebrew/opt/pcre/lib/*.dylib 239 | rm /opt/homebrew/opt/zlib/lib/*.dylib 240 | 241 | - name: Build nginx 242 | env: 243 | NGINX_MODULES: nginx/njs ${{ env.NGINX_MODULES }} 244 | CFLAGS: ${{ env.CFLAGS }} -I/opt/homebrew/opt/jansson/include -I/opt/homebrew/opt/openssl/include -I/opt/homebrew/opt/pcre/include -I/opt/homebrew/opt/zlib/include 245 | LDFLAGS: ${{ env.DARWIN_LDFLAGS }} -L/opt/homebrew/opt/jansson/lib -L/opt/homebrew/opt/openssl/lib -L/opt/homebrew/opt/pcre/lib -L/opt/homebrew/opt/zlib/lib 246 | run: ./master/scripts/build-nginx 247 | 248 | - name: Upload nginx binary to artifacts 249 | uses: actions/upload-artifact@v4 250 | with: 251 | name: nginx-${{ matrix.NGINX_VERSION }}-x86_64-darwin 252 | path: artifact/* 253 | 254 | nginx-x86_64-win32: 255 | name: nginx-${{ matrix.NGINX_VERSION }}-x86_64-win32 256 | runs-on: windows-latest 257 | strategy: 258 | matrix: 259 | NGINX_VERSION: 260 | - 1.26.x 261 | - 1.27.x 262 | - 1.28.x 263 | steps: 264 | - name: Setup MSYS2 and install packages 265 | uses: msys2/setup-msys2@v2 266 | with: 267 | update: false 268 | install: base-devel mingw-w64-x86_64-toolchain mingw-w64-x86_64-jq 269 | 270 | - name: Checkout master branch 271 | uses: actions/checkout@v4 272 | with: 273 | path: master 274 | 275 | - name: Download and extract nginx 276 | shell: msys2 {0} 277 | run: ./master/scripts/fetch-sources -d . nginx/nginx@release-${{ matrix.NGINX_VERSION }} 278 | 279 | - name: Download and extract nginx MSYS2 patches 280 | shell: msys2 {0} 281 | run: ./master/scripts/fetch-sources -d msys2 "myfreeer/nginx-build-msys2@1.22.0" 282 | 283 | - name: Download and extract nginx modules 284 | shell: msys2 {0} 285 | run: ./master/scripts/fetch-sources $NGINX_MODULES_WIN32 286 | 287 | - name: Download and extract libraries 288 | shell: msys2 {0} 289 | run: ./master/scripts/fetch-sources 'openssl@3.3.x' 'pcre@8.x' 'madler/zlib@v1.3.x' 290 | 291 | - name: Apply patches 292 | shell: msys2 {0} 293 | run: | 294 | case "${{ matrix.NGINX_VERSION }}" in 295 | 1.2[0-2].x) 296 | for i in msys2/nginx-*.patch; do 297 | patch -p1 < $i 298 | done 299 | ;; 300 | # Other patches are not needed since 1.23.4. 301 | *) patch -p1 < msys2/nginx-0007-logs-write-access-log-to-stderr.patch;; 302 | esac 303 | 304 | - name: Build nginx 305 | shell: msys2 {0} 306 | env: 307 | NGINX_MODULES: ${{ env.NGINX_MODULES_WIN32 }} 308 | # -DFD_SETSIZE=1024 is per official nginx win32 binary. 309 | CFLAGS: ${{ env.CFLAGS }} -DFD_SETSIZE=1024 310 | LDFLAGS: ${{ env.WIN32_LDFLAGS }} 311 | run: ./master/scripts/build-nginx 312 | 313 | - name: Upload nginx binary to artifacts 314 | uses: actions/upload-artifact@v4 315 | with: 316 | name: nginx-${{ matrix.NGINX_VERSION }}-x86_64-win32 317 | path: artifact/* 318 | 319 | upload: 320 | name: Upload binaries 321 | needs: 322 | - njs-multi-linux 323 | - njs-x86_64-darwin 324 | - nginx-multi-linux 325 | - nginx-x86_64-darwin 326 | - nginx-x86_64-win32 327 | if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request' 328 | runs-on: ubuntu-latest 329 | container: 330 | image: docker://alpine:3.21 331 | steps: 332 | - name: Install dependencies 333 | run: apk add -U git nodejs tree 334 | 335 | - name: Checkout master branch 336 | uses: actions/checkout@v4 337 | with: 338 | path: master 339 | 340 | - name: Checkout binaries branch 341 | uses: actions/checkout@v4 342 | with: 343 | ref: binaries 344 | path: binaries 345 | 346 | - name: Download and unpack all workflow run artifacts 347 | uses: actions/download-artifact@v4 348 | with: 349 | path: artifact 350 | merge-multiple: true 351 | 352 | - name: List unpacked artifact files 353 | run: ls -lah artifact/ 354 | 355 | # XXX: Windows builds of nginx and macOS builds of njs-debug are not reproducible. 356 | # This is a workaround to avoid unnecessary updates of binaries that are built from 357 | # very same sources as the existing (note that we track even used system libs). 358 | - name: Move binaries with changed source checksums to the repository 359 | if: env.SKIP_SAME_SOURCES == 'true' 360 | working-directory: binaries 361 | run: | 362 | mv ../artifact/*.sources . 363 | for name in $(git status --porcelain | cut -c4-); do 364 | mv -v ../artifact/${name%.sources}* . 365 | done 366 | 367 | - name: Move all binaries to the repository 368 | if: env.SKIP_SAME_SOURCES != 'true' 369 | run: mv -v artifact/* binaries/ 370 | 371 | - name: Generate index.json 372 | run: ./master/scripts/generate-index --json binaries/ binaries/index.json 373 | 374 | - name: Generate index.csv 375 | run: ./master/scripts/generate-index --csv binaries/ binaries/index.csv 376 | 377 | - name: Generate index.html 378 | working-directory: binaries 379 | run: tree -hv -H . -o index.html . 380 | 381 | - name: Check if there are any changes 382 | id: has_changes 383 | working-directory: binaries 384 | run: | 385 | git status || exit 1 386 | test -n "$(git status --porcelain)" && result=yes || result=no 387 | echo "result=$result" >> $GITHUB_OUTPUT 388 | 389 | - name: Commit changes 390 | if: steps.has_changes.outputs.result == 'yes' 391 | working-directory: binaries 392 | run: | 393 | git config --local user.email "github-actions@users.noreply.github.com" 394 | git config --local user.name "github-actions[bot]" 395 | git add --all 396 | git commit -m "Built from ${{ github.sha }}" 397 | 398 | - name: Push changes back to origin 399 | if: steps.has_changes.outputs.result == 'yes' 400 | working-directory: binaries 401 | run: | 402 | # XXX: workaround for https://github.com/orgs/community/discussions/55820 403 | git config --global http.version HTTP/1.1 404 | git push https://${GITHUB_ACTOR}:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git binaries 405 | -------------------------------------------------------------------------------- /.github/workflows/js.yml: -------------------------------------------------------------------------------- 1 | name: js 2 | on: 3 | push: 4 | paths-ignore: 5 | - .github/workflows/binaries.yml 6 | - scripts/* 7 | - README.adoc 8 | pull_request: 9 | paths-ignore: 10 | - .github/workflows/binaries.yml 11 | - scripts/* 12 | - README.adoc 13 | 14 | jobs: 15 | test: 16 | name: Test on Node ${{ matrix.node-version }} 17 | runs-on: ubuntu-latest 18 | strategy: 19 | matrix: 20 | node-version: 21 | - lts/-2 22 | - lts/-1 23 | - lts/* 24 | - latest 25 | steps: 26 | - uses: actions/checkout@v4 27 | 28 | - uses: actions/setup-node@v4 29 | with: 30 | node-version: ${{ matrix.node-version }} 31 | 32 | - run: yarn install --frozen-lockfile 33 | - run: yarn build 34 | - run: yarn test 35 | 36 | publish: 37 | name: Publish on npmjs 38 | needs: test 39 | if: startsWith(github.ref, 'refs/tags/v') && github.event_name != 'pull_request' 40 | runs-on: ubuntu-latest 41 | steps: 42 | - name: Install asciidoctor and pandoc 43 | run: sudo apt-get install asciidoctor pandoc 44 | 45 | - name: Checkout repository 46 | uses: actions/checkout@v4 47 | 48 | - run: yarn install --frozen-lockfile 49 | 50 | - run: yarn build 51 | 52 | - name: Set up .npmrc file 53 | uses: actions/setup-node@v4 54 | with: 55 | node-version: 'lts/*' 56 | registry-url: 'https://registry.npmjs.org' 57 | 58 | - run: yarn publish 59 | env: 60 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 61 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.vscode/ 2 | /lib/ 3 | node_modules/ 4 | package-lock.json 5 | README.md 6 | *.log 7 | -------------------------------------------------------------------------------- /.mocharc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extension": ["ts"], 3 | "spec": ["src/**/*.test.ts", "integration-tests/**/*.test.ts"], 4 | "require": "ts-node/register" 5 | } 6 | -------------------------------------------------------------------------------- /README.adoc: -------------------------------------------------------------------------------- 1 | = nginx and njs standalone binaries 2 | :toc: macro 3 | :toc-title: 4 | // custom 5 | :npm-name: nginx-binaries 6 | :gh-name: jirutka/{npm-name} 7 | :alpine-branch: 3.21 8 | :nginx-docs-uri: http://nginx.org/en/docs/ 9 | 10 | ifdef::env-github[] 11 | image:https://github.com/{gh-name}/workflows/binaries/badge.svg[Binaries Workflow, link=https://github.com/{gh-name}/actions?query=workflow%3A%22binaries%22] 12 | endif::env-github[] 13 | 14 | This project provides standalone nginx and njs (NGINX JavaScript) binaries for *any* Linux system footnote:[nginx binaries are built as standalone static executables, so they works on every Linux system regardless of used libc.] (x86_64, aarch64, ppc64le), macOS (x86_64), and Windows (x86_64). 15 | It also provides a JS library for downloading these binaries (for use in integration tests). 16 | 17 | ifndef::npm-readme[] 18 | 19 | You can also download the binaries manually from https://jirutka.github.io/nginx-binaries/ or https://github.com/{gh-name}/tree/binaries[binaries] branch (see <>). 20 | They are built automatically and periodically using GitHub Actions (see link:.github/workflows/binaries.yml[config]). 21 | 22 | 23 | == Table of Contents 24 | 25 | toc::[] 26 | 27 | 28 | == JS Library 29 | 30 | ifdef::env-github[] 31 | image:https://github.com/{gh-name}/workflows/js/badge.svg[JS Workflow, link=https://github.com/{gh-name}/actions?query=workflow%3A%22js%22] 32 | image:https://img.shields.io/npm/v/{npm-name}.svg[npm Version, link="https://www.npmjs.org/package/{npm-name}"] 33 | image:https://badgen.net/bundlephobia/dependency-count/{npm-name}[Dependency Count, link="https://bundlephobia.com/result?p={npm-name}"] 34 | endif::env-github[] 35 | 36 | endif::npm-readme[] 37 | 38 | === Installation 39 | 40 | [source, sh, subs="+attributes"] 41 | ---- 42 | # using npm: 43 | npm install --save-dev {npm-name} 44 | # or using yarn: 45 | yarn add --dev {npm-name} 46 | ---- 47 | 48 | 49 | === Usage Example 50 | 51 | [source, js, subs="+attributes"] 52 | ---- 53 | import { NginxBinary, NjsBinary } from '{npm-name}' 54 | 55 | await NginxBinary.versions({ version: '^1.21.5' }) 56 | // => ['1.21.5', '1.21.6', '1.22.0'] 57 | 58 | await NginxBinary.download({ version: '1.22.x' }) 59 | // => '[...]/node_modules/.cache/nginx-binaries/nginx-1.22.0-x86_64-linux' 60 | 61 | await NjsBinary.versions({ version: '^0.7.0' }) 62 | // => ['0.7.1', '0.7.2', '0.7.3', '0.7.4'] 63 | 64 | await NjsBinary.download({ version: '^0.7.0', variant: 'debug' }, '.tmp/njs') 65 | // => '.tmp/njs' 66 | ---- 67 | 68 | 69 | === API 70 | 71 | // Pandoc conversion to Markdown doesn't handle definition lists. 72 | ifdef::npm-readme[] 73 | https://github.com/{gh-name}#api[See on GitHub]. 74 | 75 | endif::npm-readme[] 76 | ifndef::npm-readme[] 77 | 78 | ==== NginxBinary / NjsBinary 79 | 80 | cacheDir `(string)`:: 81 | Path to the cache directory where the repository index and binaries are stored. 82 | + 83 | Defaults to `.cache/nginx-binaries/` relative to the nearest writable `node_modules` (nearest to `process.cwd()`) or `nginx-binaries/` in the system-preferred temp directory. 84 | 85 | cacheMaxAge `(number)`:: 86 | Maximum age in minutes for the cached repository index in `cacheDir` to be considered fresh. 87 | If the cached index is stale, the Downloader tries to refresh it before reading. 88 | + 89 | Defaults to `480` (8 hours). 90 | 91 | repoUrl `(string)`:: 92 | URL of the repository with binaries. 93 | + 94 | *Caution:* After changing `repoUrl`, you should delete old `index.json` in `cacheDir` or disable index cache by setting `cacheMaxAge` to `0`. 95 | + 96 | Defaults to `'https://jirutka.github.io/nginx-binaries'`. 97 | 98 | timeout `(number)`:: 99 | Fetch response timeout in milliseconds. 100 | + 101 | Defaults to `10000` (10 seconds). 102 | 103 | download `(query: <>, destFilePath?: string) => Promise`:: 104 | Downloads a binary specified by `query` and stores it in the `cacheDir` or in `destFilePath`, if provided. 105 | Returns path to the file. 106 | + 107 | If the file already exists and the checksums match, it just returns its path. 108 | + 109 | If multiple versions satisfies the version range, the one with highest version number is selected. 110 | 111 | search `(query: <>) => Promise<<>[]>`:: 112 | Returns metadata of available binaries that match the query. 113 | 114 | variants `(query?: <>) => Promise`:: 115 | Returns all the available variants matching the query. 116 | 117 | versions `(query?: <>) => Promise`:: 118 | Returns all the available versions matching the query. 119 | 120 | 121 | ==== Query 122 | 123 | version `(?string)`:: 124 | Specify required version as exact version number or a https://github.com/npm/node-semver#ranges[SemVer version range]. 125 | + 126 | Example: `'1.8.0'`, `'1.8.x'`, `'^1.8.0'` 127 | 128 | variant `(?string)`:: 129 | Specify build variant of the binary (e.g. `debug`). 130 | Defaults to an empty string, i.e. the default variant. 131 | 132 | os `(?string)`:: 133 | Specify target OS. 134 | Defaults to the host OS. 135 | 136 | arch `(?string)`:: 137 | Specify target CPU architecture. 138 | Defaults to the host architecture. 139 | 140 | 141 | ==== IndexEntry 142 | 143 | name `(string)`:: 144 | Name of the program: `'nginx'` or `'njs'`. 145 | 146 | version `(string)`:: 147 | Version of the program. 148 | 149 | variant `(string)`:: 150 | The build variant of the binary (e.g. `debug`). 151 | An empty string indicates the default variant. 152 | 153 | os `(string)`:: 154 | OS platform for which this binary was built: `'darwin'` (macOS), `'linux'` (Linux), or `'win32'` (Windows). 155 | 156 | arch `(string)`:: 157 | CPU architecture for which this binary was built: `'armv7'`, `'aarch64'`, `'ppc64le'`, or `'x86_64'`. 158 | 159 | filename `(string)`:: 160 | Full name of the binary file. 161 | 162 | date `(string)`:: 163 | Date and time (ISO-8601) at which the binary was built. 164 | 165 | size `(number)`:: 166 | Size of the binary file in bytes. 167 | 168 | checksum `(string)`:: 169 | Checksum of the binary file in format `:`. 170 | + 171 | Example: `'sha1:7336b675b26bd67fdda3db18c66fa7f64691e280'` 172 | 173 | bundledLibs `(Object.)`:: 174 | A record of all libraries (or modules) statically linked into the binary and the version number. 175 | + 176 | .Example: 177 | [source, js] 178 | ---- 179 | { 180 | 'openssl': '1.1.1i-r0', 181 | 'echo-nginx-module': '0.62', 182 | } 183 | ---- 184 | 185 | 186 | === Logging 187 | 188 | . If https://github.com/Download/anylogger[anylogger] is available and initialized (any adapter has been registered), then: 189 | ** all log messages will go through `anylogger` logger `nginx-binaries`. 190 | 191 | . If https://www.npmjs.com/package/debug[debug] is available, then: 192 | ** _debug_ messages will be logged via `debug` logger `nginx-binaries`, others (error, warn, info) via `console`. 193 | 194 | . otherwise: 195 | ** _error_, _warn_, and _info_ messages will be logged via `console`, _debug_ messages will be discarded. 196 | 197 | If none of these options is suitable, you can provide your own logger using `setLogger(object)`: 198 | 199 | [source, js, subs="+attributes"] 200 | ---- 201 | import { setLogger } from '{npm-name}' 202 | 203 | setLogger({ 204 | warn: console.warn, 205 | error: console.error, 206 | // undefined logging functions will be replaced with no-op 207 | }) 208 | ---- 209 | 210 | 211 | == Files Repository 212 | 213 | The built binaries are stored in https://github.com/{gh-name}/tree/binaries[binaries] branch of this git repository which is published on https://jirutka.github.io/nginx-binaries/. 214 | 215 | The repository contains the following types of files: 216 | 217 | * `index.{csv,json,html}` -- Repository index in CSV, JSON and HTML formats. 218 | * `-[-]--[.exe]` -- Program binary for particular architecture and OS. 219 | * `-[-]--[.exe].sha1` -- SHA-1 checksum of the binary file. 220 | * `-[-]--[.exe].sources` -- List of all source tarballs and system-provided static libraries from which the binary was built. 221 | 222 | See <> for description of ``, `` etc. 223 | Suffix `.exe` is used for Windows binaries only. 224 | 225 | 226 | == Binaries 227 | 228 | [cols=5] 229 | |=== 230 | | Program | Version Range(s) | Variant(s) | OS | Architecture(s) 231 | 232 | .3+| nginx 233 | .3+| 1.18.x (EOL) + 234 | 1.19.x (EOL) footnote:[The first available nginx version in branch 1.19.x is 1.19.5.] + 235 | 1.20.x (EOL) + 236 | 1.21.x (EOL) + 237 | 1.22.x (EOL) + 238 | 1.23.x (EOL) + 239 | 1.24.x (EOL) + 240 | 1.25.x (EOL) + 241 | 1.26.x (old stable) + 242 | 1.27.x (mainline) + 243 | 1.28.x (stable) 244 | 245 | .3+| _default_ 246 | | Linux 247 | | x86_64 + 248 | aarch64 + 249 | ppc64le + 250 | pass:[armv7] footnote:armv7[As of January 2023, binaries for armv7 are no longer built -- gcc runs out of memory when building njs using the QEMU emulator. If you want support for armv7, let me know in issues.] 251 | 252 | | macOS 253 | | x86_64 254 | 255 | | Windows 256 | | x86_64 (x64) 257 | 258 | .3+| njs 259 | .2+| 0.x.x footnote:[The first available njs version is 0.5.0.] 260 | .2+| _default_ + 261 | debug 262 | | Linux 263 | | x86_64 + 264 | aarch64 + 265 | ppc64le + 266 | pass:[armv7] footnote:armv7[] 267 | 268 | | macOS 269 | | x86_64 270 | |=== 271 | 272 | 273 | === nginx 274 | 275 | *Linux* binary is statically linked with https://www.musl-libc.org[musl libc], jansson, openssl (3.x), pcre and zlib from https://alpinelinux.org[Alpine Linux] {alpine-branch}. 276 | It’s compiled with debug mode, threads and aio. 277 | 278 | *macOS* binary is statically linked with jansson, openssl@3, pcre and zlib from https://brew.sh[Homebrew]. 279 | It’s compiled with debug mode, threads and aio. 280 | 281 | *Windows* binary is statically linked with latest openssl 3.3.x, pcre 8.x and zlib 1.3.x built from sources. 282 | It’s compiled with debug mode and patches from https://github.com/myfreeer/nginx-build-msys2[nginx-build-msys2] made by https://github.com/myfreeer[@myfreeer]. 283 | 284 | 285 | ==== Included Modules 286 | 287 | *Built-In Modules:* 288 | 289 | * {nginx-docs-uri}/http/ngx_http_access_module.html[ngx_http_access_module] 290 | * {nginx-docs-uri}/http/ngx_http_auth_basic_module.html[ngx_http_auth_basic_module] 291 | * {nginx-docs-uri}/http/ngx_http_auth_request_module.html[ngx_http_auth_request_module] 292 | * {nginx-docs-uri}/http/ngx_http_autoindex_module.html[ngx_http_autoindex_module] 293 | * {nginx-docs-uri}/http/ngx_http_browser_module.html[ngx_http_browser_module] 294 | * {nginx-docs-uri}/http/ngx_http_charset_module.html[ngx_http_charset_module] 295 | * {nginx-docs-uri}/http/ngx_http_empty_gif_module.html[ngx_http_empty_gif_module] 296 | * {nginx-docs-uri}/http/ngx_http_gzip_module.html[ngx_http_gzip_module] 297 | * {nginx-docs-uri}/http/ngx_http_limit_conn_module.html[ngx_http_limit_conn_module] 298 | * {nginx-docs-uri}/http/ngx_http_limit_req_module.html[ngx_http_limit_req_module] 299 | * {nginx-docs-uri}/http/ngx_http_map_module.html[ngx_http_map_module] 300 | * {nginx-docs-uri}/http/ngx_http_proxy_module.html[ngx_http_proxy_module] 301 | * {nginx-docs-uri}/http/ngx_http_realip_module.html[ngx_http_realip_module] 302 | * {nginx-docs-uri}/http/ngx_http_referer_module.html[ngx_http_referer_module] 303 | * {nginx-docs-uri}/http/ngx_http_rewrite_module.html[ngx_http_rewrite_module] 304 | * {nginx-docs-uri}/http/ngx_http_secure_link_module.html[ngx_http_secure_link_module] 305 | * {nginx-docs-uri}/http/ngx_http_ssl_module.html[ngx_http_ssl_module] 306 | * {nginx-docs-uri}/http/ngx_http_upstream_hash_module.html[ngx_http_upstream_hash_module] 307 | * {nginx-docs-uri}/http/ngx_http_upstream_ip_hash_module.html[ngx_http_upstream_ip_hash_module] 308 | * {nginx-docs-uri}/http/ngx_http_upstream_keepalive_module.html[ngx_http_upstream_keepalive_module] 309 | * {nginx-docs-uri}/http/ngx_http_upstream_least_conn_module.html[ngx_http_upstream_least_conn_module] 310 | * {nginx-docs-uri}/http/ngx_http_upstream_random_module.html[ngx_http_upstream_random_module] 311 | * {nginx-docs-uri}/http/ngx_http_upstream_zone_module.html[ngx_http_upstream_zone_module] 312 | * {nginx-docs-uri}/http/ngx_http_userid_module.html[ngx_http_userid_module] 313 | * {nginx-docs-uri}/http/ngx_http_v2_module.html[ngx_http_v2_module] 314 | 315 | *Extra Modules:* footnote:[Modules that are provided by NGINX but released separately.] 316 | 317 | * {nginx-docs-uri}/http/ngx_http_js_module.html[ngx_http_js_module] (except Windows footnote:[njs is not supported on Windows, see https://github.com/nginx/njs/issues/320[nginx/njs#320]]) 318 | 319 | Since nginx 1.22.0, the stable and mainline versions of nginx include the latest version of njs available at the time of building. 320 | The _old stable_ versions of nginx include the latest minor (i.e. x.**Y**.z) version of njs released prior to the release of a new stable nginx (and the latest patch version available at the time of building). 321 | That is, it’s the same as in NGINX’s own packages. 322 | 323 | *3rd Party Modules:* 324 | 325 | * https://github.com/openresty/echo-nginx-module[echo-nginx-module] 326 | * https://github.com/openresty/headers-more-nginx-module[headers-more-nginx-module] 327 | * https://github.com/vision5/ngx_devel_kit[ngx_devel_kit] 328 | * https://github.com/openresty/set-misc-nginx-module[set-misc-nginx-module] 329 | * https://github.com/kjdev/nginx-auth-jwt[kjdev/nginx-auth-jwt] (since 1.22.1, 1.23.4, and 1.24.0; except Windows binaries) 330 | * https://github.com/kjdev/nginx-keyval[nginx-keyval] (since 1.22.1, 1.23.4, and 1.24.0; except Windows binaries) 331 | 332 | nginx binaries include the latest version of the third-party modules available at the time of building. 333 | 334 | 335 | === njs 336 | 337 | *Linux* binary is statically linked with https://www.musl-libc.org[musl libc], libedit, openssl (3.x), ncurses, pcre and zlib from https://alpinelinux.org[Alpine Linux] {alpine-branch}. 338 | 339 | *macOS* binary is statically linked with libedit, openssl@1.1, ncurses, pcre and zlib from https://brew.sh[Homebrew]. 340 | 341 | endif::npm-readme[] 342 | -------------------------------------------------------------------------------- /integration-tests/fixtures/repo/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "formatVersion": 2, 3 | "contents": [ 4 | { 5 | "name": "nginx", 6 | "version": "1.18.0", 7 | "variant": "", 8 | "arch": "x86_64", 9 | "os": "linux", 10 | "filename": "nginx-1.18.0-x86_64-linux", 11 | "date": "2020-10-12T03:01:00Z", 12 | "size": 8744, 13 | "checksum": "sha1:f2f6e3e8e2821ee490cbe133b9647a699ee22d99", 14 | "bundledLibs": { 15 | "njs": "0.5.0", 16 | "ngx_devel_kit": "0.3.1", 17 | "echo-nginx-module": "0.62", 18 | "headers-more-nginx-module": "0.33", 19 | "set-misc-nginx-module": "0.32", 20 | "gcc": "9.3.0-r2", 21 | "musl": "1.1.24-r10", 22 | "openssl": "1.1.1i-r0", 23 | "pcre": "8.44-r0" 24 | } 25 | }, 26 | { 27 | "name": "nginx", 28 | "version": "1.18.0", 29 | "variant": "", 30 | "arch": "aarch64", 31 | "os": "linux", 32 | "filename": "nginx-1.18.0-aarch64-linux", 33 | "date": "2020-10-12T03:01:00Z", 34 | "size": 1324, 35 | "checksum": "sha1:f2f6e3e8e2821ee490cbe133b9647a699ee22d99", 36 | "bundledLibs": { 37 | "njs": "0.5.0", 38 | "ngx_devel_kit": "0.3.1", 39 | "echo-nginx-module": "0.62", 40 | "headers-more-nginx-module": "0.33", 41 | "set-misc-nginx-module": "0.32", 42 | "gcc": "9.3.0-r2", 43 | "musl": "1.1.24-r10", 44 | "openssl": "1.1.1i-r0", 45 | "pcre": "8.44-r0" 46 | } 47 | }, 48 | { 49 | "name": "nginx", 50 | "version": "1.18.0", 51 | "variant": "", 52 | "arch": "x86_64", 53 | "os": "darwin", 54 | "filename": "nginx-1.18.0-x86_64-darwin", 55 | "date": "2020-10-12T03:01:00Z", 56 | "size": 1324, 57 | "checksum": "sha1:f2f6e3e8e2821ee490cbe133b9647a699ee22d99", 58 | "bundledLibs": { 59 | "njs": "0.5.0", 60 | "ngx_devel_kit": "0.3.1", 61 | "echo-nginx-module": "0.62", 62 | "headers-more-nginx-module": "0.33", 63 | "set-misc-nginx-module": "0.32", 64 | "openssl": "1.1.1i", 65 | "pcre": "8.44", 66 | "zlib": "1.2.11" 67 | } 68 | }, 69 | { 70 | "name": "nginx", 71 | "version": "1.19.5", 72 | "variant": "", 73 | "arch": "x86_64", 74 | "os": "linux", 75 | "filename": "nginx-1.19.5-x86_64-linux", 76 | "date": "2020-12-12T23:45:32Z", 77 | "size": 12832, 78 | "checksum": "sha1:011338ae2cc8c4251d1e238e246f9bf303696ba5", 79 | "bundledLibs": { 80 | "njs": "0.5.0", 81 | "ngx_devel_kit": "0.3.1", 82 | "echo-nginx-module": "0.62", 83 | "headers-more-nginx-module": "0.33", 84 | "set-misc-nginx-module": "0.32", 85 | "gcc": "9.3.0-r2", 86 | "musl": "1.1.24-r10", 87 | "openssl": "1.1.1i-r0", 88 | "pcre": "8.44-r0" 89 | } 90 | }, 91 | { 92 | "name": "nginx", 93 | "version": "1.19.5", 94 | "variant": "", 95 | "arch": "aarch64", 96 | "os": "linux", 97 | "filename": "nginx-1.19.5-aarch64-linux", 98 | "date": "2020-12-12T23:45:32Z", 99 | "size": 1234, 100 | "checksum": "sha1:011338ae2cc8c4251d1e238e246f9bf303696ba5", 101 | "bundledLibs": { 102 | "njs": "0.5.0", 103 | "ngx_devel_kit": "0.3.1", 104 | "echo-nginx-module": "0.62", 105 | "headers-more-nginx-module": "0.33", 106 | "set-misc-nginx-module": "0.32", 107 | "gcc": "9.3.0-r2", 108 | "musl": "1.1.24-r10", 109 | "openssl": "1.1.1i-r0", 110 | "pcre": "8.44-r0" 111 | } 112 | }, 113 | { 114 | "name": "njs", 115 | "version": "0.5.0", 116 | "variant": "debug", 117 | "arch": "x86_64", 118 | "os": "linux", 119 | "filename": "njs-0.5.0-debug-x86_64-linux", 120 | "date": "2020-12-12T21:18:40Z", 121 | "size": 5495976, 122 | "checksum": "sha1:20f957c8266f655047ac18439308bbf72a915ddb", 123 | "bundledLibs": { 124 | "gcc": "9.3.0-r2", 125 | "musl": "1.1.24-r10", 126 | "libedit": "20191231.3.1-r0", 127 | "ncurses": "6.2_p20200523-r0", 128 | "pcre": "8.44-r0" 129 | } 130 | }, 131 | { 132 | "name": "njs", 133 | "version": "0.5.0", 134 | "variant": "", 135 | "arch": "x86_64", 136 | "os": "linux", 137 | "filename": "njs-0.5.0-x86_64-linux", 138 | "date": "2020-12-12T16:26:40Z", 139 | "size": 1305040, 140 | "checksum": "sha1:7336b675b26bd67fdda3db18c66fa7f64691e280", 141 | "bundledLibs": { 142 | "gcc": "9.3.0-r2", 143 | "musl": "1.1.24-r10", 144 | "libedit": "20191231.3.1-r0", 145 | "ncurses": "6.2_p20200523-r0", 146 | "pcre": "8.44-r0" 147 | } 148 | } 149 | ] 150 | } 151 | -------------------------------------------------------------------------------- /integration-tests/fixtures/repo/nginx-1.18.0-x86_64-linux: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jirutka/nginx-binaries/f43e5adfbba6aeed2fc5a59b3938211dfabdad5d/integration-tests/fixtures/repo/nginx-1.18.0-x86_64-linux -------------------------------------------------------------------------------- /integration-tests/fixtures/repo/nginx-1.19.5-x86_64-linux: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jirutka/nginx-binaries/f43e5adfbba6aeed2fc5a59b3938211dfabdad5d/integration-tests/fixtures/repo/nginx-1.19.5-x86_64-linux -------------------------------------------------------------------------------- /integration-tests/helpers/index.ts: -------------------------------------------------------------------------------- 1 | import * as FS from 'node:fs' 2 | import * as http from 'node:http' 3 | import * as OS from 'node:os' 4 | 5 | import * as finalHandler from 'finalhandler' 6 | import * as serveStatic from 'serve-static' 7 | 8 | 9 | export function createStaticServer (root: string, options?: serveStatic.ServeStaticOptions): http.Server { 10 | const serve = serveStatic(root, options) 11 | 12 | return http.createServer((req, res) => { 13 | serve(req, res, finalHandler(req, res) as () => void) 14 | }) 15 | } 16 | 17 | export function isFile (pathname: string): boolean { 18 | try { 19 | return FS.statSync(pathname).isFile() 20 | } catch { 21 | return false 22 | } 23 | } 24 | 25 | export const mktempd = (suffix: string) => FS.mkdtempSync(`${OS.tmpdir()}/${suffix}`) 26 | 27 | export function readJson (filename: string): any { 28 | return JSON.parse(FS.readFileSync(filename, 'utf8')) 29 | } 30 | -------------------------------------------------------------------------------- /integration-tests/index.test.ts: -------------------------------------------------------------------------------- 1 | import * as FS from 'node:fs' 2 | import * as OS from 'node:os' 3 | import { basename } from 'node:path' 4 | 5 | import { assert } from 'chai' 6 | import * as getPort from 'get-port' 7 | import { after, before, test } from 'mocha' 8 | 9 | import { createStaticServer, isFile, readJson } from './helpers' 10 | import { IndexEntry, NginxBinary } from '../src' 11 | import { normalizeArch } from '../src/internal/archName' 12 | import { getCacheDir } from '../src/internal/cacheDir' 13 | 14 | 15 | const fixtureRepoPath = `${__dirname}/fixtures/repo` 16 | const hostOs = OS.platform() 17 | // macOS (darwin) on ARM can run x86_64 binaries. 18 | const hostArch = hostOs === 'darwin' ? 'x86_64' : normalizeArch(OS.arch()) 19 | 20 | const server = createStaticServer(fixtureRepoPath) 21 | 22 | before(async () => { 23 | const host = '127.0.0.1' 24 | const port = await getPort({ host }) 25 | 26 | server.listen(port, host) 27 | 28 | NginxBinary.repoUrl = `http://${host}:${port}/` 29 | }) 30 | 31 | after(() => { 32 | server.close() 33 | FS.rmSync(getCacheDir('nginx-binaries'), { force: true, recursive: true }) 34 | }) 35 | 36 | describe('NginxBinary', () => { 37 | 38 | test('.download', async () => { 39 | const result = await NginxBinary.download({ version: '1.18.0', os: 'linux', arch: 'x86_64' }) 40 | 41 | assert(isFile(result), 'Expected the returned path to be a file.') 42 | 43 | const actualFile = FS.readFileSync(result) 44 | const expectedFile = FS.readFileSync(`${fixtureRepoPath}/${basename(result)}`) 45 | 46 | assert(Buffer.compare(actualFile, expectedFile) === 0, 47 | 'Expected the correct file to be fetched.') 48 | }) 49 | 50 | test('.search', async () => { 51 | const indexJson = readJson(`${fixtureRepoPath}/index.json`).contents as IndexEntry[] 52 | const expected = indexJson 53 | .filter(e => e.name === 'nginx' && e.arch === hostArch && e.os === hostOs) 54 | 55 | assert.sameDeepMembers(await NginxBinary.search({ version: '>=1.18.0' }), expected) 56 | }) 57 | 58 | test('.variants', async () => { 59 | assert.deepEqual(await NginxBinary.variants(), ['']) 60 | }) 61 | 62 | test('.versions', async () => { 63 | assert.deepEqual(await NginxBinary.versions(), ['1.19.5', '1.18.0']) 64 | }) 65 | }) 66 | -------------------------------------------------------------------------------- /nyc.config.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | module.exports = { 4 | all: true, 5 | include: ['src/**/*.ts'], 6 | tempDir: 'node_modules/.cache/nyc_output', 7 | } 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nginx-binaries", 3 | "version": "0.7.0", 4 | "description": "A downloader for nginx and njs standalone binaries.", 5 | "author": "Jakub Jirutka ", 6 | "license": "MIT", 7 | "homepage": "https://github.com/jirutka/nginx-binaries", 8 | "bugs": "https://github.com/jirutka/nginx-binaries/issues", 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/jirutka/nginx-binaries.git" 12 | }, 13 | "keywords": [ 14 | "nginx", 15 | "njs", 16 | "binary", 17 | "binaries", 18 | "static-binaries", 19 | "cross-platform" 20 | ], 21 | "type": "commonjs", 22 | "main": "lib/index.js", 23 | "types": "lib/index.d.ts", 24 | "files": [ 25 | "lib", 26 | "src" 27 | ], 28 | "scripts": { 29 | "build": "tsc -p tsconfig.build.json && rm -f lib/internal/*.d.ts*", 30 | "clean": "rm -rf lib/ node_modules/.cache/", 31 | "lint": "tsc --noEmit", 32 | "prepublishOnly": "yarn build && asciidoctor -b docbook -a npm-readme -a gh-branch=v$npm_package_version -o - README.adoc | pandoc -f docbook -t gfm --shift-heading-level-by 1 --wrap preserve -o README.md", 33 | "test": "nyc mocha" 34 | }, 35 | "engines": { 36 | "node": ">= 14.15.0" 37 | }, 38 | "dependencies": { 39 | "node-fetch": "^2.6.11", 40 | "semver": "^7.3.4" 41 | }, 42 | "devDependencies": { 43 | "@types/chai": "~4.3.5", 44 | "@types/debug": "^4.1.5", 45 | "@types/finalhandler": "~1.2.0", 46 | "@types/mocha": "~10.0.1", 47 | "@types/node": "~18.16.13", 48 | "@types/node-fetch": "~2.6.4", 49 | "@types/proxyquire": "~1.3.28", 50 | "@types/semver": "~7.5.0", 51 | "@types/serve-static": "~1.15.1", 52 | "anylogger": "~1.0.10", 53 | "anylogger-debug": "~1.0.3", 54 | "chai": "~4.3.7", 55 | "debug": "~4.3.1", 56 | "finalhandler": "~1.2.0", 57 | "get-port": "~5.1.1", 58 | "mocha": "~10.2.0", 59 | "nyc": "~15.1.0", 60 | "proxyquire": "~2.1.3", 61 | "serve-static": "~1.15.0", 62 | "ts-mockito": "~2.6.1", 63 | "ts-node": "~10.9.1", 64 | "typescript": "~5.0.4" 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /patches/nginx-1.24.x-avoid-using-openssl-config.patch: -------------------------------------------------------------------------------- 1 | Patch-Source: https://github.com/nginx/nginx/commit/bdea5b703ff6f6fcf98ac8dd4e1e9e5c9ad05017 (backported) 2 | -- 3 | From bdea5b703ff6f6fcf98ac8dd4e1e9e5c9ad05017 Mon Sep 17 00:00:00 2001 4 | From: Maxim Dounin 5 | Date: Wed, 21 Jun 2023 01:29:53 +0300 6 | Subject: [PATCH] SSL: avoid using OpenSSL config in build directory (ticket 7 | #2404). 8 | 9 | With this change, the NGX_OPENSSL_NO_CONFIG macro is defined when nginx 10 | is asked to build OpenSSL itself. And with this macro automatic loading 11 | of OpenSSL configuration (from the build directory) is prevented unless 12 | the OPENSSL_CONF environment variable is explicitly set. 13 | 14 | Note that not loading configuration is broken in OpenSSL 1.1.1 and 1.1.1a 15 | (fixed in OpenSSL 1.1.1b, see https://github.com/openssl/openssl/issues/7350). 16 | If nginx is used to compile these OpenSSL versions, configuring nginx with 17 | NGX_OPENSSL_NO_CONFIG explicitly set to 0 might be used as a workaround. 18 | --- 19 | auto/lib/openssl/conf | 2 ++ 20 | src/event/ngx_event_openssl.c | 22 +++++++++++++++++++++- 21 | 2 files changed, 23 insertions(+), 1 deletion(-) 22 | 23 | diff --git a/auto/lib/openssl/conf b/auto/lib/openssl/conf 24 | index 4fb52df7f..e2ed45d39 100644 25 | --- a/auto/lib/openssl/conf 26 | +++ b/auto/lib/openssl/conf 27 | @@ -11,6 +11,8 @@ if [ $OPENSSL != NONE ]; then 28 | have=NGX_OPENSSL . auto/have 29 | have=NGX_SSL . auto/have 30 | 31 | + have=NGX_OPENSSL_NO_CONFIG . auto/have 32 | + 33 | CFLAGS="$CFLAGS -DNO_SYS_TYPES_H" 34 | 35 | CORE_INCS="$CORE_INCS $OPENSSL/openssl/include" 36 | diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c 37 | index 104e8daf7..100d5908e 100644 38 | --- a/src/event/ngx_event_openssl.c 39 | +++ b/src/event/ngx_event_openssl.c 40 | @@ -145,7 +145,19 @@ ngx_ssl_init(ngx_log_t *log) 41 | { 42 | #if OPENSSL_VERSION_NUMBER >= 0x10100003L 43 | 44 | - if (OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL) == 0) { 45 | + uint64_t opts; 46 | + 47 | + opts = OPENSSL_INIT_LOAD_CONFIG; 48 | + 49 | +#if (NGX_OPENSSL_NO_CONFIG) 50 | + 51 | + if (getenv("OPENSSL_CONF") == NULL) { 52 | + opts = OPENSSL_INIT_NO_LOAD_CONFIG; 53 | + } 54 | + 55 | +#endif 56 | + 57 | + if (OPENSSL_init_ssl(opts, NULL) == 0) { 58 | ngx_ssl_error(NGX_LOG_ALERT, log, 0, "OPENSSL_init_ssl() failed"); 59 | return NGX_ERROR; 60 | } 61 | @@ -159,6 +171,14 @@ ngx_ssl_init(ngx_log_t *log) 62 | 63 | #else 64 | 65 | +#if (NGX_OPENSSL_NO_CONFIG) 66 | + 67 | + if (getenv("OPENSSL_CONF") == NULL) { 68 | + OPENSSL_no_config(); 69 | + } 70 | + 71 | +#endif 72 | + 73 | OPENSSL_config(NULL); 74 | 75 | SSL_library_init(); 76 | -- 77 | 2.43.0 78 | 79 | 80 | -------------------------------------------------------------------------------- /patches/njs-0.7.12-fix-module-build.patch: -------------------------------------------------------------------------------- 1 | Patch-Source: https://github.com/nginx/njs/commit/cd1ac80f692d62dc87d08458a985f4502caec934 2 | -- 3 | From cd1ac80f692d62dc87d08458a985f4502caec934 Mon Sep 17 00:00:00 2001 4 | From: Dmitry Volyntsev 5 | Date: Wed, 10 May 2023 22:36:53 -0700 6 | Subject: [PATCH] Modules: added options to disable parts dependant on 3rd 7 | party libs. 8 | 9 | The following environment variables are added: NJS_OPENSSL, NJS_LIBXSLT, 10 | NJS_ZLIB. When a variable evaluates to "NO" the part of the module 11 | related to the corresponsing library is disabled. 12 | 13 | For example to disable libxslt related code: 14 | NJS_LIBXSLT=NO ./configure .. --add-module=/path/to/njs/module 15 | --- 16 | nginx/config | 43 +++++++++++++++++++++++++++++++++++++------ 17 | nginx/ngx_js.c | 6 ++++++ 18 | 2 files changed, 43 insertions(+), 6 deletions(-) 19 | 20 | diff --git a/nginx/config b/nginx/config 21 | index 58e8cb84c..1bd922f42 100644 22 | --- a/nginx/config 23 | +++ b/nginx/config 24 | @@ -1,13 +1,42 @@ 25 | ngx_addon_name="ngx_js_module" 26 | 27 | +NJS_OPENSSL=${NJS_OPENSSL:-YES} 28 | +NJS_LIBXSLT=${NJS_LIBXSLT:-YES} 29 | +NJS_ZLIB=${NJS_ZLIB:-YES} 30 | + 31 | NJS_DEPS="$ngx_addon_dir/ngx_js.h \ 32 | $ngx_addon_dir/ngx_js_fetch.h" 33 | NJS_SRCS="$ngx_addon_dir/ngx_js.c \ 34 | $ngx_addon_dir/ngx_js_fetch.c \ 35 | - $ngx_addon_dir/ngx_js_regex.c \ 36 | - $ngx_addon_dir/../external/njs_webcrypto_module.c 37 | - $ngx_addon_dir/../external/njs_zlib_module.c 38 | - $ngx_addon_dir/../external/njs_xml_module.c" 39 | + $ngx_addon_dir/ngx_js_regex.c" 40 | + 41 | +NJS_OPENSSL_LIB= 42 | +NJS_XSLT_LIB= 43 | +NJS_ZLIB_LIB= 44 | + 45 | +if [ $NJS_OPENSSL != NO ]; then 46 | + NJS_OPENSSL_LIB=OPENSSL 47 | + have=NJS_HAVE_OPENSSL . auto/have 48 | + NJS_SRCS="$NJS_SRCS $ngx_addon_dir/../external/njs_webcrypto_module.c" 49 | + 50 | + echo " enabled webcrypto module" 51 | +fi 52 | + 53 | +if [ $NJS_LIBXSLT != NO ]; then 54 | + NJS_XSLT_LIB=LIBXSLT 55 | + have=NJS_HAVE_XML . auto/have 56 | + NJS_SRCS="$NJS_SRCS $ngx_addon_dir/../external/njs_xml_module.c" 57 | + 58 | + echo " enabled xml module" 59 | +fi 60 | + 61 | +if [ $NJS_ZLIB != NO ]; then 62 | + NJS_ZLIB_LIB=ZLIB 63 | + have=NJS_HAVE_ZLIB . auto/have 64 | + NJS_SRCS="$NJS_SRCS $ngx_addon_dir/../external/njs_zlib_module.c" 65 | + 66 | + echo " enabled zlib module" 67 | +fi 68 | 69 | if [ $HTTP != NO ]; then 70 | ngx_module_type=HTTP_AUX_FILTER 71 | @@ -15,7 +44,8 @@ if [ $HTTP != NO ]; then 72 | ngx_module_incs="$ngx_addon_dir/../src $ngx_addon_dir/../build" 73 | ngx_module_deps="$ngx_addon_dir/../build/libnjs.a $NJS_DEPS" 74 | ngx_module_srcs="$ngx_addon_dir/ngx_http_js_module.c $NJS_SRCS" 75 | - ngx_module_libs="PCRE OPENSSL ZLIB LIBXSLT $ngx_addon_dir/../build/libnjs.a -lm" 76 | + ngx_module_libs="PCRE $NJS_OPENSSL_LIB $NJS_XSLT_LIB $NJS_ZLIB_LIB \ 77 | + $ngx_addon_dir/../build/libnjs.a -lm" 78 | 79 | . auto/module 80 | 81 | @@ -30,7 +60,8 @@ if [ $STREAM != NO ]; then 82 | ngx_module_incs="$ngx_addon_dir/../src $ngx_addon_dir/../build" 83 | ngx_module_deps="$ngx_addon_dir/../build/libnjs.a $NJS_DEPS" 84 | ngx_module_srcs="$ngx_addon_dir/ngx_stream_js_module.c $NJS_SRCS" 85 | - ngx_module_libs="PCRE OPENSSL ZLIB LIBXSLT $ngx_addon_dir/../build/libnjs.a -lm" 86 | + ngx_module_libs="PCRE $NJS_OPENSSL_LIB $NJS_XSLT_LIB $NJS_ZLIB_LIB \ 87 | + $ngx_addon_dir/../build/libnjs.a -lm" 88 | 89 | . auto/module 90 | fi 91 | diff --git a/nginx/ngx_js.c b/nginx/ngx_js.c 92 | index 2b5be2cee..ed3ea5c26 100644 93 | --- a/nginx/ngx_js.c 94 | +++ b/nginx/ngx_js.c 95 | @@ -88,9 +88,15 @@ static njs_external_t ngx_js_ext_core[] = { 96 | 97 | 98 | njs_module_t *njs_js_addon_modules[] = { 99 | +#ifdef NJS_HAVE_OPENSSL 100 | &njs_webcrypto_module, 101 | +#endif 102 | +#ifdef NJS_HAVE_XML 103 | &njs_xml_module, 104 | +#endif 105 | +#ifdef NJS_HAVE_ZLIB 106 | &njs_zlib_module, 107 | +#endif 108 | NULL, 109 | }; 110 | 111 | -------------------------------------------------------------------------------- /scripts/build-nginx: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -eu 3 | 4 | SCRIPT_DIR="$(dirname "$0")" 5 | 6 | find_srcdir() { 7 | local name=$1 8 | local dir=$(sed -En "s|.* ([^ ]*) ($name)$|\2-\1|p" .SOURCES) 9 | 10 | if ! [ "$dir" ]; then 11 | echo "ERROR: Did not find $name in .SOURCES file!" >&2 12 | elif ! [ -d "$dir" ]; then 13 | echo "ERROR: Directory '$dir' does not exist!" >&2 14 | else 15 | echo "$dir" 16 | return 0 17 | fi 18 | return 1 19 | } 20 | 21 | add_module() { 22 | local dir name 23 | 24 | for name in "$@"; do 25 | dir=$(find_srcdir "${name#*/}") || return 1 26 | 27 | case "$name" in 28 | nginx/njs) dir="$dir/nginx";; 29 | esac 30 | printf -- '--add-module=%s\n' "$dir" 31 | done 32 | } 33 | 34 | configure() { 35 | set -x # log commands 36 | 37 | NJS_LIBXSLT=NO \ 38 | ./auto/configure \ 39 | --prefix="." \ 40 | --sbin-path="nginx" \ 41 | --conf-path="nginx.conf" \ 42 | --pid-path="nginx.pid" \ 43 | --lock-path="nginx.lock" \ 44 | --error-log-path=stderr \ 45 | --http-log-path=access.log \ 46 | --http-client-body-temp-path="client_body_temp" \ 47 | --http-proxy-temp-path="proxy_temp" \ 48 | --user=nobody \ 49 | --group=users \ 50 | --with-cc="${CC:-cc}" \ 51 | --with-cc-opt="${CFLAGS:-}" \ 52 | --with-ld-opt="${LDFLAGS:-}" \ 53 | --with-debug \ 54 | --with-http_ssl_module \ 55 | --with-http_v2_module \ 56 | --with-http_realip_module \ 57 | --with-http_auth_request_module \ 58 | --with-http_secure_link_module \ 59 | --without-http_ssi_module \ 60 | --without-http_mirror_module \ 61 | --without-http_geo_module \ 62 | --without-http_split_clients_module \ 63 | --without-http_fastcgi_module \ 64 | --without-http_uwsgi_module \ 65 | --without-http_scgi_module \ 66 | --without-http_grpc_module \ 67 | --without-http_memcached_module \ 68 | "$@" 69 | 70 | # Don't load openssl.cnf unless the OPENSSL_CONF env. variable is 71 | # explicitly set. This is to avoid SSL error on Fedora due to some 72 | # incompatible settings in /etc/ssl/openssl.cnf (see #17). 73 | cat >> objs/ngx_auto_config.h <<-EOF 74 | 75 | #ifndef NGX_OPENSSL_NO_CONFIG 76 | #define NGX_OPENSSL_NO_CONFIG 1 77 | #endif 78 | EOF 79 | } 80 | 81 | 82 | NGINX_VERSION=$(sed -En 's|.* ([^ ]*) nginx$|\1|p;q' .SOURCES) 83 | HOST_ARCH=$(uname -m) 84 | HOST_OS=$(uname -s | tr '[A-Z]' '[a-z]') 85 | EXEEXT='' 86 | 87 | case "$HOST_OS" in 88 | darwin) alias sha1sum='shasum -a1'; alias sed='gsed';; 89 | mingw*) HOST_OS='win32'; EXEEXT='.exe';; 90 | esac 91 | 92 | uname -a 93 | 94 | module_flags=$(add_module $NGINX_MODULES) 95 | 96 | case "$HOST_OS" in 97 | linux) 98 | configure --with-file-aio --with-threads $module_flags 99 | ;; 100 | darwin) 101 | configure --with-threads $module_flags 102 | ;; 103 | win32) 104 | openssl_dir=$(find_srcdir openssl) 105 | pcre_dir=$(find_srcdir pcre) 106 | zlib_dir=$(find_srcdir zlib) 107 | 108 | configure \ 109 | --with-openssl="$openssl_dir" \ 110 | --with-pcre="$pcre_dir" \ 111 | --with-zlib="$zlib_dir" \ 112 | --with-openssl-opt='no-asm no-tests -D_WIN32_WINNT=0x0501' \ 113 | $module_flags 114 | ;; 115 | esac 116 | 117 | make 118 | 119 | ls -lah objs 120 | strip objs/nginx$EXEEXT 121 | file objs/nginx$EXEEXT 122 | 123 | case "$HOST_OS" in 124 | darwin) otool -L objs/nginx$EXEEXT;; 125 | *) ldd objs/nginx$EXEEXT || true;; 126 | esac 127 | 128 | ./objs/nginx$EXEEXT -V 129 | 130 | if [ -f linker.map ]; then 131 | "$SCRIPT_DIR"/parse-mapfile-loaded-libs linker.map | tee -a .SOURCES 132 | fi 133 | 134 | BIN_NAME="nginx-${NGINX_VERSION}-${HOST_ARCH}-${HOST_OS}${EXEEXT}" 135 | 136 | mkdir -p artifact/ 137 | install objs/nginx$EXEEXT artifact/$BIN_NAME 138 | mv .SOURCES artifact/$BIN_NAME.sources 139 | 140 | cd artifact/ 141 | sha1sum $BIN_NAME > $BIN_NAME.sha1 142 | -------------------------------------------------------------------------------- /scripts/build-njs: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -eu 3 | 4 | SCRIPT_DIR="$(dirname "$0")" 5 | 6 | NJS_VERSION=$(sed -En 's|.* ([^ ]*) njs$|\1|p;q' .SOURCES) 7 | HOST_ARCH=$(uname -m) 8 | HOST_OS=$(uname -s | tr '[A-Z]' '[a-z]') 9 | 10 | case "$HOST_OS" in 11 | darwin) alias sha1sum='shasum -a1'; alias sed='gsed';; 12 | esac 13 | 14 | case "$VARIANT" in 15 | -debug) DEBUG='YES';; 16 | *) DEBUG='NO';; 17 | esac 18 | 19 | case "$NJS_VERSION" in 20 | 0.[5-7].*) NJS_SHELL_C='src/njs_shell.c';; 21 | *) NJS_SHELL_C='external/njs_shell.c';; 22 | esac 23 | 24 | set -x # log commands 25 | 26 | # --no-pcre2 - prefer pcre (8.x) over pcre2 (10.x), it's much smaller 27 | ./configure \ 28 | --cc-opt="$CFLAGS" \ 29 | --ld-opt="${LDFLAGS/-static/}" \ 30 | --no-libxml2 \ 31 | --no-pcre2 \ 32 | --debug="$DEBUG" 33 | NJS_CFLAGS=$(sed -n 's/^NJS_CFLAGS\s*=\s*//p' build/Makefile) 34 | 35 | make libnjs 36 | cc -o build/njs \ 37 | $NJS_CFLAGS $LDFLAGS \ 38 | -Isrc -Ibuild -Injs \ 39 | $NJS_SHELL_C \ 40 | build/libnjs.a \ 41 | -lcrypto -lm -lpcre -ledit -lncursesw -lz 42 | 43 | ls -lah build/ 44 | [ "$DEBUG" = 'YES' ] || strip build/njs 45 | file build/njs 46 | 47 | case "$HOST_OS" in 48 | darwin) otool -L build/njs;; 49 | esac 50 | 51 | ./build/njs -V 52 | 53 | if [ -f linker.map ]; then 54 | "$SCRIPT_DIR"/parse-mapfile-loaded-libs linker.map | tee -a .SOURCES 55 | fi 56 | 57 | BIN_NAME="njs-${NJS_VERSION}${VARIANT}-$HOST_ARCH-$HOST_OS" 58 | 59 | mkdir -p artifact/ 60 | install build/njs artifact/$BIN_NAME 61 | mv .SOURCES artifact/$BIN_NAME.sources 62 | 63 | cd artifact/ 64 | sha1sum $BIN_NAME > $BIN_NAME.sha1 65 | -------------------------------------------------------------------------------- /scripts/common.sh: -------------------------------------------------------------------------------- 1 | case "$(uname -s)" in 2 | Darwin) 3 | filesize() { stat -f %z "$1"; } 4 | checksum() { shasum -a 256 "$1" | cut -d' ' -f1; } 5 | alias sed='gsed' 6 | ;; 7 | *) 8 | filesize() { stat -c %s "$1"; } 9 | checksum() { sha256sum "$1" | cut -d' ' -f1; } 10 | ;; 11 | esac 12 | -------------------------------------------------------------------------------- /scripts/fetch-sources: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -eu 3 | 4 | if ( set -o pipefail 2>/dev/null ); then 5 | set -o pipefail 6 | else 7 | # dash shell (/bin/sh on Ubuntu) does not support pipefail. 8 | exec bash "$0" "$@" 9 | fi 10 | 11 | . "$(dirname "$0")"/common.sh 12 | 13 | 14 | version_mask_to_regex() { 15 | echo "$1" | sed 's/\./\\./g;s/x/[0-9]+/g' 16 | } 17 | 18 | scrape_latest_version() { 19 | local url=$1 20 | local ver_regex=$2 21 | local pattern="s/.*$ver_regex.*/\1/p" 22 | local name=$3 23 | local ver 24 | 25 | if ver=$(curl -fsS --retry 3 "$url" | sed -En "$pattern" | sort -ruV | head -1) && [ "$ver" ]; then 26 | echo "$ver" 27 | else 28 | echo "ERROR: Failed to find $name version matching /$ver_regex/" >&2 29 | return 1 30 | fi 31 | } 32 | 33 | github_latest_version_tag() { 34 | local repo_slug=$1 35 | local ver_regex=$2 36 | local tags_url="https://api.github.com/repos/$repo_slug/tags" 37 | local tag 38 | 39 | local ver_regex_esc=$(printf '%s\n' "$ver_regex" | sed 's/\\/\\\\/g') 40 | local jq_filter_tags=". | map(.name | select(test(\"^$ver_regex_esc$\")))" 41 | local jq_latest='max_by(sub("^[^0-9]+"; "") | split(".") | map(tonumber))' 42 | 43 | if tag=$(github_curl "$tags_url" | jq -er "$jq_filter_tags | $jq_latest") && [ "$tag" ]; then 44 | echo "$tag" 45 | else 46 | echo "ERROR: Failed to find $repo_slug version tag matching /$ver_regex/" >&2 47 | return 1 48 | fi 49 | } 50 | 51 | github_curl() { 52 | # Authenticate GitHub requests to avoid rate limits. 53 | curl -fsS \ 54 | --retry 3 \ 55 | --header 'Accept: application/vnd.github.v3+json' \ 56 | ${GITHUB_TOKEN:+--header "Authorization: Bearer $GITHUB_TOKEN"} \ 57 | "$@" 58 | } 59 | 60 | 61 | DEST_DIR= 62 | case "${1:-}" in 63 | -d) DEST_DIR="$2"; shift 2;; 64 | esac 65 | 66 | if [ $# -lt 1 ] || [ "$1" = '--help' ]; then 67 | echo "Usage: $0 [-d ] [@] [[@]...]" >&2 68 | exit 2 69 | fi 70 | 71 | 72 | for item in "$@"; do 73 | name=${item%@*} 74 | 75 | if [ "$name" = "${item#*@}" ]; then 76 | ver_regex='v?([0-9]+\.)+[0-9]+' 77 | else 78 | ver_regex=$(version_mask_to_regex "${item#*@}") 79 | fi 80 | 81 | case "$name" in 82 | openssl) 83 | tag=$(github_latest_version_tag openssl/openssl 'openssl-([0-9]+\.)+[0-9]+') 84 | ver=$(echo "$tag" | grep -o '[0-9].*') 85 | url="https://github.com/openssl/openssl/releases/download/$tag/${name#*/}-$ver.tar.gz" 86 | ;; 87 | pcre) 88 | base_url='https://sourceforge.net/projects/pcre' 89 | ver=$(scrape_latest_version "$base_url/rss?path=/pcre" "pcre-($ver_regex)\." 'pcre') 90 | url="$base_url/files/$name/$ver/$name-$ver.tar.gz" 91 | ;; 92 | *) 93 | tag=$(github_latest_version_tag "$name" "$ver_regex") 94 | ver=$(echo "$tag" | grep -o '[0-9].*') 95 | url="https://github.com/$name/archive/$tag/${name#*/}-$ver.tar.gz" 96 | ;; 97 | esac 98 | 99 | filename=$(basename "$url") 100 | dir=${DEST_DIR:-${filename%.tar*}} 101 | 102 | echo "Downloading $url" >&2 103 | curl -L --retry 3 -o "$filename" "$url" 104 | 105 | size=$(filesize "$filename") 106 | hash=$(checksum "$filename") 107 | 108 | mkdir -p "$dir" 109 | tar --strip-components=1 -C "$dir" -xf "$filename" 110 | rm "$filename" 111 | 112 | case "$name-$ver" in 113 | nginx/njs-0.7.12) patch --batch -d "$dir" -p1 < master/patches/njs-0.7.12-fix-module-build.patch;; 114 | nginx/nginx-1.24.*) patch --batch -d "$dir" -p1 < master/patches/nginx-1.24.x-avoid-using-openssl-config.patch;; 115 | esac 116 | 117 | echo "$url $size $hash $ver ${name#*/}" | tee -a .SOURCES 118 | done 119 | -------------------------------------------------------------------------------- /scripts/generate-index: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // @ts-check 3 | /** 4 | * @typedef {import('../src/index').IndexEntry} IndexEntry 5 | * @typedef {import('../src/index').IndexFile} IndexFile 6 | * @typedef {IndexEntry[]} Index 7 | */ 8 | const process = require('process') 9 | const fs = require('fs') 10 | const path = require('path') 11 | 12 | /** 13 | * Version of the index file format. 14 | * Keep in sync with FORMAT_VERSION in src/repoIndex.ts! 15 | */ 16 | const FORMAT_VERSION = 2 17 | 18 | /** 19 | * @template T 20 | * @template {Array} K 21 | * @param {T} obj 22 | * @param {K} keys 23 | * @return {Omit} 24 | */ 25 | const omit = (obj, ...keys) => { 26 | // @ts-ignore 27 | return Object.keys(obj).reduce((acc, key) => { 28 | // @ts-ignore 29 | if (!keys.includes(key)) { 30 | acc[key] = obj[key] 31 | } 32 | return acc 33 | }, {}) 34 | } 35 | 36 | /** 37 | * @param {string} filename 38 | * @returns {string} 39 | */ 40 | const readFileSha1 = (filename) => 41 | fs.readFileSync(`${filename}.sha1`, 'utf8').split(' ', 1)[0] 42 | 43 | /** 44 | * @param {string} filename 45 | * @returns {string} 46 | */ 47 | const fileModifiedDate = (filename) => 48 | fs.statSync(filename).mtime.toISOString().slice(0, -5) + 'Z' 49 | 50 | /** 51 | * @param {string | undefined} dest 52 | * @param {string} data 53 | * @returns {void} 54 | */ 55 | const write = (dest, data) => dest 56 | ? fs.writeFileSync(dest, data, { encoding: 'utf-8' }) 57 | : console.log(data) 58 | 59 | /** 60 | * @param {string} filename 61 | * @returns {Omit} 62 | */ 63 | const parseBinaryName = (filename) => { 64 | const [name, version, ...rest] = filename.replace(/\.exe$/, '').split('-') 65 | const [os, arch, ...variant] = rest.reverse() 66 | 67 | return { 68 | name, 69 | version, 70 | variant: variant.join('-'), 71 | // @ts-ignore 72 | arch, 73 | // @ts-ignore 74 | os, 75 | filename, 76 | } 77 | } 78 | 79 | /** 80 | * @param {string} text 81 | */ 82 | const parseSourcesFile = (text) => { 83 | const lines = text.split('\n').filter(Boolean) 84 | 85 | return lines.map(line => { 86 | const fields = line.split(' ') 87 | if (fields.length !== 5) { 88 | throw RangeError(`Expected 5 space-separated fields, but got: '${line}'`) 89 | } 90 | return { 91 | path: fields[0], 92 | size: parseInt(fields[1]), 93 | checksum: fields[2], 94 | version: fields[3], 95 | name: fields[4], 96 | } 97 | }) 98 | } 99 | 100 | /** 101 | * @param {string} sourcesFile 102 | * @param {string} programName 103 | * @returns {Record} 104 | */ 105 | const collectBundledLibs = (sourcesFile, programName) => { 106 | const text = fs.readFileSync(sourcesFile, 'utf8') 107 | 108 | return parseSourcesFile(text).reduce((acc, { name, version }) => { 109 | if (name === programName || name === 'nginx-build-msys2') { 110 | return acc 111 | } 112 | if (acc[name] && acc[name] !== version) { 113 | throw Error(`Found two versions of ${name}: ${acc[name]} and ${version}`) 114 | } 115 | acc[name] = version 116 | return acc 117 | }, {}) 118 | } 119 | 120 | /** 121 | * @returns {Index} 122 | */ 123 | const generateIndex = () => fs.readdirSync('.') 124 | .filter(filename => fs.existsSync(`${filename}.sha1`)) 125 | .map(filename => { 126 | const entry = parseBinaryName(filename) 127 | const checksum = readFileSha1(filename) 128 | return { 129 | ...entry, 130 | date: fileModifiedDate(filename), 131 | size: fs.statSync(filename).size, 132 | checksum: `sha1:${checksum}`, 133 | bundledLibs: collectBundledLibs(`${filename}.sources`, entry.name), 134 | } 135 | }) 136 | 137 | /** 138 | * Merges `oldIndex` and `newIndex`. If both includes entry with the same 139 | * filename and checksum, the old one wins. 140 | * 141 | * @param {Index} oldIndex 142 | * @param {Index} newIndex 143 | * @returns {Index} 144 | */ 145 | const mergeIndexes = (oldIndex, newIndex) => newIndex.reduce((acc, newEntry) => { 146 | const idx = oldIndex.findIndex(entry => entry.filename === newEntry.filename) 147 | if (idx < 0) { 148 | acc.push(newEntry) 149 | } else if (acc[idx].checksum !== newEntry.checksum) { 150 | acc[idx] = newEntry 151 | } 152 | return acc 153 | }, [...oldIndex]) 154 | 155 | /** 156 | * @param {Index} index 157 | * @returns {Index} 158 | */ 159 | const sortIndex = (index) => 160 | index.sort((a, b) => a.filename.localeCompare(b.filename)) 161 | 162 | /** 163 | * @param {Record[]} array 164 | * @returns {string} 165 | */ 166 | const stringifyAsCsv = (array) => { 167 | if (array.length < 1) return '' 168 | 169 | return [ 170 | Object.keys(array[0]).join(','), 171 | ...array.map(item => Object.values(item).join(',')) 172 | ].join('\n') 173 | } 174 | 175 | 176 | const argv = process.argv.slice(2) 177 | 178 | if (argv[0] === '-h' || argv[0] === '--help') { 179 | console.log('Usage: generate-index [--json | --csv] [ []]') 180 | process.exit(0) 181 | } 182 | const format = argv[0] && argv[0].startsWith('--') ? argv.shift().slice(2) : 'json' 183 | const outFile = argv[1] && path.resolve(argv[1]) 184 | if (argv[0]) { 185 | process.chdir(argv[0]) 186 | } 187 | 188 | let index = generateIndex() 189 | if (fs.existsSync('index.json')) { 190 | const indexFile = fs.readFileSync('index.json', 'utf-8') 191 | const oldIndex = JSON.parse(indexFile).contents || [] 192 | 193 | index = mergeIndexes(oldIndex, index) 194 | } 195 | index = sortIndex(index) 196 | 197 | switch (format) { 198 | case 'json': 199 | /** @type {IndexFile} */ 200 | const data = { 201 | formatVersion: FORMAT_VERSION, 202 | contents: index, 203 | } 204 | write(outFile, JSON.stringify(data, null, 2)) 205 | break 206 | case 'csv': 207 | write(outFile, stringifyAsCsv( 208 | index.map(entry => omit(entry, 'bundledLibs')), 209 | )) 210 | break 211 | default: 212 | console.error(`Unsupported format: ${format}`) 213 | process.exit(2) 214 | } 215 | -------------------------------------------------------------------------------- /scripts/parse-mapfile-loaded-libs: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -euo pipefail 3 | 4 | . "$(dirname "$0")"/common.sh 5 | 6 | PROGNAME='parse-mapfile-loaded-libs' 7 | 8 | 9 | report_files() { 10 | local who_owns=$1; shift 11 | local libpath pkgvername size sha 12 | 13 | for libpath in "$@"; do 14 | pkgvername=$($who_owns "$libpath" || echo 'unknown unknown') 15 | size=$(filesize "$libpath") 16 | sha=$(checksum "$libpath") 17 | 18 | # Skip empty archives. 19 | if [ "$size" -eq 8 ] && [ "$(cat "$libpath")" = '!' ]; then 20 | continue 21 | fi 22 | 23 | echo "$libpath $size $sha $pkgvername" 24 | done 25 | } 26 | 27 | gcc_mapfile_load_static() { 28 | grep -E "^LOAD $2$" "$1" | cut -d' ' -f 2 | xargs realpath | sort | uniq 29 | } 30 | 31 | clang_mapfile_load_static() { 32 | # LC_ALL=C - https://stackoverflow.com/a/23584470/2217862 33 | LC_ALL=C sed -En "s|^\[[0-9 ]+\] ($2)\([^)]*\)?\s*$|\1|p" "$1" | sort | uniq 34 | } 35 | 36 | # Prints " " of the package that owns file $1. 37 | apk_who_owns() { 38 | local filepath=$1 39 | local pkgname 40 | local pkgnamever 41 | 42 | pkgname=$(apk info -q --who-owns "$filepath") || return 1 43 | pkgnamever=$(apk search --origin --exact "$pkgname") || return 1 44 | 45 | echo "$pkgnamever" | sed -E 's/^(.*)-(\d[^-]+-r\d+)/\2 \1/' 46 | } 47 | 48 | # Prints " " of the package that owns file $1. 49 | brew_who_owns() { 50 | local filepath=$1 51 | local pkgdir link 52 | 53 | pkgdir=$(brew_find_pkg_root "$filepath") || return 1 54 | link=$(readlink "$pkgdir") || return 1 55 | 56 | # This is really dirty method, but brew doesn't provide any query for files. 57 | echo "$link" | sed -En 's|.*/Cellar/([^@/]+)(@[^/]+)?/([0-9][^ ]*)$|\3 \1|p' 58 | } 59 | 60 | # Prints " " of the package that owns file $1. 61 | pacman_who_owns() { 62 | local filepath="$1" 63 | 64 | pacman --query --owns "$libpath" \ 65 | | sed -En 's|.* is owned by ([^ ]+) ([^ ]+)$|\2 \1|p' \ 66 | | grep . 67 | } 68 | 69 | brew_find_pkg_root() { 70 | local path=$1 71 | local path2 72 | 73 | while true; do 74 | if [ -d "$path"/.brew ]; then 75 | echo "$path" 76 | return 0 77 | fi 78 | path2=${path%/*} 79 | [ "$path2" = "$path" ] && return 1 80 | path=$path2 81 | done 82 | } 83 | 84 | 85 | if [ $# -lt 1 ] || [ "$1" = '--help' ]; then 86 | echo "Usage: $0 []" 87 | exit 2 88 | fi 89 | mapfile=$1 90 | filter=${2:-} 91 | 92 | case "$(uname -s)" in 93 | Darwin) 94 | files=$(clang_mapfile_load_static "$mapfile" "${filter:-"/usr/.*\.a"}") 95 | report_files brew_who_owns $files 96 | ;; 97 | Linux) 98 | files=$(gcc_mapfile_load_static "$mapfile" "${filter:-"/usr/.*\.a"}") 99 | report_files apk_who_owns $files 100 | ;; 101 | MINGW*) 102 | files=$(gcc_mapfile_load_static "$mapfile" "${filter:-"[A-Z]:/.*\.a"}") 103 | report_files pacman_who_owns $files 104 | ;; 105 | *) 106 | echo "$PROGNAME: System '$(uname -s)' is not supported!" >&2 107 | exit 3 108 | ;; 109 | esac 110 | -------------------------------------------------------------------------------- /src/downloader.ts: -------------------------------------------------------------------------------- 1 | import * as OS from 'node:os' 2 | import * as path from 'node:path' 3 | 4 | import { formatQuery, getIndex, queryIndex, FORMAT_VERSION, IndexEntry, Query } from './repoIndex' 5 | import { normalizeArch } from './internal/archName' 6 | import { getCacheDir } from './internal/cacheDir' 7 | import { downloadFile } from './internal/downloadFile' 8 | import { bindAll, replaceProperty } from './internal/utils' 9 | 10 | 11 | const defaultQuery: Omit, 'version'> = { 12 | // macOS (darwin) on ARM can run x86_64 binaries. 13 | arch: OS.platform() === 'darwin' ? 'x86_64' : normalizeArch(OS.arch()) as any, 14 | os: OS.platform() as any, 15 | variant: '', 16 | } 17 | 18 | // NOTE: Keep in sync with API section in README.adoc (until I figure out how to generate it). 19 | export interface Downloader { 20 | /** 21 | * Path to the cache directory where the repository index and binaries are stored. 22 | * 23 | * Defaults to `.cache/nginx-binaries/` relative to the nearest writable `node_modules` 24 | * (nearest to `process.cwd()`) or `nginx-binaries/` in the system-preferred temp 25 | * directory. 26 | */ 27 | cacheDir: string 28 | /** 29 | * Maximum age in minutes for the cached repository index in `cacheDir` to be 30 | * considered fresh. If the cached index is stale, the Downloader tries to refresh 31 | * it before reading. 32 | * 33 | * @default 480 (8 hours) 34 | */ 35 | cacheMaxAge: number 36 | /** 37 | * URL of the repository with binaries. 38 | * 39 | * **Caution:** After changing `repoUrl`, you should delete old `index.json` in 40 | * `cacheDir` or disable index cache by setting `cacheMaxAge` to `0`. 41 | * 42 | * @default 'https://jirutka.github.io/nginx-binaries' 43 | */ 44 | repoUrl: string 45 | /** 46 | * Fetch response timeout in milliseconds. 47 | * 48 | * @default 10000 49 | */ 50 | timeout: number 51 | /** 52 | * Downloads a binary specified by `query` and stores it in the `cacheDir` or 53 | * in `destFilePath`, if provided. Returns path to the file. 54 | * 55 | * If the file already exists and the checksums match, it just returns its path. 56 | * 57 | * If multiple versions satisfies the version range, the one with highest 58 | * version number is selected. 59 | * 60 | * @param query A query that specifies what binary to download. 61 | * @param destFilePath An optional file path where to write the downloaded binary. 62 | * @return Path to the downloaded binary on the filesystem. 63 | * @throws {RangeError} if no matching binary is found. 64 | */ 65 | download: (query: Query, destFilePath?: string) => Promise 66 | /** 67 | * Returns metadata of available binaries that match the query. 68 | */ 69 | search: (query: Query) => Promise 70 | /** 71 | * Returns all the available variants matching the query. 72 | */ 73 | variants: (query?: Query) => Promise 74 | /** 75 | * Returns all the available versions matching the query. 76 | */ 77 | versions: (query?: Query) => Promise 78 | } 79 | 80 | export const createDownloader = (name: string): Downloader => bindAll({ 81 | cacheMaxAge: 8 * 60, // minutes 82 | repoUrl: 'https://jirutka.github.io/nginx-binaries', 83 | timeout: 10_000, // milliseconds 84 | 85 | get cacheDir () { 86 | // Replace accessors with plain value (lazy initialization). 87 | return replaceProperty(this, 'cacheDir', getCacheDir('nginx-binaries')) 88 | }, 89 | set cacheDir (dirpath) { 90 | this.cacheDir &&= dirpath 91 | }, 92 | 93 | async download (query, destFilePath) { 94 | const [entry, ] = await this.search(query) 95 | if (!entry) { 96 | throw RangeError(`No ${name} binary found for ${formatQuery({ ...defaultQuery, ...query })}`) 97 | } 98 | destFilePath ??= path.join(this.cacheDir, entry.filename) 99 | const url = `${this.repoUrl}/${entry.filename}` 100 | 101 | return await downloadFile(url, entry.checksum, destFilePath, { timeout: this.timeout }) 102 | }, 103 | 104 | async search (query) { 105 | const index = await getIndex(this.repoUrl, this.cacheDir, this.timeout, this.cacheMaxAge) 106 | // TODO: Move to getIndex() 107 | if (index.formatVersion !== FORMAT_VERSION) { 108 | throw Error(`Index format version mismatch, clean cache and update nginx-binaries package`) 109 | } 110 | return queryIndex(index, name, { ...defaultQuery, ...query }) 111 | }, 112 | 113 | async variants (query) { 114 | return [...new Set((await this.search(query ?? {})).map(x => x.variant))] 115 | }, 116 | 117 | async versions (query) { 118 | return [...new Set((await this.search(query ?? {})).map(x => x.version))] 119 | }, 120 | }) 121 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { createDownloader } from './downloader' 2 | 3 | export type { Downloader } from './downloader' 4 | export type { IndexEntry, IndexFile } from './repoIndex' 5 | export { setLogger } from './logger' 6 | 7 | /** 8 | * Creates a Fetcher that provides **nginx** binary. 9 | */ 10 | export const NginxBinary = createDownloader('nginx') 11 | 12 | /** 13 | * Creates a Fetcher that provides **njs** binary. 14 | */ 15 | export const NjsBinary = createDownloader('njs') 16 | -------------------------------------------------------------------------------- /src/internal/archName.ts: -------------------------------------------------------------------------------- 1 | 2 | const mapping = { 3 | arm: 'armv7', 4 | arm64: 'aarch64', 5 | x32: 'x86', 6 | x64: 'x86_64', 7 | } as Record 8 | 9 | /** 10 | * Normalizes the given architecture name to an Alpine architecture name. 11 | */ 12 | export const normalizeArch = (arch: string): string => mapping[arch] || arch 13 | -------------------------------------------------------------------------------- /src/internal/cacheDir.ts: -------------------------------------------------------------------------------- 1 | import * as FS from 'node:fs' 2 | import * as OS from 'node:os' 3 | import * as path from 'node:path' 4 | 5 | 6 | export function getCacheDir (name: string): string { 7 | const nodeModules = findPkgNodeModules(process.cwd()) 8 | 9 | return nodeModules 10 | ? path.join(nodeModules, '.cache', name) 11 | : path.join(OS.tmpdir(), name) 12 | } 13 | 14 | function findPkgNodeModules (cwd: string): string | null { 15 | let dir = path.resolve(cwd) 16 | const rootDir = path.parse(dir).root 17 | 18 | while (dir !== rootDir) { 19 | const nodeModules = path.join(dir, 'node_modules') 20 | if (isWritableDir(nodeModules)) { 21 | return nodeModules 22 | } 23 | dir = path.dirname(dir) 24 | } 25 | return null 26 | } 27 | 28 | function isWritableDir (path: string): boolean { 29 | try { 30 | if (!FS.statSync(path).isDirectory()) { 31 | return false 32 | } 33 | FS.accessSync(path, FS.constants.W_OK) 34 | return true 35 | } catch { 36 | return false 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/internal/downloadFile.ts: -------------------------------------------------------------------------------- 1 | import * as crypto from 'node:crypto' 2 | import { createReadStream, createWriteStream, mkdirSync as mkdir } from 'node:fs' 3 | import { basename, dirname } from 'node:path' 4 | import * as stream from 'node:stream' 5 | import { promisify } from 'node:util' 6 | 7 | import { RequestInit } from 'node-fetch' 8 | 9 | import { fetch } from './fetch' 10 | import { log } from '../logger' 11 | 12 | 13 | const streamPipeline = promisify(stream.pipeline) 14 | 15 | export async function downloadFile ( 16 | url: string, 17 | checksum: string, 18 | filepath: string, 19 | fetchOpts?: RequestInit, 20 | ): Promise { 21 | 22 | if (await checkFileChecksum(filepath, checksum)) { 23 | log.debug(`File ${filepath} already exists`) 24 | return filepath 25 | } 26 | 27 | const [hashAlg, expectedHash] = splitChecksumValue(checksum) 28 | const hash = crypto.createHash(hashAlg) 29 | 30 | log.info(`Downloading ${url}...`) 31 | 32 | mkdir(dirname(filepath), { recursive: true }) 33 | 34 | const resp = await fetch(url, fetchOpts) 35 | 36 | await streamPipeline( 37 | resp.body.on('data', chunk => hash.update(chunk)), 38 | createWriteStream(filepath, { flags: 'w', mode: 0o0755 }), 39 | ) 40 | 41 | if (hash.digest('hex') !== expectedHash) { 42 | throw Error(`File ${basename(filepath)} is corrupted, ${hashAlg} checksum doesn't match!`) 43 | } 44 | log.debug(`File was saved in ${filepath}`) 45 | 46 | return filepath 47 | } 48 | 49 | async function checkFileChecksum (filepath: string, checksum: string): Promise { 50 | const [hashAlg, expectedHash] = splitChecksumValue(checksum) 51 | const hash = crypto.createHash(hashAlg) 52 | 53 | try { 54 | await streamPipeline(createReadStream(filepath), hash) 55 | return hash.digest('hex') === expectedHash 56 | 57 | } catch (err: any) { 58 | if (err.code === 'ENOENT' || err.code === 'EISDIR') { 59 | return false 60 | } 61 | throw err 62 | } 63 | } 64 | 65 | function splitChecksumValue (checksum: string): [algorithm: string, value: string] { 66 | const [alg, value] = checksum.split(':', 2) 67 | if (!alg || !value) { 68 | throw RangeError(`Invalid checksum value: ${checksum}`) 69 | } 70 | return [alg, value] 71 | } 72 | -------------------------------------------------------------------------------- /src/internal/fetch.ts: -------------------------------------------------------------------------------- 1 | import nodeFetch, { FetchError, RequestInfo, RequestInit, Response } from 'node-fetch' 2 | 3 | 4 | export async function fetch (url: RequestInfo, init?: RequestInit): Promise { 5 | const resp = await nodeFetch(url, init) 6 | if (resp.status !== 200) { 7 | throw new FetchError( 8 | `Unexpected response for ${url}: ${resp.status} ${resp.statusText}`, 9 | 'invalid-response', 10 | ) 11 | } 12 | return resp 13 | } 14 | 15 | export async function fetchJson (url: string, opts: RequestInit): Promise { 16 | const resp = await fetch(url, opts) 17 | return await resp.json() 18 | } 19 | -------------------------------------------------------------------------------- /src/internal/utils.ts: -------------------------------------------------------------------------------- 1 | 2 | export function bindAll (obj: T): T { 3 | for (const propName of Object.getOwnPropertyNames(obj)) { 4 | const desc = Object.getOwnPropertyDescriptor(obj, propName)! 5 | 6 | if (typeof desc.value === 'function') { 7 | desc.value = desc.value.bind(obj) 8 | Object.defineProperty(obj, propName, desc) 9 | } 10 | } 11 | return obj 12 | } 13 | 14 | export function replaceProperty (obj: T, propName: K, value: T[K]): T[K] { 15 | delete obj[propName] 16 | obj[propName] = value 17 | 18 | return value 19 | } 20 | -------------------------------------------------------------------------------- /src/logger.test.ts: -------------------------------------------------------------------------------- 1 | import { strict as assert } from 'node:assert' 2 | 3 | import type AnyLoggerModule from 'anylogger' 4 | import debug from 'debug' 5 | import { beforeEach, describe, test } from 'mocha' 6 | import * as proxyquire from 'proxyquire' 7 | import { reset, spy, verify } from 'ts-mockito' 8 | 9 | import type * as LoggerModule from './logger' 10 | 11 | 12 | type AnyLogger = typeof AnyLoggerModule 13 | type LoggerModule = typeof LoggerModule 14 | 15 | const logLevels = ['debug', 'info', 'warn', 'error'] as const 16 | 17 | describe('logger', () => { 18 | let consoleSpy: typeof console 19 | 20 | beforeEach(() => { 21 | consoleSpy = spy(console) 22 | }) 23 | afterEach(() => { 24 | reset(consoleSpy) 25 | }) 26 | 27 | const usesConsoleLogger = ({ log, __testing: { loggerName, noop }}: LoggerModule) => { 28 | test('maps debug level to no-op, others to console[level]', () => { 29 | for (const level of logLevels.slice(1)) { 30 | log[level]('foo', 'bar') 31 | verify(consoleSpy[level](`${loggerName}:`, 'foo', 'bar')).once() 32 | } 33 | assert(log.debug === noop) 34 | }) 35 | } 36 | 37 | const usesConsoleAndDebugLogger = ({ log, __testing: { loggerName }}: LoggerModule) => { 38 | test('maps debug level to the debug logger, others to console[level]', () => { 39 | for (const level of logLevels.slice(1)) { 40 | log[level]('foo', 'bar') 41 | verify(consoleSpy[level](`${loggerName}:`, 'foo', 'bar')).once() 42 | } 43 | 44 | assert((log.debug as debug.Debugger).extend === debug(loggerName).extend, 45 | 'Expected log.debug to be from the debug library.') 46 | 47 | assert((log.debug as debug.Debugger).namespace === loggerName) 48 | }) 49 | } 50 | 51 | describe('when anylogger is available', () => { 52 | 53 | describe('but no adapter is loaded', () => { 54 | const loggerModule = proxyquire('./logger', { 55 | anylogger: proxyquire('anylogger', {}), 56 | debug: null, 57 | }) 58 | usesConsoleLogger(loggerModule) 59 | }) 60 | 61 | describe('and has adapter', () => { 62 | test('maps all levels to anylogger', () => { 63 | const anylogger = proxyquire('anylogger', {}) 64 | proxyquire('anylogger-debug', { anylogger }) 65 | 66 | const { log, __testing: { loggerName } } = proxyquire('./logger', { 67 | anylogger, 68 | debug: null, 69 | }) 70 | const loggerSpy = spy(anylogger(loggerName)) 71 | 72 | for (const level of logLevels) { 73 | log[level]('foo', 'bar') 74 | verify(loggerSpy[level]('foo', 'bar')).once() 75 | } 76 | }) 77 | }) 78 | }) 79 | 80 | describe('when anylogger is not available', () => { 81 | 82 | describe('and debug library is available', () => { 83 | const loggerModule = proxyquire('./logger', { 84 | anylogger: null, 85 | }) 86 | usesConsoleAndDebugLogger(loggerModule) 87 | }) 88 | 89 | describe('and debug library is not available', () => { 90 | const loggerModule = proxyquire('./logger', { 91 | anylogger: null, 92 | debug: null, 93 | }) 94 | usesConsoleLogger(loggerModule) 95 | }) 96 | }) 97 | }) 98 | 99 | test('setLogger', () => { 100 | const { log, setLogger, __testing: { noop } } = proxyquire('./logger', {}) 101 | 102 | const logger = { 103 | warn: () => void 0, 104 | error: () => void 0, 105 | } 106 | setLogger(logger) 107 | 108 | for (const level of logLevels) { 109 | assert(log[level] === (logger as any)[level] || noop, 110 | `Expected log.${level} to be the provided logging function or no-op if not provided.`) 111 | } 112 | }) 113 | -------------------------------------------------------------------------------- /src/logger.ts: -------------------------------------------------------------------------------- 1 | import type { BaseLogger as AnyLogger } from 'anylogger' 2 | import type { Debugger } from 'debug' 3 | 4 | 5 | const loggerName = 'nginx-binaries' 6 | const logLevels = ['debug', 'info', 'warn', 'error'] as const 7 | 8 | type Logger = Pick 9 | 10 | const noop = () => void 0 11 | 12 | /** @internal */ 13 | // Initialized in `initialize()`. 14 | export const log = {} as Logger 15 | 16 | /** 17 | * Use the given logger. Undefined logging functions will be replaced with no-op. 18 | */ 19 | export function setLogger (logger: Partial) { 20 | for (const level of logLevels) { 21 | log[level] = logger[level] || noop 22 | } 23 | } 24 | 25 | // NOTE: We cannot use dynamic `import()` because we don't have guarantee that 26 | // it will be invoked *before* `setLogger` called from the application code. 27 | (function initialize () { 28 | try { 29 | const anylogger = require('anylogger')(loggerName) as AnyLogger 30 | if (anylogger.enabledFor('error') != null) { 31 | for (const level of logLevels) { 32 | log[level] = (...args: any[]) => anylogger[level](...args) 33 | } 34 | return 35 | } 36 | } catch {} 37 | 38 | for (const level of logLevels) { 39 | log[level] = (...args: any[]) => console[level](`${loggerName}:`, ...args) 40 | } 41 | try { 42 | log.debug = require('debug')(loggerName) as Debugger 43 | } catch { 44 | log.debug = noop 45 | } 46 | })() 47 | 48 | 49 | /** @internal */ 50 | export const __testing = { loggerName, logLevels, noop } 51 | -------------------------------------------------------------------------------- /src/repoIndex.ts: -------------------------------------------------------------------------------- 1 | import * as FS from 'node:fs' 2 | import * as path from 'node:path' 3 | 4 | import { FetchError } from 'node-fetch' 5 | import * as semver from 'semver' 6 | 7 | import { normalizeArch } from './internal/archName' 8 | import { fetchJson } from './internal/fetch' 9 | import { log } from './logger' 10 | 11 | 12 | /** 13 | * Expected version of the index file. 14 | * Keep in sync with FORMAT_VERSION in scripts/generate-index! 15 | */ 16 | export const FORMAT_VERSION = 2 17 | 18 | export interface IndexFile { 19 | formatVersion: number 20 | contents: IndexEntry[] 21 | } 22 | 23 | // NOTE: Keep in sync with API section in README.adoc (until I figure out how to generate it). 24 | export interface IndexEntry { 25 | /** 26 | * Name of the program (`nginx` or `njs`). 27 | */ 28 | name: string 29 | /** 30 | * Version of the program. 31 | */ 32 | version: string 33 | /** 34 | * The build variant of the binary (e.g. `debug`). 35 | * An empty string indicates the default variant. 36 | */ 37 | variant: string 38 | /** 39 | * OS platform for which this binary was built. 40 | */ 41 | os: Platform 42 | /** 43 | * CPU architecture for which this binary was built. 44 | */ 45 | arch: Arch 46 | /** 47 | * Full name of the binary file. 48 | */ 49 | filename: string 50 | /** 51 | * Date and time (ISO-8601) at which the binary was built. 52 | */ 53 | date: string 54 | /** 55 | * Size of the binary file in bytes. 56 | */ 57 | size: number 58 | /** 59 | * Checksum of the binary file in format `:`. 60 | * 61 | * @example 'sha1:7336b675b26bd67fdda3db18c66fa7f64691e280' 62 | */ 63 | checksum: string 64 | /** 65 | * A record of all libraries (or modules) statically linked into the binary 66 | * and the version number. 67 | * 68 | * @example 69 | * { 70 | * 'openssl': '1.1.1i-r0', 71 | * 'echo-nginx-module': '0.62', 72 | * } 73 | */ 74 | bundledLibs: Record 75 | } 76 | 77 | type Platform = 'linux' | 'darwin' | 'win32' 78 | type Arch = 'armv7' | 'arm' | 'aarch64' | 'arm64' | 'ppc64le' | 'x86_64' | 'x64' 79 | 80 | // NOTE: Keep in sync with API section in README.adoc (until I figure out how to generate it). 81 | export interface Query { 82 | /** 83 | * Specify required version as exact version number or a SemVer version range. 84 | * 85 | * @example '1.8.0', '1.8.x', '^1.8.0' 86 | * @see https://github.com/npm/node-semver#ranges 87 | */ 88 | version?: string 89 | /** 90 | * Specify build variant of the binary (e.g. `debug`). 91 | * Defaults to an empty string, i.e. the default variant. 92 | */ 93 | variant?: string 94 | /** 95 | * Specify target OS. Defaults to the host OS. 96 | */ 97 | os?: Platform 98 | /** 99 | * Specify target CPU architecture. Defaults to the host architecture. 100 | */ 101 | arch?: Arch 102 | } 103 | 104 | export async function getIndex ( 105 | repoUrl: string, 106 | cacheDir: string, 107 | fetchTimeout: number, 108 | cacheMaxAge: number, 109 | ): Promise { 110 | const cachedIndexPath = path.join(cacheDir, 'index.json') 111 | 112 | const readCachedIndex = () => JSON.parse(FS.readFileSync(cachedIndexPath, 'utf8')) as IndexFile 113 | 114 | let isCached = false 115 | try { 116 | if (Date.now() - FS.statSync(cachedIndexPath).mtimeMs < cacheMaxAge * 60_000) { 117 | log.debug(`Using cached index ${cachedIndexPath}`) 118 | return readCachedIndex() 119 | } 120 | isCached = true 121 | } catch { 122 | // ignore 123 | } 124 | try { 125 | log.debug(`Fetching ${repoUrl}/index.json`) 126 | 127 | const index = await fetchJson(`${repoUrl}/index.json`, { timeout: fetchTimeout }) as IndexFile 128 | 129 | FS.mkdirSync(cacheDir, { recursive: true }) 130 | FS.writeFileSync(cachedIndexPath, JSON.stringify(index, null, 2)) 131 | 132 | return index 133 | 134 | } catch (err) { 135 | if (isCached && err instanceof FetchError && err.type === 'system') { 136 | log.warn('Failed to refresh repository index, using stale index') 137 | return readCachedIndex() 138 | } 139 | throw err 140 | } 141 | } 142 | 143 | export function queryIndex (index: IndexFile, name: string, query: Query): IndexEntry[] { 144 | log.debug(`Looking for ${name} binary matching ${formatQuery(query)}`) 145 | 146 | return index.contents 147 | .filter(x => x.name === name) 148 | .filter(queryFilter(query)) 149 | .sort((a, b) => semver.rcompare(a.version, b.version)) 150 | } 151 | 152 | export const formatQuery = (query: Query) => JSON.stringify(query) 153 | .replace(/"/g, '') 154 | .replace(/,/g, ', ') 155 | .replace(/:/g, ': ') 156 | 157 | const queryFilter = (query: Query) => (meta: IndexEntry) => objKeys(query).every(key => { 158 | return query[key] === undefined ? false 159 | : key === 'version' ? semver.satisfies(meta[key], query[key]!) 160 | : key === 'arch' ? normalizeArch(query[key]!) === meta[key] 161 | : query[key] === meta[key] 162 | }) 163 | 164 | const objKeys = (obj: T) => Object.keys(obj) as Array 165 | -------------------------------------------------------------------------------- /tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "include": [ 4 | "src/", 5 | ], 6 | "exclude": [ 7 | "**/*.test.ts", 8 | ], 9 | } 10 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig to read more about this file */ 4 | 5 | /* Projects */ 6 | // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ 7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 | // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ 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": "ES2020", /* 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 legacy experimental 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 | // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ 26 | 27 | /* Modules */ 28 | "module": "commonjs", /* Specify what module code is generated. */ 29 | // "rootDir": "./", /* Specify the root folder within your source files. */ 30 | // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ 31 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 32 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 33 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 34 | // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ 35 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 36 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 37 | // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ 38 | // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ 39 | // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ 40 | // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ 41 | // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ 42 | // "resolveJsonModule": true, /* Enable importing .json files. */ 43 | // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ 44 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ 45 | 46 | /* JavaScript Support */ 47 | "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ 48 | "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 49 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ 50 | 51 | /* Emit */ 52 | "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 53 | "declarationMap": true, /* Create sourcemaps for d.ts files. */ 54 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 55 | "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 56 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 57 | // "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. */ 58 | "outDir": "./lib", /* Specify an output folder for all emitted files. */ 59 | // "removeComments": true, /* Disable emitting comments. */ 60 | // "noEmit": true, /* Disable emitting files from a compilation. */ 61 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 62 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ 63 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 64 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 65 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 66 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 67 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 68 | "newLine": "lf", /* Set the newline character for emitting files. */ 69 | "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ 70 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ 71 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 72 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ 73 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 74 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 75 | 76 | /* Interop Constraints */ 77 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 78 | // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ 79 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 80 | // "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ 81 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 82 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 83 | 84 | /* Type Checking */ 85 | "strict": true, /* Enable all strict type-checking options. */ 86 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ 87 | // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ 88 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 89 | // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ 90 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 91 | // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ 92 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ 93 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 94 | "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ 95 | "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ 96 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 97 | "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 98 | "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 99 | "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ 100 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 101 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ 102 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 103 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 104 | 105 | /* Completeness */ 106 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 107 | "skipLibCheck": true, /* Skip type checking all .d.ts files. */ 108 | }, 109 | "exclude": [ 110 | "lib/", 111 | "node_modules/", 112 | ], 113 | } 114 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@ampproject/remapping@^2.2.0": 6 | version "2.2.1" 7 | resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" 8 | integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== 9 | dependencies: 10 | "@jridgewell/gen-mapping" "^0.3.0" 11 | "@jridgewell/trace-mapping" "^0.3.9" 12 | 13 | "@babel/code-frame@^7.22.10", "@babel/code-frame@^7.22.5": 14 | version "7.22.10" 15 | resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.10.tgz#1c20e612b768fefa75f6e90d6ecb86329247f0a3" 16 | integrity sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA== 17 | dependencies: 18 | "@babel/highlight" "^7.22.10" 19 | chalk "^2.4.2" 20 | 21 | "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.23.5": 22 | version "7.23.5" 23 | resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.23.5.tgz#9009b69a8c602293476ad598ff53e4562e15c244" 24 | integrity sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA== 25 | dependencies: 26 | "@babel/highlight" "^7.23.4" 27 | chalk "^2.4.2" 28 | 29 | "@babel/compat-data@^7.22.9": 30 | version "7.22.9" 31 | resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.9.tgz#71cdb00a1ce3a329ce4cbec3a44f9fef35669730" 32 | integrity sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ== 33 | 34 | "@babel/core@^7.7.5": 35 | version "7.22.10" 36 | resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.10.tgz#aad442c7bcd1582252cb4576747ace35bc122f35" 37 | integrity sha512-fTmqbbUBAwCcre6zPzNngvsI0aNrPZe77AeqvDxWM9Nm+04RrJ3CAmGHA9f7lJQY6ZMhRztNemy4uslDxTX4Qw== 38 | dependencies: 39 | "@ampproject/remapping" "^2.2.0" 40 | "@babel/code-frame" "^7.22.10" 41 | "@babel/generator" "^7.22.10" 42 | "@babel/helper-compilation-targets" "^7.22.10" 43 | "@babel/helper-module-transforms" "^7.22.9" 44 | "@babel/helpers" "^7.22.10" 45 | "@babel/parser" "^7.22.10" 46 | "@babel/template" "^7.22.5" 47 | "@babel/traverse" "^7.22.10" 48 | "@babel/types" "^7.22.10" 49 | convert-source-map "^1.7.0" 50 | debug "^4.1.0" 51 | gensync "^1.0.0-beta.2" 52 | json5 "^2.2.2" 53 | semver "^6.3.1" 54 | 55 | "@babel/generator@^7.22.10": 56 | version "7.22.10" 57 | resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.10.tgz#c92254361f398e160645ac58831069707382b722" 58 | integrity sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A== 59 | dependencies: 60 | "@babel/types" "^7.22.10" 61 | "@jridgewell/gen-mapping" "^0.3.2" 62 | "@jridgewell/trace-mapping" "^0.3.17" 63 | jsesc "^2.5.1" 64 | 65 | "@babel/generator@^7.23.6": 66 | version "7.23.6" 67 | resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.6.tgz#9e1fca4811c77a10580d17d26b57b036133f3c2e" 68 | integrity sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw== 69 | dependencies: 70 | "@babel/types" "^7.23.6" 71 | "@jridgewell/gen-mapping" "^0.3.2" 72 | "@jridgewell/trace-mapping" "^0.3.17" 73 | jsesc "^2.5.1" 74 | 75 | "@babel/helper-compilation-targets@^7.22.10": 76 | version "7.22.10" 77 | resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz#01d648bbc25dd88f513d862ee0df27b7d4e67024" 78 | integrity sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q== 79 | dependencies: 80 | "@babel/compat-data" "^7.22.9" 81 | "@babel/helper-validator-option" "^7.22.5" 82 | browserslist "^4.21.9" 83 | lru-cache "^5.1.1" 84 | semver "^6.3.1" 85 | 86 | "@babel/helper-environment-visitor@^7.22.20": 87 | version "7.22.20" 88 | resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" 89 | integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== 90 | 91 | "@babel/helper-environment-visitor@^7.22.5": 92 | version "7.22.5" 93 | resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz#f06dd41b7c1f44e1f8da6c4055b41ab3a09a7e98" 94 | integrity sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q== 95 | 96 | "@babel/helper-function-name@^7.23.0": 97 | version "7.23.0" 98 | resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" 99 | integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== 100 | dependencies: 101 | "@babel/template" "^7.22.15" 102 | "@babel/types" "^7.23.0" 103 | 104 | "@babel/helper-hoist-variables@^7.22.5": 105 | version "7.22.5" 106 | resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" 107 | integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== 108 | dependencies: 109 | "@babel/types" "^7.22.5" 110 | 111 | "@babel/helper-module-imports@^7.22.5": 112 | version "7.22.5" 113 | resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz#1a8f4c9f4027d23f520bd76b364d44434a72660c" 114 | integrity sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg== 115 | dependencies: 116 | "@babel/types" "^7.22.5" 117 | 118 | "@babel/helper-module-transforms@^7.22.9": 119 | version "7.22.9" 120 | resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz#92dfcb1fbbb2bc62529024f72d942a8c97142129" 121 | integrity sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ== 122 | dependencies: 123 | "@babel/helper-environment-visitor" "^7.22.5" 124 | "@babel/helper-module-imports" "^7.22.5" 125 | "@babel/helper-simple-access" "^7.22.5" 126 | "@babel/helper-split-export-declaration" "^7.22.6" 127 | "@babel/helper-validator-identifier" "^7.22.5" 128 | 129 | "@babel/helper-simple-access@^7.22.5": 130 | version "7.22.5" 131 | resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" 132 | integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== 133 | dependencies: 134 | "@babel/types" "^7.22.5" 135 | 136 | "@babel/helper-split-export-declaration@^7.22.6": 137 | version "7.22.6" 138 | resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" 139 | integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== 140 | dependencies: 141 | "@babel/types" "^7.22.5" 142 | 143 | "@babel/helper-string-parser@^7.22.5": 144 | version "7.22.5" 145 | resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" 146 | integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== 147 | 148 | "@babel/helper-string-parser@^7.23.4": 149 | version "7.23.4" 150 | resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz#9478c707febcbbe1ddb38a3d91a2e054ae622d83" 151 | integrity sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ== 152 | 153 | "@babel/helper-validator-identifier@^7.22.20": 154 | version "7.22.20" 155 | resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" 156 | integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== 157 | 158 | "@babel/helper-validator-identifier@^7.22.5": 159 | version "7.22.5" 160 | resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193" 161 | integrity sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ== 162 | 163 | "@babel/helper-validator-option@^7.22.5": 164 | version "7.22.5" 165 | resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz#de52000a15a177413c8234fa3a8af4ee8102d0ac" 166 | integrity sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw== 167 | 168 | "@babel/helpers@^7.22.10": 169 | version "7.22.10" 170 | resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.22.10.tgz#ae6005c539dfbcb5cd71fb51bfc8a52ba63bc37a" 171 | integrity sha512-a41J4NW8HyZa1I1vAndrraTlPZ/eZoga2ZgS7fEr0tZJGVU4xqdE80CEm0CcNjha5EZ8fTBYLKHF0kqDUuAwQw== 172 | dependencies: 173 | "@babel/template" "^7.22.5" 174 | "@babel/traverse" "^7.22.10" 175 | "@babel/types" "^7.22.10" 176 | 177 | "@babel/highlight@^7.22.10": 178 | version "7.22.10" 179 | resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.10.tgz#02a3f6d8c1cb4521b2fd0ab0da8f4739936137d7" 180 | integrity sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ== 181 | dependencies: 182 | "@babel/helper-validator-identifier" "^7.22.5" 183 | chalk "^2.4.2" 184 | js-tokens "^4.0.0" 185 | 186 | "@babel/highlight@^7.23.4": 187 | version "7.23.4" 188 | resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.23.4.tgz#edaadf4d8232e1a961432db785091207ead0621b" 189 | integrity sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A== 190 | dependencies: 191 | "@babel/helper-validator-identifier" "^7.22.20" 192 | chalk "^2.4.2" 193 | js-tokens "^4.0.0" 194 | 195 | "@babel/parser@^7.22.10", "@babel/parser@^7.22.5": 196 | version "7.22.10" 197 | resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.10.tgz#e37634f9a12a1716136c44624ef54283cabd3f55" 198 | integrity sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ== 199 | 200 | "@babel/parser@^7.22.15", "@babel/parser@^7.23.6": 201 | version "7.23.6" 202 | resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.6.tgz#ba1c9e512bda72a47e285ae42aff9d2a635a9e3b" 203 | integrity sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ== 204 | 205 | "@babel/template@^7.22.15": 206 | version "7.22.15" 207 | resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" 208 | integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== 209 | dependencies: 210 | "@babel/code-frame" "^7.22.13" 211 | "@babel/parser" "^7.22.15" 212 | "@babel/types" "^7.22.15" 213 | 214 | "@babel/template@^7.22.5": 215 | version "7.22.5" 216 | resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.5.tgz#0c8c4d944509875849bd0344ff0050756eefc6ec" 217 | integrity sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw== 218 | dependencies: 219 | "@babel/code-frame" "^7.22.5" 220 | "@babel/parser" "^7.22.5" 221 | "@babel/types" "^7.22.5" 222 | 223 | "@babel/traverse@^7.22.10": 224 | version "7.23.7" 225 | resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.7.tgz#9a7bf285c928cb99b5ead19c3b1ce5b310c9c305" 226 | integrity sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg== 227 | dependencies: 228 | "@babel/code-frame" "^7.23.5" 229 | "@babel/generator" "^7.23.6" 230 | "@babel/helper-environment-visitor" "^7.22.20" 231 | "@babel/helper-function-name" "^7.23.0" 232 | "@babel/helper-hoist-variables" "^7.22.5" 233 | "@babel/helper-split-export-declaration" "^7.22.6" 234 | "@babel/parser" "^7.23.6" 235 | "@babel/types" "^7.23.6" 236 | debug "^4.3.1" 237 | globals "^11.1.0" 238 | 239 | "@babel/types@^7.22.10", "@babel/types@^7.22.5": 240 | version "7.22.10" 241 | resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.10.tgz#4a9e76446048f2c66982d1a989dd12b8a2d2dc03" 242 | integrity sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg== 243 | dependencies: 244 | "@babel/helper-string-parser" "^7.22.5" 245 | "@babel/helper-validator-identifier" "^7.22.5" 246 | to-fast-properties "^2.0.0" 247 | 248 | "@babel/types@^7.22.15", "@babel/types@^7.23.0", "@babel/types@^7.23.6": 249 | version "7.23.6" 250 | resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.6.tgz#be33fdb151e1f5a56877d704492c240fc71c7ccd" 251 | integrity sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg== 252 | dependencies: 253 | "@babel/helper-string-parser" "^7.23.4" 254 | "@babel/helper-validator-identifier" "^7.22.20" 255 | to-fast-properties "^2.0.0" 256 | 257 | "@cspotcode/source-map-support@^0.8.0": 258 | version "0.8.1" 259 | resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" 260 | integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== 261 | dependencies: 262 | "@jridgewell/trace-mapping" "0.3.9" 263 | 264 | "@istanbuljs/load-nyc-config@^1.0.0": 265 | version "1.1.0" 266 | resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" 267 | integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== 268 | dependencies: 269 | camelcase "^5.3.1" 270 | find-up "^4.1.0" 271 | get-package-type "^0.1.0" 272 | js-yaml "^3.13.1" 273 | resolve-from "^5.0.0" 274 | 275 | "@istanbuljs/schema@^0.1.2": 276 | version "0.1.3" 277 | resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" 278 | integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== 279 | 280 | "@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": 281 | version "0.3.3" 282 | resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" 283 | integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== 284 | dependencies: 285 | "@jridgewell/set-array" "^1.0.1" 286 | "@jridgewell/sourcemap-codec" "^1.4.10" 287 | "@jridgewell/trace-mapping" "^0.3.9" 288 | 289 | "@jridgewell/resolve-uri@^3.0.3", "@jridgewell/resolve-uri@^3.1.0": 290 | version "3.1.1" 291 | resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" 292 | integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== 293 | 294 | "@jridgewell/set-array@^1.0.1": 295 | version "1.1.2" 296 | resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" 297 | integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== 298 | 299 | "@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": 300 | version "1.4.15" 301 | resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" 302 | integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== 303 | 304 | "@jridgewell/trace-mapping@0.3.9": 305 | version "0.3.9" 306 | resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" 307 | integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== 308 | dependencies: 309 | "@jridgewell/resolve-uri" "^3.0.3" 310 | "@jridgewell/sourcemap-codec" "^1.4.10" 311 | 312 | "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": 313 | version "0.3.19" 314 | resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz#f8a3249862f91be48d3127c3cfe992f79b4b8811" 315 | integrity sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw== 316 | dependencies: 317 | "@jridgewell/resolve-uri" "^3.1.0" 318 | "@jridgewell/sourcemap-codec" "^1.4.14" 319 | 320 | "@tsconfig/node10@^1.0.7": 321 | version "1.0.9" 322 | resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" 323 | integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== 324 | 325 | "@tsconfig/node12@^1.0.7": 326 | version "1.0.11" 327 | resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" 328 | integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== 329 | 330 | "@tsconfig/node14@^1.0.0": 331 | version "1.0.3" 332 | resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" 333 | integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== 334 | 335 | "@tsconfig/node16@^1.0.2": 336 | version "1.0.4" 337 | resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" 338 | integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== 339 | 340 | "@types/chai@~4.3.5": 341 | version "4.3.5" 342 | resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.5.tgz#ae69bcbb1bebb68c4ac0b11e9d8ed04526b3562b" 343 | integrity sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng== 344 | 345 | "@types/debug@^4.1.5": 346 | version "4.1.8" 347 | resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.8.tgz#cef723a5d0a90990313faec2d1e22aee5eecb317" 348 | integrity sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ== 349 | dependencies: 350 | "@types/ms" "*" 351 | 352 | "@types/finalhandler@~1.2.0": 353 | version "1.2.0" 354 | resolved "https://registry.yarnpkg.com/@types/finalhandler/-/finalhandler-1.2.0.tgz#149d36a0183cff42b74aaaf8c0b2d64c4b9dd183" 355 | integrity sha512-NgEZKOhxUSXkwNnWNaMXZaopQ5aFGPAYiEpEWIkQ6Dzc4iS0M1oQsvWne2t+ex9QZUAdTz/ZT4tOXJhWtP6mCw== 356 | dependencies: 357 | "@types/node" "*" 358 | 359 | "@types/http-errors@*": 360 | version "2.0.1" 361 | resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.1.tgz#20172f9578b225f6c7da63446f56d4ce108d5a65" 362 | integrity sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ== 363 | 364 | "@types/mime@*": 365 | version "3.0.1" 366 | resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10" 367 | integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA== 368 | 369 | "@types/mocha@~10.0.1": 370 | version "10.0.1" 371 | resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.1.tgz#2f4f65bb08bc368ac39c96da7b2f09140b26851b" 372 | integrity sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q== 373 | 374 | "@types/ms@*": 375 | version "0.7.31" 376 | resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197" 377 | integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== 378 | 379 | "@types/node-fetch@~2.6.4": 380 | version "2.6.4" 381 | resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.4.tgz#1bc3a26de814f6bf466b25aeb1473fa1afe6a660" 382 | integrity sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg== 383 | dependencies: 384 | "@types/node" "*" 385 | form-data "^3.0.0" 386 | 387 | "@types/node@*": 388 | version "20.5.1" 389 | resolved "https://registry.yarnpkg.com/@types/node/-/node-20.5.1.tgz#178d58ee7e4834152b0e8b4d30cbfab578b9bb30" 390 | integrity sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg== 391 | 392 | "@types/node@~18.16.13": 393 | version "18.16.20" 394 | resolved "https://registry.yarnpkg.com/@types/node/-/node-18.16.20.tgz#b27be1ceb267bfb47d8bac024ff6379998f62207" 395 | integrity sha512-nL54VfDjThdP2UXJXZao5wp76CDiDw4zSRO8d4Tk7UgDqNKGKVEQB0/t3ti63NS+YNNkIQDvwEAF04BO+WYu7Q== 396 | 397 | "@types/proxyquire@~1.3.28": 398 | version "1.3.28" 399 | resolved "https://registry.yarnpkg.com/@types/proxyquire/-/proxyquire-1.3.28.tgz#05a647bb0d8fe48fc8edcc193e43cc79310faa7d" 400 | integrity sha512-SQaNzWQ2YZSr7FqAyPPiA3FYpux2Lqh3HWMZQk47x3xbMCqgC/w0dY3dw9rGqlweDDkrySQBcaScXWeR+Yb11Q== 401 | 402 | "@types/semver@~7.5.0": 403 | version "7.5.0" 404 | resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.0.tgz#591c1ce3a702c45ee15f47a42ade72c2fd78978a" 405 | integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== 406 | 407 | "@types/serve-static@~1.15.1": 408 | version "1.15.2" 409 | resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.2.tgz#3e5419ecd1e40e7405d34093f10befb43f63381a" 410 | integrity sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw== 411 | dependencies: 412 | "@types/http-errors" "*" 413 | "@types/mime" "*" 414 | "@types/node" "*" 415 | 416 | acorn-walk@^8.1.1: 417 | version "8.2.0" 418 | resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" 419 | integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== 420 | 421 | acorn@^8.4.1: 422 | version "8.10.0" 423 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" 424 | integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== 425 | 426 | aggregate-error@^3.0.0: 427 | version "3.1.0" 428 | resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" 429 | integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== 430 | dependencies: 431 | clean-stack "^2.0.0" 432 | indent-string "^4.0.0" 433 | 434 | ansi-colors@4.1.1: 435 | version "4.1.1" 436 | resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" 437 | integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== 438 | 439 | ansi-regex@^5.0.1: 440 | version "5.0.1" 441 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" 442 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== 443 | 444 | ansi-styles@^3.2.1: 445 | version "3.2.1" 446 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" 447 | integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== 448 | dependencies: 449 | color-convert "^1.9.0" 450 | 451 | ansi-styles@^4.0.0, ansi-styles@^4.1.0: 452 | version "4.3.0" 453 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" 454 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 455 | dependencies: 456 | color-convert "^2.0.1" 457 | 458 | anylogger-debug@~1.0.3: 459 | version "1.0.3" 460 | resolved "https://registry.yarnpkg.com/anylogger-debug/-/anylogger-debug-1.0.3.tgz#50d00a425f2f23ec8f1f61a79744cf70fd98ad8d" 461 | integrity sha512-JI0aUl9ml/UAc33bDC0bT+khOReGHA9bFUFEJN0RdekJHJH+ZHqGM0oYQZQB+jdX7BcIzgCCpRQeK8DziRfUFA== 462 | dependencies: 463 | anylogger "^1.0.6" 464 | debug "^4.3.1" 465 | 466 | anylogger@^1.0.6, anylogger@~1.0.10: 467 | version "1.0.11" 468 | resolved "https://registry.yarnpkg.com/anylogger/-/anylogger-1.0.11.tgz#0ee55f294c6b921070dc29acd2ac9f1f35200625" 469 | integrity sha512-sKTWPTG2/d71kLGVmymMJQQslUppxvCz6DN/eODL3/ckmfygZzD0t4P5tRXE3qpM62jI98F/YTHHzFhM12jiJQ== 470 | 471 | anymatch@~3.1.2: 472 | version "3.1.3" 473 | resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" 474 | integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== 475 | dependencies: 476 | normalize-path "^3.0.0" 477 | picomatch "^2.0.4" 478 | 479 | append-transform@^2.0.0: 480 | version "2.0.0" 481 | resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-2.0.0.tgz#99d9d29c7b38391e6f428d28ce136551f0b77e12" 482 | integrity sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg== 483 | dependencies: 484 | default-require-extensions "^3.0.0" 485 | 486 | archy@^1.0.0: 487 | version "1.0.0" 488 | resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" 489 | integrity sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw== 490 | 491 | arg@^4.1.0: 492 | version "4.1.3" 493 | resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" 494 | integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== 495 | 496 | argparse@^1.0.7: 497 | version "1.0.10" 498 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" 499 | integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== 500 | dependencies: 501 | sprintf-js "~1.0.2" 502 | 503 | argparse@^2.0.1: 504 | version "2.0.1" 505 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" 506 | integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== 507 | 508 | assertion-error@^1.1.0: 509 | version "1.1.0" 510 | resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" 511 | integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== 512 | 513 | asynckit@^0.4.0: 514 | version "0.4.0" 515 | resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" 516 | integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== 517 | 518 | balanced-match@^1.0.0: 519 | version "1.0.2" 520 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" 521 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 522 | 523 | binary-extensions@^2.0.0: 524 | version "2.2.0" 525 | resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" 526 | integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== 527 | 528 | brace-expansion@^1.1.7: 529 | version "1.1.11" 530 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 531 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 532 | dependencies: 533 | balanced-match "^1.0.0" 534 | concat-map "0.0.1" 535 | 536 | brace-expansion@^2.0.1: 537 | version "2.0.1" 538 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" 539 | integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== 540 | dependencies: 541 | balanced-match "^1.0.0" 542 | 543 | braces@~3.0.2: 544 | version "3.0.2" 545 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" 546 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== 547 | dependencies: 548 | fill-range "^7.0.1" 549 | 550 | browser-stdout@1.3.1: 551 | version "1.3.1" 552 | resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" 553 | integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== 554 | 555 | browserslist@^4.21.9: 556 | version "4.21.10" 557 | resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.10.tgz#dbbac576628c13d3b2231332cb2ec5a46e015bb0" 558 | integrity sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ== 559 | dependencies: 560 | caniuse-lite "^1.0.30001517" 561 | electron-to-chromium "^1.4.477" 562 | node-releases "^2.0.13" 563 | update-browserslist-db "^1.0.11" 564 | 565 | caching-transform@^4.0.0: 566 | version "4.0.0" 567 | resolved "https://registry.yarnpkg.com/caching-transform/-/caching-transform-4.0.0.tgz#00d297a4206d71e2163c39eaffa8157ac0651f0f" 568 | integrity sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA== 569 | dependencies: 570 | hasha "^5.0.0" 571 | make-dir "^3.0.0" 572 | package-hash "^4.0.0" 573 | write-file-atomic "^3.0.0" 574 | 575 | camelcase@^5.0.0, camelcase@^5.3.1: 576 | version "5.3.1" 577 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" 578 | integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== 579 | 580 | camelcase@^6.0.0: 581 | version "6.3.0" 582 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" 583 | integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== 584 | 585 | caniuse-lite@^1.0.30001517: 586 | version "1.0.30001522" 587 | resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001522.tgz#44b87a406c901269adcdb834713e23582dd71856" 588 | integrity sha512-TKiyTVZxJGhsTszLuzb+6vUZSjVOAhClszBr2Ta2k9IwtNBT/4dzmL6aywt0HCgEZlmwJzXJd8yNiob6HgwTRg== 589 | 590 | chai@~4.3.7: 591 | version "4.3.7" 592 | resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.7.tgz#ec63f6df01829088e8bf55fca839bcd464a8ec51" 593 | integrity sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A== 594 | dependencies: 595 | assertion-error "^1.1.0" 596 | check-error "^1.0.2" 597 | deep-eql "^4.1.2" 598 | get-func-name "^2.0.0" 599 | loupe "^2.3.1" 600 | pathval "^1.1.1" 601 | type-detect "^4.0.5" 602 | 603 | chalk@^2.4.2: 604 | version "2.4.2" 605 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" 606 | integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== 607 | dependencies: 608 | ansi-styles "^3.2.1" 609 | escape-string-regexp "^1.0.5" 610 | supports-color "^5.3.0" 611 | 612 | chalk@^4.1.0: 613 | version "4.1.2" 614 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" 615 | integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== 616 | dependencies: 617 | ansi-styles "^4.1.0" 618 | supports-color "^7.1.0" 619 | 620 | check-error@^1.0.2: 621 | version "1.0.2" 622 | resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" 623 | integrity sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA== 624 | 625 | chokidar@3.5.3: 626 | version "3.5.3" 627 | resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" 628 | integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== 629 | dependencies: 630 | anymatch "~3.1.2" 631 | braces "~3.0.2" 632 | glob-parent "~5.1.2" 633 | is-binary-path "~2.1.0" 634 | is-glob "~4.0.1" 635 | normalize-path "~3.0.0" 636 | readdirp "~3.6.0" 637 | optionalDependencies: 638 | fsevents "~2.3.2" 639 | 640 | clean-stack@^2.0.0: 641 | version "2.2.0" 642 | resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" 643 | integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== 644 | 645 | cliui@^6.0.0: 646 | version "6.0.0" 647 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" 648 | integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== 649 | dependencies: 650 | string-width "^4.2.0" 651 | strip-ansi "^6.0.0" 652 | wrap-ansi "^6.2.0" 653 | 654 | cliui@^7.0.2: 655 | version "7.0.4" 656 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" 657 | integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== 658 | dependencies: 659 | string-width "^4.2.0" 660 | strip-ansi "^6.0.0" 661 | wrap-ansi "^7.0.0" 662 | 663 | color-convert@^1.9.0: 664 | version "1.9.3" 665 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" 666 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== 667 | dependencies: 668 | color-name "1.1.3" 669 | 670 | color-convert@^2.0.1: 671 | version "2.0.1" 672 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 673 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 674 | dependencies: 675 | color-name "~1.1.4" 676 | 677 | color-name@1.1.3: 678 | version "1.1.3" 679 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 680 | integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== 681 | 682 | color-name@~1.1.4: 683 | version "1.1.4" 684 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 685 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 686 | 687 | combined-stream@^1.0.8: 688 | version "1.0.8" 689 | resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" 690 | integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== 691 | dependencies: 692 | delayed-stream "~1.0.0" 693 | 694 | commondir@^1.0.1: 695 | version "1.0.1" 696 | resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" 697 | integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== 698 | 699 | concat-map@0.0.1: 700 | version "0.0.1" 701 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 702 | integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== 703 | 704 | convert-source-map@^1.7.0: 705 | version "1.9.0" 706 | resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" 707 | integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== 708 | 709 | create-require@^1.1.0: 710 | version "1.1.1" 711 | resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" 712 | integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== 713 | 714 | cross-spawn@^7.0.0, cross-spawn@^7.0.3: 715 | version "7.0.3" 716 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" 717 | integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== 718 | dependencies: 719 | path-key "^3.1.0" 720 | shebang-command "^2.0.0" 721 | which "^2.0.1" 722 | 723 | debug@2.6.9: 724 | version "2.6.9" 725 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" 726 | integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== 727 | dependencies: 728 | ms "2.0.0" 729 | 730 | debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@~4.3.1: 731 | version "4.3.4" 732 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" 733 | integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== 734 | dependencies: 735 | ms "2.1.2" 736 | 737 | decamelize@^1.2.0: 738 | version "1.2.0" 739 | resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" 740 | integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== 741 | 742 | decamelize@^4.0.0: 743 | version "4.0.0" 744 | resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" 745 | integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== 746 | 747 | deep-eql@^4.1.2: 748 | version "4.1.3" 749 | resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.3.tgz#7c7775513092f7df98d8df9996dd085eb668cc6d" 750 | integrity sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw== 751 | dependencies: 752 | type-detect "^4.0.0" 753 | 754 | default-require-extensions@^3.0.0: 755 | version "3.0.1" 756 | resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-3.0.1.tgz#bfae00feeaeada68c2ae256c62540f60b80625bd" 757 | integrity sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw== 758 | dependencies: 759 | strip-bom "^4.0.0" 760 | 761 | delayed-stream@~1.0.0: 762 | version "1.0.0" 763 | resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" 764 | integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== 765 | 766 | depd@2.0.0: 767 | version "2.0.0" 768 | resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" 769 | integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== 770 | 771 | destroy@1.2.0: 772 | version "1.2.0" 773 | resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" 774 | integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== 775 | 776 | diff@5.0.0: 777 | version "5.0.0" 778 | resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" 779 | integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== 780 | 781 | diff@^4.0.1: 782 | version "4.0.2" 783 | resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" 784 | integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== 785 | 786 | ee-first@1.1.1: 787 | version "1.1.1" 788 | resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" 789 | integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== 790 | 791 | electron-to-chromium@^1.4.477: 792 | version "1.4.498" 793 | resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.498.tgz#cef35341123f62a35ba7084e439c911d25e0d81b" 794 | integrity sha512-4LODxAzKGVy7CJyhhN5mebwe7U2L29P+0G+HUriHnabm0d7LSff8Yn7t+Wq+2/9ze2Fu1dhX7mww090xfv7qXQ== 795 | 796 | emoji-regex@^8.0.0: 797 | version "8.0.0" 798 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" 799 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 800 | 801 | encodeurl@~1.0.2: 802 | version "1.0.2" 803 | resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" 804 | integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== 805 | 806 | es6-error@^4.0.1: 807 | version "4.1.1" 808 | resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" 809 | integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== 810 | 811 | escalade@^3.1.1: 812 | version "3.1.1" 813 | resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" 814 | integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== 815 | 816 | escape-html@~1.0.3: 817 | version "1.0.3" 818 | resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" 819 | integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== 820 | 821 | escape-string-regexp@4.0.0: 822 | version "4.0.0" 823 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" 824 | integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== 825 | 826 | escape-string-regexp@^1.0.5: 827 | version "1.0.5" 828 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 829 | integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== 830 | 831 | esprima@^4.0.0: 832 | version "4.0.1" 833 | resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" 834 | integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== 835 | 836 | etag@~1.8.1: 837 | version "1.8.1" 838 | resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" 839 | integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== 840 | 841 | fill-keys@^1.0.2: 842 | version "1.0.2" 843 | resolved "https://registry.yarnpkg.com/fill-keys/-/fill-keys-1.0.2.tgz#9a8fa36f4e8ad634e3bf6b4f3c8882551452eb20" 844 | integrity sha512-tcgI872xXjwFF4xgQmLxi76GnwJG3g/3isB1l4/G5Z4zrbddGpBjqZCO9oEAcB5wX0Hj/5iQB3toxfO7in1hHA== 845 | dependencies: 846 | is-object "~1.0.1" 847 | merge-descriptors "~1.0.0" 848 | 849 | fill-range@^7.0.1: 850 | version "7.0.1" 851 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" 852 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== 853 | dependencies: 854 | to-regex-range "^5.0.1" 855 | 856 | finalhandler@~1.2.0: 857 | version "1.2.0" 858 | resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" 859 | integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== 860 | dependencies: 861 | debug "2.6.9" 862 | encodeurl "~1.0.2" 863 | escape-html "~1.0.3" 864 | on-finished "2.4.1" 865 | parseurl "~1.3.3" 866 | statuses "2.0.1" 867 | unpipe "~1.0.0" 868 | 869 | find-cache-dir@^3.2.0: 870 | version "3.3.2" 871 | resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" 872 | integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== 873 | dependencies: 874 | commondir "^1.0.1" 875 | make-dir "^3.0.2" 876 | pkg-dir "^4.1.0" 877 | 878 | find-up@5.0.0: 879 | version "5.0.0" 880 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" 881 | integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== 882 | dependencies: 883 | locate-path "^6.0.0" 884 | path-exists "^4.0.0" 885 | 886 | find-up@^4.0.0, find-up@^4.1.0: 887 | version "4.1.0" 888 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" 889 | integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== 890 | dependencies: 891 | locate-path "^5.0.0" 892 | path-exists "^4.0.0" 893 | 894 | flat@^5.0.2: 895 | version "5.0.2" 896 | resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" 897 | integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== 898 | 899 | foreground-child@^2.0.0: 900 | version "2.0.0" 901 | resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-2.0.0.tgz#71b32800c9f15aa8f2f83f4a6bd9bff35d861a53" 902 | integrity sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA== 903 | dependencies: 904 | cross-spawn "^7.0.0" 905 | signal-exit "^3.0.2" 906 | 907 | form-data@^3.0.0: 908 | version "3.0.1" 909 | resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" 910 | integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== 911 | dependencies: 912 | asynckit "^0.4.0" 913 | combined-stream "^1.0.8" 914 | mime-types "^2.1.12" 915 | 916 | fresh@0.5.2: 917 | version "0.5.2" 918 | resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" 919 | integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== 920 | 921 | fromentries@^1.2.0: 922 | version "1.3.2" 923 | resolved "https://registry.yarnpkg.com/fromentries/-/fromentries-1.3.2.tgz#e4bca6808816bf8f93b52750f1127f5a6fd86e3a" 924 | integrity sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg== 925 | 926 | fs.realpath@^1.0.0: 927 | version "1.0.0" 928 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 929 | integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== 930 | 931 | fsevents@~2.3.2: 932 | version "2.3.3" 933 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" 934 | integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== 935 | 936 | function-bind@^1.1.1: 937 | version "1.1.1" 938 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" 939 | integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== 940 | 941 | gensync@^1.0.0-beta.2: 942 | version "1.0.0-beta.2" 943 | resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" 944 | integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== 945 | 946 | get-caller-file@^2.0.1, get-caller-file@^2.0.5: 947 | version "2.0.5" 948 | resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" 949 | integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== 950 | 951 | get-func-name@^2.0.0: 952 | version "2.0.2" 953 | resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.2.tgz#0d7cf20cd13fda808669ffa88f4ffc7a3943fc41" 954 | integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ== 955 | 956 | get-package-type@^0.1.0: 957 | version "0.1.0" 958 | resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" 959 | integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== 960 | 961 | get-port@~5.1.1: 962 | version "5.1.1" 963 | resolved "https://registry.yarnpkg.com/get-port/-/get-port-5.1.1.tgz#0469ed07563479de6efb986baf053dcd7d4e3193" 964 | integrity sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ== 965 | 966 | glob-parent@~5.1.2: 967 | version "5.1.2" 968 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" 969 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== 970 | dependencies: 971 | is-glob "^4.0.1" 972 | 973 | glob@7.2.0: 974 | version "7.2.0" 975 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" 976 | integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== 977 | dependencies: 978 | fs.realpath "^1.0.0" 979 | inflight "^1.0.4" 980 | inherits "2" 981 | minimatch "^3.0.4" 982 | once "^1.3.0" 983 | path-is-absolute "^1.0.0" 984 | 985 | glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: 986 | version "7.2.3" 987 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" 988 | integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== 989 | dependencies: 990 | fs.realpath "^1.0.0" 991 | inflight "^1.0.4" 992 | inherits "2" 993 | minimatch "^3.1.1" 994 | once "^1.3.0" 995 | path-is-absolute "^1.0.0" 996 | 997 | globals@^11.1.0: 998 | version "11.12.0" 999 | resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" 1000 | integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== 1001 | 1002 | graceful-fs@^4.1.15: 1003 | version "4.2.11" 1004 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" 1005 | integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== 1006 | 1007 | has-flag@^3.0.0: 1008 | version "3.0.0" 1009 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 1010 | integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== 1011 | 1012 | has-flag@^4.0.0: 1013 | version "4.0.0" 1014 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" 1015 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== 1016 | 1017 | has@^1.0.3: 1018 | version "1.0.3" 1019 | resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" 1020 | integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== 1021 | dependencies: 1022 | function-bind "^1.1.1" 1023 | 1024 | hasha@^5.0.0: 1025 | version "5.2.2" 1026 | resolved "https://registry.yarnpkg.com/hasha/-/hasha-5.2.2.tgz#a48477989b3b327aea3c04f53096d816d97522a1" 1027 | integrity sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ== 1028 | dependencies: 1029 | is-stream "^2.0.0" 1030 | type-fest "^0.8.0" 1031 | 1032 | he@1.2.0: 1033 | version "1.2.0" 1034 | resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" 1035 | integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== 1036 | 1037 | html-escaper@^2.0.0: 1038 | version "2.0.2" 1039 | resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" 1040 | integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== 1041 | 1042 | http-errors@2.0.0: 1043 | version "2.0.0" 1044 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" 1045 | integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== 1046 | dependencies: 1047 | depd "2.0.0" 1048 | inherits "2.0.4" 1049 | setprototypeof "1.2.0" 1050 | statuses "2.0.1" 1051 | toidentifier "1.0.1" 1052 | 1053 | imurmurhash@^0.1.4: 1054 | version "0.1.4" 1055 | resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" 1056 | integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== 1057 | 1058 | indent-string@^4.0.0: 1059 | version "4.0.0" 1060 | resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" 1061 | integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== 1062 | 1063 | inflight@^1.0.4: 1064 | version "1.0.6" 1065 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 1066 | integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== 1067 | dependencies: 1068 | once "^1.3.0" 1069 | wrappy "1" 1070 | 1071 | inherits@2, inherits@2.0.4: 1072 | version "2.0.4" 1073 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 1074 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 1075 | 1076 | is-binary-path@~2.1.0: 1077 | version "2.1.0" 1078 | resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" 1079 | integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== 1080 | dependencies: 1081 | binary-extensions "^2.0.0" 1082 | 1083 | is-core-module@^2.13.0: 1084 | version "2.13.0" 1085 | resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" 1086 | integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== 1087 | dependencies: 1088 | has "^1.0.3" 1089 | 1090 | is-extglob@^2.1.1: 1091 | version "2.1.1" 1092 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" 1093 | integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== 1094 | 1095 | is-fullwidth-code-point@^3.0.0: 1096 | version "3.0.0" 1097 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" 1098 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== 1099 | 1100 | is-glob@^4.0.1, is-glob@~4.0.1: 1101 | version "4.0.3" 1102 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" 1103 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== 1104 | dependencies: 1105 | is-extglob "^2.1.1" 1106 | 1107 | is-number@^7.0.0: 1108 | version "7.0.0" 1109 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" 1110 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 1111 | 1112 | is-object@~1.0.1: 1113 | version "1.0.2" 1114 | resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.2.tgz#a56552e1c665c9e950b4a025461da87e72f86fcf" 1115 | integrity sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA== 1116 | 1117 | is-plain-obj@^2.1.0: 1118 | version "2.1.0" 1119 | resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" 1120 | integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== 1121 | 1122 | is-stream@^2.0.0: 1123 | version "2.0.1" 1124 | resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" 1125 | integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== 1126 | 1127 | is-typedarray@^1.0.0: 1128 | version "1.0.0" 1129 | resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" 1130 | integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== 1131 | 1132 | is-unicode-supported@^0.1.0: 1133 | version "0.1.0" 1134 | resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" 1135 | integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== 1136 | 1137 | is-windows@^1.0.2: 1138 | version "1.0.2" 1139 | resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" 1140 | integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== 1141 | 1142 | isexe@^2.0.0: 1143 | version "2.0.0" 1144 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 1145 | integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== 1146 | 1147 | istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: 1148 | version "3.2.0" 1149 | resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" 1150 | integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== 1151 | 1152 | istanbul-lib-hook@^3.0.0: 1153 | version "3.0.0" 1154 | resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz#8f84c9434888cc6b1d0a9d7092a76d239ebf0cc6" 1155 | integrity sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ== 1156 | dependencies: 1157 | append-transform "^2.0.0" 1158 | 1159 | istanbul-lib-instrument@^4.0.0: 1160 | version "4.0.3" 1161 | resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d" 1162 | integrity sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ== 1163 | dependencies: 1164 | "@babel/core" "^7.7.5" 1165 | "@istanbuljs/schema" "^0.1.2" 1166 | istanbul-lib-coverage "^3.0.0" 1167 | semver "^6.3.0" 1168 | 1169 | istanbul-lib-processinfo@^2.0.2: 1170 | version "2.0.3" 1171 | resolved "https://registry.yarnpkg.com/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz#366d454cd0dcb7eb6e0e419378e60072c8626169" 1172 | integrity sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg== 1173 | dependencies: 1174 | archy "^1.0.0" 1175 | cross-spawn "^7.0.3" 1176 | istanbul-lib-coverage "^3.2.0" 1177 | p-map "^3.0.0" 1178 | rimraf "^3.0.0" 1179 | uuid "^8.3.2" 1180 | 1181 | istanbul-lib-report@^3.0.0: 1182 | version "3.0.1" 1183 | resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d" 1184 | integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== 1185 | dependencies: 1186 | istanbul-lib-coverage "^3.0.0" 1187 | make-dir "^4.0.0" 1188 | supports-color "^7.1.0" 1189 | 1190 | istanbul-lib-source-maps@^4.0.0: 1191 | version "4.0.1" 1192 | resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" 1193 | integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== 1194 | dependencies: 1195 | debug "^4.1.1" 1196 | istanbul-lib-coverage "^3.0.0" 1197 | source-map "^0.6.1" 1198 | 1199 | istanbul-reports@^3.0.2: 1200 | version "3.1.6" 1201 | resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.6.tgz#2544bcab4768154281a2f0870471902704ccaa1a" 1202 | integrity sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg== 1203 | dependencies: 1204 | html-escaper "^2.0.0" 1205 | istanbul-lib-report "^3.0.0" 1206 | 1207 | js-tokens@^4.0.0: 1208 | version "4.0.0" 1209 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" 1210 | integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== 1211 | 1212 | js-yaml@4.1.0: 1213 | version "4.1.0" 1214 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" 1215 | integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== 1216 | dependencies: 1217 | argparse "^2.0.1" 1218 | 1219 | js-yaml@^3.13.1: 1220 | version "3.14.1" 1221 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" 1222 | integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== 1223 | dependencies: 1224 | argparse "^1.0.7" 1225 | esprima "^4.0.0" 1226 | 1227 | jsesc@^2.5.1: 1228 | version "2.5.2" 1229 | resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" 1230 | integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== 1231 | 1232 | json5@^2.2.2: 1233 | version "2.2.3" 1234 | resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" 1235 | integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== 1236 | 1237 | locate-path@^5.0.0: 1238 | version "5.0.0" 1239 | resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" 1240 | integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== 1241 | dependencies: 1242 | p-locate "^4.1.0" 1243 | 1244 | locate-path@^6.0.0: 1245 | version "6.0.0" 1246 | resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" 1247 | integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== 1248 | dependencies: 1249 | p-locate "^5.0.0" 1250 | 1251 | lodash.flattendeep@^4.4.0: 1252 | version "4.4.0" 1253 | resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" 1254 | integrity sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ== 1255 | 1256 | lodash@^4.17.5: 1257 | version "4.17.21" 1258 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" 1259 | integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== 1260 | 1261 | log-symbols@4.1.0: 1262 | version "4.1.0" 1263 | resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" 1264 | integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== 1265 | dependencies: 1266 | chalk "^4.1.0" 1267 | is-unicode-supported "^0.1.0" 1268 | 1269 | loupe@^2.3.1: 1270 | version "2.3.6" 1271 | resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.6.tgz#76e4af498103c532d1ecc9be102036a21f787b53" 1272 | integrity sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA== 1273 | dependencies: 1274 | get-func-name "^2.0.0" 1275 | 1276 | lru-cache@^5.1.1: 1277 | version "5.1.1" 1278 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" 1279 | integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== 1280 | dependencies: 1281 | yallist "^3.0.2" 1282 | 1283 | lru-cache@^6.0.0: 1284 | version "6.0.0" 1285 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" 1286 | integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== 1287 | dependencies: 1288 | yallist "^4.0.0" 1289 | 1290 | make-dir@^3.0.0, make-dir@^3.0.2: 1291 | version "3.1.0" 1292 | resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" 1293 | integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== 1294 | dependencies: 1295 | semver "^6.0.0" 1296 | 1297 | make-dir@^4.0.0: 1298 | version "4.0.0" 1299 | resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" 1300 | integrity sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw== 1301 | dependencies: 1302 | semver "^7.5.3" 1303 | 1304 | make-error@^1.1.1: 1305 | version "1.3.6" 1306 | resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" 1307 | integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== 1308 | 1309 | merge-descriptors@~1.0.0: 1310 | version "1.0.1" 1311 | resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" 1312 | integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== 1313 | 1314 | mime-db@1.52.0: 1315 | version "1.52.0" 1316 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" 1317 | integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== 1318 | 1319 | mime-types@^2.1.12: 1320 | version "2.1.35" 1321 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" 1322 | integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== 1323 | dependencies: 1324 | mime-db "1.52.0" 1325 | 1326 | mime@1.6.0: 1327 | version "1.6.0" 1328 | resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" 1329 | integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== 1330 | 1331 | minimatch@5.0.1: 1332 | version "5.0.1" 1333 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" 1334 | integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== 1335 | dependencies: 1336 | brace-expansion "^2.0.1" 1337 | 1338 | minimatch@^3.0.4, minimatch@^3.1.1: 1339 | version "3.1.2" 1340 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" 1341 | integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== 1342 | dependencies: 1343 | brace-expansion "^1.1.7" 1344 | 1345 | mocha@~10.2.0: 1346 | version "10.2.0" 1347 | resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8" 1348 | integrity sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg== 1349 | dependencies: 1350 | ansi-colors "4.1.1" 1351 | browser-stdout "1.3.1" 1352 | chokidar "3.5.3" 1353 | debug "4.3.4" 1354 | diff "5.0.0" 1355 | escape-string-regexp "4.0.0" 1356 | find-up "5.0.0" 1357 | glob "7.2.0" 1358 | he "1.2.0" 1359 | js-yaml "4.1.0" 1360 | log-symbols "4.1.0" 1361 | minimatch "5.0.1" 1362 | ms "2.1.3" 1363 | nanoid "3.3.3" 1364 | serialize-javascript "6.0.0" 1365 | strip-json-comments "3.1.1" 1366 | supports-color "8.1.1" 1367 | workerpool "6.2.1" 1368 | yargs "16.2.0" 1369 | yargs-parser "20.2.4" 1370 | yargs-unparser "2.0.0" 1371 | 1372 | module-not-found-error@^1.0.1: 1373 | version "1.0.1" 1374 | resolved "https://registry.yarnpkg.com/module-not-found-error/-/module-not-found-error-1.0.1.tgz#cf8b4ff4f29640674d6cdd02b0e3bc523c2bbdc0" 1375 | integrity sha512-pEk4ECWQXV6z2zjhRZUongnLJNUeGQJ3w6OQ5ctGwD+i5o93qjRQUk2Rt6VdNeu3sEP0AB4LcfvdebpxBRVr4g== 1376 | 1377 | ms@2.0.0: 1378 | version "2.0.0" 1379 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 1380 | integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== 1381 | 1382 | ms@2.1.2: 1383 | version "2.1.2" 1384 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 1385 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 1386 | 1387 | ms@2.1.3: 1388 | version "2.1.3" 1389 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" 1390 | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== 1391 | 1392 | nanoid@3.3.3: 1393 | version "3.3.3" 1394 | resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" 1395 | integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== 1396 | 1397 | node-fetch@^2.6.11: 1398 | version "2.6.13" 1399 | resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.13.tgz#a20acbbec73c2e09f9007de5cda17104122e0010" 1400 | integrity sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA== 1401 | dependencies: 1402 | whatwg-url "^5.0.0" 1403 | 1404 | node-preload@^0.2.1: 1405 | version "0.2.1" 1406 | resolved "https://registry.yarnpkg.com/node-preload/-/node-preload-0.2.1.tgz#c03043bb327f417a18fee7ab7ee57b408a144301" 1407 | integrity sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ== 1408 | dependencies: 1409 | process-on-spawn "^1.0.0" 1410 | 1411 | node-releases@^2.0.13: 1412 | version "2.0.13" 1413 | resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" 1414 | integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== 1415 | 1416 | normalize-path@^3.0.0, normalize-path@~3.0.0: 1417 | version "3.0.0" 1418 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" 1419 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== 1420 | 1421 | nyc@~15.1.0: 1422 | version "15.1.0" 1423 | resolved "https://registry.yarnpkg.com/nyc/-/nyc-15.1.0.tgz#1335dae12ddc87b6e249d5a1994ca4bdaea75f02" 1424 | integrity sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A== 1425 | dependencies: 1426 | "@istanbuljs/load-nyc-config" "^1.0.0" 1427 | "@istanbuljs/schema" "^0.1.2" 1428 | caching-transform "^4.0.0" 1429 | convert-source-map "^1.7.0" 1430 | decamelize "^1.2.0" 1431 | find-cache-dir "^3.2.0" 1432 | find-up "^4.1.0" 1433 | foreground-child "^2.0.0" 1434 | get-package-type "^0.1.0" 1435 | glob "^7.1.6" 1436 | istanbul-lib-coverage "^3.0.0" 1437 | istanbul-lib-hook "^3.0.0" 1438 | istanbul-lib-instrument "^4.0.0" 1439 | istanbul-lib-processinfo "^2.0.2" 1440 | istanbul-lib-report "^3.0.0" 1441 | istanbul-lib-source-maps "^4.0.0" 1442 | istanbul-reports "^3.0.2" 1443 | make-dir "^3.0.0" 1444 | node-preload "^0.2.1" 1445 | p-map "^3.0.0" 1446 | process-on-spawn "^1.0.0" 1447 | resolve-from "^5.0.0" 1448 | rimraf "^3.0.0" 1449 | signal-exit "^3.0.2" 1450 | spawn-wrap "^2.0.0" 1451 | test-exclude "^6.0.0" 1452 | yargs "^15.0.2" 1453 | 1454 | on-finished@2.4.1: 1455 | version "2.4.1" 1456 | resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" 1457 | integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== 1458 | dependencies: 1459 | ee-first "1.1.1" 1460 | 1461 | once@^1.3.0: 1462 | version "1.4.0" 1463 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 1464 | integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== 1465 | dependencies: 1466 | wrappy "1" 1467 | 1468 | p-limit@^2.2.0: 1469 | version "2.3.0" 1470 | resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" 1471 | integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== 1472 | dependencies: 1473 | p-try "^2.0.0" 1474 | 1475 | p-limit@^3.0.2: 1476 | version "3.1.0" 1477 | resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" 1478 | integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== 1479 | dependencies: 1480 | yocto-queue "^0.1.0" 1481 | 1482 | p-locate@^4.1.0: 1483 | version "4.1.0" 1484 | resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" 1485 | integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== 1486 | dependencies: 1487 | p-limit "^2.2.0" 1488 | 1489 | p-locate@^5.0.0: 1490 | version "5.0.0" 1491 | resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" 1492 | integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== 1493 | dependencies: 1494 | p-limit "^3.0.2" 1495 | 1496 | p-map@^3.0.0: 1497 | version "3.0.0" 1498 | resolved "https://registry.yarnpkg.com/p-map/-/p-map-3.0.0.tgz#d704d9af8a2ba684e2600d9a215983d4141a979d" 1499 | integrity sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ== 1500 | dependencies: 1501 | aggregate-error "^3.0.0" 1502 | 1503 | p-try@^2.0.0: 1504 | version "2.2.0" 1505 | resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" 1506 | integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== 1507 | 1508 | package-hash@^4.0.0: 1509 | version "4.0.0" 1510 | resolved "https://registry.yarnpkg.com/package-hash/-/package-hash-4.0.0.tgz#3537f654665ec3cc38827387fc904c163c54f506" 1511 | integrity sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ== 1512 | dependencies: 1513 | graceful-fs "^4.1.15" 1514 | hasha "^5.0.0" 1515 | lodash.flattendeep "^4.4.0" 1516 | release-zalgo "^1.0.0" 1517 | 1518 | parseurl@~1.3.3: 1519 | version "1.3.3" 1520 | resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" 1521 | integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== 1522 | 1523 | path-exists@^4.0.0: 1524 | version "4.0.0" 1525 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" 1526 | integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== 1527 | 1528 | path-is-absolute@^1.0.0: 1529 | version "1.0.1" 1530 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 1531 | integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== 1532 | 1533 | path-key@^3.1.0: 1534 | version "3.1.1" 1535 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" 1536 | integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== 1537 | 1538 | path-parse@^1.0.7: 1539 | version "1.0.7" 1540 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" 1541 | integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== 1542 | 1543 | pathval@^1.1.1: 1544 | version "1.1.1" 1545 | resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" 1546 | integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== 1547 | 1548 | picocolors@^1.0.0: 1549 | version "1.0.0" 1550 | resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" 1551 | integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== 1552 | 1553 | picomatch@^2.0.4, picomatch@^2.2.1: 1554 | version "2.3.1" 1555 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" 1556 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== 1557 | 1558 | pkg-dir@^4.1.0: 1559 | version "4.2.0" 1560 | resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" 1561 | integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== 1562 | dependencies: 1563 | find-up "^4.0.0" 1564 | 1565 | process-on-spawn@^1.0.0: 1566 | version "1.0.0" 1567 | resolved "https://registry.yarnpkg.com/process-on-spawn/-/process-on-spawn-1.0.0.tgz#95b05a23073d30a17acfdc92a440efd2baefdc93" 1568 | integrity sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg== 1569 | dependencies: 1570 | fromentries "^1.2.0" 1571 | 1572 | proxyquire@~2.1.3: 1573 | version "2.1.3" 1574 | resolved "https://registry.yarnpkg.com/proxyquire/-/proxyquire-2.1.3.tgz#2049a7eefa10a9a953346a18e54aab2b4268df39" 1575 | integrity sha512-BQWfCqYM+QINd+yawJz23tbBM40VIGXOdDw3X344KcclI/gtBbdWF6SlQ4nK/bYhF9d27KYug9WzljHC6B9Ysg== 1576 | dependencies: 1577 | fill-keys "^1.0.2" 1578 | module-not-found-error "^1.0.1" 1579 | resolve "^1.11.1" 1580 | 1581 | randombytes@^2.1.0: 1582 | version "2.1.0" 1583 | resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" 1584 | integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== 1585 | dependencies: 1586 | safe-buffer "^5.1.0" 1587 | 1588 | range-parser@~1.2.1: 1589 | version "1.2.1" 1590 | resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" 1591 | integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== 1592 | 1593 | readdirp@~3.6.0: 1594 | version "3.6.0" 1595 | resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" 1596 | integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== 1597 | dependencies: 1598 | picomatch "^2.2.1" 1599 | 1600 | release-zalgo@^1.0.0: 1601 | version "1.0.0" 1602 | resolved "https://registry.yarnpkg.com/release-zalgo/-/release-zalgo-1.0.0.tgz#09700b7e5074329739330e535c5a90fb67851730" 1603 | integrity sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA== 1604 | dependencies: 1605 | es6-error "^4.0.1" 1606 | 1607 | require-directory@^2.1.1: 1608 | version "2.1.1" 1609 | resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" 1610 | integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== 1611 | 1612 | require-main-filename@^2.0.0: 1613 | version "2.0.0" 1614 | resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" 1615 | integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== 1616 | 1617 | resolve-from@^5.0.0: 1618 | version "5.0.0" 1619 | resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" 1620 | integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== 1621 | 1622 | resolve@^1.11.1: 1623 | version "1.22.4" 1624 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34" 1625 | integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== 1626 | dependencies: 1627 | is-core-module "^2.13.0" 1628 | path-parse "^1.0.7" 1629 | supports-preserve-symlinks-flag "^1.0.0" 1630 | 1631 | rimraf@^3.0.0: 1632 | version "3.0.2" 1633 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" 1634 | integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== 1635 | dependencies: 1636 | glob "^7.1.3" 1637 | 1638 | safe-buffer@^5.1.0: 1639 | version "5.2.1" 1640 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 1641 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 1642 | 1643 | semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: 1644 | version "6.3.1" 1645 | resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" 1646 | integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== 1647 | 1648 | semver@^7.3.4, semver@^7.5.3: 1649 | version "7.5.4" 1650 | resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" 1651 | integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== 1652 | dependencies: 1653 | lru-cache "^6.0.0" 1654 | 1655 | send@0.18.0: 1656 | version "0.18.0" 1657 | resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" 1658 | integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== 1659 | dependencies: 1660 | debug "2.6.9" 1661 | depd "2.0.0" 1662 | destroy "1.2.0" 1663 | encodeurl "~1.0.2" 1664 | escape-html "~1.0.3" 1665 | etag "~1.8.1" 1666 | fresh "0.5.2" 1667 | http-errors "2.0.0" 1668 | mime "1.6.0" 1669 | ms "2.1.3" 1670 | on-finished "2.4.1" 1671 | range-parser "~1.2.1" 1672 | statuses "2.0.1" 1673 | 1674 | serialize-javascript@6.0.0: 1675 | version "6.0.0" 1676 | resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" 1677 | integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== 1678 | dependencies: 1679 | randombytes "^2.1.0" 1680 | 1681 | serve-static@~1.15.0: 1682 | version "1.15.0" 1683 | resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" 1684 | integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== 1685 | dependencies: 1686 | encodeurl "~1.0.2" 1687 | escape-html "~1.0.3" 1688 | parseurl "~1.3.3" 1689 | send "0.18.0" 1690 | 1691 | set-blocking@^2.0.0: 1692 | version "2.0.0" 1693 | resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" 1694 | integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== 1695 | 1696 | setprototypeof@1.2.0: 1697 | version "1.2.0" 1698 | resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" 1699 | integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== 1700 | 1701 | shebang-command@^2.0.0: 1702 | version "2.0.0" 1703 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" 1704 | integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== 1705 | dependencies: 1706 | shebang-regex "^3.0.0" 1707 | 1708 | shebang-regex@^3.0.0: 1709 | version "3.0.0" 1710 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" 1711 | integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== 1712 | 1713 | signal-exit@^3.0.2: 1714 | version "3.0.7" 1715 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" 1716 | integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== 1717 | 1718 | source-map@^0.6.1: 1719 | version "0.6.1" 1720 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" 1721 | integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== 1722 | 1723 | spawn-wrap@^2.0.0: 1724 | version "2.0.0" 1725 | resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-2.0.0.tgz#103685b8b8f9b79771318827aa78650a610d457e" 1726 | integrity sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg== 1727 | dependencies: 1728 | foreground-child "^2.0.0" 1729 | is-windows "^1.0.2" 1730 | make-dir "^3.0.0" 1731 | rimraf "^3.0.0" 1732 | signal-exit "^3.0.2" 1733 | which "^2.0.1" 1734 | 1735 | sprintf-js@~1.0.2: 1736 | version "1.0.3" 1737 | resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" 1738 | integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== 1739 | 1740 | statuses@2.0.1: 1741 | version "2.0.1" 1742 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" 1743 | integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== 1744 | 1745 | string-width@^4.1.0, string-width@^4.2.0: 1746 | version "4.2.3" 1747 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" 1748 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== 1749 | dependencies: 1750 | emoji-regex "^8.0.0" 1751 | is-fullwidth-code-point "^3.0.0" 1752 | strip-ansi "^6.0.1" 1753 | 1754 | strip-ansi@^6.0.0, strip-ansi@^6.0.1: 1755 | version "6.0.1" 1756 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" 1757 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== 1758 | dependencies: 1759 | ansi-regex "^5.0.1" 1760 | 1761 | strip-bom@^4.0.0: 1762 | version "4.0.0" 1763 | resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" 1764 | integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== 1765 | 1766 | strip-json-comments@3.1.1: 1767 | version "3.1.1" 1768 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" 1769 | integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== 1770 | 1771 | supports-color@8.1.1: 1772 | version "8.1.1" 1773 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" 1774 | integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== 1775 | dependencies: 1776 | has-flag "^4.0.0" 1777 | 1778 | supports-color@^5.3.0: 1779 | version "5.5.0" 1780 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" 1781 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== 1782 | dependencies: 1783 | has-flag "^3.0.0" 1784 | 1785 | supports-color@^7.1.0: 1786 | version "7.2.0" 1787 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" 1788 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== 1789 | dependencies: 1790 | has-flag "^4.0.0" 1791 | 1792 | supports-preserve-symlinks-flag@^1.0.0: 1793 | version "1.0.0" 1794 | resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" 1795 | integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== 1796 | 1797 | test-exclude@^6.0.0: 1798 | version "6.0.0" 1799 | resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" 1800 | integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== 1801 | dependencies: 1802 | "@istanbuljs/schema" "^0.1.2" 1803 | glob "^7.1.4" 1804 | minimatch "^3.0.4" 1805 | 1806 | to-fast-properties@^2.0.0: 1807 | version "2.0.0" 1808 | resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" 1809 | integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== 1810 | 1811 | to-regex-range@^5.0.1: 1812 | version "5.0.1" 1813 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" 1814 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 1815 | dependencies: 1816 | is-number "^7.0.0" 1817 | 1818 | toidentifier@1.0.1: 1819 | version "1.0.1" 1820 | resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" 1821 | integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== 1822 | 1823 | tr46@~0.0.3: 1824 | version "0.0.3" 1825 | resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" 1826 | integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== 1827 | 1828 | ts-mockito@~2.6.1: 1829 | version "2.6.1" 1830 | resolved "https://registry.yarnpkg.com/ts-mockito/-/ts-mockito-2.6.1.tgz#bc9ee2619033934e6fad1c4455aca5b5ace34e73" 1831 | integrity sha512-qU9m/oEBQrKq5hwfbJ7MgmVN5Gu6lFnIGWvpxSjrqq6YYEVv+RwVFWySbZMBgazsWqv6ctAyVBpo9TmAxnOEKw== 1832 | dependencies: 1833 | lodash "^4.17.5" 1834 | 1835 | ts-node@~10.9.1: 1836 | version "10.9.1" 1837 | resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" 1838 | integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== 1839 | dependencies: 1840 | "@cspotcode/source-map-support" "^0.8.0" 1841 | "@tsconfig/node10" "^1.0.7" 1842 | "@tsconfig/node12" "^1.0.7" 1843 | "@tsconfig/node14" "^1.0.0" 1844 | "@tsconfig/node16" "^1.0.2" 1845 | acorn "^8.4.1" 1846 | acorn-walk "^8.1.1" 1847 | arg "^4.1.0" 1848 | create-require "^1.1.0" 1849 | diff "^4.0.1" 1850 | make-error "^1.1.1" 1851 | v8-compile-cache-lib "^3.0.1" 1852 | yn "3.1.1" 1853 | 1854 | type-detect@^4.0.0, type-detect@^4.0.5: 1855 | version "4.0.8" 1856 | resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" 1857 | integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== 1858 | 1859 | type-fest@^0.8.0: 1860 | version "0.8.1" 1861 | resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" 1862 | integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== 1863 | 1864 | typedarray-to-buffer@^3.1.5: 1865 | version "3.1.5" 1866 | resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" 1867 | integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== 1868 | dependencies: 1869 | is-typedarray "^1.0.0" 1870 | 1871 | typescript@~5.0.4: 1872 | version "5.0.4" 1873 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.4.tgz#b217fd20119bd61a94d4011274e0ab369058da3b" 1874 | integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw== 1875 | 1876 | unpipe@~1.0.0: 1877 | version "1.0.0" 1878 | resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" 1879 | integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== 1880 | 1881 | update-browserslist-db@^1.0.11: 1882 | version "1.0.11" 1883 | resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940" 1884 | integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== 1885 | dependencies: 1886 | escalade "^3.1.1" 1887 | picocolors "^1.0.0" 1888 | 1889 | uuid@^8.3.2: 1890 | version "8.3.2" 1891 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" 1892 | integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== 1893 | 1894 | v8-compile-cache-lib@^3.0.1: 1895 | version "3.0.1" 1896 | resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" 1897 | integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== 1898 | 1899 | webidl-conversions@^3.0.0: 1900 | version "3.0.1" 1901 | resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" 1902 | integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== 1903 | 1904 | whatwg-url@^5.0.0: 1905 | version "5.0.0" 1906 | resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" 1907 | integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== 1908 | dependencies: 1909 | tr46 "~0.0.3" 1910 | webidl-conversions "^3.0.0" 1911 | 1912 | which-module@^2.0.0: 1913 | version "2.0.1" 1914 | resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.1.tgz#776b1fe35d90aebe99e8ac15eb24093389a4a409" 1915 | integrity sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ== 1916 | 1917 | which@^2.0.1: 1918 | version "2.0.2" 1919 | resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" 1920 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== 1921 | dependencies: 1922 | isexe "^2.0.0" 1923 | 1924 | workerpool@6.2.1: 1925 | version "6.2.1" 1926 | resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" 1927 | integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== 1928 | 1929 | wrap-ansi@^6.2.0: 1930 | version "6.2.0" 1931 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" 1932 | integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== 1933 | dependencies: 1934 | ansi-styles "^4.0.0" 1935 | string-width "^4.1.0" 1936 | strip-ansi "^6.0.0" 1937 | 1938 | wrap-ansi@^7.0.0: 1939 | version "7.0.0" 1940 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" 1941 | integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== 1942 | dependencies: 1943 | ansi-styles "^4.0.0" 1944 | string-width "^4.1.0" 1945 | strip-ansi "^6.0.0" 1946 | 1947 | wrappy@1: 1948 | version "1.0.2" 1949 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 1950 | integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== 1951 | 1952 | write-file-atomic@^3.0.0: 1953 | version "3.0.3" 1954 | resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" 1955 | integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== 1956 | dependencies: 1957 | imurmurhash "^0.1.4" 1958 | is-typedarray "^1.0.0" 1959 | signal-exit "^3.0.2" 1960 | typedarray-to-buffer "^3.1.5" 1961 | 1962 | y18n@^4.0.0: 1963 | version "4.0.3" 1964 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" 1965 | integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== 1966 | 1967 | y18n@^5.0.5: 1968 | version "5.0.8" 1969 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" 1970 | integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== 1971 | 1972 | yallist@^3.0.2: 1973 | version "3.1.1" 1974 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" 1975 | integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== 1976 | 1977 | yallist@^4.0.0: 1978 | version "4.0.0" 1979 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" 1980 | integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== 1981 | 1982 | yargs-parser@20.2.4: 1983 | version "20.2.4" 1984 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" 1985 | integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== 1986 | 1987 | yargs-parser@^18.1.2: 1988 | version "18.1.3" 1989 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" 1990 | integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== 1991 | dependencies: 1992 | camelcase "^5.0.0" 1993 | decamelize "^1.2.0" 1994 | 1995 | yargs-parser@^20.2.2: 1996 | version "20.2.9" 1997 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" 1998 | integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== 1999 | 2000 | yargs-unparser@2.0.0: 2001 | version "2.0.0" 2002 | resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" 2003 | integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== 2004 | dependencies: 2005 | camelcase "^6.0.0" 2006 | decamelize "^4.0.0" 2007 | flat "^5.0.2" 2008 | is-plain-obj "^2.1.0" 2009 | 2010 | yargs@16.2.0: 2011 | version "16.2.0" 2012 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" 2013 | integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== 2014 | dependencies: 2015 | cliui "^7.0.2" 2016 | escalade "^3.1.1" 2017 | get-caller-file "^2.0.5" 2018 | require-directory "^2.1.1" 2019 | string-width "^4.2.0" 2020 | y18n "^5.0.5" 2021 | yargs-parser "^20.2.2" 2022 | 2023 | yargs@^15.0.2: 2024 | version "15.4.1" 2025 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" 2026 | integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== 2027 | dependencies: 2028 | cliui "^6.0.0" 2029 | decamelize "^1.2.0" 2030 | find-up "^4.1.0" 2031 | get-caller-file "^2.0.1" 2032 | require-directory "^2.1.1" 2033 | require-main-filename "^2.0.0" 2034 | set-blocking "^2.0.0" 2035 | string-width "^4.2.0" 2036 | which-module "^2.0.0" 2037 | y18n "^4.0.0" 2038 | yargs-parser "^18.1.2" 2039 | 2040 | yn@3.1.1: 2041 | version "3.1.1" 2042 | resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" 2043 | integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== 2044 | 2045 | yocto-queue@^0.1.0: 2046 | version "0.1.0" 2047 | resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" 2048 | integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== 2049 | --------------------------------------------------------------------------------