diff --git a/.dockerignore b/.dockerignore
index 6381947a..1e140910 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -1,151 +1,4 @@
-# custom paths:
-src/data/*
-.tmp
-docker/master
-docker/slave
-.test*
-# Created by https://www.toptal.com/developers/gitignore/api/node
-### Node ###
-*-audit.json
-# Logs
-logs
-*.log
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-lerna-debug.log*
-.pnpm-debug.log*
-
-# Diagnostic reports (https://nodejs.org/api/report.html)
-report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
-
-# Runtime data
-pids
-*.pid
-*.seed
-*.pid.lock
-
-# Directory for instrumented libs generated by jscoverage/JSCover
-lib-cov
-
-# Coverage directory used by tools like istanbul
-coverage
-*.lcov
-
-# nyc test coverage
-.nyc_output
-
-# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
-.grunt
-
-# Bower dependency directory (https://bower.io/)
-bower_components
-
-# node-waf configuration
-.lock-wscript
-
-# Compiled binary addons (https://nodejs.org/api/addons.html)
-build/Release
-
-# Dependency directories
-node_modules/
-jspm_packages/
-
-# Snowpack dependency directory (https://snowpack.dev/)
-web_modules/
-
-# TypeScript cache
-*.tsbuildinfo
-
-# Optional npm cache directory
-.npm
-
-# Optional eslint cache
-.eslintcache
-
-# Optional stylelint cache
-.stylelintcache
-
-# Microbundle cache
-.rpt2_cache/
-.rts2_cache_cjs/
-.rts2_cache_es/
-.rts2_cache_umd/
-
-# Optional REPL history
-.node_repl_history
-
-# Output of 'npm pack'
-*.tgz
-
-# Yarn Integrity file
-.yarn-integrity
-
-# dotenv environment variable files
-.env
-.env.development.local
-.env.test.local
-.env.production.local
-.env.local
-
-# parcel-bundler cache (https://parceljs.org/)
-.cache
-.parcel-cache
-
-# Next.js build output
-.next
-out
-
-# Nuxt.js build / generate output
-.nuxt
-dist
-
-# Gatsby files
-.cache/
-# Comment in the public line in if your project uses Gatsby and not Next.js
-# https://nextjs.org/blog/next-9-1#public-directory-support
-# public
-
-# vuepress build output
-.vuepress/dist
-
-# vuepress v2.x temp and cache directory
-.temp
-
-# Docusaurus cache and generated files
-.docusaurus
-
-# Serverless directories
-.serverless/
-
-# FuseBox cache
-.fusebox/
-
-# DynamoDB Local files
-.dynamodb/
-
-# TernJS port file
-.tern-port
-
-# Stores VSCode versions used for testing VSCode extensions
-.vscode-test
-
-# yarn v2
-.yarn/cache
-.yarn/unplugged
-.yarn/build-state.yml
-.yarn/install-state.gz
-.pnp.*
-
-### Node Patch ###
-# Serverless Webpack directories
-.webpack/
-
-# Optional stylelint cache
-
-# SvelteKit build / generate output
-.svelte-kit
-/test-results/
-/playwright-report/
-/blob-report/
-/playwright/.cache/
+*.db*
+/stacks
+/node_modules
+*.md
\ No newline at end of file
diff --git a/.github/DockStat-dark.png b/.github/DockStat-dark.png
deleted file mode 100644
index 00ac779a..00000000
Binary files a/.github/DockStat-dark.png and /dev/null differ
diff --git a/.github/workflows/build-image.yaml b/.github/workflows/build-image.yaml
deleted file mode 100644
index 9d43ff17..00000000
--- a/.github/workflows/build-image.yaml
+++ /dev/null
@@ -1,63 +0,0 @@
-name: "Build and Push Docker Image"
-
-on:
- release:
- types: [published]
-
-permissions:
- packages: write
- contents: read
-
-jobs:
- build-release:
- runs-on: ubuntu-24.04
- steps:
- - name: Checkout repository
- uses: actions/checkout@v4
-
- - name: Set up QEMU
- uses: docker/setup-qemu-action@v3
-
- - name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v3
-
- - name: Login to GitHub Container Registry
- uses: docker/login-action@v3
- with:
- registry: ghcr.io
- username: ${{ github.repository_owner }}
- password: ${{ github.token }}
-
- - name: Extract version and create tag
- id: get-tag
- run: |
- # Remove 'v' prefix from release tag if present
- VERSION="${GITHUB_REF#refs/tags/v}"
- # Check if pre-release and append '-pre'
- if ${{ github.event.release.prerelease }}; then
- TAG="$VERSION-pre"
- else
- TAG="$VERSION"
- fi
- echo "tag=$TAG" >> $GITHUB_OUTPUT
-
- - name: Generate Docker metadata
- uses: docker/metadata-action@v5
- id: metadata
- with:
- images: ghcr.io/${{ github.repository }}
- tags: |
- type=raw,value=${{ steps.get-tag.outputs.tag }}
- type=raw,value=latest,enable=${{ !github.event.release.prerelease }}
-
- - name: Build and push
- uses: docker/build-push-action@v6
- with:
- platforms: linux/amd64,linux/arm64
- context: .
- file: docker/Dockerfile-base
- push: true
- tags: ${{ steps.metadata.outputs.tags }}
- labels: ${{ steps.metadata.outputs.labels }}
- cache-from: type=gha
- cache-to: type=gha,mode=max
diff --git a/.github/workflows/cloc.yaml b/.github/workflows/cloc.yaml
deleted file mode 100644
index 0f4245f9..00000000
--- a/.github/workflows/cloc.yaml
+++ /dev/null
@@ -1,27 +0,0 @@
-name: "Count Lines of Code"
-
-permissions:
- issues: write
- pull-requests: write
-
-on:
- pull_request:
- branches: [main, dev]
-
-jobs:
- cloc:
- runs-on: ubuntu-24.04
-
- steps:
- - uses: actions/checkout@v4
-
- - name: Count Lines of Code (cloc)
- uses: djdefi/cloc-action@6
- with:
- options: --md --report-file=cloc.md --exclude-dir=node_modules --exclude-lang=YAML,JSON --exclude-list-file=package-lock.json
-
- - name: Create comment from markdown file
- uses: GrantBirki/comment@v2
- with:
- file: cloc.md
- issue-number: ${{ github.event.number }}
diff --git a/.github/workflows/remove-stale.yaml b/.github/workflows/remove-stale.yaml
deleted file mode 100644
index 47f9ae24..00000000
--- a/.github/workflows/remove-stale.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-name: "Close stale issues and PR"
-on:
- schedule:
- - cron: "30 1 * * *"
-
-jobs:
- remove-stale:
- runs-on: ubuntu-24.04
- steps:
- - uses: actions/stale@v9
- with:
- stale-issue-message: "This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days."
- stale-pr-message: "This PR is stale because it has been open 45 days with no activity. Remove stale label or comment or this will be closed in 10 days."
- close-issue-message: "This issue was closed because it has been stalled for 5 days with no activity."
- days-before-stale: 30
- days-before-close: 5
- days-before-pr-close: -1
diff --git a/.github/workflows/validation.yaml b/.github/workflows/validation.yaml
deleted file mode 100644
index 9a9ec937..00000000
--- a/.github/workflows/validation.yaml
+++ /dev/null
@@ -1,211 +0,0 @@
-name: "CI/CD Pipeline"
-
-on:
- push:
- release:
- types: [published]
-
-jobs:
- validation:
- name: "Code Validation & Tests"
- runs-on: ubuntu-24.04
- permissions:
- actions: read
- contents: read
- packages: read
- steps:
- - name: Checkout
- uses: actions/checkout@v4
-
- - name: Setup Node.js 20
- uses: actions/setup-node@v4
- with:
- node-version: 20
- cache: npm
-
- - name: Install dependencies
- run: npm ci
-
- - name: Create varaibles.json
- run: npm run local-env-file
-
- - name: Run code formatting
- run: npm run prettier
-
- - name: Run linter
- run: npm run lint
-
- - name: Build project
- run: npm run build:mini
-
- - name: Audit packages
- run: npm audit --audit-level=high
-
- - name: Run tests
- run: npm run test:silent
-
- security-analysis:
- name: "Security Analysis"
- runs-on: ubuntu-24.04
- needs: validation
- permissions:
- security-events: write
- contents: read
- packages: read
- steps:
- - name: Checkout repository
- uses: actions/checkout@v4
-
- - name: Initialize CodeQL
- uses: github/codeql-action/init@v3
- with:
- languages: javascript-typescript
- queries: security-extended
- config: |
- query-filter:
- - exclude:
- tags: /cwe-200/
-
- - name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v3
-
- container-scanning:
- name: "Container Security"
- runs-on: ubuntu-24.04
- needs: validation
- permissions:
- security-events: write
- contents: read
- steps:
- - name: Checkout repository
- uses: actions/checkout@v4
-
- - name: Download Grype
- run: |
- curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b $HOME/bin
- echo "$HOME/bin" >> $GITHUB_PATH
-
- - name: Build Docker image
- run: docker build . --file docker/Dockerfile-base --tag localbuild/testimage:latest
-
- - name: Run vulnerability scan
- run: grype -o sarif localbuild/testimage:latest > results.sarif
-
- - name: Upload SARIF report
- uses: github/codeql-action/upload-sarif@v3
- with:
- sarif_file: ./results.sarif
-
- build-test:
- name: "Docker Build Test"
- runs-on: ubuntu-24.04
- needs: validation
- permissions:
- contents: read
- packages: read
- steps:
- - name: Checkout repository
- uses: actions/checkout@v4
-
- - name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v3
-
- - name: Build Docker image
- uses: docker/build-push-action@v6
- with:
- context: .
- file: docker/Dockerfile-base
- platforms: linux/amd64,linux/arm64
- push: false
- cache-from: type=gha
- cache-to: type=gha,mode=max
-
- todo-management:
- name: "TODO Issue Management"
- runs-on: ubuntu-24.04
- needs: validation
- permissions:
- contents: write
- issues: write
- steps:
- - name: Checkout repository
- uses: actions/checkout@v4
-
- - name: Process TODOs
- uses: alstr/todo-to-issue-action@v5
- with:
- INSERT_ISSUE_URLS: "true"
-
- - name: Commit changes
- run: |
- git config --global user.name "github-actions[bot]"
- git config --global user.email "github-actions[bot]@users.noreply.github.com"
- git add -A
- if [[ $(git status --porcelain) ]]; then
- git commit -m "Automatically process TODOs [skip ci]"
- git push
- fi
-
- deployment:
- name: "Docker Deployment"
- runs-on: ubuntu-24.04
- needs: [security-analysis, container-scanning, build-test]
- permissions:
- packages: write
- contents: read
- strategy:
- matrix:
- include:
- - type: dev
- # Only enable when pushing to the dev branch
- enabled: ${{ github.ref_name == 'dev' }}
- - type: pre-release
- # Only enable when a release event is published and it's a prerelease
- enabled: ${{ github.event_name == 'release' && github.event.release.prerelease }}
- - type: release
- # Only enable when a release event is published and it's NOT a prerelease
- enabled: ${{ github.event_name == 'release' && !github.event.release.prerelease }}
- steps:
- - name: Exit early if deployment is not enabled
- if: ${{ !matrix.enabled }}
- run: |
- echo "Skipping deployment for matrix type '${{ matrix.type }}' because conditions are not met."
- exit 0
-
- - name: Checkout repository
- if: ${{ matrix.enabled }}
- uses: actions/checkout@v4
-
- - name: Set up Docker Buildx
- if: ${{ matrix.enabled }}
- uses: docker/setup-buildx-action@v3
-
- - name: Login to GitHub Container Registry
- if: ${{ matrix.enabled }}
- uses: docker/login-action@v3
- with:
- registry: ghcr.io
- username: ${{ github.repository_owner }}
- password: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Determine tags
- if: ${{ matrix.enabled }}
- id: tags
- uses: docker/metadata-action@v5
- with:
- images: ghcr.io/${{ github.repository }}
- tags: |
- type=raw,value=${{ matrix.type == 'dev' && 'nightly' || matrix.type == 'pre-release' && 'pre' || matrix.type == 'release' && 'latest' }}
-
- - name: Build and push
- if: ${{ matrix.enabled }}
- uses: docker/build-push-action@v6
- with:
- context: .
- file: docker/Dockerfile-dev
- platforms: linux/amd64,linux/arm64
- push: ${{ github.event_name != 'pull_request' }}
- tags: ${{ steps.tags.outputs.tags }}
- labels: ${{ steps.tags.outputs.labels }}
- cache-from: type=gha
- cache-to: type=gha,mode=max
diff --git a/.gitignore b/.gitignore
index 9e264ac0..aa426ba1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,154 +1,3 @@
-# custom paths:
-src/data/*
-src/data/frontendConfiguration.json
-
-.tmp
-docker/master
-docker/slave
-.test*
-stacks
-# Created by https://www.toptal.com/developers/gitignore/api/node
-### Node ###
-*-audit.json
-# Logs
-logs
-*.log
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-lerna-debug.log*
-.pnpm-debug.log*
-
-# Diagnostic reports (https://nodejs.org/api/report.html)
-report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
-
-# Runtime data
-pids
-*.pid
-*.seed
-*.pid.lock
-
-# Directory for instrumented libs generated by jscoverage/JSCover
-lib-cov
-
-# Coverage directory used by tools like istanbul
-coverage
-*.lcov
-
-# nyc test coverage
-.nyc_output
-
-# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
-.grunt
-
-# Bower dependency directory (https://bower.io/)
-bower_components
-
-# node-waf configuration
-.lock-wscript
-
-# Compiled binary addons (https://nodejs.org/api/addons.html)
-build/Release
-
-# Dependency directories
-node_modules/
-jspm_packages/
-
-# Snowpack dependency directory (https://snowpack.dev/)
-web_modules/
-
-# TypeScript cache
-*.tsbuildinfo
-
-# Optional npm cache directory
-.npm
-
-# Optional eslint cache
-.eslintcache
-
-# Optional stylelint cache
-.stylelintcache
-
-# Microbundle cache
-.rpt2_cache/
-.rts2_cache_cjs/
-.rts2_cache_es/
-.rts2_cache_umd/
-
-# Optional REPL history
-.node_repl_history
-
-# Output of 'npm pack'
-*.tgz
-
-# Yarn Integrity file
-.yarn-integrity
-
-# dotenv environment variable files
-.env
-.env.development.local
-.env.test.local
-.env.production.local
-.env.local
-
-# parcel-bundler cache (https://parceljs.org/)
-.cache
-.parcel-cache
-
-# Next.js build output
-.next
-out
-
-# Nuxt.js build / generate output
-.nuxt
-dist
-
-# Gatsby files
-.cache/
-# Comment in the public line in if your project uses Gatsby and not Next.js
-# https://nextjs.org/blog/next-9-1#public-directory-support
-# public
-
-# vuepress build output
-.vuepress/dist
-
-# vuepress v2.x temp and cache directory
-.temp
-
-# Docusaurus cache and generated files
-.docusaurus
-
-# Serverless directories
-.serverless/
-
-# FuseBox cache
-.fusebox/
-
-# DynamoDB Local files
-.dynamodb/
-
-# TernJS port file
-.tern-port
-
-# Stores VSCode versions used for testing VSCode extensions
-.vscode-test
-
-# yarn v2
-.yarn/cache
-.yarn/unplugged
-.yarn/build-state.yml
-.yarn/install-state.gz
-.pnp.*
-
-### Node Patch ###
-# Serverless Webpack directories
-.webpack/
-
-# Optional stylelint cache
-
-# SvelteKit build / generate output
-.svelte-kit
-/test-results/
-/playwright-report/
-/blob-report/
-/playwright/.cache/
+*.db*
+/stacks
+/node_modules
\ No newline at end of file
diff --git a/.local-tests/stacks.md b/.local-tests/stacks.md
new file mode 100644
index 00000000..4d9290cb
--- /dev/null
+++ b/.local-tests/stacks.md
@@ -0,0 +1,39 @@
+# Testing Stacks
+
+## Deployment
+
+### Values
+
+- compose_spec
+- name
+- version
+- automatic_reboot_on_error
+- isCustom
+- image_updates
+- source
+- stack_prefix
+
+### JSON
+```json
+{
+ "compose_spec": {
+ "name": "Local Test",
+ "services": {
+ "nginx": {
+ "container_name": "Local-test-nginx",
+ "image": "dockerbogo/docker-nginx-hello-world",
+ "ports": [
+ "8081:80"
+ ]
+ }
+ }
+ },
+ "name": "Local-Test",
+ "version": 1,
+ "automatic_reboot_on_error": true,
+ "isCustom": true,
+ "image_updates": true,
+ "source": "Local",
+ "stack_prefix": ""
+}
+```
diff --git a/.npmrc b/.npmrc
deleted file mode 100644
index 4fd02195..00000000
--- a/.npmrc
+++ /dev/null
@@ -1 +0,0 @@
-engine-strict=true
\ No newline at end of file
diff --git a/.nvmrc b/.nvmrc
deleted file mode 100644
index 209e3ef4..00000000
--- a/.nvmrc
+++ /dev/null
@@ -1 +0,0 @@
-20
diff --git a/CREDITS.md b/CREDITS.md
deleted file mode 100644
index 6dd2d893..00000000
--- a/CREDITS.md
+++ /dev/null
@@ -1,106 +0,0 @@
-# CREDITS
-
-This file shows all npm packages used in DockStatAPI (also Dev packages)
-
-### License: (MIT AND CC-BY-3.0)
-
-| Name | Repository | Publisher |
-| ----------------- | -------------------------------------------- | -------------------- |
-| spdx-ranges@2.1.1 | https://github.com/kemitchell/spdx-ranges.js | The Linux Foundation |
-
-### License: Apache 2.0
-
-| Name | Repository | Publisher |
-| ---------------------- | ------------------------------------------ | --------- |
-| qrcode-terminal@0.12.0 | https://github.com/gtanner/qrcode-terminal | N/A |
-
-### License: Apache-2.0
-
-| Name | Repository | Publisher |
-| ------------------------------------ | ------------------------------------------------------------------------ | -------------------- |
-| @ampproject/remapping@2.3.0 | https://github.com/ampproject/remapping | Justin Ridgewell |
-| @balena/dockerignore@1.0.2 | https://github.com/balena-io-modules/dockerignore | N/A |
-| @eslint/config-array@0.19.2 | https://github.com/eslint/rewrite | Nicholas C. Zakas |
-| @eslint/core@0.10.0 | https://github.com/eslint/rewrite | Nicholas C. Zakas |
-| @eslint/core@0.11.0 | https://github.com/eslint/rewrite | Nicholas C. Zakas |
-| @eslint/object-schema@2.1.6 | https://github.com/eslint/rewrite | Nicholas C. Zakas |
-| @eslint/plugin-kit@0.2.5 | https://github.com/eslint/rewrite | Nicholas C. Zakas |
-| @grpc/grpc-js@1.12.6 | https://github.com/grpc/grpc-node/tree/master/packages/grpc-js | Google Inc. |
-| @grpc/proto-loader@0.7.13 | https://github.com/grpc/grpc-node | Google Inc. |
-| @humanfs/core@0.19.1 | https://github.com/humanwhocodes/humanfs | Nicholas C. Zakas |
-| @humanfs/node@0.16.6 | https://github.com/humanwhocodes/humanfs | Nicholas C. Zakas |
-| @humanwhocodes/module-importer@1.0.1 | https://github.com/humanwhocodes/module-importer | Nicholas C. Zaks |
-| @humanwhocodes/retry@0.3.1 | https://github.com/humanwhocodes/retry | Nicholas C. Zaks |
-| @humanwhocodes/retry@0.4.1 | https://github.com/humanwhocodes/retry | Nicholas C. Zaks |
-| @puppeteer/browsers@2.7.1 | https://github.com/puppeteer/puppeteer/tree/main/packages/browsers | The Chromium Authors |
-| @scarf/scarf@1.4.0 | https://github.com/scarf-sh/scarf-js | Scarf Systems |
-| @sigstore/bundle@3.0.0 | https://github.com/sigstore/sigstore-js | bdehamer@github.com |
-| @sigstore/core@2.0.0 | https://github.com/sigstore/sigstore-js | bdehamer@github.com |
-| @sigstore/protobuf-specs@0.3.3 | https://github.com/sigstore/protobuf-specs | bdehamer@github.com |
-| @sigstore/sign@3.0.0 | https://github.com/sigstore/sigstore-js | bdehamer@github.com |
-| @sigstore/tuf@3.0.0 | https://github.com/sigstore/sigstore-js | bdehamer@github.com |
-| @sigstore/verify@2.0.0 | https://github.com/sigstore/sigstore-js | bdehamer@github.com |
-| b4a@1.6.7 | https://github.com/holepunchto/b4a | Holepunch |
-| bare-events@2.5.4 | https://github.com/holepunchto/bare-events | Holepunch |
-| bare-fs@4.0.1 | https://github.com/holepunchto/bare-fs | Holepunch |
-| bare-os@3.4.0 | https://github.com/holepunchto/bare-os | Holepunch |
-| bare-path@3.0.0 | https://github.com/holepunchto/bare-path | Holepunch |
-| bare-stream@2.6.5 | https://github.com/holepunchto/bare-stream | Holepunch |
-| bser@2.1.1 | https://github.com/facebook/watchman | Wez Furlong |
-| chromium-bidi@1.2.0 | https://github.com/GoogleChromeLabs/chromium-bidi | The Chromium Authors |
-| detect-libc@2.0.3 | https://github.com/lovell/detect-libc | Lovell Fuller |
-| docker-modem@5.0.6 | https://github.com/apocas/docker-modem | Pedro Dias |
-| dockerode@4.0.4 | https://github.com/apocas/dockerode | Pedro Dias |
-| ejs@3.1.10 | https://github.com/mde/ejs | Matthew Eernisse |
-| eslint-visitor-keys@3.4.3 | https://github.com/eslint/eslint-visitor-keys | Toru Nagashima |
-| eslint-visitor-keys@4.2.0 | https://github.com/eslint/js | Toru Nagashima |
-| exponential-backoff@3.1.1 | https://github.com/coveo/exponential-backoff | Sami Sayegh |
-| fb-watchman@2.0.2 | https://github.com/facebook/watchman | Wez Furlong |
-| filelist@1.0.4 | https://github.com/mde/filelist | Matthew Eernisse |
-| human-signals@2.1.0 | https://github.com/ehmicky/human-signals | ehmicky |
-| jake@10.9.2 | https://github.com/jakejs/jake | Matthew Eernisse |
-| long@5.2.4 | https://github.com/dcodeIO/long.js | Daniel Wirtz |
-| puppeteer-core@24.2.0 | https://github.com/puppeteer/puppeteer/tree/main/packages/puppeteer-core | The Chromium Authors |
-| puppeteer@24.2.0 | https://github.com/puppeteer/puppeteer/tree/main/packages/puppeteer | The Chromium Authors |
-| sigstore@3.0.0 | https://github.com/sigstore/sigstore-js | bdehamer@github.com |
-| spdx-correct@3.2.0 | https://github.com/jslicense/spdx-correct.js | N/A |
-| swagger-ui-dist@5.18.3 | https://github.com/swagger-api/swagger-ui | N/A |
-| text-decoder@1.2.3 | https://github.com/holepunchto/text-decoder | Holepunch |
-| tunnel-agent@0.6.0 | https://github.com/mikeal/tunnel-agent | Mikeal Rogers |
-| typescript@5.7.3 | https://github.com/microsoft/TypeScript | Microsoft Corp. |
-| validate-npm-package-license@3.0.4 | https://github.com/kemitchell/validate-npm-package-license.js | Kyle E. Mitchell |
-| walker@1.0.8 | https://github.com/daaku/nodejs-walker | Naitik Shah |
-
-### License: Artistic-2.0
-
-| Name | Repository | Publisher |
-| ---------- | -------------------------- | ----------- |
-| npm@11.1.0 | https://github.com/npm/cli | GitHub Inc. |
-
-### License: BlueOak-1.0.0
-
-| Name | Repository | Publisher |
-| ---------------------------- | ------------------------------------------------ | ------------------ |
-| chownr@3.0.0 | https://github.com/isaacs/chownr | Isaac Z. Schlueter |
-| jackspeak@3.4.3 | https://github.com/isaacs/jackspeak | Isaac Z. Schlueter |
-| package-json-from-dist@1.0.1 | https://github.com/isaacs/package-json-from-dist | Isaac Z. Schlueter |
-| path-scurry@1.11.1 | https://github.com/isaacs/path-scurry | Isaac Z. Schlueter |
-| yallist@5.0.0 | https://github.com/isaacs/yallist | Isaac Z. Schlueter |
-
-### License: CC-BY-3.0
-
-| Name | Repository | Publisher |
-| --------------------- | -------------------------------------------------- | -------------------- |
-| spdx-exceptions@2.5.0 | https://github.com/kemitchell/spdx-exceptions.json | The Linux Foundation |
-
-### License: CC-BY-4.0
-
-| Name | Repository | Publisher |
-| ------------------------- | -------------------------------------------- | ---------- |
-| caniuse-lite@1.0.30001698 | https://github.com/browserslist/caniuse-lite | Ben Briggs |
-
-### License: Python-2.0
-
-| Name | Repository | Publisher |
-| -------------- | ---------------------------------- | --------- |
-| argparse@2.0.1 | https://github.com/nodeca/argparse | N/A |
diff --git a/LICENSE b/LICENSE
index 1e9ecebd..428e5953 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,28 +1,407 @@
-BSD 3-Clause License
-
-Copyright (c) 2024, ItsNik
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
-
-2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
-3. Neither the name of the copyright holder nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+Attribution-NonCommercial 4.0 International
+
+=======================================================================
+
+Creative Commons Corporation ("Creative Commons") is not a law firm and
+does not provide legal services or legal advice. Distribution of
+Creative Commons public licenses does not create a lawyer-client or
+other relationship. Creative Commons makes its licenses and related
+information available on an "as-is" basis. Creative Commons gives no
+warranties regarding its licenses, any material licensed under their
+terms and conditions, or any related information. Creative Commons
+disclaims all liability for damages resulting from their use to the
+fullest extent possible.
+
+Using Creative Commons Public Licenses
+
+Creative Commons public licenses provide a standard set of terms and
+conditions that creators and other rights holders may use to share
+original works of authorship and other material subject to copyright
+and certain other rights specified in the public license below. The
+following considerations are for informational purposes only, are not
+exhaustive, and do not form part of our licenses.
+
+ Considerations for licensors: Our public licenses are
+ intended for use by those authorized to give the public
+ permission to use material in ways otherwise restricted by
+ copyright and certain other rights. Our licenses are
+ irrevocable. Licensors should read and understand the terms
+ and conditions of the license they choose before applying it.
+ Licensors should also secure all rights necessary before
+ applying our licenses so that the public can reuse the
+ material as expected. Licensors should clearly mark any
+ material not subject to the license. This includes other CC-
+ licensed material, or material used under an exception or
+ limitation to copyright. More considerations for licensors:
+ wiki.creativecommons.org/Considerations_for_licensors
+
+ Considerations for the public: By using one of our public
+ licenses, a licensor grants the public permission to use the
+ licensed material under specified terms and conditions. If
+ the licensor's permission is not necessary for any reason--for
+ example, because of any applicable exception or limitation to
+ copyright--then that use is not regulated by the license. Our
+ licenses grant only permissions under copyright and certain
+ other rights that a licensor has authority to grant. Use of
+ the licensed material may still be restricted for other
+ reasons, including because others have copyright or other
+ rights in the material. A licensor may make special requests,
+ such as asking that all changes be marked or described.
+ Although not required by our licenses, you are encouraged to
+ respect those requests where reasonable. More considerations
+ for the public:
+ wiki.creativecommons.org/Considerations_for_licensees
+
+=======================================================================
+
+Creative Commons Attribution-NonCommercial 4.0 International Public
+License
+
+By exercising the Licensed Rights (defined below), You accept and agree
+to be bound by the terms and conditions of this Creative Commons
+Attribution-NonCommercial 4.0 International Public License ("Public
+License"). To the extent this Public License may be interpreted as a
+contract, You are granted the Licensed Rights in consideration of Your
+acceptance of these terms and conditions, and the Licensor grants You
+such rights in consideration of benefits the Licensor receives from
+making the Licensed Material available under these terms and
+conditions.
+
+
+Section 1 -- Definitions.
+
+ a. Adapted Material means material subject to Copyright and Similar
+ Rights that is derived from or based upon the Licensed Material
+ and in which the Licensed Material is translated, altered,
+ arranged, transformed, or otherwise modified in a manner requiring
+ permission under the Copyright and Similar Rights held by the
+ Licensor. For purposes of this Public License, where the Licensed
+ Material is a musical work, performance, or sound recording,
+ Adapted Material is always produced where the Licensed Material is
+ synched in timed relation with a moving image.
+
+ b. Adapter's License means the license You apply to Your Copyright
+ and Similar Rights in Your contributions to Adapted Material in
+ accordance with the terms and conditions of this Public License.
+
+ c. Copyright and Similar Rights means copyright and/or similar rights
+ closely related to copyright including, without limitation,
+ performance, broadcast, sound recording, and Sui Generis Database
+ Rights, without regard to how the rights are labeled or
+ categorized. For purposes of this Public License, the rights
+ specified in Section 2(b)(1)-(2) are not Copyright and Similar
+ Rights.
+ d. Effective Technological Measures means those measures that, in the
+ absence of proper authority, may not be circumvented under laws
+ fulfilling obligations under Article 11 of the WIPO Copyright
+ Treaty adopted on December 20, 1996, and/or similar international
+ agreements.
+
+ e. Exceptions and Limitations means fair use, fair dealing, and/or
+ any other exception or limitation to Copyright and Similar Rights
+ that applies to Your use of the Licensed Material.
+
+ f. Licensed Material means the artistic or literary work, database,
+ or other material to which the Licensor applied this Public
+ License.
+
+ g. Licensed Rights means the rights granted to You subject to the
+ terms and conditions of this Public License, which are limited to
+ all Copyright and Similar Rights that apply to Your use of the
+ Licensed Material and that the Licensor has authority to license.
+
+ h. Licensor means the individual(s) or entity(ies) granting rights
+ under this Public License.
+
+ i. NonCommercial means not primarily intended for or directed towards
+ commercial advantage or monetary compensation. For purposes of
+ this Public License, the exchange of the Licensed Material for
+ other material subject to Copyright and Similar Rights by digital
+ file-sharing or similar means is NonCommercial provided there is
+ no payment of monetary compensation in connection with the
+ exchange.
+
+ j. Share means to provide material to the public by any means or
+ process that requires permission under the Licensed Rights, such
+ as reproduction, public display, public performance, distribution,
+ dissemination, communication, or importation, and to make material
+ available to the public including in ways that members of the
+ public may access the material from a place and at a time
+ individually chosen by them.
+
+ k. Sui Generis Database Rights means rights other than copyright
+ resulting from Directive 96/9/EC of the European Parliament and of
+ the Council of 11 March 1996 on the legal protection of databases,
+ as amended and/or succeeded, as well as other essentially
+ equivalent rights anywhere in the world.
+
+ l. You means the individual or entity exercising the Licensed Rights
+ under this Public License. Your has a corresponding meaning.
+
+
+Section 2 -- Scope.
+
+ a. License grant.
+
+ 1. Subject to the terms and conditions of this Public License,
+ the Licensor hereby grants You a worldwide, royalty-free,
+ non-sublicensable, non-exclusive, irrevocable license to
+ exercise the Licensed Rights in the Licensed Material to:
+
+ a. reproduce and Share the Licensed Material, in whole or
+ in part, for NonCommercial purposes only; and
+
+ b. produce, reproduce, and Share Adapted Material for
+ NonCommercial purposes only.
+
+ 2. Exceptions and Limitations. For the avoidance of doubt, where
+ Exceptions and Limitations apply to Your use, this Public
+ License does not apply, and You do not need to comply with
+ its terms and conditions.
+
+ 3. Term. The term of this Public License is specified in Section
+ 6(a).
+
+ 4. Media and formats; technical modifications allowed. The
+ Licensor authorizes You to exercise the Licensed Rights in
+ all media and formats whether now known or hereafter created,
+ and to make technical modifications necessary to do so. The
+ Licensor waives and/or agrees not to assert any right or
+ authority to forbid You from making technical modifications
+ necessary to exercise the Licensed Rights, including
+ technical modifications necessary to circumvent Effective
+ Technological Measures. For purposes of this Public License,
+ simply making modifications authorized by this Section 2(a)
+ (4) never produces Adapted Material.
+
+ 5. Downstream recipients.
+
+ a. Offer from the Licensor -- Licensed Material. Every
+ recipient of the Licensed Material automatically
+ receives an offer from the Licensor to exercise the
+ Licensed Rights under the terms and conditions of this
+ Public License.
+
+ b. No downstream restrictions. You may not offer or impose
+ any additional or different terms or conditions on, or
+ apply any Effective Technological Measures to, the
+ Licensed Material if doing so restricts exercise of the
+ Licensed Rights by any recipient of the Licensed
+ Material.
+
+ 6. No endorsement. Nothing in this Public License constitutes or
+ may be construed as permission to assert or imply that You
+ are, or that Your use of the Licensed Material is, connected
+ with, or sponsored, endorsed, or granted official status by,
+ the Licensor or others designated to receive attribution as
+ provided in Section 3(a)(1)(A)(i).
+
+ b. Other rights.
+
+ 1. Moral rights, such as the right of integrity, are not
+ licensed under this Public License, nor are publicity,
+ privacy, and/or other similar personality rights; however, to
+ the extent possible, the Licensor waives and/or agrees not to
+ assert any such rights held by the Licensor to the limited
+ extent necessary to allow You to exercise the Licensed
+ Rights, but not otherwise.
+
+ 2. Patent and trademark rights are not licensed under this
+ Public License.
+
+ 3. To the extent possible, the Licensor waives any right to
+ collect royalties from You for the exercise of the Licensed
+ Rights, whether directly or through a collecting society
+ under any voluntary or waivable statutory or compulsory
+ licensing scheme. In all other cases the Licensor expressly
+ reserves any right to collect such royalties, including when
+ the Licensed Material is used other than for NonCommercial
+ purposes.
+
+
+Section 3 -- License Conditions.
+
+Your exercise of the Licensed Rights is expressly made subject to the
+following conditions.
+
+ a. Attribution.
+
+ 1. If You Share the Licensed Material (including in modified
+ form), You must:
+
+ a. retain the following if it is supplied by the Licensor
+ with the Licensed Material:
+
+ i. identification of the creator(s) of the Licensed
+ Material and any others designated to receive
+ attribution, in any reasonable manner requested by
+ the Licensor (including by pseudonym if
+ designated);
+
+ ii. a copyright notice;
+
+ iii. a notice that refers to this Public License;
+
+ iv. a notice that refers to the disclaimer of
+ warranties;
+
+ v. a URI or hyperlink to the Licensed Material to the
+ extent reasonably practicable;
+
+ b. indicate if You modified the Licensed Material and
+ retain an indication of any previous modifications; and
+
+ c. indicate the Licensed Material is licensed under this
+ Public License, and include the text of, or the URI or
+ hyperlink to, this Public License.
+
+ 2. You may satisfy the conditions in Section 3(a)(1) in any
+ reasonable manner based on the medium, means, and context in
+ which You Share the Licensed Material. For example, it may be
+ reasonable to satisfy the conditions by providing a URI or
+ hyperlink to a resource that includes the required
+ information.
+
+ 3. If requested by the Licensor, You must remove any of the
+ information required by Section 3(a)(1)(A) to the extent
+ reasonably practicable.
+
+ 4. If You Share Adapted Material You produce, the Adapter's
+ License You apply must not prevent recipients of the Adapted
+ Material from complying with this Public License.
+
+
+Section 4 -- Sui Generis Database Rights.
+
+Where the Licensed Rights include Sui Generis Database Rights that
+apply to Your use of the Licensed Material:
+
+ a. for the avoidance of doubt, Section 2(a)(1) grants You the right
+ to extract, reuse, reproduce, and Share all or a substantial
+ portion of the contents of the database for NonCommercial purposes
+ only;
+
+ b. if You include all or a substantial portion of the database
+ contents in a database in which You have Sui Generis Database
+ Rights, then the database in which You have Sui Generis Database
+ Rights (but not its individual contents) is Adapted Material; and
+
+ c. You must comply with the conditions in Section 3(a) if You Share
+ all or a substantial portion of the contents of the database.
+
+For the avoidance of doubt, this Section 4 supplements and does not
+replace Your obligations under this Public License where the Licensed
+Rights include other Copyright and Similar Rights.
+
+
+Section 5 -- Disclaimer of Warranties and Limitation of Liability.
+
+ a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
+ EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
+ AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
+ ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
+ IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
+ WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
+ ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
+ KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
+ ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
+
+ b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
+ TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
+ NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
+ INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
+ COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
+ USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
+ DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
+ IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
+
+ c. The disclaimer of warranties and limitation of liability provided
+ above shall be interpreted in a manner that, to the extent
+ possible, most closely approximates an absolute disclaimer and
+ waiver of all liability.
+
+
+Section 6 -- Term and Termination.
+
+ a. This Public License applies for the term of the Copyright and
+ Similar Rights licensed here. However, if You fail to comply with
+ this Public License, then Your rights under this Public License
+ terminate automatically.
+
+ b. Where Your right to use the Licensed Material has terminated under
+ Section 6(a), it reinstates:
+
+ 1. automatically as of the date the violation is cured, provided
+ it is cured within 30 days of Your discovery of the
+ violation; or
+
+ 2. upon express reinstatement by the Licensor.
+
+ For the avoidance of doubt, this Section 6(b) does not affect any
+ right the Licensor may have to seek remedies for Your violations
+ of this Public License.
+
+ c. For the avoidance of doubt, the Licensor may also offer the
+ Licensed Material under separate terms or conditions or stop
+ distributing the Licensed Material at any time; however, doing so
+ will not terminate this Public License.
+
+ d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
+ License.
+
+
+Section 7 -- Other Terms and Conditions.
+
+ a. The Licensor shall not be bound by any additional or different
+ terms or conditions communicated by You unless expressly agreed.
+
+ b. Any arrangements, understandings, or agreements regarding the
+ Licensed Material not stated herein are separate from and
+ independent of the terms and conditions of this Public License.
+
+
+Section 8 -- Interpretation.
+
+ a. For the avoidance of doubt, this Public License does not, and
+ shall not be interpreted to, reduce, limit, restrict, or impose
+ conditions on any use of the Licensed Material that could lawfully
+ be made without permission under this Public License.
+
+ b. To the extent possible, if any provision of this Public License is
+ deemed unenforceable, it shall be automatically reformed to the
+ minimum extent necessary to make it enforceable. If the provision
+ cannot be reformed, it shall be severed from this Public License
+ without affecting the enforceability of the remaining terms and
+ conditions.
+
+ c. No term or condition of this Public License will be waived and no
+ failure to comply consented to unless expressly agreed to by the
+ Licensor.
+
+ d. Nothing in this Public License constitutes or may be interpreted
+ as a limitation upon, or waiver of, any privileges and immunities
+ that apply to the Licensor or You, including from the legal
+ processes of any jurisdiction or authority.
+
+=======================================================================
+
+Creative Commons is not a party to its public
+licenses. Notwithstanding, Creative Commons may elect to apply one of
+its public licenses to material it publishes and in those instances
+will be considered the "Licensor." The text of the Creative Commons
+public licenses is dedicated to the public domain under the CC0 Public
+Domain Dedication. Except for the limited purpose of indicating that
+material is shared under a Creative Commons public license or as
+otherwise permitted by the Creative Commons policies published at
+creativecommons.org/policies, Creative Commons does not authorize the
+use of the trademark "Creative Commons" or any other trademark or logo
+of Creative Commons without its prior written consent including,
+without limitation, in connection with any unauthorized modifications
+to any of its public licenses or any other arrangements,
+understandings, or agreements concerning use of licensed material. For
+the avoidance of doubt, this paragraph does not form part of the
+public licenses.
+
+Creative Commons may be contacted at creativecommons.org.
diff --git a/README.md b/README.md
index 4fc979cf..cbb25b7a 100644
--- a/README.md
+++ b/README.md
@@ -1,75 +1,72 @@
-# Deprecation Warning!
-# V2 is abondend, since there where to many issues in the codebase!
-# Please see v3 (next commit from this one onwards, all other branches which are not based on bun will be deleted!)
+# DockStat API v3
-# DockStatAPI v2
+! WIP Documentation !
-
+## Usage
-
+The DockStat API provides the following endpoints:
-# Pipelines
+### Docker Containers
+- `GET /docker/containers`: Retrieve statistics for all containers across all configured Docker hosts.
-[](https://github.com/Its4Nik/dockstatapi/actions/workflows/build-image.yml)
-[](https://github.com/Its4Nik/dockstatapi/actions/workflows/validation.yml)
+### Docker Hosts
+- `GET /docker/hosts/:id`: Retrieve configuration and statistics for a specific Docker host.
-
+### Docker Configuration
+- `POST /docker-config/add-host`: Add a new Docker host.
+- `POST /docker-config/update-host`: Update an existing Docker host.
+- `GET /docker-config/hosts`: Retrieve a list of all configured Docker hosts.
-This specific branch contains the currently WIP **DockStatAPI-v2**, this update will bring major breaking changes so please be careful.
-With this new release a couple of extra features (compared to v1) are going to be available.
+### API Configuration
+- `GET /config/get`: Retrieve the current API configuration.
+- `POST /config/update`: Update the API configuration.
-### Feature List:
+### Logs
+- `GET /logs`: Retrieve all backend logs.
+- `GET /logs/:level`: Retrieve logs filtered by log level.
+- `DELETE /logs`: Clear all backend logs.
+- `DELETE /logs/:level`: Clear logs by log level.
-- Swagger API Documentation
-- Database (Keeps data for 24 hours max)
-- Advanced authentication using hashes and salt
-- Custom TypeScript/JavaScript notification modules! (Easy to add and configure!)
-- `http` API to configure the backend
-- Multi-arch docker builds (using buildx github action)
-- Advanced security through middlewares: rate-limiting and authentication
-- Multi Arch Docker builds through docker buildx
-- High Availability using single master and unlimited worker nodes!
-- Dynamically created Graphs
+### Websocket
+- `WS(S) /docker/stats`: Retrieve the current API configuration.
-# 🔗 DockStatAPI v2 Documentation
+## API
-_⚠️ = Deprecation warning_
+The DockStat API exposes the following endpoints:
-- [Introduction](https://outline.itsnik.de/s/dockstat)
+| Endpoint | Method | Description |
+| --- | --- | --- |
+| `/docker/containers` | `GET` | Retrieve statistics for all containers across all configured Docker hosts. |
+| `/docker/hosts/:id` | `GET` | Retrieve configuration and statistics for a specific Docker host. |
+| `/docker-config/add-host` | `POST` | Add a new Docker host. |
+| `/docker-config/update-host` | `POST` | Update an existing Docker host. |
+| `/docker-config/hosts` | `GET` | Retrieve a list of all configured Docker hosts. |
+| `/config/get` | `GET` | Retrieve the current API configuration. |
+| `/config/update` | `POST` | Update the API configuration. |
+| `/logs` | `GET` | Retrieve all backend logs. |
+| `/logs/:level` | `GET` | Retrieve logs filtered by log level. |
+| `/logs` | `DELETE` | Clear all backend logs. |
+| `/logs/:level` | `DELETE` | Clear logs by log level. |
- - [DockstatAPI v2](https://outline.itsnik.de/s/dockstat/doc/dockstatapi-v2-XRMDKRqMIg)
+## Contributing
- - [API reference](https://outline.itsnik.de/s/dockstat/doc/api-reference-1PTxqx1MQ6)
- - [How dependency graphs are made](https://outline.itsnik.de/s/dockstat/doc/how-the-dependecy-graphs-are-made-svuZbEHH9g)
+1. Fork the repository.
+2. Create a new branch for your feature or bug fix.
+3. Make your changes and commit them.
+4. Push your branch to your forked repository.
+5. Submit a pull request to the main repository.
- - [DockStat v1](https://outline.itsnik.de/s/dockstat/doc/dockstat-v1-zVaFS4zROI)
+## License
- - [⚠️ Customisation](https://outline.itsnik.de/s/dockstat/doc/customization-PiBz4OpQIZ)
- - [⚠️ Themes](https://outline.itsnik.de/s/dockstat/doc/themes-BFhN6ZBbYx)
- - [⚠️ Installation](https://outline.itsnik.de/s/dockstat/doc/installation-DaO99bB86q)
+This project is licensed under the CC BY-NC 4.0 License.
+
- - [⚠️ DockStatAPI v1](https://outline.itsnik.de/s/dockstat/doc/dockstatapi-v1-jLcVCfPNmS)
- - [⚠️ Integrations](https://outline.itsnik.de/s/dockstat/doc/integrations-Agq1oL6HxF)
- - [⚠️ Backend API reference](https://outline.itsnik.de/s/dockstat/doc/backend-api-reference-YzcBbDvY33)
+## Testing
-# Dependencies
-
-Please see [CREDITS.md](./CREDITS.md).
-
-To create the credits file use: `npm run license`
-
-Or if you want it as a pre-commit hook create this file:
-
-```bash
-#!/bin/bash
-# .git/hooks/pre-commit
-
-npm run license
+To run the tests, execute the following command:
+(Currently no tests configured!)
+```
+bun test
```
-# DockStat(APIs) goals
-
-DockStack tries to be a lightweigh and more "dashboard" like then [portainer](https://github.com/portainer/portainer), [cAdvisor](https://github.com/google/cadvisor), [dockge](https://github.com/louislam/dockge), ...
-I also try to add some "extensions", like in V1 with [🥤cup](https://github.com/sergi0g/cup).
-Everything is configured through a backend with Swagger documentation, so that you can follow the code and understand the new v2 frontend better!
-DockStat is mainly used for teaching [myself](https://github.com/Its4Nik) more about TypeScript, APIs and backend development!
+This will run the test suite and report the results.
diff --git a/TODO.md b/TODO.md
deleted file mode 100644
index b850ba72..00000000
--- a/TODO.md
+++ /dev/null
@@ -1,18 +0,0 @@
-- [x] ~Better Offline mode using "faker" library or self written (probably self written)~ Not needed since there is a docker-compsoe file for local testing integrated inside the repo
-- [x] HA compatibility
-- [x] !!! Needs testing !!! Add automatic notifications when container state changes, according to selected level for notification service
-- [ ] Image update and update notifications
-- [ ] trigger container restart / stop / start via backend routes
-- [x] Add more logging
-- [x] Structure code differently
-- [x] Write new README and make the docs better
-- [x] Update more files to correct TS syntax => remove "any"
-- [x] Websockets
-- [x] Better /api/status endpoint with connection status of each host
-- [x] Update notification service
-- [x] Adjust process.env variables since they don't really work as expected (See [commit](https://github.com/Its4Nik/dockstatapi/pull/21/commits/a03b58c7a17e269f46216df5492e18d008774961))
-- [ ] Better project structure
-- [x] Update logging => Better errors
-- [x] Update json responses
-- [x] Swagger update
-- [ ] Edge case testing
diff --git a/__tests__/auth.spec.ts b/__tests__/auth.spec.ts
deleted file mode 100644
index 84c5f04a..00000000
--- a/__tests__/auth.spec.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-export const testPass = "123456789";
-import { Server } from "http";
-import supertest from "supertest";
-import { startServer } from "../src/utils/startServer";
-import app from "../src/server";
-
-const port = 13001;
-const server = new Server(app);
-
-startServer(app, server, port);
-
-const request = supertest(`http://localhost:${port}`);
-
-describe("Authentication", () => {
- it("Enable Authentication", async () => {
- const res = await request.post(`/auth/enable?password=${testPass}`);
- expect(res.status).toEqual(200);
- expect(res.type).toEqual(expect.stringContaining("json"));
- expect(res.body).toHaveProperty(
- "message",
- "Authentication enabled successfully",
- );
- });
-
- it("Test no password", async () => {
- const res = await request.get("/api/status");
- expect(res.status).toEqual(403);
- expect(res.type).toEqual(expect.stringContaining("json"));
- });
-
- it("Disable authentication", async () => {
- const res = await request
- .post(`/auth/disable?password=${testPass}`)
- .set("x-password", testPass);
- expect(res.status).toEqual(200);
- expect(res.type).toEqual(expect.stringContaining("json"));
- });
-});
diff --git a/__tests__/config.spec.ts b/__tests__/config.spec.ts
deleted file mode 100644
index 2650e9ed..00000000
--- a/__tests__/config.spec.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import supertest from "supertest";
-import { startServer } from "../src/utils/startServer";
-import app from "../src/server";
-import { Server } from "http";
-
-const port = 13002;
-const server = new Server(app);
-
-startServer(app, server, port);
-
-const request = supertest(`http://localhost:${port}`);
-
-const mockServerName: string = "mockstatapi";
-const mockServerIP: string = "127.0.0.1";
-const mockServerPort: number = 2375;
-
-describe("Config endpoints", () => {
- it("Add an host", async () => {
- let res = await request.put(
- `/conf/addHost?name=${mockServerName}&url=${mockServerIP}&port=${mockServerPort}`,
- );
- expect(res.status).toEqual(200);
-
- res = await request.get("/api/hosts");
- expect(res.status).toEqual(200);
- expect(res.body).toContain("mockstatapi");
- });
-
- it("Adjust scheduler", async () => {
- let res = await request.put("/conf/scheduler?interval=10m");
- expect(res.status).toEqual(200);
-
- res = await request.get("/api/current-schedule");
- expect(res.status).toEqual(200);
-
- // Reset to standart 5m
- res = await request.put("/conf/scheduler?interval=5m");
- expect(res.status).toEqual(200);
- });
-
- it("Remove Host from config", async () => {
- let res = await request.delete(`/conf/removeHost?hostName=mockstatapi`);
- expect(res.status).toEqual(200);
-
- res = await request.get("/api/hosts");
- expect(res.status).toEqual(200);
- expect(res.body).not.toHaveProperty("mockstatapi");
- });
-});
diff --git a/__tests__/database.spec.ts b/__tests__/database.spec.ts
deleted file mode 100644
index 55102ce9..00000000
--- a/__tests__/database.spec.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import supertest from "supertest";
-import { startServer } from "../src/utils/startServer";
-import app from "../src/server";
-import { Server } from "http";
-
-const port = 13003;
-const server = new Server(app);
-
-startServer(app, server, port);
-
-const request = supertest(`http://localhost:${port}`);
-
-describe("Database", () => {
- it("Get latest database entry", async () => {
- const res = await request.get("/data/latest");
- expect(res.status).toEqual(200);
- });
-
- it("Get all database entries", async () => {
- const res = await request.get("/data/all");
- expect(res.status).toEqual(200);
- });
-
- it("Clear database", async () => {
- let res = await request.delete("/data/clear");
- expect(res.status).toEqual(200);
-
- res = await request.get("/data/latest");
- expect(res.status).toEqual(404);
- expect(res.body).toHaveProperty(
- "message",
- "No data available for /data/latest",
- );
- });
-});
diff --git a/__tests__/frontend.spec.ts b/__tests__/frontend.spec.ts
deleted file mode 100644
index af25adc5..00000000
--- a/__tests__/frontend.spec.ts
+++ /dev/null
@@ -1,123 +0,0 @@
-import supertest from "supertest";
-import { startServer } from "../src/utils/startServer";
-import app from "../src/server";
-import { Server } from "http";
-
-const port = 13004;
-const server = new Server(app);
-
-startServer(app, server, port);
-
-const request = supertest(`http://localhost:${port}`);
-
-const sec: number = 1000;
-
-const mockContainer: string = "dockstatapi";
-const mockLink: string = "https://github.com/its4nik/dockstatapi";
-const mockIcon: string = "dockstatapi.png";
-const mockTag1: string = "backend";
-const mockTag2: string = "local";
-
-const verifiedResponse = [
- {
- name: "dockstatapi",
- tags: ["backend", "local"],
- pinned: true,
- link: "https://github.com/its4nik/dockstatapi",
- icon: "dockstatapi.png",
- hidden: true,
- },
-];
-
-describe("Test frontend specific configurations", () => {
- it(
- "Setup the configuration file",
- async () => {
- // Hide container
- let res = await request.delete(`/frontend/hide/${mockContainer}`);
-
- expect(res.status).toEqual(200);
-
- // Add Tag(s)
- res = await request.post(`/frontend/tag/${mockContainer}/${mockTag1}`);
-
- expect(res.status).toEqual(200);
- res = await request.post(`/frontend/tag/${mockContainer}/${mockTag2}`);
-
- expect(res.status).toEqual(200);
-
- // Pin container
- res = await request.post(`/frontend/pin/${mockContainer}`);
-
- expect(res.status).toEqual(200);
-
- // Add link
- res = await request.post(
- `/frontend/add-link/${mockContainer}/${encodeURIComponent(mockLink)}`,
- );
-
- expect(res.status).toEqual(200);
-
- // Add icon
- res = await request.post(
- `/frontend/add-icon/${mockContainer}/${mockIcon}/false`,
- );
-
- expect(res.status).toEqual(200);
- },
- 60 * sec,
- );
-
- it("Verify the configuration", async () => {
- const res = await request.get("/api/frontend-config");
-
- expect(res.status).toEqual(200);
- expect(res.body).toEqual(verifiedResponse);
- });
-
- it(
- "Reset configuration",
- async () => {
- // Show container
- let res = await request.post(`/frontend/show/${mockContainer}`);
-
- expect(res.status).toEqual(200);
-
- // Remove tag(s)
- res = await request.delete(
- `/frontend/remove-tag/${mockContainer}/${mockTag1}`,
- );
-
- expect(res.status).toEqual(200);
-
- res = await request.delete(
- `/frontend/remove-tag/${mockContainer}/${mockTag2}`,
- );
-
- expect(res.status).toEqual(200);
-
- // Unpin
- res = await request.delete(`/frontend/unpin/${mockContainer}`);
-
- expect(res.status).toEqual(200);
-
- // Remove link
- res = await request.delete(`/frontend/remove-link/${mockContainer}`);
-
- expect(res.status).toEqual(200);
-
- // Remove icon
- res = await request.delete(`/frontend/remove-icon/${mockContainer}`);
-
- expect(res.status).toEqual(200);
- },
- 60 * sec,
- );
-
- it("Verify the reset configuration", async () => {
- const res = await request.get("/api/frontend-config");
-
- expect(res.status).toEqual(200);
- expect(res.body).toEqual([]);
- });
-});
diff --git a/__tests__/getters.spec.ts b/__tests__/getters.spec.ts
deleted file mode 100644
index f951f42a..00000000
--- a/__tests__/getters.spec.ts
+++ /dev/null
@@ -1,99 +0,0 @@
-import { createPreviousResponse } from "./util/previousResponse";
-import supertest from "supertest";
-import { startServer } from "../src/utils/startServer";
-import app from "../src/server";
-import { Server } from "http";
-
-const port = 13005;
-const server = new Server(app);
-
-startServer(app, server, port);
-
-const request = supertest(`http://localhost:${port}`);
-const PreviousResponse = createPreviousResponse();
-
-describe("Get endpoints", () => {
- it("GET /api/hosts", async () => {
- const res = await request.get("/api/hosts");
- expect(res.status).toEqual(200);
- expect(res.type).toEqual(expect.stringContaining("json"));
-
- const hosts: string[] = res.body;
-
- if (hosts.length >= 1) {
- expect(Array.isArray(hosts)).toBe(true);
- expect(hosts.length).toBeGreaterThan(0);
- expect(typeof hosts[0]).toBe("string");
- PreviousResponse.set(hosts[0]);
- }
- });
-
- it("GET /api/host/:host/stats", async () => {
- const host = PreviousResponse.get();
-
- if (!host) {
- console.log("No hosts found, skipping /api/host/:host/stats test");
- return;
- }
-
- const res = await request.get(`/api/host/${host}/stats`);
-
- expect(res.status).toEqual(200);
- expect(res.type).toEqual(expect.stringContaining("json"));
- });
-
- it("GET /api/system", async () => {
- const res = await request.get("/api/system");
- expect(res.status).toEqual(200);
- expect(res.type).toEqual(expect.stringContaining("json"));
- });
-
- it("GET /api/status", async () => {
- const res = await request.get("/api/status");
- expect(res.status).toEqual(200);
- expect(res.type).toEqual(expect.stringContaining("json"));
- expect(res.body).toHaveProperty("ApiReachable", true);
- });
-
- it("GET /api/containers", async () => {
- const res = await request.get("/api/containers");
- expect(res.status).toEqual(200);
- expect(res.type).toEqual(expect.stringContaining("json"));
- });
-
- it("GET /api/config", async () => {
- const res = await request.get("/api/config");
- expect(res.status).toEqual(200);
- expect(res.type).toEqual(expect.stringContaining("json"));
- expect(res.body).toHaveProperty("hosts");
- });
-
- it("GET /api/current-schedule", async () => {
- const res = await request.get("/api/current-schedule");
-
- expect(res.status).toEqual(200);
- expect(res.type).toEqual(expect.stringContaining("json"));
- expect(res.body).toHaveProperty("interval");
- });
-
- it("GET /api/frontend-config", async () => {
- const res = await request.get("/api/frontend-config");
-
- expect(res.status).toEqual(200);
- expect(res.type).toEqual(expect.stringContaining("json"));
- });
-
- it("GET /ha/config", async () => {
- const res = await request.get("/ha/config");
- expect(res.status).toEqual(200);
- expect(res.type).toEqual(expect.stringContaining("json"));
- });
-
- it("GET /notification-service/get-template", async () => {
- const res = await request.get("/notification-service/get-template");
-
- expect(res.status).toEqual(200);
- expect(res.type).toEqual(expect.stringContaining("json"));
- expect(res.body).toHaveProperty("text");
- });
-});
diff --git a/__tests__/util/previousResponse.ts b/__tests__/util/previousResponse.ts
deleted file mode 100644
index 774a862a..00000000
--- a/__tests__/util/previousResponse.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-let response: string = "";
-
-class PreviousResponse {
- set(body: unknown): void {
- try {
- response = JSON.stringify(body).replace(/[" ]/g, "");
- } catch (error: unknown) {
- console.error("Error in setting response:", error);
- throw new Error("Failed to set response");
- }
- }
-
- get(): string {
- try {
- return response;
- } catch (error: unknown) {
- console.error("Error in getting response:", error);
- throw new Error("Failed to get response");
- }
- }
-}
-
-export const createPreviousResponse = () => new PreviousResponse();
diff --git a/bun.lock b/bun.lock
new file mode 100644
index 00000000..f91ae698
--- /dev/null
+++ b/bun.lock
@@ -0,0 +1,311 @@
+{
+ "lockfileVersion": 1,
+ "workspaces": {
+ "": {
+ "name": "dockstatapi",
+ "dependencies": {
+ "@elysiajs/static": "^1.2.0",
+ "@elysiajs/swagger": "^1.2.2",
+ "chalk": "^5.4.1",
+ "docker-compose": "^1.1.1",
+ "dockerode": "^4.0.4",
+ "elysia": "latest",
+ "split2": "^4.2.0",
+ "winston": "^3.17.0",
+ "winston-transport": "^4.9.0",
+ "yaml": "^2.7.0",
+ },
+ "devDependencies": {
+ "@types/dockerode": "^3.3.34",
+ "@types/split2": "^4.2.3",
+ "bun-types": "latest",
+ "cross-env": "^7.0.3",
+ "wrap-ansi": "^9.0.0",
+ },
+ },
+ },
+ "trustedDependencies": [
+ "protobufjs",
+ ],
+ "packages": {
+ "@balena/dockerignore": ["@balena/dockerignore@1.0.2", "", {}, "sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q=="],
+
+ "@colors/colors": ["@colors/colors@1.6.0", "", {}, "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA=="],
+
+ "@dabh/diagnostics": ["@dabh/diagnostics@2.0.3", "", { "dependencies": { "colorspace": "1.1.x", "enabled": "2.0.x", "kuler": "^2.0.0" } }, "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA=="],
+
+ "@elysiajs/static": ["@elysiajs/static@1.2.0", "", { "dependencies": { "node-cache": "^5.1.2" }, "peerDependencies": { "elysia": ">= 1.2.0" } }, "sha512-oLpAi8c+maPpA0XhhK3BELaIjIG+nXg/K9p8cFfW4q5ayRD59a3MOMOOGgpiXZkHJzLPWcouhhyyLAYtaANW4g=="],
+
+ "@elysiajs/swagger": ["@elysiajs/swagger@1.2.2", "", { "dependencies": { "@scalar/themes": "^0.9.52", "@scalar/types": "^0.0.12", "openapi-types": "^12.1.3", "pathe": "^1.1.2" }, "peerDependencies": { "elysia": ">= 1.2.0" } }, "sha512-DG0PbX/wzQNQ6kIpFFPCvmkkWTIbNWDS7lVLv3Puy6ONklF14B4NnbDfpYjX1hdSYKeCqKBBOuenh6jKm8tbYA=="],
+
+ "@grpc/grpc-js": ["@grpc/grpc-js@1.12.6", "", { "dependencies": { "@grpc/proto-loader": "^0.7.13", "@js-sdsl/ordered-map": "^4.4.2" } }, "sha512-JXUj6PI0oqqzTGvKtzOkxtpsyPRNsrmhh41TtIz/zEB6J+AUiZZ0dxWzcMwO9Ns5rmSPuMdghlTbUuqIM48d3Q=="],
+
+ "@grpc/proto-loader": ["@grpc/proto-loader@0.7.13", "", { "dependencies": { "lodash.camelcase": "^4.3.0", "long": "^5.0.0", "protobufjs": "^7.2.5", "yargs": "^17.7.2" }, "bin": { "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" } }, "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw=="],
+
+ "@js-sdsl/ordered-map": ["@js-sdsl/ordered-map@4.4.2", "", {}, "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw=="],
+
+ "@protobufjs/aspromise": ["@protobufjs/aspromise@1.1.2", "", {}, "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="],
+
+ "@protobufjs/base64": ["@protobufjs/base64@1.1.2", "", {}, "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="],
+
+ "@protobufjs/codegen": ["@protobufjs/codegen@2.0.4", "", {}, "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="],
+
+ "@protobufjs/eventemitter": ["@protobufjs/eventemitter@1.1.0", "", {}, "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q=="],
+
+ "@protobufjs/fetch": ["@protobufjs/fetch@1.1.0", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.1", "@protobufjs/inquire": "^1.1.0" } }, "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ=="],
+
+ "@protobufjs/float": ["@protobufjs/float@1.0.2", "", {}, "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="],
+
+ "@protobufjs/inquire": ["@protobufjs/inquire@1.1.0", "", {}, "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="],
+
+ "@protobufjs/path": ["@protobufjs/path@1.1.2", "", {}, "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="],
+
+ "@protobufjs/pool": ["@protobufjs/pool@1.1.0", "", {}, "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="],
+
+ "@protobufjs/utf8": ["@protobufjs/utf8@1.1.0", "", {}, "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="],
+
+ "@scalar/openapi-types": ["@scalar/openapi-types@0.1.1", "", {}, "sha512-NMy3QNk6ytcCoPUGJH0t4NNr36OWXgZhA3ormr3TvhX1NDgoF95wFyodGVH8xiHeUyn2/FxtETm8UBLbB5xEmg=="],
+
+ "@scalar/themes": ["@scalar/themes@0.9.68", "", { "dependencies": { "@scalar/types": "0.0.34" } }, "sha512-466ac2fdQJOBBSLkGUf88vuZVF+qNMeVpjb0aAHrKkxhpjucTPKdTYO8r2dsX1R5k9A13gWPnm594VW5G/bGHw=="],
+
+ "@scalar/types": ["@scalar/types@0.0.12", "", { "dependencies": { "@scalar/openapi-types": "0.1.1", "@unhead/schema": "^1.9.5" } }, "sha512-XYZ36lSEx87i4gDqopQlGCOkdIITHHEvgkuJFrXFATQs9zHARop0PN0g4RZYWj+ZpCUclOcaOjbCt8JGe22mnQ=="],
+
+ "@sinclair/typebox": ["@sinclair/typebox@0.34.27", "", {}, "sha512-C7mxE1VC3WC2McOufZXEU48IfRVI+BcKxk4NOyNn3+JMUNdJHEWGS5CqjuDX+ij2NCCz8/nse1mT7yn8Fv2GHg=="],
+
+ "@types/docker-modem": ["@types/docker-modem@3.0.6", "", { "dependencies": { "@types/node": "*", "@types/ssh2": "*" } }, "sha512-yKpAGEuKRSS8wwx0joknWxsmLha78wNMe9R2S3UNsVOkZded8UqOrV8KoeDXoXsjndxwyF3eIhyClGbO1SEhEg=="],
+
+ "@types/dockerode": ["@types/dockerode@3.3.34", "", { "dependencies": { "@types/docker-modem": "*", "@types/node": "*", "@types/ssh2": "*" } }, "sha512-mH9SuIb8NuTDsMus5epcbTzSbEo52fKLBMo0zapzYIAIyfDqoIFn7L3trekHLKC8qmxGV++pPUP4YqQ9n5v2Zg=="],
+
+ "@types/node": ["@types/node@22.13.5", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-+lTU0PxZXn0Dr1NBtC7Y8cR21AJr87dLLU953CWA6pMxxv/UDc7jYAY90upcrie1nRcD6XNG5HOYEDtgW5TxAg=="],
+
+ "@types/split2": ["@types/split2@4.2.3", "", { "dependencies": { "@types/node": "*" } }, "sha512-59OXIlfUsi2k++H6CHgUQKEb2HKRokUA39HY1i1dS8/AIcqVjtAAFdf8u+HxTWK/4FUHMJQlKSZ4I6irCBJ1Zw=="],
+
+ "@types/ssh2": ["@types/ssh2@1.15.4", "", { "dependencies": { "@types/node": "^18.11.18" } }, "sha512-9JTQgVBWSgq6mAen6PVnrAmty1lqgCMvpfN+1Ck5WRUsyMYPa6qd50/vMJ0y1zkGpOEgLzm8m8Dx/Y5vRouLaA=="],
+
+ "@types/triple-beam": ["@types/triple-beam@1.3.5", "", {}, "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw=="],
+
+ "@types/ws": ["@types/ws@8.5.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw=="],
+
+ "@unhead/schema": ["@unhead/schema@1.11.19", "", { "dependencies": { "hookable": "^5.5.3", "zhead": "^2.2.4" } }, "sha512-7VhYHWK7xHgljdv+C01MepCSYZO2v6OhgsfKWPxRQBDDGfUKCUaChox0XMq3tFvXP6u4zSp6yzcDw2yxCfVMwg=="],
+
+ "ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="],
+
+ "ansi-styles": ["ansi-styles@6.2.1", "", {}, "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="],
+
+ "asn1": ["asn1@0.2.6", "", { "dependencies": { "safer-buffer": "~2.1.0" } }, "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ=="],
+
+ "async": ["async@3.2.6", "", {}, "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA=="],
+
+ "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="],
+
+ "bcrypt-pbkdf": ["bcrypt-pbkdf@1.0.2", "", { "dependencies": { "tweetnacl": "^0.14.3" } }, "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w=="],
+
+ "bl": ["bl@4.1.0", "", { "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w=="],
+
+ "buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="],
+
+ "buildcheck": ["buildcheck@0.0.6", "", {}, "sha512-8f9ZJCUXyT1M35Jx7MkBgmBMo3oHTTBIPLiY9xyL0pl3T5RwcPEY8cUHr5LBNfu/fk6c2T4DJZuVM/8ZZT2D2A=="],
+
+ "bun-types": ["bun-types@1.2.3", "", { "dependencies": { "@types/node": "*", "@types/ws": "~8.5.10" } }, "sha512-P7AeyTseLKAvgaZqQrvp3RqFM3yN9PlcLuSTe7SoJOfZkER73mLdT2vEQi8U64S1YvM/ldcNiQjn0Sn7H9lGgg=="],
+
+ "chalk": ["chalk@5.4.1", "", {}, "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w=="],
+
+ "chownr": ["chownr@1.1.4", "", {}, "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="],
+
+ "cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="],
+
+ "clone": ["clone@2.1.2", "", {}, "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w=="],
+
+ "color": ["color@3.2.1", "", { "dependencies": { "color-convert": "^1.9.3", "color-string": "^1.6.0" } }, "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA=="],
+
+ "color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="],
+
+ "color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="],
+
+ "color-string": ["color-string@1.9.1", "", { "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" } }, "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg=="],
+
+ "colorspace": ["colorspace@1.1.4", "", { "dependencies": { "color": "^3.1.3", "text-hex": "1.0.x" } }, "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w=="],
+
+ "cookie": ["cookie@1.0.2", "", {}, "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA=="],
+
+ "cpu-features": ["cpu-features@0.0.10", "", { "dependencies": { "buildcheck": "~0.0.6", "nan": "^2.19.0" } }, "sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA=="],
+
+ "cross-env": ["cross-env@7.0.3", "", { "dependencies": { "cross-spawn": "^7.0.1" }, "bin": { "cross-env": "src/bin/cross-env.js", "cross-env-shell": "src/bin/cross-env-shell.js" } }, "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw=="],
+
+ "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
+
+ "debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
+
+ "docker-compose": ["docker-compose@1.1.1", "", { "dependencies": { "yaml": "^2.2.2" } }, "sha512-UkIUz0LtzuO17Ijm6SXMGtfZMs7IvbNwvuJBiBuN93PIhr/n9/sbJMqpvYFaCBGfwu1ZM4PPPDgQzeeke4lEoA=="],
+
+ "docker-modem": ["docker-modem@5.0.6", "", { "dependencies": { "debug": "^4.1.1", "readable-stream": "^3.5.0", "split-ca": "^1.0.1", "ssh2": "^1.15.0" } }, "sha512-ens7BiayssQz/uAxGzH8zGXCtiV24rRWXdjNha5V4zSOcxmAZsfGVm/PPFbwQdqEkDnhG+SyR9E3zSHUbOKXBQ=="],
+
+ "dockerode": ["dockerode@4.0.4", "", { "dependencies": { "@balena/dockerignore": "^1.0.2", "@grpc/grpc-js": "^1.11.1", "@grpc/proto-loader": "^0.7.13", "docker-modem": "^5.0.6", "protobufjs": "^7.3.2", "tar-fs": "~2.0.1", "uuid": "^10.0.0" } }, "sha512-6GYP/EdzEY50HaOxTVTJ2p+mB5xDHTMJhS+UoGrVyS6VC+iQRh7kZ4FRpUYq6nziby7hPqWhOrFFUFTMUZJJ5w=="],
+
+ "elysia": ["elysia@1.2.21", "", { "dependencies": { "@sinclair/typebox": "^0.34.27", "cookie": "^1.0.2", "memoirist": "^0.3.0", "openapi-types": "^12.1.3" }, "peerDependencies": { "typescript": ">= 5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-E9b1JcB7fiQ2ptk24W8OnBrMYUoKzffIXob9uTVUKhqOKxaXAd9UyWBeyr7JCDa/VD/b/9S8aIey9/YJsK5sLg=="],
+
+ "emoji-regex": ["emoji-regex@10.4.0", "", {}, "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw=="],
+
+ "enabled": ["enabled@2.0.0", "", {}, "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ=="],
+
+ "end-of-stream": ["end-of-stream@1.4.4", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q=="],
+
+ "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
+
+ "fecha": ["fecha@4.2.3", "", {}, "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw=="],
+
+ "fn.name": ["fn.name@1.1.0", "", {}, "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw=="],
+
+ "fs-constants": ["fs-constants@1.0.0", "", {}, "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="],
+
+ "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="],
+
+ "get-east-asian-width": ["get-east-asian-width@1.3.0", "", {}, "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ=="],
+
+ "hookable": ["hookable@5.5.3", "", {}, "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ=="],
+
+ "ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
+
+ "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
+
+ "is-arrayish": ["is-arrayish@0.3.2", "", {}, "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="],
+
+ "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="],
+
+ "is-stream": ["is-stream@2.0.1", "", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="],
+
+ "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
+
+ "kuler": ["kuler@2.0.0", "", {}, "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A=="],
+
+ "lodash.camelcase": ["lodash.camelcase@4.3.0", "", {}, "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA=="],
+
+ "logform": ["logform@2.7.0", "", { "dependencies": { "@colors/colors": "1.6.0", "@types/triple-beam": "^1.3.2", "fecha": "^4.2.0", "ms": "^2.1.1", "safe-stable-stringify": "^2.3.1", "triple-beam": "^1.3.0" } }, "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ=="],
+
+ "long": ["long@5.3.1", "", {}, "sha512-ka87Jz3gcx/I7Hal94xaN2tZEOPoUOEVftkQqZx2EeQRN7LGdfLlI3FvZ+7WDplm+vK2Urx9ULrvSowtdCieng=="],
+
+ "memoirist": ["memoirist@0.3.0", "", {}, "sha512-wR+4chMgVPq+T6OOsk40u9Wlpw1Pjx66NMNiYxCQQ4EUJ7jDs3D9kTCeKdBOkvAiqXlHLVJlvYL01PvIJ1MPNg=="],
+
+ "mkdirp-classic": ["mkdirp-classic@0.5.3", "", {}, "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="],
+
+ "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
+
+ "nan": ["nan@2.22.1", "", {}, "sha512-pfRR4ZcNTSm2ZFHaztuvbICf+hyiG6ecA06SfAxoPmuHjvMu0KUIae7Y8GyVkbBqeEIidsmXeYooWIX9+qjfRQ=="],
+
+ "node-cache": ["node-cache@5.1.2", "", { "dependencies": { "clone": "2.x" } }, "sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg=="],
+
+ "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="],
+
+ "one-time": ["one-time@1.0.0", "", { "dependencies": { "fn.name": "1.x.x" } }, "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g=="],
+
+ "openapi-types": ["openapi-types@12.1.3", "", {}, "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw=="],
+
+ "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
+
+ "pathe": ["pathe@1.1.2", "", {}, "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ=="],
+
+ "protobufjs": ["protobufjs@7.4.0", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw=="],
+
+ "pump": ["pump@3.0.2", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw=="],
+
+ "readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
+
+ "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="],
+
+ "safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
+
+ "safe-stable-stringify": ["safe-stable-stringify@2.5.0", "", {}, "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA=="],
+
+ "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
+
+ "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
+
+ "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
+
+ "simple-swizzle": ["simple-swizzle@0.2.2", "", { "dependencies": { "is-arrayish": "^0.3.1" } }, "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg=="],
+
+ "split-ca": ["split-ca@1.0.1", "", {}, "sha512-Q5thBSxp5t8WPTTJQS59LrGqOZqOsrhDGDVm8azCqIBjSBd7nd9o2PM+mDulQQkh8h//4U6hFZnc/mul8t5pWQ=="],
+
+ "split2": ["split2@4.2.0", "", {}, "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg=="],
+
+ "ssh2": ["ssh2@1.16.0", "", { "dependencies": { "asn1": "^0.2.6", "bcrypt-pbkdf": "^1.0.2" }, "optionalDependencies": { "cpu-features": "~0.0.10", "nan": "^2.20.0" } }, "sha512-r1X4KsBGedJqo7h8F5c4Ybpcr5RjyP+aWIG007uBPRjmdQWfEiVLzSK71Zji1B9sKxwaCvD8y8cwSkYrlLiRRg=="],
+
+ "stack-trace": ["stack-trace@0.0.10", "", {}, "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg=="],
+
+ "string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="],
+
+ "string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="],
+
+ "strip-ansi": ["strip-ansi@7.1.0", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ=="],
+
+ "tar-fs": ["tar-fs@2.0.1", "", { "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", "tar-stream": "^2.0.0" } }, "sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA=="],
+
+ "tar-stream": ["tar-stream@2.2.0", "", { "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" } }, "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ=="],
+
+ "text-hex": ["text-hex@1.0.0", "", {}, "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg=="],
+
+ "triple-beam": ["triple-beam@1.4.1", "", {}, "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg=="],
+
+ "tweetnacl": ["tweetnacl@0.14.5", "", {}, "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA=="],
+
+ "typescript": ["typescript@5.8.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ=="],
+
+ "undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="],
+
+ "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
+
+ "uuid": ["uuid@10.0.0", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ=="],
+
+ "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
+
+ "winston": ["winston@3.17.0", "", { "dependencies": { "@colors/colors": "^1.6.0", "@dabh/diagnostics": "^2.0.2", "async": "^3.2.3", "is-stream": "^2.0.0", "logform": "^2.7.0", "one-time": "^1.0.0", "readable-stream": "^3.4.0", "safe-stable-stringify": "^2.3.1", "stack-trace": "0.0.x", "triple-beam": "^1.3.0", "winston-transport": "^4.9.0" } }, "sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw=="],
+
+ "winston-transport": ["winston-transport@4.9.0", "", { "dependencies": { "logform": "^2.7.0", "readable-stream": "^3.6.2", "triple-beam": "^1.3.0" } }, "sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A=="],
+
+ "wrap-ansi": ["wrap-ansi@9.0.0", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q=="],
+
+ "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="],
+
+ "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="],
+
+ "yaml": ["yaml@2.7.0", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA=="],
+
+ "yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="],
+
+ "yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="],
+
+ "zhead": ["zhead@2.2.4", "", {}, "sha512-8F0OI5dpWIA5IGG5NHUg9staDwz/ZPxZtvGVf01j7vHqSyZ0raHY+78atOVxRqb73AotX22uV1pXt3gYSstGag=="],
+
+ "@scalar/themes/@scalar/types": ["@scalar/types@0.0.34", "", { "dependencies": { "@scalar/openapi-types": "0.1.8", "@unhead/schema": "^1.11.11" } }, "sha512-q01ctijmHArM5KOny2zU+sHfhpsgOAENrDENecK2TsQNn5FYLmFZouMKeW2M6F7KFLPZnFxUiL/rT88b6Rp/Kg=="],
+
+ "@types/ssh2/@types/node": ["@types/node@18.19.76", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-yvR7Q9LdPz2vGpmpJX5LolrgRdWvB67MJKDPSgIIzpFbaf9a1j/f5DnLp5VDyHGMR0QZHlTr1afsD87QCXFHKw=="],
+
+ "cliui/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
+
+ "cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
+
+ "cliui/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
+
+ "yargs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
+
+ "@scalar/themes/@scalar/types/@scalar/openapi-types": ["@scalar/openapi-types@0.1.8", "", {}, "sha512-iufA5/6hPCmRIVD2eh7qGpoKvoA08Gw/qUb2JECifBtAwA93fo7+1k9uHK440f2LMJsbxIzA+nv7RS0BmfiO/g=="],
+
+ "@types/ssh2/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
+
+ "cliui/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
+
+ "cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
+
+ "cliui/wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
+
+ "yargs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
+
+ "yargs/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
+
+ "cliui/wrap-ansi/ansi-styles/color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
+
+ "yargs/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
+
+ "cliui/wrap-ansi/ansi-styles/color-convert/color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
+ }
+}
diff --git a/docker/Dockerfile b/docker/Dockerfile
new file mode 100644
index 00000000..fdd42344
--- /dev/null
+++ b/docker/Dockerfile
@@ -0,0 +1,3 @@
+FROM oven/bun AS base
+
+WORKDIR /base
diff --git a/docker/Dockerfile-base b/docker/Dockerfile-base
deleted file mode 100644
index f21146ba..00000000
--- a/docker/Dockerfile-base
+++ /dev/null
@@ -1,76 +0,0 @@
-# Stage 1: Build stage
-FROM node:20-alpine AS builder
-
-LABEL maintainer="https://github.com/its4nik"
-LABEL version="2.0.1"
-LABEL description="API for DockStat"
-LABEL license="BSD-3-Clause license"
-LABEL repository="https://github.com/its4nik/dockstatapi"
-LABEL documentation="https://github.com/its4nik/dockstatapi"
-LABEL org.opencontainers.image.description="The DockSatAPI is a free and OpenSource backend for gathering container statistics across hosts"
-LABEL org.opencontainers.image.licenses="BSD-3-Clause license"
-LABEL org.opencontainers.image.source="https://github.com/its4nik/dockstatapi"
-
-WORKDIR /app
-
-ENV NODE_NO_WARNINGS=1
-
-RUN apk add --no-cache curl bash
-
-COPY package*.json tsconfig.json environment.d.ts ./
-
-RUN npm ci --include=dev
-
-COPY ./src ./src
-RUN mv ./src/sample-variable.json ./src/data/variables.json
-
-RUN npm run build:mini
-
-# --------------------------------------
-# Stage 2: Dependency pruning stage
-FROM node:20-alpine AS deps
-WORKDIR /api
-COPY --from=builder /app/package*.json .
-RUN npm ci --omit=dev
-
-# --------------------------------------
-# Stage 3: Final production image
-FROM node:20-alpine AS prod
-
-WORKDIR /api
-
-RUN apk add --no-cache docker-cli bash curl && \
- mkdir -p /usr/libexec/docker/cli-plugins && \
- curl -sSL "https://github.com/docker/compose/releases/latest/download/docker-compose-linux-$(uname -m)" \
- -o /usr/libexec/docker/cli-plugins/docker-compose && \
- chmod +x /usr/libexec/docker/cli-plugins/docker-compose && \
- rm -rf /var/cache/apk/*
-
-ARG USER_ID=10001
-ARG GROUP_ID=10001
-RUN addgroup -g $GROUP_ID dockstatapi && \
- adduser -u $USER_ID -G dockstatapi -h /api -s /bin/sh -D dockstatapi
-
-COPY --from=builder --chown=dockstatapi:dockstatapi /app/dist/src ./src
-COPY --from=builder --chown=dockstatapi:dockstatapi /app/src/config/swagger.yaml ./src/config/swagger.yaml
-COPY --from=builder --chown=dockstatapi:dockstatapi /app/src/utils/assets ./src/utils/assets
-COPY --from=builder /app/package.json ./
-COPY --from=deps --chown=dockstatapi:dockstatapi /api/node_modules ./node_modules
-
-COPY --from=builder --chown=dockstatapi:dockstatapi /app/src/misc/entrypoint.sh .
-COPY --from=builder --chown=dockstatapi:dockstatapi /app/src/misc/createEnvFile.sh .
-RUN chmod +x *.sh
-
-RUN mkdir -p /api/src/data && \
- chown -R dockstatapi:dockstatapi /api && \
- chmod -R 755 /api && \
- chmod 775 /api/src/data
-
-HEALTHCHECK --interval=5m --timeout=3s \
- CMD curl -f http://localhost:9876/api/status || exit 1
-
-EXPOSE 9876
-STOPSIGNAL 130
-USER dockstatapi
-
-ENTRYPOINT [ "sh", "./entrypoint.sh", "--prod" ]
diff --git a/docker/Dockerfile-dev b/docker/Dockerfile-dev
deleted file mode 100644
index 00b88008..00000000
--- a/docker/Dockerfile-dev
+++ /dev/null
@@ -1,76 +0,0 @@
-# Stage 1: Build stage
-FROM node:20-alpine AS builder
-
-LABEL maintainer="https://github.com/its4nik"
-LABEL version="2.0.1"
-LABEL description="API for DockStat"
-LABEL license="BSD-3-Clause license"
-LABEL repository="https://github.com/its4nik/dockstatapi"
-LABEL documentation="https://github.com/its4nik/dockstatapi"
-LABEL org.opencontainers.image.description="The DockSatAPI is a free and OpenSource backend for gathering container statistics across hosts"
-LABEL org.opencontainers.image.licenses="BSD-3-Clause license"
-LABEL org.opencontainers.image.source="https://github.com/its4nik/dockstatapi"
-
-WORKDIR /app
-
-ENV NODE_NO_WARNINGS=1
-
-RUN apk add --no-cache curl bash
-
-COPY package*.json tsconfig.json environment.d.ts ./
-
-RUN npm ci --include=dev
-
-COPY ./src ./src
-RUN mv ./src/sample-variable.json ./src/data/variables.json
-
-RUN npm run build
-
-# --------------------------------------
-# Stage 2: Dependency pruning stage
-FROM node:20-alpine AS deps
-WORKDIR /api
-COPY --from=builder /app/package*.json .
-RUN npm ci --omit=dev
-
-# --------------------------------------
-# Stage 3: Final production image
-FROM node:20-alpine AS prod
-
-WORKDIR /api
-
-RUN apk add --no-cache docker-cli bash curl && \
- mkdir -p /usr/libexec/docker/cli-plugins && \
- curl -sSL "https://github.com/docker/compose/releases/latest/download/docker-compose-linux-$(uname -m)" \
- -o /usr/libexec/docker/cli-plugins/docker-compose && \
- chmod +x /usr/libexec/docker/cli-plugins/docker-compose && \
- rm -rf /var/cache/apk/*
-
-ARG USER_ID=10001
-ARG GROUP_ID=10001
-RUN addgroup -g $GROUP_ID dockstatapi && \
- adduser -u $USER_ID -G dockstatapi -h /api -s /bin/sh -D dockstatapi
-
-COPY --from=builder --chown=dockstatapi:dockstatapi /app/dist/src ./src
-COPY --from=builder --chown=dockstatapi:dockstatapi /app/src/config/swagger.yaml ./src/config/swagger.yaml
-COPY --from=builder --chown=dockstatapi:dockstatapi /app/src/utils/assets ./src/utils/assets
-COPY --from=builder /app/package.json ./
-COPY --from=deps --chown=dockstatapi:dockstatapi /api/node_modules ./node_modules
-
-COPY --from=builder --chown=dockstatapi:dockstatapi /app/src/misc/entrypoint.sh .
-COPY --from=builder --chown=dockstatapi:dockstatapi /app/src/misc/createEnvFile.sh .
-RUN chmod +x *.sh
-
-RUN mkdir -p /api/src/data && \
- chown -R dockstatapi:dockstatapi /api && \
- chmod -R 755 /api && \
- chmod 775 /api/src/data
-
-HEALTHCHECK --interval=5m --timeout=3s \
- CMD curl -f http://localhost:9876/api/status || exit 1
-
-EXPOSE 9876
-STOPSIGNAL 130
-USER dockstatapi
-
-ENTRYPOINT [ "sh", "./entrypoint.sh", "--dev" ]
diff --git a/docker/docker-compose.dev.yaml b/docker/docker-compose.dev.yaml
index 7bc3773f..39da6d6b 100644
--- a/docker/docker-compose.dev.yaml
+++ b/docker/docker-compose.dev.yaml
@@ -1,40 +1,52 @@
+name: "DockStatAPI - Dev"
services:
- test-socket-proxy:
+ socket-proxy:
+ container_name: Socket-Proxy
image: lscr.io/linuxserver/socket-proxy:latest
- container_name: test-socket-proxy
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock:ro
+ restart: unless-stopped
+ read_only: true
+ tmpfs:
+ - /run
+ ports:
+ - 2375:2375
environment:
- ALLOW_START=1 #optional
- ALLOW_STOP=1 #optional
- ALLOW_RESTARTS=1 #optional
- - AUTH=0 #optional
- - BUILD=0 #optional
- - COMMIT=0 #optional
- - CONFIGS=0 #optional
+ - AUTH=1 #optional
+ - BUILD=1 #optional
+ - COMMIT=1 #optional
+ - CONFIGS=1 #optional
- CONTAINERS=1 #optional
- - DISABLE_IPV6=0 #optional
- - DISTRIBUTION=0 #optional
+ - DISABLE_IPV6=1 #optional
+ - DISTRIBUTION=1 #optional
- EVENTS=1 #optional
- - EXEC=0 #optional
- - IMAGES=0 #optional
+ - EXEC=1 #optional
+ - IMAGES=1 #optional
- INFO=1 #optional
- NETWORKS=1 #optional
- NODES=1 #optional
- PING=1 #optional
- - POST=0 #optional
- - PLUGINS=0 #optional
- - SECRETS=0 #optional
- - SERVICES=0 #optional
- - SESSION=0 #optional
- - SWARM=0 #optional
- - SYSTEM=0 #optional
- - TASKS=0 #optional
+ - PLUGINS=1 #optional
+ - POST=1 #optional
+ - PROXY_READ_TIMEOUT=240 #optional
+ - SECRETS=1 #optional
+ - SERVICES=1 #optional
+ - SESSION=1 #optional
+ - SWARM=1 #optional
+ - SYSTEM=1 #optional
+ - TASKS=1 #optional
- VERSION=1 #optional
- - VOLUMES=0 #optional
- volumes:
- - /var/run/docker.sock:/var/run/docker.sock:ro
- restart: unless-stopped
- read_only: true
- tmpfs:
- - /run
+ - VOLUMES=1 #optional
+
+ sqlite-web:
+ container_name: SQLite-web
+ image: ghcr.io/coleifer/sqlite-web:latest
ports:
- - 2375:2375
\ No newline at end of file
+ - 8080:8080
+ volumes:
+ - ../:/data:ro
+ environment:
+ - SQLITE_DATABASE=dockstatapi.db
diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml
deleted file mode 100644
index 436d8a21..00000000
--- a/docker/docker-compose.yaml
+++ /dev/null
@@ -1,82 +0,0 @@
-networks:
- shared-network:
- driver: bridge
-
-services:
- master:
- container_name: master
- user: "${UID:-1000}:${GID:-1000}"
- environment:
- - NODE_ENV=development
- - HA_MASTER=true
- - HA_MASTER_IP=master:9876
- - HA_NODE=slave:9876
- - HA_UNSAFE=true
- volumes:
- - ./master/data:/api/src/data
- - ./master/logs:/api/logs
- ports:
- - 9876:9876
- image: dockstatapi:local
- networks:
- - shared-network
- depends_on:
- - slave
- - test-socket-proxy
-
- slave:
- container_name: slave
- user: "${UID:-1000}:${GID:-1000}"
- environment:
- - NODE_ENV=development
- volumes:
- - ./slave/data:/api/src/data
- - ./slave/logs:/api/logs
- ports:
- - 6789:9876
- image: dockstatapi:local
- depends_on:
- - test-socket-proxy
- networks:
- - shared-network
-
- test-socket-proxy:
- image: lscr.io/linuxserver/socket-proxy:latest
- container_name: test-socket-proxy
- environment:
- - ALLOW_START=1 #optional
- - ALLOW_STOP=1 #optional
- - ALLOW_RESTARTS=1 #optional
- - AUTH=0 #optional
- - BUILD=0 #optional
- - COMMIT=0 #optional
- - CONFIGS=0 #optional
- - CONTAINERS=1 #optional
- - DISABLE_IPV6=0 #optional
- - DISTRIBUTION=0 #optional
- - EVENTS=1 #optional
- - EXEC=0 #optional
- - IMAGES=0 #optional
- - INFO=1 #optional
- - NETWORKS=1 #optional
- - NODES=1 #optional
- - PING=1 #optional
- - POST=0 #optional
- - PLUGINS=0 #optional
- - SECRETS=0 #optional
- - SERVICES=0 #optional
- - SESSION=0 #optional
- - SWARM=0 #optional
- - SYSTEM=0 #optional
- - TASKS=0 #optional
- - VERSION=1 #optional
- - VOLUMES=0 #optional
- volumes:
- - /var/run/docker.sock:/var/run/docker.sock:ro
- restart: unless-stopped
- read_only: true
- tmpfs:
- - /run
- networks:
- - shared-network
-
diff --git a/environment.d.ts b/environment.d.ts
deleted file mode 100644
index df2595f5..00000000
--- a/environment.d.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-declare global {
- namespace NodeJS {
- interface ProcessEnv {
- // Node specific:
- NODE_ENV: "development" | "production" | "testing";
- PORT: string | undefined;
- CI: "true" | null;
- }
- }
-}
-
-export {};
diff --git a/eslint.config.mjs b/eslint.config.mjs
deleted file mode 100644
index 56994a62..00000000
--- a/eslint.config.mjs
+++ /dev/null
@@ -1,12 +0,0 @@
-import globals from "globals";
-import pluginJs from "@eslint/js";
-import tseslint from "typescript-eslint";
-
-/** @type {import('eslint').Linter.Config[]} */
-export default [
- { ignores: ["node_modules/*", "dist/*"] },
- { files: ["src/**/*.ts"] },
- { languageOptions: { globals: globals.node } },
- pluginJs.configs.recommended,
- ...tseslint.configs.recommended,
-];
diff --git a/nodemon.json b/nodemon.json
deleted file mode 100644
index be32c75d..00000000
--- a/nodemon.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "ignore": [
- "**/data/**",
- "src/logs",
- "**/fixtures/**",
- ".gitignore",
- "**/*.json",
- "**/__tests__/**"
- ],
- "execMap": {
- "ts": "tsx"
- },
- "delay": 2500
-}
diff --git a/package-lock.json b/package-lock.json
deleted file mode 100644
index 6efc7ed3..00000000
--- a/package-lock.json
+++ /dev/null
@@ -1,13317 +0,0 @@
-{
- "name": "dockstatapi",
- "version": "2.0.1",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "dockstatapi",
- "version": "2.0.1",
- "license": "BSD 3-Clause License",
- "dependencies": {
- "bcrypt": "^5.1.1",
- "chokidar": "^4.0.1",
- "cors": "^2.8.5",
- "cytoscape": "^3.30.4",
- "docker-compose": "^1.1.0",
- "dockerode": "^4.0.2",
- "express": "^4.21.1",
- "express-rate-limit": "^7.4.1",
- "https": "^1.0.0",
- "i": "^0.3.7",
- "ipaddr.js": "^2.2.0",
- "nodemailer": "^6.9.16",
- "npm": "^11.0.0",
- "puppeteer": "^24.0.0",
- "sqlite3": "^5.1.7",
- "swagger-ui-express": "^5.0.1",
- "winston": "^3.15.0",
- "winston-daily-rotate-file": "^5.0.0",
- "yamljs": "^0.3.0"
- },
- "devDependencies": {
- "@eslint/js": "^9.17.0",
- "@types/bcrypt": "^5.0.2",
- "@types/cors": "^2.8.17",
- "@types/cytoscape": "^3.21.8",
- "@types/dockerode": "^3.3.31",
- "@types/express": "^5.0.0",
- "@types/express-handlebars": "^5.3.1",
- "@types/jest": "^29.5.14",
- "@types/node": "^22.9.0",
- "@types/node-fetch": "^2.6.12",
- "@types/nodemailer": "^6.4.17",
- "@types/supertest": "^6.0.2",
- "@types/supports-color": "^8.1.3",
- "@types/swagger-jsdoc": "^6.0.4",
- "@types/swagger-ui-express": "^4.1.7",
- "@types/ws": "^8.5.14",
- "@types/yamljs": "^0.2.34",
- "@typescript-eslint/eslint-plugin": "^8.18.2",
- "@typescript-eslint/parser": "^8.18.2",
- "dependency-cruiser": "^16.5.0",
- "eslint": "^9.17.0",
- "globals": "^15.14.0",
- "jest": "^29.7.0",
- "license-checker": "^25.0.1",
- "nodemon": "^3.1.7",
- "prettier": "^3.4.2",
- "supertest": "^7.0.0",
- "ts-jest": "^29.2.5",
- "ts-node": "^10.9.2",
- "tsx": "^4.19.2",
- "typescript-eslint": "^8.18.2",
- "uglify-js": "^3.19.3"
- },
- "engines": {
- "npm": ">=10.8.2"
- }
- },
- "node_modules/@ampproject/remapping": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
- "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.24"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@babel/code-frame": {
- "version": "7.26.2",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz",
- "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-validator-identifier": "^7.25.9",
- "js-tokens": "^4.0.0",
- "picocolors": "^1.0.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/compat-data": {
- "version": "7.26.5",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.5.tgz",
- "integrity": "sha512-XvcZi1KWf88RVbF9wn8MN6tYFloU5qX8KjuF3E1PVBmJ9eypXfs4GRiJwLuTZL0iSnJUKn1BFPa5BPZZJyFzPg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/core": {
- "version": "7.26.7",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.7.tgz",
- "integrity": "sha512-SRijHmF0PSPgLIBYlWnG0hyeJLwXE2CgpsXaMOrtt2yp9/86ALw6oUlj9KYuZ0JN07T4eBMVIW4li/9S1j2BGA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@ampproject/remapping": "^2.2.0",
- "@babel/code-frame": "^7.26.2",
- "@babel/generator": "^7.26.5",
- "@babel/helper-compilation-targets": "^7.26.5",
- "@babel/helper-module-transforms": "^7.26.0",
- "@babel/helpers": "^7.26.7",
- "@babel/parser": "^7.26.7",
- "@babel/template": "^7.25.9",
- "@babel/traverse": "^7.26.7",
- "@babel/types": "^7.26.7",
- "convert-source-map": "^2.0.0",
- "debug": "^4.1.0",
- "gensync": "^1.0.0-beta.2",
- "json5": "^2.2.3",
- "semver": "^6.3.1"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/babel"
- }
- },
- "node_modules/@babel/core/node_modules/semver": {
- "version": "6.3.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
- "dev": true,
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- }
- },
- "node_modules/@babel/generator": {
- "version": "7.26.5",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.5.tgz",
- "integrity": "sha512-2caSP6fN9I7HOe6nqhtft7V4g7/V/gfDsC3Ag4W7kEzzvRGKqiv0pu0HogPiZ3KaVSoNDhUws6IJjDjpfmYIXw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/parser": "^7.26.5",
- "@babel/types": "^7.26.5",
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.25",
- "jsesc": "^3.0.2"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-compilation-targets": {
- "version": "7.26.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz",
- "integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/compat-data": "^7.26.5",
- "@babel/helper-validator-option": "^7.25.9",
- "browserslist": "^4.24.0",
- "lru-cache": "^5.1.1",
- "semver": "^6.3.1"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-compilation-targets/node_modules/semver": {
- "version": "6.3.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
- "dev": true,
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- }
- },
- "node_modules/@babel/helper-module-imports": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz",
- "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/traverse": "^7.25.9",
- "@babel/types": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-module-transforms": {
- "version": "7.26.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz",
- "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-module-imports": "^7.25.9",
- "@babel/helper-validator-identifier": "^7.25.9",
- "@babel/traverse": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/helper-plugin-utils": {
- "version": "7.26.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz",
- "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-string-parser": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
- "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-identifier": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
- "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-option": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz",
- "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helpers": {
- "version": "7.26.7",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.7.tgz",
- "integrity": "sha512-8NHiL98vsi0mbPQmYAGWwfcFaOy4j2HY49fXJCfuDcdE7fMIsH9a7GdaeXpIBsbT7307WU8KCMp5pUVDNL4f9A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/template": "^7.25.9",
- "@babel/types": "^7.26.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/parser": {
- "version": "7.26.7",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.7.tgz",
- "integrity": "sha512-kEvgGGgEjRUutvdVvZhbn/BxVt+5VSpwXz1j3WYXQbXDo8KzFOPNG2GQbdAiNq8g6wn1yKk7C/qrke03a84V+w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.26.7"
- },
- "bin": {
- "parser": "bin/babel-parser.js"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@babel/plugin-syntax-async-generators": {
- "version": "7.8.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
- "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-bigint": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz",
- "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-class-properties": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
- "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.12.13"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-class-static-block": {
- "version": "7.14.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz",
- "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.14.5"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-import-attributes": {
- "version": "7.26.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz",
- "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-import-meta": {
- "version": "7.10.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
- "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.10.4"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-json-strings": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
- "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-jsx": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz",
- "integrity": "sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-logical-assignment-operators": {
- "version": "7.10.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
- "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.10.4"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
- "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-numeric-separator": {
- "version": "7.10.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
- "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.10.4"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-object-rest-spread": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
- "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-optional-catch-binding": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
- "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-optional-chaining": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
- "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-private-property-in-object": {
- "version": "7.14.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz",
- "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.14.5"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-top-level-await": {
- "version": "7.14.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
- "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.14.5"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-typescript": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz",
- "integrity": "sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/template": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz",
- "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.25.9",
- "@babel/parser": "^7.25.9",
- "@babel/types": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/traverse": {
- "version": "7.26.7",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.7.tgz",
- "integrity": "sha512-1x1sgeyRLC3r5fQOM0/xtQKsYjyxmFjaOrLJNtZ81inNjyJHGIolTULPiSc/2qe1/qfpFLisLQYFnnZl7QoedA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.26.2",
- "@babel/generator": "^7.26.5",
- "@babel/parser": "^7.26.7",
- "@babel/template": "^7.25.9",
- "@babel/types": "^7.26.7",
- "debug": "^4.3.1",
- "globals": "^11.1.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/traverse/node_modules/globals": {
- "version": "11.12.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
- "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/@babel/types": {
- "version": "7.26.7",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.7.tgz",
- "integrity": "sha512-t8kDRGrKXyp6+tjUh7hw2RLyclsW4TRoRvRHtSyAX9Bb5ldlFh+90YAYY6awRXrlB4G5G2izNeGySpATlFzmOg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-string-parser": "^7.25.9",
- "@babel/helper-validator-identifier": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@balena/dockerignore": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/@balena/dockerignore/-/dockerignore-1.0.2.tgz",
- "integrity": "sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q==",
- "license": "Apache-2.0"
- },
- "node_modules/@bcoe/v8-coverage": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
- "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@colors/colors": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz",
- "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==",
- "license": "MIT",
- "engines": {
- "node": ">=0.1.90"
- }
- },
- "node_modules/@cspotcode/source-map-support": {
- "version": "0.8.1",
- "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
- "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/trace-mapping": "0.3.9"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.9",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
- "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.0.3",
- "@jridgewell/sourcemap-codec": "^1.4.10"
- }
- },
- "node_modules/@dabh/diagnostics": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz",
- "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==",
- "license": "MIT",
- "dependencies": {
- "colorspace": "1.1.x",
- "enabled": "2.0.x",
- "kuler": "^2.0.0"
- }
- },
- "node_modules/@esbuild/aix-ppc64": {
- "version": "0.23.1",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz",
- "integrity": "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "aix"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/android-arm": {
- "version": "0.23.1",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.1.tgz",
- "integrity": "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/android-arm64": {
- "version": "0.23.1",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz",
- "integrity": "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/android-x64": {
- "version": "0.23.1",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.1.tgz",
- "integrity": "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/darwin-arm64": {
- "version": "0.23.1",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz",
- "integrity": "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/darwin-x64": {
- "version": "0.23.1",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz",
- "integrity": "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/freebsd-arm64": {
- "version": "0.23.1",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz",
- "integrity": "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/freebsd-x64": {
- "version": "0.23.1",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz",
- "integrity": "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-arm": {
- "version": "0.23.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz",
- "integrity": "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-arm64": {
- "version": "0.23.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz",
- "integrity": "sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-ia32": {
- "version": "0.23.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz",
- "integrity": "sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-loong64": {
- "version": "0.23.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz",
- "integrity": "sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-mips64el": {
- "version": "0.23.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz",
- "integrity": "sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==",
- "cpu": [
- "mips64el"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-ppc64": {
- "version": "0.23.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz",
- "integrity": "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-riscv64": {
- "version": "0.23.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz",
- "integrity": "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-s390x": {
- "version": "0.23.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz",
- "integrity": "sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==",
- "cpu": [
- "s390x"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-x64": {
- "version": "0.23.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz",
- "integrity": "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/netbsd-x64": {
- "version": "0.23.1",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz",
- "integrity": "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "netbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openbsd-arm64": {
- "version": "0.23.1",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz",
- "integrity": "sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openbsd-x64": {
- "version": "0.23.1",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz",
- "integrity": "sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/sunos-x64": {
- "version": "0.23.1",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz",
- "integrity": "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "sunos"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-arm64": {
- "version": "0.23.1",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz",
- "integrity": "sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-ia32": {
- "version": "0.23.1",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz",
- "integrity": "sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-x64": {
- "version": "0.23.1",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz",
- "integrity": "sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@eslint-community/eslint-utils": {
- "version": "4.4.1",
- "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz",
- "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "eslint-visitor-keys": "^3.4.3"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- },
- "peerDependencies": {
- "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
- }
- },
- "node_modules/@eslint-community/regexpp": {
- "version": "4.12.1",
- "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz",
- "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
- }
- },
- "node_modules/@eslint/config-array": {
- "version": "0.19.2",
- "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz",
- "integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@eslint/object-schema": "^2.1.6",
- "debug": "^4.3.1",
- "minimatch": "^3.1.2"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
- "node_modules/@eslint/config-array/node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/@eslint/config-array/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/@eslint/core": {
- "version": "0.11.0",
- "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.11.0.tgz",
- "integrity": "sha512-DWUB2pksgNEb6Bz2fggIy1wh6fGgZP4Xyy/Mt0QZPiloKKXerbqq9D3SBQTlCRYOrcRPu4vuz+CGjwdfqxnoWA==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@types/json-schema": "^7.0.15"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
- "node_modules/@eslint/eslintrc": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz",
- "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ajv": "^6.12.4",
- "debug": "^4.3.2",
- "espree": "^10.0.1",
- "globals": "^14.0.0",
- "ignore": "^5.2.0",
- "import-fresh": "^3.2.1",
- "js-yaml": "^4.1.0",
- "minimatch": "^3.1.2",
- "strip-json-comments": "^3.1.1"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/@eslint/eslintrc/node_modules/ajv": {
- "version": "6.12.6",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
- "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "fast-deep-equal": "^3.1.1",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.4.1",
- "uri-js": "^4.2.2"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
- }
- },
- "node_modules/@eslint/eslintrc/node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/@eslint/eslintrc/node_modules/globals": {
- "version": "14.0.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
- "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
- "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@eslint/eslintrc/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/@eslint/js": {
- "version": "9.20.0",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.20.0.tgz",
- "integrity": "sha512-iZA07H9io9Wn836aVTytRaNqh00Sad+EamwOVJT12GTLw1VGMFV/4JaME+JjLtr9fiGaoWgYnS54wrfWsSs4oQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
- "node_modules/@eslint/object-schema": {
- "version": "2.1.6",
- "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz",
- "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
- "node_modules/@eslint/plugin-kit": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.5.tgz",
- "integrity": "sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@eslint/core": "^0.10.0",
- "levn": "^0.4.1"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
- "node_modules/@eslint/plugin-kit/node_modules/@eslint/core": {
- "version": "0.10.0",
- "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.10.0.tgz",
- "integrity": "sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@types/json-schema": "^7.0.15"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
- "node_modules/@gar/promisify": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
- "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==",
- "license": "MIT",
- "optional": true
- },
- "node_modules/@grpc/grpc-js": {
- "version": "1.12.6",
- "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.12.6.tgz",
- "integrity": "sha512-JXUj6PI0oqqzTGvKtzOkxtpsyPRNsrmhh41TtIz/zEB6J+AUiZZ0dxWzcMwO9Ns5rmSPuMdghlTbUuqIM48d3Q==",
- "license": "Apache-2.0",
- "dependencies": {
- "@grpc/proto-loader": "^0.7.13",
- "@js-sdsl/ordered-map": "^4.4.2"
- },
- "engines": {
- "node": ">=12.10.0"
- }
- },
- "node_modules/@grpc/proto-loader": {
- "version": "0.7.13",
- "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.13.tgz",
- "integrity": "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==",
- "license": "Apache-2.0",
- "dependencies": {
- "lodash.camelcase": "^4.3.0",
- "long": "^5.0.0",
- "protobufjs": "^7.2.5",
- "yargs": "^17.7.2"
- },
- "bin": {
- "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/@humanfs/core": {
- "version": "0.19.1",
- "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
- "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": ">=18.18.0"
- }
- },
- "node_modules/@humanfs/node": {
- "version": "0.16.6",
- "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz",
- "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@humanfs/core": "^0.19.1",
- "@humanwhocodes/retry": "^0.3.0"
- },
- "engines": {
- "node": ">=18.18.0"
- }
- },
- "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz",
- "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": ">=18.18"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/nzakas"
- }
- },
- "node_modules/@humanwhocodes/module-importer": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
- "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": ">=12.22"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/nzakas"
- }
- },
- "node_modules/@humanwhocodes/retry": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz",
- "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": ">=18.18"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/nzakas"
- }
- },
- "node_modules/@istanbuljs/load-nyc-config": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
- "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "camelcase": "^5.3.1",
- "find-up": "^4.1.0",
- "get-package-type": "^0.1.0",
- "js-yaml": "^3.13.1",
- "resolve-from": "^5.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
- "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "sprintf-js": "~1.0.2"
- }
- },
- "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
- "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "locate-path": "^5.0.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": {
- "version": "3.14.1",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
- "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "argparse": "^1.0.7",
- "esprima": "^4.0.0"
- },
- "bin": {
- "js-yaml": "bin/js-yaml.js"
- }
- },
- "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
- "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "p-locate": "^4.1.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
- "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "p-try": "^2.0.0"
- },
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
- "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "p-limit": "^2.2.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
- "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@istanbuljs/load-nyc-config/node_modules/sprintf-js": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
- "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
- "dev": true,
- "license": "BSD-3-Clause"
- },
- "node_modules/@istanbuljs/schema": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
- "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@jest/console": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz",
- "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/types": "^29.6.3",
- "@types/node": "*",
- "chalk": "^4.0.0",
- "jest-message-util": "^29.7.0",
- "jest-util": "^29.7.0",
- "slash": "^3.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jest/core": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz",
- "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/console": "^29.7.0",
- "@jest/reporters": "^29.7.0",
- "@jest/test-result": "^29.7.0",
- "@jest/transform": "^29.7.0",
- "@jest/types": "^29.6.3",
- "@types/node": "*",
- "ansi-escapes": "^4.2.1",
- "chalk": "^4.0.0",
- "ci-info": "^3.2.0",
- "exit": "^0.1.2",
- "graceful-fs": "^4.2.9",
- "jest-changed-files": "^29.7.0",
- "jest-config": "^29.7.0",
- "jest-haste-map": "^29.7.0",
- "jest-message-util": "^29.7.0",
- "jest-regex-util": "^29.6.3",
- "jest-resolve": "^29.7.0",
- "jest-resolve-dependencies": "^29.7.0",
- "jest-runner": "^29.7.0",
- "jest-runtime": "^29.7.0",
- "jest-snapshot": "^29.7.0",
- "jest-util": "^29.7.0",
- "jest-validate": "^29.7.0",
- "jest-watcher": "^29.7.0",
- "micromatch": "^4.0.4",
- "pretty-format": "^29.7.0",
- "slash": "^3.0.0",
- "strip-ansi": "^6.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- },
- "peerDependencies": {
- "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
- },
- "peerDependenciesMeta": {
- "node-notifier": {
- "optional": true
- }
- }
- },
- "node_modules/@jest/environment": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz",
- "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/fake-timers": "^29.7.0",
- "@jest/types": "^29.6.3",
- "@types/node": "*",
- "jest-mock": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jest/expect": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz",
- "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "expect": "^29.7.0",
- "jest-snapshot": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jest/expect-utils": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz",
- "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "jest-get-type": "^29.6.3"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jest/fake-timers": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz",
- "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/types": "^29.6.3",
- "@sinonjs/fake-timers": "^10.0.2",
- "@types/node": "*",
- "jest-message-util": "^29.7.0",
- "jest-mock": "^29.7.0",
- "jest-util": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jest/globals": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz",
- "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/environment": "^29.7.0",
- "@jest/expect": "^29.7.0",
- "@jest/types": "^29.6.3",
- "jest-mock": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jest/reporters": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz",
- "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@bcoe/v8-coverage": "^0.2.3",
- "@jest/console": "^29.7.0",
- "@jest/test-result": "^29.7.0",
- "@jest/transform": "^29.7.0",
- "@jest/types": "^29.6.3",
- "@jridgewell/trace-mapping": "^0.3.18",
- "@types/node": "*",
- "chalk": "^4.0.0",
- "collect-v8-coverage": "^1.0.0",
- "exit": "^0.1.2",
- "glob": "^7.1.3",
- "graceful-fs": "^4.2.9",
- "istanbul-lib-coverage": "^3.0.0",
- "istanbul-lib-instrument": "^6.0.0",
- "istanbul-lib-report": "^3.0.0",
- "istanbul-lib-source-maps": "^4.0.0",
- "istanbul-reports": "^3.1.3",
- "jest-message-util": "^29.7.0",
- "jest-util": "^29.7.0",
- "jest-worker": "^29.7.0",
- "slash": "^3.0.0",
- "string-length": "^4.0.1",
- "strip-ansi": "^6.0.0",
- "v8-to-istanbul": "^9.0.1"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- },
- "peerDependencies": {
- "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
- },
- "peerDependenciesMeta": {
- "node-notifier": {
- "optional": true
- }
- }
- },
- "node_modules/@jest/schemas": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
- "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@sinclair/typebox": "^0.27.8"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jest/source-map": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz",
- "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/trace-mapping": "^0.3.18",
- "callsites": "^3.0.0",
- "graceful-fs": "^4.2.9"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jest/test-result": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz",
- "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/console": "^29.7.0",
- "@jest/types": "^29.6.3",
- "@types/istanbul-lib-coverage": "^2.0.0",
- "collect-v8-coverage": "^1.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jest/test-sequencer": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz",
- "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/test-result": "^29.7.0",
- "graceful-fs": "^4.2.9",
- "jest-haste-map": "^29.7.0",
- "slash": "^3.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jest/transform": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz",
- "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/core": "^7.11.6",
- "@jest/types": "^29.6.3",
- "@jridgewell/trace-mapping": "^0.3.18",
- "babel-plugin-istanbul": "^6.1.1",
- "chalk": "^4.0.0",
- "convert-source-map": "^2.0.0",
- "fast-json-stable-stringify": "^2.1.0",
- "graceful-fs": "^4.2.9",
- "jest-haste-map": "^29.7.0",
- "jest-regex-util": "^29.6.3",
- "jest-util": "^29.7.0",
- "micromatch": "^4.0.4",
- "pirates": "^4.0.4",
- "slash": "^3.0.0",
- "write-file-atomic": "^4.0.2"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jest/types": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
- "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/schemas": "^29.6.3",
- "@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^3.0.0",
- "@types/node": "*",
- "@types/yargs": "^17.0.8",
- "chalk": "^4.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.8",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
- "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/set-array": "^1.2.1",
- "@jridgewell/sourcemap-codec": "^1.4.10",
- "@jridgewell/trace-mapping": "^0.3.24"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
- "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/set-array": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
- "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
- "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.25",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
- "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.1.0",
- "@jridgewell/sourcemap-codec": "^1.4.14"
- }
- },
- "node_modules/@js-sdsl/ordered-map": {
- "version": "4.4.2",
- "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz",
- "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==",
- "license": "MIT",
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/js-sdsl"
- }
- },
- "node_modules/@mapbox/node-pre-gyp": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz",
- "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==",
- "license": "BSD-3-Clause",
- "dependencies": {
- "detect-libc": "^2.0.0",
- "https-proxy-agent": "^5.0.0",
- "make-dir": "^3.1.0",
- "node-fetch": "^2.6.7",
- "nopt": "^5.0.0",
- "npmlog": "^5.0.1",
- "rimraf": "^3.0.2",
- "semver": "^7.3.5",
- "tar": "^6.1.11"
- },
- "bin": {
- "node-pre-gyp": "bin/node-pre-gyp"
- }
- },
- "node_modules/@nodelib/fs.scandir": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
- "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@nodelib/fs.stat": "2.0.5",
- "run-parallel": "^1.1.9"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@nodelib/fs.stat": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
- "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@nodelib/fs.walk": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
- "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@nodelib/fs.scandir": "2.1.5",
- "fastq": "^1.6.0"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@npmcli/fs": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz",
- "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==",
- "license": "ISC",
- "optional": true,
- "dependencies": {
- "@gar/promisify": "^1.0.1",
- "semver": "^7.3.5"
- }
- },
- "node_modules/@npmcli/move-file": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz",
- "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==",
- "deprecated": "This functionality has been moved to @npmcli/fs",
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "mkdirp": "^1.0.4",
- "rimraf": "^3.0.2"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@npmcli/move-file/node_modules/mkdirp": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
- "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
- "license": "MIT",
- "optional": true,
- "bin": {
- "mkdirp": "bin/cmd.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@protobufjs/aspromise": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
- "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==",
- "license": "BSD-3-Clause"
- },
- "node_modules/@protobufjs/base64": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
- "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==",
- "license": "BSD-3-Clause"
- },
- "node_modules/@protobufjs/codegen": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
- "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==",
- "license": "BSD-3-Clause"
- },
- "node_modules/@protobufjs/eventemitter": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
- "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==",
- "license": "BSD-3-Clause"
- },
- "node_modules/@protobufjs/fetch": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
- "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
- "license": "BSD-3-Clause",
- "dependencies": {
- "@protobufjs/aspromise": "^1.1.1",
- "@protobufjs/inquire": "^1.1.0"
- }
- },
- "node_modules/@protobufjs/float": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
- "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==",
- "license": "BSD-3-Clause"
- },
- "node_modules/@protobufjs/inquire": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
- "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==",
- "license": "BSD-3-Clause"
- },
- "node_modules/@protobufjs/path": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
- "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==",
- "license": "BSD-3-Clause"
- },
- "node_modules/@protobufjs/pool": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
- "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==",
- "license": "BSD-3-Clause"
- },
- "node_modules/@protobufjs/utf8": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
- "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==",
- "license": "BSD-3-Clause"
- },
- "node_modules/@puppeteer/browsers": {
- "version": "2.7.1",
- "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.7.1.tgz",
- "integrity": "sha512-MK7rtm8JjaxPN7Mf1JdZIZKPD2Z+W7osvrC1vjpvfOX1K0awDIHYbNi89f7eotp7eMUn2shWnt03HwVbriXtKQ==",
- "license": "Apache-2.0",
- "dependencies": {
- "debug": "^4.4.0",
- "extract-zip": "^2.0.1",
- "progress": "^2.0.3",
- "proxy-agent": "^6.5.0",
- "semver": "^7.7.0",
- "tar-fs": "^3.0.8",
- "yargs": "^17.7.2"
- },
- "bin": {
- "browsers": "lib/cjs/main-cli.js"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@puppeteer/browsers/node_modules/tar-fs": {
- "version": "3.0.8",
- "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.8.tgz",
- "integrity": "sha512-ZoROL70jptorGAlgAYiLoBLItEKw/fUxg9BSYK/dF/GAGYFJOJJJMvjPAKDJraCXFwadD456FCuvLWgfhMsPwg==",
- "license": "MIT",
- "dependencies": {
- "pump": "^3.0.0",
- "tar-stream": "^3.1.5"
- },
- "optionalDependencies": {
- "bare-fs": "^4.0.1",
- "bare-path": "^3.0.0"
- }
- },
- "node_modules/@puppeteer/browsers/node_modules/tar-stream": {
- "version": "3.1.7",
- "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz",
- "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==",
- "license": "MIT",
- "dependencies": {
- "b4a": "^1.6.4",
- "fast-fifo": "^1.2.0",
- "streamx": "^2.15.0"
- }
- },
- "node_modules/@scarf/scarf": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/@scarf/scarf/-/scarf-1.4.0.tgz",
- "integrity": "sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==",
- "hasInstallScript": true,
- "license": "Apache-2.0"
- },
- "node_modules/@sinclair/typebox": {
- "version": "0.27.8",
- "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
- "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@sinonjs/commons": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz",
- "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "type-detect": "4.0.8"
- }
- },
- "node_modules/@sinonjs/fake-timers": {
- "version": "10.3.0",
- "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz",
- "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "@sinonjs/commons": "^3.0.0"
- }
- },
- "node_modules/@tootallnate/once": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
- "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
- "license": "MIT",
- "optional": true,
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/@tootallnate/quickjs-emscripten": {
- "version": "0.23.0",
- "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz",
- "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==",
- "license": "MIT"
- },
- "node_modules/@tsconfig/node10": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
- "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@tsconfig/node12": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
- "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@tsconfig/node14": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
- "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@tsconfig/node16": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
- "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/babel__core": {
- "version": "7.20.5",
- "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
- "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/parser": "^7.20.7",
- "@babel/types": "^7.20.7",
- "@types/babel__generator": "*",
- "@types/babel__template": "*",
- "@types/babel__traverse": "*"
- }
- },
- "node_modules/@types/babel__generator": {
- "version": "7.6.8",
- "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz",
- "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.0.0"
- }
- },
- "node_modules/@types/babel__template": {
- "version": "7.4.4",
- "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
- "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/parser": "^7.1.0",
- "@babel/types": "^7.0.0"
- }
- },
- "node_modules/@types/babel__traverse": {
- "version": "7.20.6",
- "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz",
- "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.20.7"
- }
- },
- "node_modules/@types/bcrypt": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.2.tgz",
- "integrity": "sha512-6atioO8Y75fNcbmj0G7UjI9lXN2pQ/IGJ2FWT4a/btd0Lk9lQalHLKhkgKVZ3r+spnmWUKfbMi1GEe9wyHQfNQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/node": "*"
- }
- },
- "node_modules/@types/body-parser": {
- "version": "1.19.5",
- "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz",
- "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/connect": "*",
- "@types/node": "*"
- }
- },
- "node_modules/@types/connect": {
- "version": "3.4.38",
- "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
- "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/node": "*"
- }
- },
- "node_modules/@types/cookiejar": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.5.tgz",
- "integrity": "sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/cors": {
- "version": "2.8.17",
- "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz",
- "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/node": "*"
- }
- },
- "node_modules/@types/cytoscape": {
- "version": "3.21.9",
- "resolved": "https://registry.npmjs.org/@types/cytoscape/-/cytoscape-3.21.9.tgz",
- "integrity": "sha512-JyrG4tllI6jvuISPjHK9j2Xv/LTbnLekLke5otGStjFluIyA9JjgnvgZrSBsp8cEDpiTjwgZUZwpPv8TSBcoLw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/docker-modem": {
- "version": "3.0.6",
- "resolved": "https://registry.npmjs.org/@types/docker-modem/-/docker-modem-3.0.6.tgz",
- "integrity": "sha512-yKpAGEuKRSS8wwx0joknWxsmLha78wNMe9R2S3UNsVOkZded8UqOrV8KoeDXoXsjndxwyF3eIhyClGbO1SEhEg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/node": "*",
- "@types/ssh2": "*"
- }
- },
- "node_modules/@types/dockerode": {
- "version": "3.3.34",
- "resolved": "https://registry.npmjs.org/@types/dockerode/-/dockerode-3.3.34.tgz",
- "integrity": "sha512-mH9SuIb8NuTDsMus5epcbTzSbEo52fKLBMo0zapzYIAIyfDqoIFn7L3trekHLKC8qmxGV++pPUP4YqQ9n5v2Zg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/docker-modem": "*",
- "@types/node": "*",
- "@types/ssh2": "*"
- }
- },
- "node_modules/@types/estree": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
- "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/express": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.0.tgz",
- "integrity": "sha512-DvZriSMehGHL1ZNLzi6MidnsDhUZM/x2pRdDIKdwbUNqqwHxMlRdkxtn6/EPKyqKpHqTl/4nRZsRNLpZxZRpPQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/body-parser": "*",
- "@types/express-serve-static-core": "^5.0.0",
- "@types/qs": "*",
- "@types/serve-static": "*"
- }
- },
- "node_modules/@types/express-handlebars": {
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/@types/express-handlebars/-/express-handlebars-5.3.1.tgz",
- "integrity": "sha512-DSzaERLO4gHb8AqnrL58jzSDyT0yDdl6HqDc+bGz1Hf0nrG1FK30nHGzv8NBEGR8QV9eUGB/YaE0Qj3NjF7siw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/express-serve-static-core": {
- "version": "5.0.6",
- "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.6.tgz",
- "integrity": "sha512-3xhRnjJPkULekpSzgtoNYYcTWgEZkp4myc+Saevii5JPnHNvHMRlBSHDbs7Bh1iPPoVTERHEZXyhyLbMEsExsA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/node": "*",
- "@types/qs": "*",
- "@types/range-parser": "*",
- "@types/send": "*"
- }
- },
- "node_modules/@types/graceful-fs": {
- "version": "4.1.9",
- "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz",
- "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/node": "*"
- }
- },
- "node_modules/@types/http-errors": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz",
- "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/istanbul-lib-coverage": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
- "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/istanbul-lib-report": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz",
- "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/istanbul-lib-coverage": "*"
- }
- },
- "node_modules/@types/istanbul-reports": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
- "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/istanbul-lib-report": "*"
- }
- },
- "node_modules/@types/jest": {
- "version": "29.5.14",
- "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.14.tgz",
- "integrity": "sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "expect": "^29.0.0",
- "pretty-format": "^29.0.0"
- }
- },
- "node_modules/@types/json-schema": {
- "version": "7.0.15",
- "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
- "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/methods": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/@types/methods/-/methods-1.1.4.tgz",
- "integrity": "sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/mime": {
- "version": "1.3.5",
- "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
- "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/node": {
- "version": "22.13.1",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.1.tgz",
- "integrity": "sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew==",
- "license": "MIT",
- "dependencies": {
- "undici-types": "~6.20.0"
- }
- },
- "node_modules/@types/node-fetch": {
- "version": "2.6.12",
- "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz",
- "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/node": "*",
- "form-data": "^4.0.0"
- }
- },
- "node_modules/@types/nodemailer": {
- "version": "6.4.17",
- "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.17.tgz",
- "integrity": "sha512-I9CCaIp6DTldEg7vyUTZi8+9Vo0hi1/T8gv3C89yk1rSAAzoKQ8H8ki/jBYJSFoH/BisgLP8tkZMlQ91CIquww==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/node": "*"
- }
- },
- "node_modules/@types/qs": {
- "version": "6.9.18",
- "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.18.tgz",
- "integrity": "sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/range-parser": {
- "version": "1.2.7",
- "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz",
- "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/send": {
- "version": "0.17.4",
- "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz",
- "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/mime": "^1",
- "@types/node": "*"
- }
- },
- "node_modules/@types/serve-static": {
- "version": "1.15.7",
- "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz",
- "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/http-errors": "*",
- "@types/node": "*",
- "@types/send": "*"
- }
- },
- "node_modules/@types/ssh2": {
- "version": "1.15.4",
- "resolved": "https://registry.npmjs.org/@types/ssh2/-/ssh2-1.15.4.tgz",
- "integrity": "sha512-9JTQgVBWSgq6mAen6PVnrAmty1lqgCMvpfN+1Ck5WRUsyMYPa6qd50/vMJ0y1zkGpOEgLzm8m8Dx/Y5vRouLaA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/node": "^18.11.18"
- }
- },
- "node_modules/@types/ssh2/node_modules/@types/node": {
- "version": "18.19.75",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.75.tgz",
- "integrity": "sha512-UIksWtThob6ZVSyxcOqCLOUNg/dyO1Qvx4McgeuhrEtHTLFTf7BBhEazaE4K806FGTPtzd/2sE90qn4fVr7cyw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "undici-types": "~5.26.4"
- }
- },
- "node_modules/@types/ssh2/node_modules/undici-types": {
- "version": "5.26.5",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
- "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/stack-utils": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
- "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/superagent": {
- "version": "8.1.9",
- "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-8.1.9.tgz",
- "integrity": "sha512-pTVjI73witn+9ILmoJdajHGW2jkSaOzhiFYF1Rd3EQ94kymLqB9PjD9ISg7WaALC7+dCHT0FGe9T2LktLq/3GQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/cookiejar": "^2.1.5",
- "@types/methods": "^1.1.4",
- "@types/node": "*",
- "form-data": "^4.0.0"
- }
- },
- "node_modules/@types/supertest": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/@types/supertest/-/supertest-6.0.2.tgz",
- "integrity": "sha512-137ypx2lk/wTQbW6An6safu9hXmajAifU/s7szAHLN/FeIm5w7yR0Wkl9fdJMRSHwOn4HLAI0DaB2TOORuhPDg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/methods": "^1.1.4",
- "@types/superagent": "^8.1.0"
- }
- },
- "node_modules/@types/supports-color": {
- "version": "8.1.3",
- "resolved": "https://registry.npmjs.org/@types/supports-color/-/supports-color-8.1.3.tgz",
- "integrity": "sha512-Hy6UMpxhE3j1tLpl27exp1XqHD7n8chAiNPzWfz16LPZoMMoSc4dzLl6w9qijkEb/r5O1ozdu1CWGA2L83ZeZg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/swagger-jsdoc": {
- "version": "6.0.4",
- "resolved": "https://registry.npmjs.org/@types/swagger-jsdoc/-/swagger-jsdoc-6.0.4.tgz",
- "integrity": "sha512-W+Xw5epcOZrF/AooUM/PccNMSAFOKWZA5dasNyMujTwsBkU74njSJBpvCCJhHAJ95XRMzQrrW844Btu0uoetwQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/swagger-ui-express": {
- "version": "4.1.7",
- "resolved": "https://registry.npmjs.org/@types/swagger-ui-express/-/swagger-ui-express-4.1.7.tgz",
- "integrity": "sha512-ovLM9dNincXkzH4YwyYpll75vhzPBlWx6La89wwvYH7mHjVpf0X0K/vR/aUM7SRxmr5tt9z7E5XJcjQ46q+S3g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/express": "*",
- "@types/serve-static": "*"
- }
- },
- "node_modules/@types/triple-beam": {
- "version": "1.3.5",
- "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz",
- "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==",
- "license": "MIT"
- },
- "node_modules/@types/ws": {
- "version": "8.5.14",
- "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.14.tgz",
- "integrity": "sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/node": "*"
- }
- },
- "node_modules/@types/yamljs": {
- "version": "0.2.34",
- "resolved": "https://registry.npmjs.org/@types/yamljs/-/yamljs-0.2.34.tgz",
- "integrity": "sha512-gJvfRlv9ErxdOv7ux7UsJVePtX54NAvQyd8ncoiFqK8G5aeHIfQfGH2fbruvjAQ9657HwAaO54waS+Dsk2QTUQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/yargs": {
- "version": "17.0.33",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
- "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/yargs-parser": "*"
- }
- },
- "node_modules/@types/yargs-parser": {
- "version": "21.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz",
- "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/yauzl": {
- "version": "2.10.3",
- "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz",
- "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==",
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@types/node": "*"
- }
- },
- "node_modules/@typescript-eslint/eslint-plugin": {
- "version": "8.23.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.23.0.tgz",
- "integrity": "sha512-vBz65tJgRrA1Q5gWlRfvoH+w943dq9K1p1yDBY2pc+a1nbBLZp7fB9+Hk8DaALUbzjqlMfgaqlVPT1REJdkt/w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@eslint-community/regexpp": "^4.10.0",
- "@typescript-eslint/scope-manager": "8.23.0",
- "@typescript-eslint/type-utils": "8.23.0",
- "@typescript-eslint/utils": "8.23.0",
- "@typescript-eslint/visitor-keys": "8.23.0",
- "graphemer": "^1.4.0",
- "ignore": "^5.3.1",
- "natural-compare": "^1.4.0",
- "ts-api-utils": "^2.0.1"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0",
- "eslint": "^8.57.0 || ^9.0.0",
- "typescript": ">=4.8.4 <5.8.0"
- }
- },
- "node_modules/@typescript-eslint/parser": {
- "version": "8.23.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.23.0.tgz",
- "integrity": "sha512-h2lUByouOXFAlMec2mILeELUbME5SZRN/7R9Cw2RD2lRQQY08MWMM+PmVVKKJNK1aIwqTo9t/0CvOxwPbRIE2Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/scope-manager": "8.23.0",
- "@typescript-eslint/types": "8.23.0",
- "@typescript-eslint/typescript-estree": "8.23.0",
- "@typescript-eslint/visitor-keys": "8.23.0",
- "debug": "^4.3.4"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^8.57.0 || ^9.0.0",
- "typescript": ">=4.8.4 <5.8.0"
- }
- },
- "node_modules/@typescript-eslint/scope-manager": {
- "version": "8.23.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.23.0.tgz",
- "integrity": "sha512-OGqo7+dXHqI7Hfm+WqkZjKjsiRtFUQHPdGMXzk5mYXhJUedO7e/Y7i8AK3MyLMgZR93TX4bIzYrfyVjLC+0VSw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/types": "8.23.0",
- "@typescript-eslint/visitor-keys": "8.23.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/@typescript-eslint/type-utils": {
- "version": "8.23.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.23.0.tgz",
- "integrity": "sha512-iIuLdYpQWZKbiH+RkCGc6iu+VwscP5rCtQ1lyQ7TYuKLrcZoeJVpcLiG8DliXVkUxirW/PWlmS+d6yD51L9jvA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/typescript-estree": "8.23.0",
- "@typescript-eslint/utils": "8.23.0",
- "debug": "^4.3.4",
- "ts-api-utils": "^2.0.1"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^8.57.0 || ^9.0.0",
- "typescript": ">=4.8.4 <5.8.0"
- }
- },
- "node_modules/@typescript-eslint/types": {
- "version": "8.23.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.23.0.tgz",
- "integrity": "sha512-1sK4ILJbCmZOTt9k4vkoulT6/y5CHJ1qUYxqpF1K/DBAd8+ZUL4LlSCxOssuH5m4rUaaN0uS0HlVPvd45zjduQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/@typescript-eslint/typescript-estree": {
- "version": "8.23.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.23.0.tgz",
- "integrity": "sha512-LcqzfipsB8RTvH8FX24W4UUFk1bl+0yTOf9ZA08XngFwMg4Kj8A+9hwz8Cr/ZS4KwHrmo9PJiLZkOt49vPnuvQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/types": "8.23.0",
- "@typescript-eslint/visitor-keys": "8.23.0",
- "debug": "^4.3.4",
- "fast-glob": "^3.3.2",
- "is-glob": "^4.0.3",
- "minimatch": "^9.0.4",
- "semver": "^7.6.0",
- "ts-api-utils": "^2.0.1"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "typescript": ">=4.8.4 <5.8.0"
- }
- },
- "node_modules/@typescript-eslint/utils": {
- "version": "8.23.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.23.0.tgz",
- "integrity": "sha512-uB/+PSo6Exu02b5ZEiVtmY6RVYO7YU5xqgzTIVZwTHvvK3HsL8tZZHFaTLFtRG3CsV4A5mhOv+NZx5BlhXPyIA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@eslint-community/eslint-utils": "^4.4.0",
- "@typescript-eslint/scope-manager": "8.23.0",
- "@typescript-eslint/types": "8.23.0",
- "@typescript-eslint/typescript-estree": "8.23.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^8.57.0 || ^9.0.0",
- "typescript": ">=4.8.4 <5.8.0"
- }
- },
- "node_modules/@typescript-eslint/visitor-keys": {
- "version": "8.23.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.23.0.tgz",
- "integrity": "sha512-oWWhcWDLwDfu++BGTZcmXWqpwtkwb5o7fxUIGksMQQDSdPW9prsSnfIOZMlsj4vBOSrcnjIUZMiIjODgGosFhQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/types": "8.23.0",
- "eslint-visitor-keys": "^4.2.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz",
- "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/abbrev": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
- "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
- "license": "ISC"
- },
- "node_modules/accepts": {
- "version": "1.3.8",
- "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
- "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
- "license": "MIT",
- "dependencies": {
- "mime-types": "~2.1.34",
- "negotiator": "0.6.3"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/acorn": {
- "version": "8.14.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
- "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "acorn": "bin/acorn"
- },
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/acorn-jsx": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
- "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
- "dev": true,
- "license": "MIT",
- "peerDependencies": {
- "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
- }
- },
- "node_modules/acorn-jsx-walk": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/acorn-jsx-walk/-/acorn-jsx-walk-2.0.0.tgz",
- "integrity": "sha512-uuo6iJj4D4ygkdzd6jPtcxs8vZgDX9YFIkqczGImoypX2fQ4dVImmu3UzA4ynixCIMTrEOWW+95M2HuBaCEOVA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/acorn-loose": {
- "version": "8.4.0",
- "resolved": "https://registry.npmjs.org/acorn-loose/-/acorn-loose-8.4.0.tgz",
- "integrity": "sha512-M0EUka6rb+QC4l9Z3T0nJEzNOO7JcoJlYMrBlyBCiFSXRyxjLKayd4TbQs2FDRWQU1h9FR7QVNHt+PEaoNL5rQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "acorn": "^8.11.0"
- },
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/acorn-walk": {
- "version": "8.3.4",
- "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
- "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "acorn": "^8.11.0"
- },
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/agent-base": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
- "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
- "license": "MIT",
- "dependencies": {
- "debug": "4"
- },
- "engines": {
- "node": ">= 6.0.0"
- }
- },
- "node_modules/agentkeepalive": {
- "version": "4.6.0",
- "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz",
- "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==",
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "humanize-ms": "^1.2.1"
- },
- "engines": {
- "node": ">= 8.0.0"
- }
- },
- "node_modules/aggregate-error": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
- "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "clean-stack": "^2.0.0",
- "indent-string": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/ajv": {
- "version": "8.17.1",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
- "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "fast-deep-equal": "^3.1.3",
- "fast-uri": "^3.0.1",
- "json-schema-traverse": "^1.0.0",
- "require-from-string": "^2.0.2"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
- }
- },
- "node_modules/ansi-escapes": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
- "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "type-fest": "^0.21.3"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "license": "MIT",
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/anymatch": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
- "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "normalize-path": "^3.0.0",
- "picomatch": "^2.0.4"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/anymatch/node_modules/picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/aproba": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
- "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==",
- "license": "ISC"
- },
- "node_modules/are-we-there-yet": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz",
- "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==",
- "deprecated": "This package is no longer supported.",
- "license": "ISC",
- "dependencies": {
- "delegates": "^1.0.0",
- "readable-stream": "^3.6.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/arg": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
- "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/argparse": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "license": "Python-2.0"
- },
- "node_modules/array-find-index": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
- "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/array-flatten": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
- "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
- "license": "MIT"
- },
- "node_modules/asap": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
- "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/asn1": {
- "version": "0.2.6",
- "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
- "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
- "license": "MIT",
- "dependencies": {
- "safer-buffer": "~2.1.0"
- }
- },
- "node_modules/ast-types": {
- "version": "0.13.4",
- "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz",
- "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==",
- "license": "MIT",
- "dependencies": {
- "tslib": "^2.0.1"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/async": {
- "version": "3.2.6",
- "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
- "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
- "license": "MIT"
- },
- "node_modules/asynckit": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/b4a": {
- "version": "1.6.7",
- "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz",
- "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==",
- "license": "Apache-2.0"
- },
- "node_modules/babel-jest": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz",
- "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/transform": "^29.7.0",
- "@types/babel__core": "^7.1.14",
- "babel-plugin-istanbul": "^6.1.1",
- "babel-preset-jest": "^29.6.3",
- "chalk": "^4.0.0",
- "graceful-fs": "^4.2.9",
- "slash": "^3.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.8.0"
- }
- },
- "node_modules/babel-plugin-istanbul": {
- "version": "6.1.1",
- "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz",
- "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.0.0",
- "@istanbuljs/load-nyc-config": "^1.0.0",
- "@istanbuljs/schema": "^0.1.2",
- "istanbul-lib-instrument": "^5.0.4",
- "test-exclude": "^6.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz",
- "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "@babel/core": "^7.12.3",
- "@babel/parser": "^7.14.7",
- "@istanbuljs/schema": "^0.1.2",
- "istanbul-lib-coverage": "^3.2.0",
- "semver": "^6.3.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/babel-plugin-istanbul/node_modules/semver": {
- "version": "6.3.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
- "dev": true,
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- }
- },
- "node_modules/babel-plugin-jest-hoist": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz",
- "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/template": "^7.3.3",
- "@babel/types": "^7.3.3",
- "@types/babel__core": "^7.1.14",
- "@types/babel__traverse": "^7.0.6"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/babel-preset-current-node-syntax": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz",
- "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/plugin-syntax-async-generators": "^7.8.4",
- "@babel/plugin-syntax-bigint": "^7.8.3",
- "@babel/plugin-syntax-class-properties": "^7.12.13",
- "@babel/plugin-syntax-class-static-block": "^7.14.5",
- "@babel/plugin-syntax-import-attributes": "^7.24.7",
- "@babel/plugin-syntax-import-meta": "^7.10.4",
- "@babel/plugin-syntax-json-strings": "^7.8.3",
- "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
- "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
- "@babel/plugin-syntax-numeric-separator": "^7.10.4",
- "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
- "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
- "@babel/plugin-syntax-optional-chaining": "^7.8.3",
- "@babel/plugin-syntax-private-property-in-object": "^7.14.5",
- "@babel/plugin-syntax-top-level-await": "^7.14.5"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/babel-preset-jest": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz",
- "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "babel-plugin-jest-hoist": "^29.6.3",
- "babel-preset-current-node-syntax": "^1.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/balanced-match": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
- "license": "MIT"
- },
- "node_modules/bare-events": {
- "version": "2.5.4",
- "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.4.tgz",
- "integrity": "sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==",
- "license": "Apache-2.0",
- "optional": true
- },
- "node_modules/bare-fs": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.0.1.tgz",
- "integrity": "sha512-ilQs4fm/l9eMfWY2dY0WCIUplSUp7U0CT1vrqMg1MUdeZl4fypu5UP0XcDBK5WBQPJAKP1b7XEodISmekH/CEg==",
- "license": "Apache-2.0",
- "optional": true,
- "dependencies": {
- "bare-events": "^2.0.0",
- "bare-path": "^3.0.0",
- "bare-stream": "^2.0.0"
- },
- "engines": {
- "bare": ">=1.7.0"
- }
- },
- "node_modules/bare-os": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.4.0.tgz",
- "integrity": "sha512-9Ous7UlnKbe3fMi7Y+qh0DwAup6A1JkYgPnjvMDNOlmnxNRQvQ/7Nst+OnUQKzk0iAT0m9BisbDVp9gCv8+ETA==",
- "license": "Apache-2.0",
- "optional": true,
- "engines": {
- "bare": ">=1.6.0"
- }
- },
- "node_modules/bare-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz",
- "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==",
- "license": "Apache-2.0",
- "optional": true,
- "dependencies": {
- "bare-os": "^3.0.1"
- }
- },
- "node_modules/bare-stream": {
- "version": "2.6.5",
- "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.6.5.tgz",
- "integrity": "sha512-jSmxKJNJmHySi6hC42zlZnq00rga4jjxcgNZjY9N5WlOe/iOoGRtdwGsHzQv2RlH2KOYMwGUXhf2zXd32BA9RA==",
- "license": "Apache-2.0",
- "optional": true,
- "dependencies": {
- "streamx": "^2.21.0"
- },
- "peerDependencies": {
- "bare-buffer": "*",
- "bare-events": "*"
- },
- "peerDependenciesMeta": {
- "bare-buffer": {
- "optional": true
- },
- "bare-events": {
- "optional": true
- }
- }
- },
- "node_modules/base64-js": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
- "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT"
- },
- "node_modules/basic-ftp": {
- "version": "5.0.5",
- "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz",
- "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==",
- "license": "MIT",
- "engines": {
- "node": ">=10.0.0"
- }
- },
- "node_modules/bcrypt": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz",
- "integrity": "sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==",
- "hasInstallScript": true,
- "license": "MIT",
- "dependencies": {
- "@mapbox/node-pre-gyp": "^1.0.11",
- "node-addon-api": "^5.0.0"
- },
- "engines": {
- "node": ">= 10.0.0"
- }
- },
- "node_modules/bcrypt-pbkdf": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
- "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==",
- "license": "BSD-3-Clause",
- "dependencies": {
- "tweetnacl": "^0.14.3"
- }
- },
- "node_modules/binary-extensions": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
- "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/bindings": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
- "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
- "license": "MIT",
- "dependencies": {
- "file-uri-to-path": "1.0.0"
- }
- },
- "node_modules/bl": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
- "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
- "license": "MIT",
- "dependencies": {
- "buffer": "^5.5.0",
- "inherits": "^2.0.4",
- "readable-stream": "^3.4.0"
- }
- },
- "node_modules/body-parser": {
- "version": "1.20.3",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
- "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
- "license": "MIT",
- "dependencies": {
- "bytes": "3.1.2",
- "content-type": "~1.0.5",
- "debug": "2.6.9",
- "depd": "2.0.0",
- "destroy": "1.2.0",
- "http-errors": "2.0.0",
- "iconv-lite": "0.4.24",
- "on-finished": "2.4.1",
- "qs": "6.13.0",
- "raw-body": "2.5.2",
- "type-is": "~1.6.18",
- "unpipe": "1.0.0"
- },
- "engines": {
- "node": ">= 0.8",
- "npm": "1.2.8000 || >= 1.4.16"
- }
- },
- "node_modules/body-parser/node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "license": "MIT",
- "dependencies": {
- "ms": "2.0.0"
- }
- },
- "node_modules/body-parser/node_modules/ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
- "license": "MIT"
- },
- "node_modules/brace-expansion": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
- "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0"
- }
- },
- "node_modules/braces": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
- "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "fill-range": "^7.1.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/browserslist": {
- "version": "4.24.4",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz",
- "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/browserslist"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "caniuse-lite": "^1.0.30001688",
- "electron-to-chromium": "^1.5.73",
- "node-releases": "^2.0.19",
- "update-browserslist-db": "^1.1.1"
- },
- "bin": {
- "browserslist": "cli.js"
- },
- "engines": {
- "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
- }
- },
- "node_modules/bs-logger": {
- "version": "0.2.6",
- "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz",
- "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "fast-json-stable-stringify": "2.x"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/bser": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
- "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "node-int64": "^0.4.0"
- }
- },
- "node_modules/buffer": {
- "version": "5.7.1",
- "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
- "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "base64-js": "^1.3.1",
- "ieee754": "^1.1.13"
- }
- },
- "node_modules/buffer-crc32": {
- "version": "0.2.13",
- "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
- "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
- "license": "MIT",
- "engines": {
- "node": "*"
- }
- },
- "node_modules/buffer-from": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
- "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/buildcheck": {
- "version": "0.0.6",
- "resolved": "https://registry.npmjs.org/buildcheck/-/buildcheck-0.0.6.tgz",
- "integrity": "sha512-8f9ZJCUXyT1M35Jx7MkBgmBMo3oHTTBIPLiY9xyL0pl3T5RwcPEY8cUHr5LBNfu/fk6c2T4DJZuVM/8ZZT2D2A==",
- "optional": true,
- "engines": {
- "node": ">=10.0.0"
- }
- },
- "node_modules/bytes": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
- "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/cacache": {
- "version": "15.3.0",
- "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz",
- "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==",
- "license": "ISC",
- "optional": true,
- "dependencies": {
- "@npmcli/fs": "^1.0.0",
- "@npmcli/move-file": "^1.0.1",
- "chownr": "^2.0.0",
- "fs-minipass": "^2.0.0",
- "glob": "^7.1.4",
- "infer-owner": "^1.0.4",
- "lru-cache": "^6.0.0",
- "minipass": "^3.1.1",
- "minipass-collect": "^1.0.2",
- "minipass-flush": "^1.0.5",
- "minipass-pipeline": "^1.2.2",
- "mkdirp": "^1.0.3",
- "p-map": "^4.0.0",
- "promise-inflight": "^1.0.1",
- "rimraf": "^3.0.2",
- "ssri": "^8.0.1",
- "tar": "^6.0.2",
- "unique-filename": "^1.1.1"
- },
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/cacache/node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "license": "ISC",
- "optional": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/cacache/node_modules/mkdirp": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
- "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
- "license": "MIT",
- "optional": true,
- "bin": {
- "mkdirp": "bin/cmd.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/cacache/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "license": "ISC",
- "optional": true
- },
- "node_modules/call-bind-apply-helpers": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz",
- "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "function-bind": "^1.1.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/call-bound": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz",
- "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==",
- "license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.1",
- "get-intrinsic": "^1.2.6"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/callsites": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
- "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/camelcase": {
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
- "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/caniuse-lite": {
- "version": "1.0.30001698",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001698.tgz",
- "integrity": "sha512-xJ3km2oiG/MbNU8G6zIq6XRZ6HtAOVXsbOrP/blGazi52kc5Yy7b6sDA5O+FbROzRrV7BSTllLHuNvmawYUJjw==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "CC-BY-4.0"
- },
- "node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/char-regex": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
- "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/chokidar": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
- "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
- "license": "MIT",
- "dependencies": {
- "readdirp": "^4.0.1"
- },
- "engines": {
- "node": ">= 14.16.0"
- },
- "funding": {
- "url": "https://paulmillr.com/funding/"
- }
- },
- "node_modules/chownr": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
- "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
- "license": "ISC",
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/chromium-bidi": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-1.2.0.tgz",
- "integrity": "sha512-XtdJ1GSN6S3l7tO7F77GhNsw0K367p0IsLYf2yZawCVAKKC3lUvDhPdMVrB2FNhmhfW43QGYbEX3Wg6q0maGwQ==",
- "license": "Apache-2.0",
- "dependencies": {
- "mitt": "^3.0.1",
- "zod": "^3.24.1"
- },
- "peerDependencies": {
- "devtools-protocol": "*"
- }
- },
- "node_modules/ci-info": {
- "version": "3.9.0",
- "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
- "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/sibiraj-s"
- }
- ],
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/cjs-module-lexer": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz",
- "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/clean-stack": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
- "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
- "license": "MIT",
- "optional": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/cliui": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
- "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
- "license": "ISC",
- "dependencies": {
- "string-width": "^4.2.0",
- "strip-ansi": "^6.0.1",
- "wrap-ansi": "^7.0.0"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/co": {
- "version": "4.6.0",
- "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
- "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "iojs": ">= 1.0.0",
- "node": ">= 0.12.0"
- }
- },
- "node_modules/collect-v8-coverage": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz",
- "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/color": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz",
- "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==",
- "license": "MIT",
- "dependencies": {
- "color-convert": "^1.9.3",
- "color-string": "^1.6.0"
- }
- },
- "node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "license": "MIT",
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "license": "MIT"
- },
- "node_modules/color-string": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
- "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
- "license": "MIT",
- "dependencies": {
- "color-name": "^1.0.0",
- "simple-swizzle": "^0.2.2"
- }
- },
- "node_modules/color-support": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
- "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
- "license": "ISC",
- "bin": {
- "color-support": "bin.js"
- }
- },
- "node_modules/color/node_modules/color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
- "license": "MIT",
- "dependencies": {
- "color-name": "1.1.3"
- }
- },
- "node_modules/color/node_modules/color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
- "license": "MIT"
- },
- "node_modules/colorspace": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz",
- "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==",
- "license": "MIT",
- "dependencies": {
- "color": "^3.1.3",
- "text-hex": "1.0.x"
- }
- },
- "node_modules/combined-stream": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
- "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "delayed-stream": "~1.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/commander": {
- "version": "13.1.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz",
- "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/component-emitter": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz",
- "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==",
- "dev": true,
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
- "license": "MIT"
- },
- "node_modules/console-control-strings": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
- "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==",
- "license": "ISC"
- },
- "node_modules/content-disposition": {
- "version": "0.5.4",
- "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
- "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
- "license": "MIT",
- "dependencies": {
- "safe-buffer": "5.2.1"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/content-type": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
- "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/convert-source-map": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
- "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/cookie": {
- "version": "0.7.1",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
- "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/cookie-signature": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
- "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
- "license": "MIT"
- },
- "node_modules/cookiejar": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz",
- "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/cors": {
- "version": "2.8.5",
- "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
- "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
- "license": "MIT",
- "dependencies": {
- "object-assign": "^4",
- "vary": "^1"
- },
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/cosmiconfig": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz",
- "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==",
- "license": "MIT",
- "dependencies": {
- "env-paths": "^2.2.1",
- "import-fresh": "^3.3.0",
- "js-yaml": "^4.1.0",
- "parse-json": "^5.2.0"
- },
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/sponsors/d-fischer"
- },
- "peerDependencies": {
- "typescript": ">=4.9.5"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/cpu-features": {
- "version": "0.0.10",
- "resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.10.tgz",
- "integrity": "sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA==",
- "hasInstallScript": true,
- "optional": true,
- "dependencies": {
- "buildcheck": "~0.0.6",
- "nan": "^2.19.0"
- },
- "engines": {
- "node": ">=10.0.0"
- }
- },
- "node_modules/create-jest": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz",
- "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/types": "^29.6.3",
- "chalk": "^4.0.0",
- "exit": "^0.1.2",
- "graceful-fs": "^4.2.9",
- "jest-config": "^29.7.0",
- "jest-util": "^29.7.0",
- "prompts": "^2.0.1"
- },
- "bin": {
- "create-jest": "bin/create-jest.js"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/create-require": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
- "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/cross-spawn": {
- "version": "7.0.6",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
- "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "path-key": "^3.1.0",
- "shebang-command": "^2.0.0",
- "which": "^2.0.1"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/cytoscape": {
- "version": "3.31.0",
- "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.31.0.tgz",
- "integrity": "sha512-zDGn1K/tfZwEnoGOcHc0H4XazqAAXAuDpcYw9mUnUjATjqljyCNGJv8uEvbvxGaGHaVshxMecyl6oc6uKzRfbw==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10"
- }
- },
- "node_modules/data-uri-to-buffer": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz",
- "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==",
- "license": "MIT",
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/debug": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
- "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/debuglog": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz",
- "integrity": "sha512-syBZ+rnAK3EgMsH2aYEOLUW7mZSY9Gb+0wUMCFsZvcmiz+HigA0LOcq/HoQqVuGG+EKykunc7QG2bzrponfaSw==",
- "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "*"
- }
- },
- "node_modules/decompress-response": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
- "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
- "license": "MIT",
- "dependencies": {
- "mimic-response": "^3.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/dedent": {
- "version": "1.5.3",
- "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz",
- "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==",
- "dev": true,
- "license": "MIT",
- "peerDependencies": {
- "babel-plugin-macros": "^3.1.0"
- },
- "peerDependenciesMeta": {
- "babel-plugin-macros": {
- "optional": true
- }
- }
- },
- "node_modules/deep-extend": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
- "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
- "license": "MIT",
- "engines": {
- "node": ">=4.0.0"
- }
- },
- "node_modules/deep-is": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
- "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/deepmerge": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
- "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/degenerator": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz",
- "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==",
- "license": "MIT",
- "dependencies": {
- "ast-types": "^0.13.4",
- "escodegen": "^2.1.0",
- "esprima": "^4.0.1"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/delayed-stream": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
- "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/delegates": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
- "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==",
- "license": "MIT"
- },
- "node_modules/depd": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
- "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/dependency-cruiser": {
- "version": "16.9.0",
- "resolved": "https://registry.npmjs.org/dependency-cruiser/-/dependency-cruiser-16.9.0.tgz",
- "integrity": "sha512-Gc/xHNOBq1nk5i7FPCuexCD0m2OXB/WEfiSHfNYQaQaHZiZltnl5Ixp/ZG38Jvi8aEhKBQTHV4Aw6gmR7rWlOw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "acorn": "^8.14.0",
- "acorn-jsx": "^5.3.2",
- "acorn-jsx-walk": "^2.0.0",
- "acorn-loose": "^8.4.0",
- "acorn-walk": "^8.3.4",
- "ajv": "^8.17.1",
- "commander": "^13.0.0",
- "enhanced-resolve": "^5.18.0",
- "ignore": "^7.0.0",
- "interpret": "^3.1.1",
- "is-installed-globally": "^1.0.0",
- "json5": "^2.2.3",
- "memoize": "^10.0.0",
- "picocolors": "^1.1.1",
- "picomatch": "^4.0.2",
- "prompts": "^2.4.2",
- "rechoir": "^0.8.0",
- "safe-regex": "^2.1.1",
- "semver": "^7.6.3",
- "teamcity-service-messages": "^0.1.14",
- "tsconfig-paths-webpack-plugin": "^4.2.0",
- "watskeburt": "^4.2.2"
- },
- "bin": {
- "depcruise": "bin/dependency-cruise.mjs",
- "depcruise-baseline": "bin/depcruise-baseline.mjs",
- "depcruise-fmt": "bin/depcruise-fmt.mjs",
- "depcruise-wrap-stream-in-html": "bin/wrap-stream-in-html.mjs",
- "dependency-cruise": "bin/dependency-cruise.mjs",
- "dependency-cruiser": "bin/dependency-cruise.mjs"
- },
- "engines": {
- "node": "^18.17||>=20"
- }
- },
- "node_modules/dependency-cruiser/node_modules/ignore": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.3.tgz",
- "integrity": "sha512-bAH5jbK/F3T3Jls4I0SO1hmPR0dKU0a7+SY6n1yzRtG54FLO8d6w/nxLFX2Nb7dBu6cCWXPaAME6cYqFUMmuCA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 4"
- }
- },
- "node_modules/destroy": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
- "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8",
- "npm": "1.2.8000 || >= 1.4.16"
- }
- },
- "node_modules/detect-libc": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
- "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/detect-newline": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
- "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/devtools-protocol": {
- "version": "0.0.1402036",
- "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1402036.tgz",
- "integrity": "sha512-JwAYQgEvm3yD45CHB+RmF5kMbWtXBaOGwuxa87sZogHcLCv8c/IqnThaoQ1y60d7pXWjSKWQphPEc+1rAScVdg==",
- "license": "BSD-3-Clause"
- },
- "node_modules/dezalgo": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz",
- "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "asap": "^2.0.0",
- "wrappy": "1"
- }
- },
- "node_modules/diff": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
- "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
- "dev": true,
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.3.1"
- }
- },
- "node_modules/diff-sequences": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz",
- "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/docker-compose": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/docker-compose/-/docker-compose-1.1.0.tgz",
- "integrity": "sha512-VrkQJNafPQ5d6bGULW0P6KqcxSkv3ZU5Wn2wQA19oB71o7+55vQ9ogFe2MMeNbK+jc9rrKVy280DnHO5JLMWOQ==",
- "license": "MIT",
- "dependencies": {
- "yaml": "^2.2.2"
- },
- "engines": {
- "node": ">= 6.0.0"
- }
- },
- "node_modules/docker-modem": {
- "version": "5.0.6",
- "resolved": "https://registry.npmjs.org/docker-modem/-/docker-modem-5.0.6.tgz",
- "integrity": "sha512-ens7BiayssQz/uAxGzH8zGXCtiV24rRWXdjNha5V4zSOcxmAZsfGVm/PPFbwQdqEkDnhG+SyR9E3zSHUbOKXBQ==",
- "license": "Apache-2.0",
- "dependencies": {
- "debug": "^4.1.1",
- "readable-stream": "^3.5.0",
- "split-ca": "^1.0.1",
- "ssh2": "^1.15.0"
- },
- "engines": {
- "node": ">= 8.0"
- }
- },
- "node_modules/dockerode": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/dockerode/-/dockerode-4.0.4.tgz",
- "integrity": "sha512-6GYP/EdzEY50HaOxTVTJ2p+mB5xDHTMJhS+UoGrVyS6VC+iQRh7kZ4FRpUYq6nziby7hPqWhOrFFUFTMUZJJ5w==",
- "license": "Apache-2.0",
- "dependencies": {
- "@balena/dockerignore": "^1.0.2",
- "@grpc/grpc-js": "^1.11.1",
- "@grpc/proto-loader": "^0.7.13",
- "docker-modem": "^5.0.6",
- "protobufjs": "^7.3.2",
- "tar-fs": "~2.0.1",
- "uuid": "^10.0.0"
- },
- "engines": {
- "node": ">= 8.0"
- }
- },
- "node_modules/dunder-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
- "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
- "license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.1",
- "es-errors": "^1.3.0",
- "gopd": "^1.2.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/ee-first": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
- "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
- "license": "MIT"
- },
- "node_modules/ejs": {
- "version": "3.1.10",
- "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
- "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "jake": "^10.8.5"
- },
- "bin": {
- "ejs": "bin/cli.js"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/electron-to-chromium": {
- "version": "1.5.96",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.96.tgz",
- "integrity": "sha512-8AJUW6dh75Fm/ny8+kZKJzI1pgoE8bKLZlzDU2W1ENd+DXKJrx7I7l9hb8UWR4ojlnb5OlixMt00QWiYJoVw1w==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/emittery": {
- "version": "0.13.1",
- "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz",
- "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sindresorhus/emittery?sponsor=1"
- }
- },
- "node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "license": "MIT"
- },
- "node_modules/enabled": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz",
- "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==",
- "license": "MIT"
- },
- "node_modules/encodeurl": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
- "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/encoding": {
- "version": "0.1.13",
- "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
- "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "iconv-lite": "^0.6.2"
- }
- },
- "node_modules/encoding/node_modules/iconv-lite": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
- "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "safer-buffer": ">= 2.1.2 < 3.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/end-of-stream": {
- "version": "1.4.4",
- "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
- "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
- "license": "MIT",
- "dependencies": {
- "once": "^1.4.0"
- }
- },
- "node_modules/enhanced-resolve": {
- "version": "5.18.1",
- "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz",
- "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "graceful-fs": "^4.2.4",
- "tapable": "^2.2.0"
- },
- "engines": {
- "node": ">=10.13.0"
- }
- },
- "node_modules/env-paths": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
- "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/err-code": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
- "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
- "license": "MIT",
- "optional": true
- },
- "node_modules/error-ex": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
- "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
- "license": "MIT",
- "dependencies": {
- "is-arrayish": "^0.2.1"
- }
- },
- "node_modules/es-define-property": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
- "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-errors": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
- "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-object-atoms": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
- "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/esbuild": {
- "version": "0.23.1",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz",
- "integrity": "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==",
- "dev": true,
- "hasInstallScript": true,
- "license": "MIT",
- "bin": {
- "esbuild": "bin/esbuild"
- },
- "engines": {
- "node": ">=18"
- },
- "optionalDependencies": {
- "@esbuild/aix-ppc64": "0.23.1",
- "@esbuild/android-arm": "0.23.1",
- "@esbuild/android-arm64": "0.23.1",
- "@esbuild/android-x64": "0.23.1",
- "@esbuild/darwin-arm64": "0.23.1",
- "@esbuild/darwin-x64": "0.23.1",
- "@esbuild/freebsd-arm64": "0.23.1",
- "@esbuild/freebsd-x64": "0.23.1",
- "@esbuild/linux-arm": "0.23.1",
- "@esbuild/linux-arm64": "0.23.1",
- "@esbuild/linux-ia32": "0.23.1",
- "@esbuild/linux-loong64": "0.23.1",
- "@esbuild/linux-mips64el": "0.23.1",
- "@esbuild/linux-ppc64": "0.23.1",
- "@esbuild/linux-riscv64": "0.23.1",
- "@esbuild/linux-s390x": "0.23.1",
- "@esbuild/linux-x64": "0.23.1",
- "@esbuild/netbsd-x64": "0.23.1",
- "@esbuild/openbsd-arm64": "0.23.1",
- "@esbuild/openbsd-x64": "0.23.1",
- "@esbuild/sunos-x64": "0.23.1",
- "@esbuild/win32-arm64": "0.23.1",
- "@esbuild/win32-ia32": "0.23.1",
- "@esbuild/win32-x64": "0.23.1"
- }
- },
- "node_modules/escalade": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
- "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/escape-html": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
- "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
- "license": "MIT"
- },
- "node_modules/escape-string-regexp": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
- "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/escodegen": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz",
- "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==",
- "license": "BSD-2-Clause",
- "dependencies": {
- "esprima": "^4.0.1",
- "estraverse": "^5.2.0",
- "esutils": "^2.0.2"
- },
- "bin": {
- "escodegen": "bin/escodegen.js",
- "esgenerate": "bin/esgenerate.js"
- },
- "engines": {
- "node": ">=6.0"
- },
- "optionalDependencies": {
- "source-map": "~0.6.1"
- }
- },
- "node_modules/eslint": {
- "version": "9.20.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.20.0.tgz",
- "integrity": "sha512-aL4F8167Hg4IvsW89ejnpTwx+B/UQRzJPGgbIOl+4XqffWsahVVsLEWoZvnrVuwpWmnRd7XeXmQI1zlKcFDteA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@eslint-community/eslint-utils": "^4.2.0",
- "@eslint-community/regexpp": "^4.12.1",
- "@eslint/config-array": "^0.19.0",
- "@eslint/core": "^0.11.0",
- "@eslint/eslintrc": "^3.2.0",
- "@eslint/js": "9.20.0",
- "@eslint/plugin-kit": "^0.2.5",
- "@humanfs/node": "^0.16.6",
- "@humanwhocodes/module-importer": "^1.0.1",
- "@humanwhocodes/retry": "^0.4.1",
- "@types/estree": "^1.0.6",
- "@types/json-schema": "^7.0.15",
- "ajv": "^6.12.4",
- "chalk": "^4.0.0",
- "cross-spawn": "^7.0.6",
- "debug": "^4.3.2",
- "escape-string-regexp": "^4.0.0",
- "eslint-scope": "^8.2.0",
- "eslint-visitor-keys": "^4.2.0",
- "espree": "^10.3.0",
- "esquery": "^1.5.0",
- "esutils": "^2.0.2",
- "fast-deep-equal": "^3.1.3",
- "file-entry-cache": "^8.0.0",
- "find-up": "^5.0.0",
- "glob-parent": "^6.0.2",
- "ignore": "^5.2.0",
- "imurmurhash": "^0.1.4",
- "is-glob": "^4.0.0",
- "json-stable-stringify-without-jsonify": "^1.0.1",
- "lodash.merge": "^4.6.2",
- "minimatch": "^3.1.2",
- "natural-compare": "^1.4.0",
- "optionator": "^0.9.3"
- },
- "bin": {
- "eslint": "bin/eslint.js"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://eslint.org/donate"
- },
- "peerDependencies": {
- "jiti": "*"
- },
- "peerDependenciesMeta": {
- "jiti": {
- "optional": true
- }
- }
- },
- "node_modules/eslint-scope": {
- "version": "8.2.0",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz",
- "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "esrecurse": "^4.3.0",
- "estraverse": "^5.2.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/eslint-visitor-keys": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
- "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/eslint/node_modules/ajv": {
- "version": "6.12.6",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
- "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "fast-deep-equal": "^3.1.1",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.4.1",
- "uri-js": "^4.2.2"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
- }
- },
- "node_modules/eslint/node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/eslint/node_modules/eslint-visitor-keys": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz",
- "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/eslint/node_modules/json-schema-traverse": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
- "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/eslint/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/espree": {
- "version": "10.3.0",
- "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz",
- "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "acorn": "^8.14.0",
- "acorn-jsx": "^5.3.2",
- "eslint-visitor-keys": "^4.2.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/espree/node_modules/eslint-visitor-keys": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz",
- "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/esprima": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
- "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
- "license": "BSD-2-Clause",
- "bin": {
- "esparse": "bin/esparse.js",
- "esvalidate": "bin/esvalidate.js"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/esquery": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
- "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "estraverse": "^5.1.0"
- },
- "engines": {
- "node": ">=0.10"
- }
- },
- "node_modules/esrecurse": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
- "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "estraverse": "^5.2.0"
- },
- "engines": {
- "node": ">=4.0"
- }
- },
- "node_modules/estraverse": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
- "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=4.0"
- }
- },
- "node_modules/esutils": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
- "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/etag": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
- "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/execa": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
- "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "cross-spawn": "^7.0.3",
- "get-stream": "^6.0.0",
- "human-signals": "^2.1.0",
- "is-stream": "^2.0.0",
- "merge-stream": "^2.0.0",
- "npm-run-path": "^4.0.1",
- "onetime": "^5.1.2",
- "signal-exit": "^3.0.3",
- "strip-final-newline": "^2.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sindresorhus/execa?sponsor=1"
- }
- },
- "node_modules/exit": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
- "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==",
- "dev": true,
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/expand-template": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
- "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
- "license": "(MIT OR WTFPL)",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/expect": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz",
- "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/expect-utils": "^29.7.0",
- "jest-get-type": "^29.6.3",
- "jest-matcher-utils": "^29.7.0",
- "jest-message-util": "^29.7.0",
- "jest-util": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/express": {
- "version": "4.21.2",
- "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
- "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
- "license": "MIT",
- "dependencies": {
- "accepts": "~1.3.8",
- "array-flatten": "1.1.1",
- "body-parser": "1.20.3",
- "content-disposition": "0.5.4",
- "content-type": "~1.0.4",
- "cookie": "0.7.1",
- "cookie-signature": "1.0.6",
- "debug": "2.6.9",
- "depd": "2.0.0",
- "encodeurl": "~2.0.0",
- "escape-html": "~1.0.3",
- "etag": "~1.8.1",
- "finalhandler": "1.3.1",
- "fresh": "0.5.2",
- "http-errors": "2.0.0",
- "merge-descriptors": "1.0.3",
- "methods": "~1.1.2",
- "on-finished": "2.4.1",
- "parseurl": "~1.3.3",
- "path-to-regexp": "0.1.12",
- "proxy-addr": "~2.0.7",
- "qs": "6.13.0",
- "range-parser": "~1.2.1",
- "safe-buffer": "5.2.1",
- "send": "0.19.0",
- "serve-static": "1.16.2",
- "setprototypeof": "1.2.0",
- "statuses": "2.0.1",
- "type-is": "~1.6.18",
- "utils-merge": "1.0.1",
- "vary": "~1.1.2"
- },
- "engines": {
- "node": ">= 0.10.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
- }
- },
- "node_modules/express-rate-limit": {
- "version": "7.5.0",
- "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.0.tgz",
- "integrity": "sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg==",
- "license": "MIT",
- "engines": {
- "node": ">= 16"
- },
- "funding": {
- "url": "https://github.com/sponsors/express-rate-limit"
- },
- "peerDependencies": {
- "express": "^4.11 || 5 || ^5.0.0-beta.1"
- }
- },
- "node_modules/express/node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "license": "MIT",
- "dependencies": {
- "ms": "2.0.0"
- }
- },
- "node_modules/express/node_modules/ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
- "license": "MIT"
- },
- "node_modules/extract-zip": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
- "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
- "license": "BSD-2-Clause",
- "dependencies": {
- "debug": "^4.1.1",
- "get-stream": "^5.1.0",
- "yauzl": "^2.10.0"
- },
- "bin": {
- "extract-zip": "cli.js"
- },
- "engines": {
- "node": ">= 10.17.0"
- },
- "optionalDependencies": {
- "@types/yauzl": "^2.9.1"
- }
- },
- "node_modules/extract-zip/node_modules/get-stream": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
- "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
- "license": "MIT",
- "dependencies": {
- "pump": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/fast-deep-equal": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
- "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/fast-fifo": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz",
- "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==",
- "license": "MIT"
- },
- "node_modules/fast-glob": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
- "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@nodelib/fs.stat": "^2.0.2",
- "@nodelib/fs.walk": "^1.2.3",
- "glob-parent": "^5.1.2",
- "merge2": "^1.3.0",
- "micromatch": "^4.0.8"
- },
- "engines": {
- "node": ">=8.6.0"
- }
- },
- "node_modules/fast-glob/node_modules/glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "is-glob": "^4.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/fast-json-stable-stringify": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
- "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/fast-levenshtein": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
- "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/fast-safe-stringify": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
- "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/fast-uri": {
- "version": "3.0.6",
- "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz",
- "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/fastify"
- },
- {
- "type": "opencollective",
- "url": "https://opencollective.com/fastify"
- }
- ],
- "license": "BSD-3-Clause"
- },
- "node_modules/fastq": {
- "version": "1.19.0",
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.0.tgz",
- "integrity": "sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "reusify": "^1.0.4"
- }
- },
- "node_modules/fb-watchman": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz",
- "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "bser": "2.1.1"
- }
- },
- "node_modules/fd-slicer": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
- "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
- "license": "MIT",
- "dependencies": {
- "pend": "~1.2.0"
- }
- },
- "node_modules/fecha": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz",
- "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==",
- "license": "MIT"
- },
- "node_modules/file-entry-cache": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
- "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "flat-cache": "^4.0.0"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/file-stream-rotator": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/file-stream-rotator/-/file-stream-rotator-0.6.1.tgz",
- "integrity": "sha512-u+dBid4PvZw17PmDeRcNOtCP9CCK/9lRN2w+r1xIS7yOL9JFrIBKTvrYsxT4P0pGtThYTn++QS5ChHaUov3+zQ==",
- "license": "MIT",
- "dependencies": {
- "moment": "^2.29.1"
- }
- },
- "node_modules/file-uri-to-path": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
- "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
- "license": "MIT"
- },
- "node_modules/filelist": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
- "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "minimatch": "^5.0.1"
- }
- },
- "node_modules/filelist/node_modules/minimatch": {
- "version": "5.1.6",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
- "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^2.0.1"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/fill-range": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
- "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "to-regex-range": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/finalhandler": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
- "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
- "license": "MIT",
- "dependencies": {
- "debug": "2.6.9",
- "encodeurl": "~2.0.0",
- "escape-html": "~1.0.3",
- "on-finished": "2.4.1",
- "parseurl": "~1.3.3",
- "statuses": "2.0.1",
- "unpipe": "~1.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/finalhandler/node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "license": "MIT",
- "dependencies": {
- "ms": "2.0.0"
- }
- },
- "node_modules/finalhandler/node_modules/ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
- "license": "MIT"
- },
- "node_modules/find-up": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
- "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "locate-path": "^6.0.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/flat-cache": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
- "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "flatted": "^3.2.9",
- "keyv": "^4.5.4"
- },
- "engines": {
- "node": ">=16"
- }
- },
- "node_modules/flatted": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz",
- "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/fn.name": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz",
- "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==",
- "license": "MIT"
- },
- "node_modules/form-data": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz",
- "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "asynckit": "^0.4.0",
- "combined-stream": "^1.0.8",
- "mime-types": "^2.1.12"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/formidable": {
- "version": "3.5.2",
- "resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.2.tgz",
- "integrity": "sha512-Jqc1btCy3QzRbJaICGwKcBfGWuLADRerLzDqi2NwSt/UkXLsHJw2TVResiaoBufHVHy9aSgClOHCeJsSsFLTbg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "dezalgo": "^1.0.4",
- "hexoid": "^2.0.0",
- "once": "^1.4.0"
- },
- "funding": {
- "url": "https://ko-fi.com/tunnckoCore/commissions"
- }
- },
- "node_modules/forwarded": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
- "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/fresh": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
- "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/fs-constants": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
- "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
- "license": "MIT"
- },
- "node_modules/fs-minipass": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
- "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
- "license": "ISC",
- "dependencies": {
- "minipass": "^3.0.0"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/fs.realpath": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
- "license": "ISC"
- },
- "node_modules/fsevents": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
- "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
- "dev": true,
- "hasInstallScript": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
- }
- },
- "node_modules/function-bind": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
- "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/gauge": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz",
- "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==",
- "deprecated": "This package is no longer supported.",
- "license": "ISC",
- "dependencies": {
- "aproba": "^1.0.3 || ^2.0.0",
- "color-support": "^1.1.2",
- "console-control-strings": "^1.0.0",
- "has-unicode": "^2.0.1",
- "object-assign": "^4.1.1",
- "signal-exit": "^3.0.0",
- "string-width": "^4.2.3",
- "strip-ansi": "^6.0.1",
- "wide-align": "^1.1.2"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/gensync": {
- "version": "1.0.0-beta.2",
- "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
- "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/get-caller-file": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
- "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
- "license": "ISC",
- "engines": {
- "node": "6.* || 8.* || >= 10.*"
- }
- },
- "node_modules/get-intrinsic": {
- "version": "1.2.7",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz",
- "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==",
- "license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.1",
- "es-define-property": "^1.0.1",
- "es-errors": "^1.3.0",
- "es-object-atoms": "^1.0.0",
- "function-bind": "^1.1.2",
- "get-proto": "^1.0.0",
- "gopd": "^1.2.0",
- "has-symbols": "^1.1.0",
- "hasown": "^2.0.2",
- "math-intrinsics": "^1.1.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/get-package-type": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
- "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8.0.0"
- }
- },
- "node_modules/get-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
- "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
- "license": "MIT",
- "dependencies": {
- "dunder-proto": "^1.0.1",
- "es-object-atoms": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/get-stream": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
- "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/get-tsconfig": {
- "version": "4.10.0",
- "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.0.tgz",
- "integrity": "sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "resolve-pkg-maps": "^1.0.0"
- },
- "funding": {
- "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
- }
- },
- "node_modules/get-uri": {
- "version": "6.0.4",
- "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.4.tgz",
- "integrity": "sha512-E1b1lFFLvLgak2whF2xDBcOy6NLVGZBqqjJjsIhvopKfWWEi64pLVTWWehV8KlLerZkfNTA95sTe2OdJKm1OzQ==",
- "license": "MIT",
- "dependencies": {
- "basic-ftp": "^5.0.2",
- "data-uri-to-buffer": "^6.0.2",
- "debug": "^4.3.4"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/github-from-package": {
- "version": "0.0.0",
- "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
- "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
- "license": "MIT"
- },
- "node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "deprecated": "Glob versions prior to v9 are no longer supported",
- "license": "ISC",
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/glob-parent": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
- "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "is-glob": "^4.0.3"
- },
- "engines": {
- "node": ">=10.13.0"
- }
- },
- "node_modules/glob/node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/glob/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/global-directory": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz",
- "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ini": "4.1.1"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/globals": {
- "version": "15.14.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-15.14.0.tgz",
- "integrity": "sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/gopd": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
- "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/graceful-fs": {
- "version": "4.2.11",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
- "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
- "devOptional": true,
- "license": "ISC"
- },
- "node_modules/graphemer": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
- "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/has-symbols": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
- "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/has-unicode": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
- "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==",
- "license": "ISC"
- },
- "node_modules/hasown": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
- "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
- "license": "MIT",
- "dependencies": {
- "function-bind": "^1.1.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/hexoid": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-2.0.0.tgz",
- "integrity": "sha512-qlspKUK7IlSQv2o+5I7yhUd7TxlOG2Vr5LTa3ve2XSNVKAL/n/u/7KLvKmFNimomDIKvZFXWHv0T12mv7rT8Aw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/hosted-git-info": {
- "version": "2.8.9",
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
- "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/html-escaper": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
- "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/http-cache-semantics": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
- "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==",
- "license": "BSD-2-Clause",
- "optional": true
- },
- "node_modules/http-errors": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
- "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
- "license": "MIT",
- "dependencies": {
- "depd": "2.0.0",
- "inherits": "2.0.4",
- "setprototypeof": "1.2.0",
- "statuses": "2.0.1",
- "toidentifier": "1.0.1"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/http-proxy-agent": {
- "version": "7.0.2",
- "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
- "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
- "license": "MIT",
- "dependencies": {
- "agent-base": "^7.1.0",
- "debug": "^4.3.4"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/http-proxy-agent/node_modules/agent-base": {
- "version": "7.1.3",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
- "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==",
- "license": "MIT",
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/https": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/https/-/https-1.0.0.tgz",
- "integrity": "sha512-4EC57ddXrkaF0x83Oj8sM6SLQHAWXw90Skqu2M4AEWENZ3F02dFJE/GARA8igO79tcgYqGrD7ae4f5L3um2lgg==",
- "license": "ISC"
- },
- "node_modules/https-proxy-agent": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
- "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
- "license": "MIT",
- "dependencies": {
- "agent-base": "6",
- "debug": "4"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/human-signals": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
- "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": ">=10.17.0"
- }
- },
- "node_modules/humanize-ms": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
- "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "ms": "^2.0.0"
- }
- },
- "node_modules/i": {
- "version": "0.3.7",
- "resolved": "https://registry.npmjs.org/i/-/i-0.3.7.tgz",
- "integrity": "sha512-FYz4wlXgkQwIPqhzC5TdNMLSE5+GS1IIDJZY/1ZiEPCT2S3COUVZeT5OW4BmW4r5LHLQuOosSwsvnroG9GR59Q==",
- "engines": {
- "node": ">=0.4"
- }
- },
- "node_modules/iconv-lite": {
- "version": "0.4.24",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
- "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
- "license": "MIT",
- "dependencies": {
- "safer-buffer": ">= 2.1.2 < 3"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/ieee754": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
- "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "BSD-3-Clause"
- },
- "node_modules/ignore": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
- "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 4"
- }
- },
- "node_modules/ignore-by-default": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
- "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/import-fresh": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
- "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
- "license": "MIT",
- "dependencies": {
- "parent-module": "^1.0.0",
- "resolve-from": "^4.0.0"
- },
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/import-local": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz",
- "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "pkg-dir": "^4.2.0",
- "resolve-cwd": "^3.0.0"
- },
- "bin": {
- "import-local-fixture": "fixtures/cli.js"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/imurmurhash": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
- "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
- "devOptional": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.8.19"
- }
- },
- "node_modules/indent-string": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
- "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
- "license": "MIT",
- "optional": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/infer-owner": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
- "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==",
- "license": "ISC",
- "optional": true
- },
- "node_modules/inflight": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
- "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
- "license": "ISC",
- "dependencies": {
- "once": "^1.3.0",
- "wrappy": "1"
- }
- },
- "node_modules/inherits": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
- "license": "ISC"
- },
- "node_modules/ini": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz",
- "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==",
- "dev": true,
- "license": "ISC",
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/interpret": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz",
- "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10.13.0"
- }
- },
- "node_modules/ip-address": {
- "version": "9.0.5",
- "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz",
- "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==",
- "license": "MIT",
- "dependencies": {
- "jsbn": "1.1.0",
- "sprintf-js": "^1.1.3"
- },
- "engines": {
- "node": ">= 12"
- }
- },
- "node_modules/ipaddr.js": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz",
- "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==",
- "license": "MIT",
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/is-arrayish": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
- "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
- "license": "MIT"
- },
- "node_modules/is-binary-path": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
- "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "binary-extensions": "^2.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-core-module": {
- "version": "2.16.1",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
- "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "hasown": "^2.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-generator-fn": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz",
- "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-extglob": "^2.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-installed-globally": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-1.0.0.tgz",
- "integrity": "sha512-K55T22lfpQ63N4KEN57jZUAaAYqYHEe8veb/TycJRk9DdSCLLcovXz/mL6mOnhQaZsQGwPhuFopdQIlqGSEjiQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "global-directory": "^4.0.1",
- "is-path-inside": "^4.0.0"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/is-lambda": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz",
- "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==",
- "license": "MIT",
- "optional": true
- },
- "node_modules/is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.12.0"
- }
- },
- "node_modules/is-path-inside": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-4.0.0.tgz",
- "integrity": "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/is-stream": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
- "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/isexe": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
- "devOptional": true,
- "license": "ISC"
- },
- "node_modules/istanbul-lib-coverage": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
- "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
- "dev": true,
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/istanbul-lib-instrument": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz",
- "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "@babel/core": "^7.23.9",
- "@babel/parser": "^7.23.9",
- "@istanbuljs/schema": "^0.1.3",
- "istanbul-lib-coverage": "^3.2.0",
- "semver": "^7.5.4"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/istanbul-lib-report": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
- "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "istanbul-lib-coverage": "^3.0.0",
- "make-dir": "^4.0.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/istanbul-lib-report/node_modules/make-dir": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
- "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "semver": "^7.5.3"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/istanbul-lib-source-maps": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
- "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "debug": "^4.1.1",
- "istanbul-lib-coverage": "^3.0.0",
- "source-map": "^0.6.1"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/istanbul-reports": {
- "version": "3.1.7",
- "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz",
- "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "html-escaper": "^2.0.0",
- "istanbul-lib-report": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jake": {
- "version": "10.9.2",
- "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz",
- "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "async": "^3.2.3",
- "chalk": "^4.0.2",
- "filelist": "^1.0.4",
- "minimatch": "^3.1.2"
- },
- "bin": {
- "jake": "bin/cli.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/jake/node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/jake/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/jest": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz",
- "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/core": "^29.7.0",
- "@jest/types": "^29.6.3",
- "import-local": "^3.0.2",
- "jest-cli": "^29.7.0"
- },
- "bin": {
- "jest": "bin/jest.js"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- },
- "peerDependencies": {
- "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
- },
- "peerDependenciesMeta": {
- "node-notifier": {
- "optional": true
- }
- }
- },
- "node_modules/jest-changed-files": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz",
- "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "execa": "^5.0.0",
- "jest-util": "^29.7.0",
- "p-limit": "^3.1.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-circus": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz",
- "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/environment": "^29.7.0",
- "@jest/expect": "^29.7.0",
- "@jest/test-result": "^29.7.0",
- "@jest/types": "^29.6.3",
- "@types/node": "*",
- "chalk": "^4.0.0",
- "co": "^4.6.0",
- "dedent": "^1.0.0",
- "is-generator-fn": "^2.0.0",
- "jest-each": "^29.7.0",
- "jest-matcher-utils": "^29.7.0",
- "jest-message-util": "^29.7.0",
- "jest-runtime": "^29.7.0",
- "jest-snapshot": "^29.7.0",
- "jest-util": "^29.7.0",
- "p-limit": "^3.1.0",
- "pretty-format": "^29.7.0",
- "pure-rand": "^6.0.0",
- "slash": "^3.0.0",
- "stack-utils": "^2.0.3"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-cli": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz",
- "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/core": "^29.7.0",
- "@jest/test-result": "^29.7.0",
- "@jest/types": "^29.6.3",
- "chalk": "^4.0.0",
- "create-jest": "^29.7.0",
- "exit": "^0.1.2",
- "import-local": "^3.0.2",
- "jest-config": "^29.7.0",
- "jest-util": "^29.7.0",
- "jest-validate": "^29.7.0",
- "yargs": "^17.3.1"
- },
- "bin": {
- "jest": "bin/jest.js"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- },
- "peerDependencies": {
- "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
- },
- "peerDependenciesMeta": {
- "node-notifier": {
- "optional": true
- }
- }
- },
- "node_modules/jest-config": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz",
- "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/core": "^7.11.6",
- "@jest/test-sequencer": "^29.7.0",
- "@jest/types": "^29.6.3",
- "babel-jest": "^29.7.0",
- "chalk": "^4.0.0",
- "ci-info": "^3.2.0",
- "deepmerge": "^4.2.2",
- "glob": "^7.1.3",
- "graceful-fs": "^4.2.9",
- "jest-circus": "^29.7.0",
- "jest-environment-node": "^29.7.0",
- "jest-get-type": "^29.6.3",
- "jest-regex-util": "^29.6.3",
- "jest-resolve": "^29.7.0",
- "jest-runner": "^29.7.0",
- "jest-util": "^29.7.0",
- "jest-validate": "^29.7.0",
- "micromatch": "^4.0.4",
- "parse-json": "^5.2.0",
- "pretty-format": "^29.7.0",
- "slash": "^3.0.0",
- "strip-json-comments": "^3.1.1"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- },
- "peerDependencies": {
- "@types/node": "*",
- "ts-node": ">=9.0.0"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- },
- "ts-node": {
- "optional": true
- }
- }
- },
- "node_modules/jest-diff": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz",
- "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "chalk": "^4.0.0",
- "diff-sequences": "^29.6.3",
- "jest-get-type": "^29.6.3",
- "pretty-format": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-docblock": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz",
- "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "detect-newline": "^3.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-each": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz",
- "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/types": "^29.6.3",
- "chalk": "^4.0.0",
- "jest-get-type": "^29.6.3",
- "jest-util": "^29.7.0",
- "pretty-format": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-environment-node": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz",
- "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/environment": "^29.7.0",
- "@jest/fake-timers": "^29.7.0",
- "@jest/types": "^29.6.3",
- "@types/node": "*",
- "jest-mock": "^29.7.0",
- "jest-util": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-get-type": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz",
- "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-haste-map": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz",
- "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/types": "^29.6.3",
- "@types/graceful-fs": "^4.1.3",
- "@types/node": "*",
- "anymatch": "^3.0.3",
- "fb-watchman": "^2.0.0",
- "graceful-fs": "^4.2.9",
- "jest-regex-util": "^29.6.3",
- "jest-util": "^29.7.0",
- "jest-worker": "^29.7.0",
- "micromatch": "^4.0.4",
- "walker": "^1.0.8"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- },
- "optionalDependencies": {
- "fsevents": "^2.3.2"
- }
- },
- "node_modules/jest-leak-detector": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz",
- "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "jest-get-type": "^29.6.3",
- "pretty-format": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-matcher-utils": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz",
- "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "chalk": "^4.0.0",
- "jest-diff": "^29.7.0",
- "jest-get-type": "^29.6.3",
- "pretty-format": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-message-util": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz",
- "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.12.13",
- "@jest/types": "^29.6.3",
- "@types/stack-utils": "^2.0.0",
- "chalk": "^4.0.0",
- "graceful-fs": "^4.2.9",
- "micromatch": "^4.0.4",
- "pretty-format": "^29.7.0",
- "slash": "^3.0.0",
- "stack-utils": "^2.0.3"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-mock": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz",
- "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/types": "^29.6.3",
- "@types/node": "*",
- "jest-util": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-pnp-resolver": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz",
- "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- },
- "peerDependencies": {
- "jest-resolve": "*"
- },
- "peerDependenciesMeta": {
- "jest-resolve": {
- "optional": true
- }
- }
- },
- "node_modules/jest-regex-util": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz",
- "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-resolve": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz",
- "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "chalk": "^4.0.0",
- "graceful-fs": "^4.2.9",
- "jest-haste-map": "^29.7.0",
- "jest-pnp-resolver": "^1.2.2",
- "jest-util": "^29.7.0",
- "jest-validate": "^29.7.0",
- "resolve": "^1.20.0",
- "resolve.exports": "^2.0.0",
- "slash": "^3.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-resolve-dependencies": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz",
- "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "jest-regex-util": "^29.6.3",
- "jest-snapshot": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-runner": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz",
- "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/console": "^29.7.0",
- "@jest/environment": "^29.7.0",
- "@jest/test-result": "^29.7.0",
- "@jest/transform": "^29.7.0",
- "@jest/types": "^29.6.3",
- "@types/node": "*",
- "chalk": "^4.0.0",
- "emittery": "^0.13.1",
- "graceful-fs": "^4.2.9",
- "jest-docblock": "^29.7.0",
- "jest-environment-node": "^29.7.0",
- "jest-haste-map": "^29.7.0",
- "jest-leak-detector": "^29.7.0",
- "jest-message-util": "^29.7.0",
- "jest-resolve": "^29.7.0",
- "jest-runtime": "^29.7.0",
- "jest-util": "^29.7.0",
- "jest-watcher": "^29.7.0",
- "jest-worker": "^29.7.0",
- "p-limit": "^3.1.0",
- "source-map-support": "0.5.13"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-runtime": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz",
- "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/environment": "^29.7.0",
- "@jest/fake-timers": "^29.7.0",
- "@jest/globals": "^29.7.0",
- "@jest/source-map": "^29.6.3",
- "@jest/test-result": "^29.7.0",
- "@jest/transform": "^29.7.0",
- "@jest/types": "^29.6.3",
- "@types/node": "*",
- "chalk": "^4.0.0",
- "cjs-module-lexer": "^1.0.0",
- "collect-v8-coverage": "^1.0.0",
- "glob": "^7.1.3",
- "graceful-fs": "^4.2.9",
- "jest-haste-map": "^29.7.0",
- "jest-message-util": "^29.7.0",
- "jest-mock": "^29.7.0",
- "jest-regex-util": "^29.6.3",
- "jest-resolve": "^29.7.0",
- "jest-snapshot": "^29.7.0",
- "jest-util": "^29.7.0",
- "slash": "^3.0.0",
- "strip-bom": "^4.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-snapshot": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz",
- "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/core": "^7.11.6",
- "@babel/generator": "^7.7.2",
- "@babel/plugin-syntax-jsx": "^7.7.2",
- "@babel/plugin-syntax-typescript": "^7.7.2",
- "@babel/types": "^7.3.3",
- "@jest/expect-utils": "^29.7.0",
- "@jest/transform": "^29.7.0",
- "@jest/types": "^29.6.3",
- "babel-preset-current-node-syntax": "^1.0.0",
- "chalk": "^4.0.0",
- "expect": "^29.7.0",
- "graceful-fs": "^4.2.9",
- "jest-diff": "^29.7.0",
- "jest-get-type": "^29.6.3",
- "jest-matcher-utils": "^29.7.0",
- "jest-message-util": "^29.7.0",
- "jest-util": "^29.7.0",
- "natural-compare": "^1.4.0",
- "pretty-format": "^29.7.0",
- "semver": "^7.5.3"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-util": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz",
- "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/types": "^29.6.3",
- "@types/node": "*",
- "chalk": "^4.0.0",
- "ci-info": "^3.2.0",
- "graceful-fs": "^4.2.9",
- "picomatch": "^2.2.3"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-util/node_modules/picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/jest-validate": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz",
- "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/types": "^29.6.3",
- "camelcase": "^6.2.0",
- "chalk": "^4.0.0",
- "jest-get-type": "^29.6.3",
- "leven": "^3.1.0",
- "pretty-format": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-validate/node_modules/camelcase": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
- "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/jest-watcher": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz",
- "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/test-result": "^29.7.0",
- "@jest/types": "^29.6.3",
- "@types/node": "*",
- "ansi-escapes": "^4.2.1",
- "chalk": "^4.0.0",
- "emittery": "^0.13.1",
- "jest-util": "^29.7.0",
- "string-length": "^4.0.1"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-worker": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz",
- "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/node": "*",
- "jest-util": "^29.7.0",
- "merge-stream": "^2.0.0",
- "supports-color": "^8.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-worker/node_modules/supports-color": {
- "version": "8.1.1",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
- "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/supports-color?sponsor=1"
- }
- },
- "node_modules/js-tokens": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
- "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
- "license": "MIT"
- },
- "node_modules/js-yaml": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
- "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
- "license": "MIT",
- "dependencies": {
- "argparse": "^2.0.1"
- },
- "bin": {
- "js-yaml": "bin/js-yaml.js"
- }
- },
- "node_modules/jsbn": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
- "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==",
- "license": "MIT"
- },
- "node_modules/jsesc": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
- "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "jsesc": "bin/jsesc"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/json-buffer": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
- "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/json-parse-even-better-errors": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
- "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
- "license": "MIT"
- },
- "node_modules/json-schema-traverse": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
- "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/json-stable-stringify-without-jsonify": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
- "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/json5": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
- "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "json5": "lib/cli.js"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/keyv": {
- "version": "4.5.4",
- "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
- "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "json-buffer": "3.0.1"
- }
- },
- "node_modules/kleur": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
- "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/kuler": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz",
- "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==",
- "license": "MIT"
- },
- "node_modules/leven": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
- "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/levn": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
- "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "prelude-ls": "^1.2.1",
- "type-check": "~0.4.0"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/license-checker": {
- "version": "25.0.1",
- "resolved": "https://registry.npmjs.org/license-checker/-/license-checker-25.0.1.tgz",
- "integrity": "sha512-mET5AIwl7MR2IAKYYoVBBpV0OnkKQ1xGj2IMMeEFIs42QAkEVjRtFZGWmQ28WeU7MP779iAgOaOy93Mn44mn6g==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "chalk": "^2.4.1",
- "debug": "^3.1.0",
- "mkdirp": "^0.5.1",
- "nopt": "^4.0.1",
- "read-installed": "~4.0.3",
- "semver": "^5.5.0",
- "spdx-correct": "^3.0.0",
- "spdx-expression-parse": "^3.0.0",
- "spdx-satisfies": "^4.0.0",
- "treeify": "^1.1.0"
- },
- "bin": {
- "license-checker": "bin/license-checker"
- }
- },
- "node_modules/license-checker/node_modules/ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "color-convert": "^1.9.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/license-checker/node_modules/chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/license-checker/node_modules/color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "color-name": "1.1.3"
- }
- },
- "node_modules/license-checker/node_modules/color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/license-checker/node_modules/debug": {
- "version": "3.2.7",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
- "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.1"
- }
- },
- "node_modules/license-checker/node_modules/escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.8.0"
- }
- },
- "node_modules/license-checker/node_modules/has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/license-checker/node_modules/nopt": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz",
- "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "abbrev": "1",
- "osenv": "^0.1.4"
- },
- "bin": {
- "nopt": "bin/nopt.js"
- }
- },
- "node_modules/license-checker/node_modules/semver": {
- "version": "5.7.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
- "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
- "dev": true,
- "license": "ISC",
- "bin": {
- "semver": "bin/semver"
- }
- },
- "node_modules/license-checker/node_modules/supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "has-flag": "^3.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/lines-and-columns": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
- "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
- "license": "MIT"
- },
- "node_modules/locate-path": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
- "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "p-locate": "^5.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/lodash.camelcase": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
- "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==",
- "license": "MIT"
- },
- "node_modules/lodash.memoize": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
- "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/lodash.merge": {
- "version": "4.6.2",
- "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
- "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/logform": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/logform/-/logform-2.7.0.tgz",
- "integrity": "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==",
- "license": "MIT",
- "dependencies": {
- "@colors/colors": "1.6.0",
- "@types/triple-beam": "^1.3.2",
- "fecha": "^4.2.0",
- "ms": "^2.1.1",
- "safe-stable-stringify": "^2.3.1",
- "triple-beam": "^1.3.0"
- },
- "engines": {
- "node": ">= 12.0.0"
- }
- },
- "node_modules/long": {
- "version": "5.2.4",
- "resolved": "https://registry.npmjs.org/long/-/long-5.2.4.tgz",
- "integrity": "sha512-qtzLbJE8hq7VabR3mISmVGtoXP8KGc2Z/AT8OuqlYD7JTR3oqrgwdjnk07wpj1twXxYmgDXgoKVWUG/fReSzHg==",
- "license": "Apache-2.0"
- },
- "node_modules/lru-cache": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
- "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "yallist": "^3.0.2"
- }
- },
- "node_modules/make-dir": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
- "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
- "license": "MIT",
- "dependencies": {
- "semver": "^6.0.0"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/make-dir/node_modules/semver": {
- "version": "6.3.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- }
- },
- "node_modules/make-error": {
- "version": "1.3.6",
- "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
- "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/make-fetch-happen": {
- "version": "9.1.0",
- "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz",
- "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==",
- "license": "ISC",
- "optional": true,
- "dependencies": {
- "agentkeepalive": "^4.1.3",
- "cacache": "^15.2.0",
- "http-cache-semantics": "^4.1.0",
- "http-proxy-agent": "^4.0.1",
- "https-proxy-agent": "^5.0.0",
- "is-lambda": "^1.0.1",
- "lru-cache": "^6.0.0",
- "minipass": "^3.1.3",
- "minipass-collect": "^1.0.2",
- "minipass-fetch": "^1.3.2",
- "minipass-flush": "^1.0.5",
- "minipass-pipeline": "^1.2.4",
- "negotiator": "^0.6.2",
- "promise-retry": "^2.0.1",
- "socks-proxy-agent": "^6.0.0",
- "ssri": "^8.0.0"
- },
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/make-fetch-happen/node_modules/http-proxy-agent": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
- "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@tootallnate/once": "1",
- "agent-base": "6",
- "debug": "4"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/make-fetch-happen/node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "license": "ISC",
- "optional": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/make-fetch-happen/node_modules/socks-proxy-agent": {
- "version": "6.2.1",
- "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz",
- "integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==",
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "agent-base": "^6.0.2",
- "debug": "^4.3.3",
- "socks": "^2.6.2"
- },
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/make-fetch-happen/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "license": "ISC",
- "optional": true
- },
- "node_modules/makeerror": {
- "version": "1.0.12",
- "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
- "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "tmpl": "1.0.5"
- }
- },
- "node_modules/math-intrinsics": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
- "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/media-typer": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
- "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/memoize": {
- "version": "10.0.0",
- "resolved": "https://registry.npmjs.org/memoize/-/memoize-10.0.0.tgz",
- "integrity": "sha512-H6cBLgsi6vMWOcCpvVCdFFnl3kerEXbrYh9q+lY6VXvQSmM6CkmV08VOwT+WE2tzIEqRPFfAq3fm4v/UIW6mSA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "mimic-function": "^5.0.0"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sindresorhus/memoize?sponsor=1"
- }
- },
- "node_modules/merge-descriptors": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
- "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/merge-stream": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
- "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/merge2": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
- "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/methods": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
- "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/micromatch": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
- "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "braces": "^3.0.3",
- "picomatch": "^2.3.1"
- },
- "engines": {
- "node": ">=8.6"
- }
- },
- "node_modules/micromatch/node_modules/picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/mime": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
- "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
- "license": "MIT",
- "bin": {
- "mime": "cli.js"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/mime-db": {
- "version": "1.52.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
- "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/mime-types": {
- "version": "2.1.35",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
- "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
- "license": "MIT",
- "dependencies": {
- "mime-db": "1.52.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/mimic-fn": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
- "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/mimic-function": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz",
- "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/mimic-response": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
- "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/minimatch": {
- "version": "9.0.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
- "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^2.0.1"
- },
- "engines": {
- "node": ">=16 || 14 >=14.17"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/minimist": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
- "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/minipass": {
- "version": "3.3.6",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
- "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
- "license": "ISC",
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/minipass-collect": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
- "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
- "license": "ISC",
- "optional": true,
- "dependencies": {
- "minipass": "^3.0.0"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/minipass-fetch": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz",
- "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==",
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "minipass": "^3.1.0",
- "minipass-sized": "^1.0.3",
- "minizlib": "^2.0.0"
- },
- "engines": {
- "node": ">=8"
- },
- "optionalDependencies": {
- "encoding": "^0.1.12"
- }
- },
- "node_modules/minipass-flush": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
- "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
- "license": "ISC",
- "optional": true,
- "dependencies": {
- "minipass": "^3.0.0"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/minipass-pipeline": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
- "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
- "license": "ISC",
- "optional": true,
- "dependencies": {
- "minipass": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/minipass-sized": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz",
- "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==",
- "license": "ISC",
- "optional": true,
- "dependencies": {
- "minipass": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/minipass/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "license": "ISC"
- },
- "node_modules/minizlib": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
- "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
- "license": "MIT",
- "dependencies": {
- "minipass": "^3.0.0",
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/minizlib/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "license": "ISC"
- },
- "node_modules/mitt": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz",
- "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==",
- "license": "MIT"
- },
- "node_modules/mkdirp": {
- "version": "0.5.6",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
- "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "minimist": "^1.2.6"
- },
- "bin": {
- "mkdirp": "bin/cmd.js"
- }
- },
- "node_modules/mkdirp-classic": {
- "version": "0.5.3",
- "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
- "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
- "license": "MIT"
- },
- "node_modules/moment": {
- "version": "2.30.1",
- "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
- "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
- "license": "MIT",
- "engines": {
- "node": "*"
- }
- },
- "node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "license": "MIT"
- },
- "node_modules/nan": {
- "version": "2.22.0",
- "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.0.tgz",
- "integrity": "sha512-nbajikzWTMwsW+eSsNm3QwlOs7het9gGJU5dDZzRTQGk03vyBOauxgI4VakDzE0PtsGTmXPsXTbbjVhRwR5mpw==",
- "license": "MIT",
- "optional": true
- },
- "node_modules/napi-build-utils": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz",
- "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==",
- "license": "MIT"
- },
- "node_modules/natural-compare": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
- "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/negotiator": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
- "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/netmask": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz",
- "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4.0"
- }
- },
- "node_modules/node-abi": {
- "version": "3.74.0",
- "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.74.0.tgz",
- "integrity": "sha512-c5XK0MjkGBrQPGYG24GBADZud0NCbznxNx0ZkS+ebUTrmV1qTDxPxSL8zEAPURXSbLRWVexxmP4986BziahL5w==",
- "license": "MIT",
- "dependencies": {
- "semver": "^7.3.5"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/node-addon-api": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz",
- "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==",
- "license": "MIT"
- },
- "node_modules/node-fetch": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
- "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
- "license": "MIT",
- "dependencies": {
- "whatwg-url": "^5.0.0"
- },
- "engines": {
- "node": "4.x || >=6.0.0"
- },
- "peerDependencies": {
- "encoding": "^0.1.0"
- },
- "peerDependenciesMeta": {
- "encoding": {
- "optional": true
- }
- }
- },
- "node_modules/node-gyp": {
- "version": "8.4.1",
- "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz",
- "integrity": "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==",
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "env-paths": "^2.2.0",
- "glob": "^7.1.4",
- "graceful-fs": "^4.2.6",
- "make-fetch-happen": "^9.1.0",
- "nopt": "^5.0.0",
- "npmlog": "^6.0.0",
- "rimraf": "^3.0.2",
- "semver": "^7.3.5",
- "tar": "^6.1.2",
- "which": "^2.0.2"
- },
- "bin": {
- "node-gyp": "bin/node-gyp.js"
- },
- "engines": {
- "node": ">= 10.12.0"
- }
- },
- "node_modules/node-gyp/node_modules/are-we-there-yet": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz",
- "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==",
- "deprecated": "This package is no longer supported.",
- "license": "ISC",
- "optional": true,
- "dependencies": {
- "delegates": "^1.0.0",
- "readable-stream": "^3.6.0"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
- }
- },
- "node_modules/node-gyp/node_modules/gauge": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz",
- "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==",
- "deprecated": "This package is no longer supported.",
- "license": "ISC",
- "optional": true,
- "dependencies": {
- "aproba": "^1.0.3 || ^2.0.0",
- "color-support": "^1.1.3",
- "console-control-strings": "^1.1.0",
- "has-unicode": "^2.0.1",
- "signal-exit": "^3.0.7",
- "string-width": "^4.2.3",
- "strip-ansi": "^6.0.1",
- "wide-align": "^1.1.5"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
- }
- },
- "node_modules/node-gyp/node_modules/npmlog": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz",
- "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==",
- "deprecated": "This package is no longer supported.",
- "license": "ISC",
- "optional": true,
- "dependencies": {
- "are-we-there-yet": "^3.0.0",
- "console-control-strings": "^1.1.0",
- "gauge": "^4.0.3",
- "set-blocking": "^2.0.0"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
- }
- },
- "node_modules/node-int64": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
- "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/node-releases": {
- "version": "2.0.19",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
- "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/nodemailer": {
- "version": "6.10.0",
- "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.10.0.tgz",
- "integrity": "sha512-SQ3wZCExjeSatLE/HBaXS5vqUOQk6GtBdIIKxiFdmm01mOQZX/POJkO3SUX1wDiYcwUOJwT23scFSC9fY2H8IA==",
- "license": "MIT-0",
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/nodemon": {
- "version": "3.1.9",
- "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.9.tgz",
- "integrity": "sha512-hdr1oIb2p6ZSxu3PB2JWWYS7ZQ0qvaZsc3hK8DR8f02kRzc8rjYmxAIvdz+aYC+8F2IjNaB7HMcSDg8nQpJxyg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "chokidar": "^3.5.2",
- "debug": "^4",
- "ignore-by-default": "^1.0.1",
- "minimatch": "^3.1.2",
- "pstree.remy": "^1.1.8",
- "semver": "^7.5.3",
- "simple-update-notifier": "^2.0.0",
- "supports-color": "^5.5.0",
- "touch": "^3.1.0",
- "undefsafe": "^2.0.5"
- },
- "bin": {
- "nodemon": "bin/nodemon.js"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/nodemon"
- }
- },
- "node_modules/nodemon/node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/nodemon/node_modules/chokidar": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
- "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "anymatch": "~3.1.2",
- "braces": "~3.0.2",
- "glob-parent": "~5.1.2",
- "is-binary-path": "~2.1.0",
- "is-glob": "~4.0.1",
- "normalize-path": "~3.0.0",
- "readdirp": "~3.6.0"
- },
- "engines": {
- "node": ">= 8.10.0"
- },
- "funding": {
- "url": "https://paulmillr.com/funding/"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.2"
- }
- },
- "node_modules/nodemon/node_modules/glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "is-glob": "^4.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/nodemon/node_modules/has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/nodemon/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/nodemon/node_modules/picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/nodemon/node_modules/readdirp": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
- "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "picomatch": "^2.2.1"
- },
- "engines": {
- "node": ">=8.10.0"
- }
- },
- "node_modules/nodemon/node_modules/supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "has-flag": "^3.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/nopt": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
- "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
- "license": "ISC",
- "dependencies": {
- "abbrev": "1"
- },
- "bin": {
- "nopt": "bin/nopt.js"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/normalize-package-data": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
- "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "hosted-git-info": "^2.1.4",
- "resolve": "^1.10.0",
- "semver": "2 || 3 || 4 || 5",
- "validate-npm-package-license": "^3.0.1"
- }
- },
- "node_modules/normalize-package-data/node_modules/semver": {
- "version": "5.7.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
- "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
- "dev": true,
- "license": "ISC",
- "bin": {
- "semver": "bin/semver"
- }
- },
- "node_modules/normalize-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
- "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/npm": {
- "version": "11.1.0",
- "resolved": "https://registry.npmjs.org/npm/-/npm-11.1.0.tgz",
- "integrity": "sha512-rPMBrZud26lI/LcjQeLw/K5Hf1apXMKgkpNNEzp0YQYmM877+T1ZNKPcB2hnTi7e6fBNz8xLtMMn/w46fVUqGw==",
- "bundleDependencies": [
- "@isaacs/string-locale-compare",
- "@npmcli/arborist",
- "@npmcli/config",
- "@npmcli/fs",
- "@npmcli/map-workspaces",
- "@npmcli/package-json",
- "@npmcli/promise-spawn",
- "@npmcli/redact",
- "@npmcli/run-script",
- "@sigstore/tuf",
- "abbrev",
- "archy",
- "cacache",
- "chalk",
- "ci-info",
- "cli-columns",
- "fastest-levenshtein",
- "fs-minipass",
- "glob",
- "graceful-fs",
- "hosted-git-info",
- "ini",
- "init-package-json",
- "is-cidr",
- "json-parse-even-better-errors",
- "libnpmaccess",
- "libnpmdiff",
- "libnpmexec",
- "libnpmfund",
- "libnpmorg",
- "libnpmpack",
- "libnpmpublish",
- "libnpmsearch",
- "libnpmteam",
- "libnpmversion",
- "make-fetch-happen",
- "minimatch",
- "minipass",
- "minipass-pipeline",
- "ms",
- "node-gyp",
- "nopt",
- "normalize-package-data",
- "npm-audit-report",
- "npm-install-checks",
- "npm-package-arg",
- "npm-pick-manifest",
- "npm-profile",
- "npm-registry-fetch",
- "npm-user-validate",
- "p-map",
- "pacote",
- "parse-conflict-json",
- "proc-log",
- "qrcode-terminal",
- "read",
- "semver",
- "spdx-expression-parse",
- "ssri",
- "supports-color",
- "tar",
- "text-table",
- "tiny-relative-date",
- "treeverse",
- "validate-npm-package-name",
- "which"
- ],
- "license": "Artistic-2.0",
- "workspaces": [
- "docs",
- "smoke-tests",
- "mock-globals",
- "mock-registry",
- "workspaces/*"
- ],
- "dependencies": {
- "@isaacs/string-locale-compare": "^1.1.0",
- "@npmcli/arborist": "^9.0.0",
- "@npmcli/config": "^10.0.1",
- "@npmcli/fs": "^4.0.0",
- "@npmcli/map-workspaces": "^4.0.2",
- "@npmcli/package-json": "^6.1.1",
- "@npmcli/promise-spawn": "^8.0.2",
- "@npmcli/redact": "^3.0.0",
- "@npmcli/run-script": "^9.0.1",
- "@sigstore/tuf": "^3.0.0",
- "abbrev": "^3.0.0",
- "archy": "~1.0.0",
- "cacache": "^19.0.1",
- "chalk": "^5.4.1",
- "ci-info": "^4.1.0",
- "cli-columns": "^4.0.0",
- "fastest-levenshtein": "^1.0.16",
- "fs-minipass": "^3.0.3",
- "glob": "^10.4.5",
- "graceful-fs": "^4.2.11",
- "hosted-git-info": "^8.0.2",
- "ini": "^5.0.0",
- "init-package-json": "^8.0.0",
- "is-cidr": "^5.1.0",
- "json-parse-even-better-errors": "^4.0.0",
- "libnpmaccess": "^10.0.0",
- "libnpmdiff": "^8.0.0",
- "libnpmexec": "^10.0.0",
- "libnpmfund": "^7.0.0",
- "libnpmorg": "^8.0.0",
- "libnpmpack": "^9.0.0",
- "libnpmpublish": "^11.0.0",
- "libnpmsearch": "^9.0.0",
- "libnpmteam": "^8.0.0",
- "libnpmversion": "^8.0.0",
- "make-fetch-happen": "^14.0.3",
- "minimatch": "^9.0.5",
- "minipass": "^7.1.1",
- "minipass-pipeline": "^1.2.4",
- "ms": "^2.1.2",
- "node-gyp": "^11.0.0",
- "nopt": "^8.0.0",
- "normalize-package-data": "^7.0.0",
- "npm-audit-report": "^6.0.0",
- "npm-install-checks": "^7.1.1",
- "npm-package-arg": "^12.0.1",
- "npm-pick-manifest": "^10.0.0",
- "npm-profile": "^11.0.1",
- "npm-registry-fetch": "^18.0.2",
- "npm-user-validate": "^3.0.0",
- "p-map": "^7.0.3",
- "pacote": "^21.0.0",
- "parse-conflict-json": "^4.0.0",
- "proc-log": "^5.0.0",
- "qrcode-terminal": "^0.12.0",
- "read": "^4.0.0",
- "semver": "^7.6.3",
- "spdx-expression-parse": "^4.0.0",
- "ssri": "^12.0.0",
- "supports-color": "^9.4.0",
- "tar": "^6.2.1",
- "text-table": "~0.2.0",
- "tiny-relative-date": "^1.3.0",
- "treeverse": "^3.0.0",
- "validate-npm-package-name": "^6.0.0",
- "which": "^5.0.0"
- },
- "bin": {
- "npm": "bin/npm-cli.js",
- "npx": "bin/npx-cli.js"
- },
- "engines": {
- "node": "^20.17.0 || >=22.9.0"
- }
- },
- "node_modules/npm-normalize-package-bin": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz",
- "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/npm-run-path": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
- "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "path-key": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/npm/node_modules/@isaacs/cliui": {
- "version": "8.0.2",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "string-width": "^5.1.2",
- "string-width-cjs": "npm:string-width@^4.2.0",
- "strip-ansi": "^7.0.1",
- "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
- "wrap-ansi": "^8.1.0",
- "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/npm/node_modules/@isaacs/cliui/node_modules/ansi-regex": {
- "version": "6.1.0",
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-regex?sponsor=1"
- }
- },
- "node_modules/npm/node_modules/@isaacs/cliui/node_modules/emoji-regex": {
- "version": "9.2.2",
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/npm/node_modules/@isaacs/cliui/node_modules/string-width": {
- "version": "5.1.2",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "eastasianwidth": "^0.2.0",
- "emoji-regex": "^9.2.2",
- "strip-ansi": "^7.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/npm/node_modules/@isaacs/cliui/node_modules/strip-ansi": {
- "version": "7.1.0",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^6.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/strip-ansi?sponsor=1"
- }
- },
- "node_modules/npm/node_modules/@isaacs/fs-minipass": {
- "version": "4.0.1",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "minipass": "^7.0.4"
- },
- "engines": {
- "node": ">=18.0.0"
- }
- },
- "node_modules/npm/node_modules/@isaacs/string-locale-compare": {
- "version": "1.1.0",
- "inBundle": true,
- "license": "ISC"
- },
- "node_modules/npm/node_modules/@npmcli/agent": {
- "version": "3.0.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "agent-base": "^7.1.0",
- "http-proxy-agent": "^7.0.0",
- "https-proxy-agent": "^7.0.1",
- "lru-cache": "^10.0.1",
- "socks-proxy-agent": "^8.0.3"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/@npmcli/arborist": {
- "version": "9.0.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "@isaacs/string-locale-compare": "^1.1.0",
- "@npmcli/fs": "^4.0.0",
- "@npmcli/installed-package-contents": "^3.0.0",
- "@npmcli/map-workspaces": "^4.0.1",
- "@npmcli/metavuln-calculator": "^9.0.0",
- "@npmcli/name-from-folder": "^3.0.0",
- "@npmcli/node-gyp": "^4.0.0",
- "@npmcli/package-json": "^6.0.1",
- "@npmcli/query": "^4.0.0",
- "@npmcli/redact": "^3.0.0",
- "@npmcli/run-script": "^9.0.1",
- "bin-links": "^5.0.0",
- "cacache": "^19.0.1",
- "common-ancestor-path": "^1.0.1",
- "hosted-git-info": "^8.0.0",
- "json-stringify-nice": "^1.1.4",
- "lru-cache": "^10.2.2",
- "minimatch": "^9.0.4",
- "nopt": "^8.0.0",
- "npm-install-checks": "^7.1.0",
- "npm-package-arg": "^12.0.0",
- "npm-pick-manifest": "^10.0.0",
- "npm-registry-fetch": "^18.0.1",
- "pacote": "^21.0.0",
- "parse-conflict-json": "^4.0.0",
- "proc-log": "^5.0.0",
- "proggy": "^3.0.0",
- "promise-all-reject-late": "^1.0.0",
- "promise-call-limit": "^3.0.1",
- "read-package-json-fast": "^4.0.0",
- "semver": "^7.3.7",
- "ssri": "^12.0.0",
- "treeverse": "^3.0.0",
- "walk-up-path": "^4.0.0"
- },
- "bin": {
- "arborist": "bin/index.js"
- },
- "engines": {
- "node": "^20.17.0 || >=22.9.0"
- }
- },
- "node_modules/npm/node_modules/@npmcli/config": {
- "version": "10.0.1",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "@npmcli/map-workspaces": "^4.0.1",
- "@npmcli/package-json": "^6.0.1",
- "ci-info": "^4.0.0",
- "ini": "^5.0.0",
- "nopt": "^8.0.0",
- "proc-log": "^5.0.0",
- "semver": "^7.3.5",
- "walk-up-path": "^4.0.0"
- },
- "engines": {
- "node": "^20.17.0 || >=22.9.0"
- }
- },
- "node_modules/npm/node_modules/@npmcli/fs": {
- "version": "4.0.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "semver": "^7.3.5"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/@npmcli/git": {
- "version": "6.0.1",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "@npmcli/promise-spawn": "^8.0.0",
- "ini": "^5.0.0",
- "lru-cache": "^10.0.1",
- "npm-pick-manifest": "^10.0.0",
- "proc-log": "^5.0.0",
- "promise-inflight": "^1.0.1",
- "promise-retry": "^2.0.1",
- "semver": "^7.3.5",
- "which": "^5.0.0"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/@npmcli/installed-package-contents": {
- "version": "3.0.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "npm-bundled": "^4.0.0",
- "npm-normalize-package-bin": "^4.0.0"
- },
- "bin": {
- "installed-package-contents": "bin/index.js"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/@npmcli/map-workspaces": {
- "version": "4.0.2",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "@npmcli/name-from-folder": "^3.0.0",
- "@npmcli/package-json": "^6.0.0",
- "glob": "^10.2.2",
- "minimatch": "^9.0.0"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/@npmcli/metavuln-calculator": {
- "version": "9.0.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "cacache": "^19.0.0",
- "json-parse-even-better-errors": "^4.0.0",
- "pacote": "^21.0.0",
- "proc-log": "^5.0.0",
- "semver": "^7.3.5"
- },
- "engines": {
- "node": "^20.17.0 || >=22.9.0"
- }
- },
- "node_modules/npm/node_modules/@npmcli/name-from-folder": {
- "version": "3.0.0",
- "inBundle": true,
- "license": "ISC",
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/@npmcli/node-gyp": {
- "version": "4.0.0",
- "inBundle": true,
- "license": "ISC",
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/@npmcli/package-json": {
- "version": "6.1.1",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "@npmcli/git": "^6.0.0",
- "glob": "^10.2.2",
- "hosted-git-info": "^8.0.0",
- "json-parse-even-better-errors": "^4.0.0",
- "proc-log": "^5.0.0",
- "semver": "^7.5.3",
- "validate-npm-package-license": "^3.0.4"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/@npmcli/promise-spawn": {
- "version": "8.0.2",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "which": "^5.0.0"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/@npmcli/query": {
- "version": "4.0.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "postcss-selector-parser": "^6.1.2"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/@npmcli/redact": {
- "version": "3.0.0",
- "inBundle": true,
- "license": "ISC",
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/@npmcli/run-script": {
- "version": "9.0.2",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "@npmcli/node-gyp": "^4.0.0",
- "@npmcli/package-json": "^6.0.0",
- "@npmcli/promise-spawn": "^8.0.0",
- "node-gyp": "^11.0.0",
- "proc-log": "^5.0.0",
- "which": "^5.0.0"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/@pkgjs/parseargs": {
- "version": "0.11.0",
- "inBundle": true,
- "license": "MIT",
- "optional": true,
- "engines": {
- "node": ">=14"
- }
- },
- "node_modules/npm/node_modules/@sigstore/bundle": {
- "version": "3.0.0",
- "inBundle": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@sigstore/protobuf-specs": "^0.3.2"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/@sigstore/core": {
- "version": "2.0.0",
- "inBundle": true,
- "license": "Apache-2.0",
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/@sigstore/protobuf-specs": {
- "version": "0.3.3",
- "inBundle": true,
- "license": "Apache-2.0",
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/@sigstore/sign": {
- "version": "3.0.0",
- "inBundle": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@sigstore/bundle": "^3.0.0",
- "@sigstore/core": "^2.0.0",
- "@sigstore/protobuf-specs": "^0.3.2",
- "make-fetch-happen": "^14.0.1",
- "proc-log": "^5.0.0",
- "promise-retry": "^2.0.1"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/@sigstore/tuf": {
- "version": "3.0.0",
- "inBundle": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@sigstore/protobuf-specs": "^0.3.2",
- "tuf-js": "^3.0.1"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/@sigstore/verify": {
- "version": "2.0.0",
- "inBundle": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@sigstore/bundle": "^3.0.0",
- "@sigstore/core": "^2.0.0",
- "@sigstore/protobuf-specs": "^0.3.2"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/@tufjs/canonical-json": {
- "version": "2.0.0",
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": "^16.14.0 || >=18.0.0"
- }
- },
- "node_modules/npm/node_modules/@tufjs/models": {
- "version": "3.0.1",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "@tufjs/canonical-json": "2.0.0",
- "minimatch": "^9.0.5"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/abbrev": {
- "version": "3.0.0",
- "inBundle": true,
- "license": "ISC",
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/agent-base": {
- "version": "7.1.3",
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/npm/node_modules/ansi-regex": {
- "version": "5.0.1",
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/npm/node_modules/ansi-styles": {
- "version": "6.2.1",
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/npm/node_modules/aproba": {
- "version": "2.0.0",
- "inBundle": true,
- "license": "ISC"
- },
- "node_modules/npm/node_modules/archy": {
- "version": "1.0.0",
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/npm/node_modules/balanced-match": {
- "version": "1.0.2",
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/npm/node_modules/bin-links": {
- "version": "5.0.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "cmd-shim": "^7.0.0",
- "npm-normalize-package-bin": "^4.0.0",
- "proc-log": "^5.0.0",
- "read-cmd-shim": "^5.0.0",
- "write-file-atomic": "^6.0.0"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/binary-extensions": {
- "version": "3.0.0",
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=18.20"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/npm/node_modules/brace-expansion": {
- "version": "2.0.1",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0"
- }
- },
- "node_modules/npm/node_modules/cacache": {
- "version": "19.0.1",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "@npmcli/fs": "^4.0.0",
- "fs-minipass": "^3.0.0",
- "glob": "^10.2.2",
- "lru-cache": "^10.0.1",
- "minipass": "^7.0.3",
- "minipass-collect": "^2.0.1",
- "minipass-flush": "^1.0.5",
- "minipass-pipeline": "^1.2.4",
- "p-map": "^7.0.2",
- "ssri": "^12.0.0",
- "tar": "^7.4.3",
- "unique-filename": "^4.0.0"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/cacache/node_modules/chownr": {
- "version": "3.0.0",
- "inBundle": true,
- "license": "BlueOak-1.0.0",
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/npm/node_modules/cacache/node_modules/minizlib": {
- "version": "3.0.1",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "minipass": "^7.0.4",
- "rimraf": "^5.0.5"
- },
- "engines": {
- "node": ">= 18"
- }
- },
- "node_modules/npm/node_modules/cacache/node_modules/mkdirp": {
- "version": "3.0.1",
- "inBundle": true,
- "license": "MIT",
- "bin": {
- "mkdirp": "dist/cjs/src/bin.js"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/npm/node_modules/cacache/node_modules/tar": {
- "version": "7.4.3",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "@isaacs/fs-minipass": "^4.0.0",
- "chownr": "^3.0.0",
- "minipass": "^7.1.2",
- "minizlib": "^3.0.1",
- "mkdirp": "^3.0.1",
- "yallist": "^5.0.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/npm/node_modules/cacache/node_modules/yallist": {
- "version": "5.0.0",
- "inBundle": true,
- "license": "BlueOak-1.0.0",
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/npm/node_modules/chalk": {
- "version": "5.4.1",
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": "^12.17.0 || ^14.13 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/npm/node_modules/chownr": {
- "version": "2.0.0",
- "inBundle": true,
- "license": "ISC",
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/npm/node_modules/ci-info": {
- "version": "4.1.0",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/sibiraj-s"
- }
- ],
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/npm/node_modules/cidr-regex": {
- "version": "4.1.1",
- "inBundle": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "ip-regex": "^5.0.0"
- },
- "engines": {
- "node": ">=14"
- }
- },
- "node_modules/npm/node_modules/cli-columns": {
- "version": "4.0.0",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "string-width": "^4.2.3",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/npm/node_modules/cmd-shim": {
- "version": "7.0.0",
- "inBundle": true,
- "license": "ISC",
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/color-convert": {
- "version": "2.0.1",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/npm/node_modules/color-name": {
- "version": "1.1.4",
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/npm/node_modules/common-ancestor-path": {
- "version": "1.0.1",
- "inBundle": true,
- "license": "ISC"
- },
- "node_modules/npm/node_modules/cross-spawn": {
- "version": "7.0.6",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "path-key": "^3.1.0",
- "shebang-command": "^2.0.0",
- "which": "^2.0.1"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/npm/node_modules/cross-spawn/node_modules/which": {
- "version": "2.0.2",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "isexe": "^2.0.0"
- },
- "bin": {
- "node-which": "bin/node-which"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/npm/node_modules/cssesc": {
- "version": "3.0.0",
- "inBundle": true,
- "license": "MIT",
- "bin": {
- "cssesc": "bin/cssesc"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/npm/node_modules/debug": {
- "version": "4.4.0",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/npm/node_modules/diff": {
- "version": "7.0.0",
- "inBundle": true,
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.3.1"
- }
- },
- "node_modules/npm/node_modules/eastasianwidth": {
- "version": "0.2.0",
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/npm/node_modules/emoji-regex": {
- "version": "8.0.0",
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/npm/node_modules/encoding": {
- "version": "0.1.13",
- "inBundle": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "iconv-lite": "^0.6.2"
- }
- },
- "node_modules/npm/node_modules/env-paths": {
- "version": "2.2.1",
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/npm/node_modules/err-code": {
- "version": "2.0.3",
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/npm/node_modules/exponential-backoff": {
- "version": "3.1.1",
- "inBundle": true,
- "license": "Apache-2.0"
- },
- "node_modules/npm/node_modules/fastest-levenshtein": {
- "version": "1.0.16",
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">= 4.9.1"
- }
- },
- "node_modules/npm/node_modules/foreground-child": {
- "version": "3.3.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "cross-spawn": "^7.0.0",
- "signal-exit": "^4.0.1"
- },
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/npm/node_modules/fs-minipass": {
- "version": "3.0.3",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "minipass": "^7.0.3"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/npm/node_modules/glob": {
- "version": "10.4.5",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "foreground-child": "^3.1.0",
- "jackspeak": "^3.1.2",
- "minimatch": "^9.0.4",
- "minipass": "^7.1.2",
- "package-json-from-dist": "^1.0.0",
- "path-scurry": "^1.11.1"
- },
- "bin": {
- "glob": "dist/esm/bin.mjs"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/npm/node_modules/graceful-fs": {
- "version": "4.2.11",
- "inBundle": true,
- "license": "ISC"
- },
- "node_modules/npm/node_modules/hosted-git-info": {
- "version": "8.0.2",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "lru-cache": "^10.0.1"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/http-cache-semantics": {
- "version": "4.1.1",
- "inBundle": true,
- "license": "BSD-2-Clause"
- },
- "node_modules/npm/node_modules/http-proxy-agent": {
- "version": "7.0.2",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "agent-base": "^7.1.0",
- "debug": "^4.3.4"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/npm/node_modules/https-proxy-agent": {
- "version": "7.0.6",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "agent-base": "^7.1.2",
- "debug": "4"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/npm/node_modules/iconv-lite": {
- "version": "0.6.3",
- "inBundle": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "safer-buffer": ">= 2.1.2 < 3.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/npm/node_modules/ignore-walk": {
- "version": "7.0.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "minimatch": "^9.0.0"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/imurmurhash": {
- "version": "0.1.4",
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.8.19"
- }
- },
- "node_modules/npm/node_modules/ini": {
- "version": "5.0.0",
- "inBundle": true,
- "license": "ISC",
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/init-package-json": {
- "version": "8.0.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "@npmcli/package-json": "^6.1.0",
- "npm-package-arg": "^12.0.0",
- "promzard": "^2.0.0",
- "read": "^4.0.0",
- "semver": "^7.3.5",
- "validate-npm-package-license": "^3.0.4",
- "validate-npm-package-name": "^6.0.0"
- },
- "engines": {
- "node": "^20.17.0 || >=22.9.0"
- }
- },
- "node_modules/npm/node_modules/ip-address": {
- "version": "9.0.5",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "jsbn": "1.1.0",
- "sprintf-js": "^1.1.3"
- },
- "engines": {
- "node": ">= 12"
- }
- },
- "node_modules/npm/node_modules/ip-regex": {
- "version": "5.0.0",
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/npm/node_modules/is-cidr": {
- "version": "5.1.0",
- "inBundle": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "cidr-regex": "^4.1.1"
- },
- "engines": {
- "node": ">=14"
- }
- },
- "node_modules/npm/node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/npm/node_modules/isexe": {
- "version": "2.0.0",
- "inBundle": true,
- "license": "ISC"
- },
- "node_modules/npm/node_modules/jackspeak": {
- "version": "3.4.3",
- "inBundle": true,
- "license": "BlueOak-1.0.0",
- "dependencies": {
- "@isaacs/cliui": "^8.0.2"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- },
- "optionalDependencies": {
- "@pkgjs/parseargs": "^0.11.0"
- }
- },
- "node_modules/npm/node_modules/jsbn": {
- "version": "1.1.0",
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/npm/node_modules/json-parse-even-better-errors": {
- "version": "4.0.0",
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/json-stringify-nice": {
- "version": "1.1.4",
- "inBundle": true,
- "license": "ISC",
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/npm/node_modules/jsonparse": {
- "version": "1.3.1",
- "engines": [
- "node >= 0.2.0"
- ],
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/npm/node_modules/just-diff": {
- "version": "6.0.2",
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/npm/node_modules/just-diff-apply": {
- "version": "5.5.0",
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/npm/node_modules/libnpmaccess": {
- "version": "10.0.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "npm-package-arg": "^12.0.0",
- "npm-registry-fetch": "^18.0.1"
- },
- "engines": {
- "node": "^20.17.0 || >=22.9.0"
- }
- },
- "node_modules/npm/node_modules/libnpmdiff": {
- "version": "8.0.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "@npmcli/arborist": "^9.0.0",
- "@npmcli/installed-package-contents": "^3.0.0",
- "binary-extensions": "^3.0.0",
- "diff": "^7.0.0",
- "minimatch": "^9.0.4",
- "npm-package-arg": "^12.0.0",
- "pacote": "^21.0.0",
- "tar": "^6.2.1"
- },
- "engines": {
- "node": "^20.17.0 || >=22.9.0"
- }
- },
- "node_modules/npm/node_modules/libnpmexec": {
- "version": "10.0.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "@npmcli/arborist": "^9.0.0",
- "@npmcli/run-script": "^9.0.1",
- "ci-info": "^4.0.0",
- "npm-package-arg": "^12.0.0",
- "pacote": "^21.0.0",
- "proc-log": "^5.0.0",
- "read": "^4.0.0",
- "read-package-json-fast": "^4.0.0",
- "semver": "^7.3.7",
- "walk-up-path": "^4.0.0"
- },
- "engines": {
- "node": "^20.17.0 || >=22.9.0"
- }
- },
- "node_modules/npm/node_modules/libnpmfund": {
- "version": "7.0.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "@npmcli/arborist": "^9.0.0"
- },
- "engines": {
- "node": "^20.17.0 || >=22.9.0"
- }
- },
- "node_modules/npm/node_modules/libnpmorg": {
- "version": "8.0.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "aproba": "^2.0.0",
- "npm-registry-fetch": "^18.0.1"
- },
- "engines": {
- "node": "^20.17.0 || >=22.9.0"
- }
- },
- "node_modules/npm/node_modules/libnpmpack": {
- "version": "9.0.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "@npmcli/arborist": "^9.0.0",
- "@npmcli/run-script": "^9.0.1",
- "npm-package-arg": "^12.0.0",
- "pacote": "^21.0.0"
- },
- "engines": {
- "node": "^20.17.0 || >=22.9.0"
- }
- },
- "node_modules/npm/node_modules/libnpmpublish": {
- "version": "11.0.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "ci-info": "^4.0.0",
- "normalize-package-data": "^7.0.0",
- "npm-package-arg": "^12.0.0",
- "npm-registry-fetch": "^18.0.1",
- "proc-log": "^5.0.0",
- "semver": "^7.3.7",
- "sigstore": "^3.0.0",
- "ssri": "^12.0.0"
- },
- "engines": {
- "node": "^20.17.0 || >=22.9.0"
- }
- },
- "node_modules/npm/node_modules/libnpmsearch": {
- "version": "9.0.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "npm-registry-fetch": "^18.0.1"
- },
- "engines": {
- "node": "^20.17.0 || >=22.9.0"
- }
- },
- "node_modules/npm/node_modules/libnpmteam": {
- "version": "8.0.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "aproba": "^2.0.0",
- "npm-registry-fetch": "^18.0.1"
- },
- "engines": {
- "node": "^20.17.0 || >=22.9.0"
- }
- },
- "node_modules/npm/node_modules/libnpmversion": {
- "version": "8.0.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "@npmcli/git": "^6.0.1",
- "@npmcli/run-script": "^9.0.1",
- "json-parse-even-better-errors": "^4.0.0",
- "proc-log": "^5.0.0",
- "semver": "^7.3.7"
- },
- "engines": {
- "node": "^20.17.0 || >=22.9.0"
- }
- },
- "node_modules/npm/node_modules/lru-cache": {
- "version": "10.4.3",
- "inBundle": true,
- "license": "ISC"
- },
- "node_modules/npm/node_modules/make-fetch-happen": {
- "version": "14.0.3",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "@npmcli/agent": "^3.0.0",
- "cacache": "^19.0.1",
- "http-cache-semantics": "^4.1.1",
- "minipass": "^7.0.2",
- "minipass-fetch": "^4.0.0",
- "minipass-flush": "^1.0.5",
- "minipass-pipeline": "^1.2.4",
- "negotiator": "^1.0.0",
- "proc-log": "^5.0.0",
- "promise-retry": "^2.0.1",
- "ssri": "^12.0.0"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/make-fetch-happen/node_modules/negotiator": {
- "version": "1.0.0",
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/npm/node_modules/minimatch": {
- "version": "9.0.5",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^2.0.1"
- },
- "engines": {
- "node": ">=16 || 14 >=14.17"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/npm/node_modules/minipass": {
- "version": "7.1.2",
- "inBundle": true,
- "license": "ISC",
- "engines": {
- "node": ">=16 || 14 >=14.17"
- }
- },
- "node_modules/npm/node_modules/minipass-collect": {
- "version": "2.0.1",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "minipass": "^7.0.3"
- },
- "engines": {
- "node": ">=16 || 14 >=14.17"
- }
- },
- "node_modules/npm/node_modules/minipass-fetch": {
- "version": "4.0.0",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "minipass": "^7.0.3",
- "minipass-sized": "^1.0.3",
- "minizlib": "^3.0.1"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- },
- "optionalDependencies": {
- "encoding": "^0.1.13"
- }
- },
- "node_modules/npm/node_modules/minipass-fetch/node_modules/minizlib": {
- "version": "3.0.1",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "minipass": "^7.0.4",
- "rimraf": "^5.0.5"
- },
- "engines": {
- "node": ">= 18"
- }
- },
- "node_modules/npm/node_modules/minipass-flush": {
- "version": "1.0.5",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "minipass": "^3.0.0"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/npm/node_modules/minipass-flush/node_modules/minipass": {
- "version": "3.3.6",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/npm/node_modules/minipass-pipeline": {
- "version": "1.2.4",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "minipass": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/npm/node_modules/minipass-pipeline/node_modules/minipass": {
- "version": "3.3.6",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/npm/node_modules/minipass-sized": {
- "version": "1.0.3",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "minipass": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/npm/node_modules/minipass-sized/node_modules/minipass": {
- "version": "3.3.6",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/npm/node_modules/minizlib": {
- "version": "2.1.2",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "minipass": "^3.0.0",
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/npm/node_modules/minizlib/node_modules/minipass": {
- "version": "3.3.6",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/npm/node_modules/mkdirp": {
- "version": "1.0.4",
- "inBundle": true,
- "license": "MIT",
- "bin": {
- "mkdirp": "bin/cmd.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/npm/node_modules/ms": {
- "version": "2.1.3",
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/npm/node_modules/mute-stream": {
- "version": "2.0.0",
- "inBundle": true,
- "license": "ISC",
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/node-gyp": {
- "version": "11.0.0",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "env-paths": "^2.2.0",
- "exponential-backoff": "^3.1.1",
- "glob": "^10.3.10",
- "graceful-fs": "^4.2.6",
- "make-fetch-happen": "^14.0.3",
- "nopt": "^8.0.0",
- "proc-log": "^5.0.0",
- "semver": "^7.3.5",
- "tar": "^7.4.3",
- "which": "^5.0.0"
- },
- "bin": {
- "node-gyp": "bin/node-gyp.js"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/node-gyp/node_modules/chownr": {
- "version": "3.0.0",
- "inBundle": true,
- "license": "BlueOak-1.0.0",
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/npm/node_modules/node-gyp/node_modules/minizlib": {
- "version": "3.0.1",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "minipass": "^7.0.4",
- "rimraf": "^5.0.5"
- },
- "engines": {
- "node": ">= 18"
- }
- },
- "node_modules/npm/node_modules/node-gyp/node_modules/mkdirp": {
- "version": "3.0.1",
- "inBundle": true,
- "license": "MIT",
- "bin": {
- "mkdirp": "dist/cjs/src/bin.js"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/npm/node_modules/node-gyp/node_modules/tar": {
- "version": "7.4.3",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "@isaacs/fs-minipass": "^4.0.0",
- "chownr": "^3.0.0",
- "minipass": "^7.1.2",
- "minizlib": "^3.0.1",
- "mkdirp": "^3.0.1",
- "yallist": "^5.0.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/npm/node_modules/node-gyp/node_modules/yallist": {
- "version": "5.0.0",
- "inBundle": true,
- "license": "BlueOak-1.0.0",
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/npm/node_modules/nopt": {
- "version": "8.0.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "abbrev": "^2.0.0"
- },
- "bin": {
- "nopt": "bin/nopt.js"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/nopt/node_modules/abbrev": {
- "version": "2.0.0",
- "inBundle": true,
- "license": "ISC",
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/npm/node_modules/normalize-package-data": {
- "version": "7.0.0",
- "inBundle": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "hosted-git-info": "^8.0.0",
- "semver": "^7.3.5",
- "validate-npm-package-license": "^3.0.4"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/npm-audit-report": {
- "version": "6.0.0",
- "inBundle": true,
- "license": "ISC",
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/npm-bundled": {
- "version": "4.0.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "npm-normalize-package-bin": "^4.0.0"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/npm-install-checks": {
- "version": "7.1.1",
- "inBundle": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "semver": "^7.1.1"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/npm-normalize-package-bin": {
- "version": "4.0.0",
- "inBundle": true,
- "license": "ISC",
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/npm-package-arg": {
- "version": "12.0.1",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "hosted-git-info": "^8.0.0",
- "proc-log": "^5.0.0",
- "semver": "^7.3.5",
- "validate-npm-package-name": "^6.0.0"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/npm-packlist": {
- "version": "10.0.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "ignore-walk": "^7.0.0"
- },
- "engines": {
- "node": "^20.17.0 || >=22.9.0"
- }
- },
- "node_modules/npm/node_modules/npm-pick-manifest": {
- "version": "10.0.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "npm-install-checks": "^7.1.0",
- "npm-normalize-package-bin": "^4.0.0",
- "npm-package-arg": "^12.0.0",
- "semver": "^7.3.5"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/npm-profile": {
- "version": "11.0.1",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "npm-registry-fetch": "^18.0.0",
- "proc-log": "^5.0.0"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/npm-registry-fetch": {
- "version": "18.0.2",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "@npmcli/redact": "^3.0.0",
- "jsonparse": "^1.3.1",
- "make-fetch-happen": "^14.0.0",
- "minipass": "^7.0.2",
- "minipass-fetch": "^4.0.0",
- "minizlib": "^3.0.1",
- "npm-package-arg": "^12.0.0",
- "proc-log": "^5.0.0"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/npm-registry-fetch/node_modules/minizlib": {
- "version": "3.0.1",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "minipass": "^7.0.4",
- "rimraf": "^5.0.5"
- },
- "engines": {
- "node": ">= 18"
- }
- },
- "node_modules/npm/node_modules/npm-user-validate": {
- "version": "3.0.0",
- "inBundle": true,
- "license": "BSD-2-Clause",
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/p-map": {
- "version": "7.0.3",
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/npm/node_modules/package-json-from-dist": {
- "version": "1.0.1",
- "inBundle": true,
- "license": "BlueOak-1.0.0"
- },
- "node_modules/npm/node_modules/pacote": {
- "version": "21.0.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "@npmcli/git": "^6.0.0",
- "@npmcli/installed-package-contents": "^3.0.0",
- "@npmcli/package-json": "^6.0.0",
- "@npmcli/promise-spawn": "^8.0.0",
- "@npmcli/run-script": "^9.0.0",
- "cacache": "^19.0.0",
- "fs-minipass": "^3.0.0",
- "minipass": "^7.0.2",
- "npm-package-arg": "^12.0.0",
- "npm-packlist": "^10.0.0",
- "npm-pick-manifest": "^10.0.0",
- "npm-registry-fetch": "^18.0.0",
- "proc-log": "^5.0.0",
- "promise-retry": "^2.0.1",
- "sigstore": "^3.0.0",
- "ssri": "^12.0.0",
- "tar": "^6.1.11"
- },
- "bin": {
- "pacote": "bin/index.js"
- },
- "engines": {
- "node": "^20.17.0 || >=22.9.0"
- }
- },
- "node_modules/npm/node_modules/parse-conflict-json": {
- "version": "4.0.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "json-parse-even-better-errors": "^4.0.0",
- "just-diff": "^6.0.0",
- "just-diff-apply": "^5.2.0"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/path-key": {
- "version": "3.1.1",
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/npm/node_modules/path-scurry": {
- "version": "1.11.1",
- "inBundle": true,
- "license": "BlueOak-1.0.0",
- "dependencies": {
- "lru-cache": "^10.2.0",
- "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
- },
- "engines": {
- "node": ">=16 || 14 >=14.18"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/npm/node_modules/postcss-selector-parser": {
- "version": "6.1.2",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "cssesc": "^3.0.0",
- "util-deprecate": "^1.0.2"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/npm/node_modules/proc-log": {
- "version": "5.0.0",
- "inBundle": true,
- "license": "ISC",
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/proggy": {
- "version": "3.0.0",
- "inBundle": true,
- "license": "ISC",
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/promise-all-reject-late": {
- "version": "1.0.1",
- "inBundle": true,
- "license": "ISC",
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/npm/node_modules/promise-call-limit": {
- "version": "3.0.2",
- "inBundle": true,
- "license": "ISC",
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/npm/node_modules/promise-inflight": {
- "version": "1.0.1",
- "inBundle": true,
- "license": "ISC"
- },
- "node_modules/npm/node_modules/promise-retry": {
- "version": "2.0.1",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "err-code": "^2.0.2",
- "retry": "^0.12.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/npm/node_modules/promzard": {
- "version": "2.0.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "read": "^4.0.0"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/qrcode-terminal": {
- "version": "0.12.0",
- "inBundle": true,
- "bin": {
- "qrcode-terminal": "bin/qrcode-terminal.js"
- }
- },
- "node_modules/npm/node_modules/read": {
- "version": "4.0.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "mute-stream": "^2.0.0"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/read-cmd-shim": {
- "version": "5.0.0",
- "inBundle": true,
- "license": "ISC",
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/read-package-json-fast": {
- "version": "4.0.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "json-parse-even-better-errors": "^4.0.0",
- "npm-normalize-package-bin": "^4.0.0"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/retry": {
- "version": "0.12.0",
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">= 4"
- }
- },
- "node_modules/npm/node_modules/rimraf": {
- "version": "5.0.10",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "glob": "^10.3.7"
- },
- "bin": {
- "rimraf": "dist/esm/bin.mjs"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/npm/node_modules/safer-buffer": {
- "version": "2.1.2",
- "inBundle": true,
- "license": "MIT",
- "optional": true
- },
- "node_modules/npm/node_modules/semver": {
- "version": "7.6.3",
- "inBundle": true,
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/npm/node_modules/shebang-command": {
- "version": "2.0.0",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "shebang-regex": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/npm/node_modules/shebang-regex": {
- "version": "3.0.0",
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/npm/node_modules/signal-exit": {
- "version": "4.1.0",
- "inBundle": true,
- "license": "ISC",
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/npm/node_modules/sigstore": {
- "version": "3.0.0",
- "inBundle": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@sigstore/bundle": "^3.0.0",
- "@sigstore/core": "^2.0.0",
- "@sigstore/protobuf-specs": "^0.3.2",
- "@sigstore/sign": "^3.0.0",
- "@sigstore/tuf": "^3.0.0",
- "@sigstore/verify": "^2.0.0"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/smart-buffer": {
- "version": "4.2.0",
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">= 6.0.0",
- "npm": ">= 3.0.0"
- }
- },
- "node_modules/npm/node_modules/socks": {
- "version": "2.8.3",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "ip-address": "^9.0.5",
- "smart-buffer": "^4.2.0"
- },
- "engines": {
- "node": ">= 10.0.0",
- "npm": ">= 3.0.0"
- }
- },
- "node_modules/npm/node_modules/socks-proxy-agent": {
- "version": "8.0.5",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "agent-base": "^7.1.2",
- "debug": "^4.3.4",
- "socks": "^2.8.3"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/npm/node_modules/spdx-correct": {
- "version": "3.2.0",
- "inBundle": true,
- "license": "Apache-2.0",
- "dependencies": {
- "spdx-expression-parse": "^3.0.0",
- "spdx-license-ids": "^3.0.0"
- }
- },
- "node_modules/npm/node_modules/spdx-correct/node_modules/spdx-expression-parse": {
- "version": "3.0.1",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "spdx-exceptions": "^2.1.0",
- "spdx-license-ids": "^3.0.0"
- }
- },
- "node_modules/npm/node_modules/spdx-exceptions": {
- "version": "2.5.0",
- "inBundle": true,
- "license": "CC-BY-3.0"
- },
- "node_modules/npm/node_modules/spdx-expression-parse": {
- "version": "4.0.0",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "spdx-exceptions": "^2.1.0",
- "spdx-license-ids": "^3.0.0"
- }
- },
- "node_modules/npm/node_modules/spdx-license-ids": {
- "version": "3.0.21",
- "inBundle": true,
- "license": "CC0-1.0"
- },
- "node_modules/npm/node_modules/sprintf-js": {
- "version": "1.1.3",
- "inBundle": true,
- "license": "BSD-3-Clause"
- },
- "node_modules/npm/node_modules/ssri": {
- "version": "12.0.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "minipass": "^7.0.3"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/string-width": {
- "version": "4.2.3",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/npm/node_modules/string-width-cjs": {
- "name": "string-width",
- "version": "4.2.3",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/npm/node_modules/strip-ansi": {
- "version": "6.0.1",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/npm/node_modules/strip-ansi-cjs": {
- "name": "strip-ansi",
- "version": "6.0.1",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/npm/node_modules/supports-color": {
- "version": "9.4.0",
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/supports-color?sponsor=1"
- }
- },
- "node_modules/npm/node_modules/tar": {
- "version": "6.2.1",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "chownr": "^2.0.0",
- "fs-minipass": "^2.0.0",
- "minipass": "^5.0.0",
- "minizlib": "^2.1.1",
- "mkdirp": "^1.0.3",
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/npm/node_modules/tar/node_modules/fs-minipass": {
- "version": "2.1.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "minipass": "^3.0.0"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/npm/node_modules/tar/node_modules/fs-minipass/node_modules/minipass": {
- "version": "3.3.6",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/npm/node_modules/tar/node_modules/minipass": {
- "version": "5.0.0",
- "inBundle": true,
- "license": "ISC",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/npm/node_modules/text-table": {
- "version": "0.2.0",
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/npm/node_modules/tiny-relative-date": {
- "version": "1.3.0",
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/npm/node_modules/treeverse": {
- "version": "3.0.0",
- "inBundle": true,
- "license": "ISC",
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/npm/node_modules/tuf-js": {
- "version": "3.0.1",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "@tufjs/models": "3.0.1",
- "debug": "^4.3.6",
- "make-fetch-happen": "^14.0.1"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/unique-filename": {
- "version": "4.0.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "unique-slug": "^5.0.0"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/unique-slug": {
- "version": "5.0.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "imurmurhash": "^0.1.4"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/util-deprecate": {
- "version": "1.0.2",
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/npm/node_modules/validate-npm-package-license": {
- "version": "3.0.4",
- "inBundle": true,
- "license": "Apache-2.0",
- "dependencies": {
- "spdx-correct": "^3.0.0",
- "spdx-expression-parse": "^3.0.0"
- }
- },
- "node_modules/npm/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse": {
- "version": "3.0.1",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "spdx-exceptions": "^2.1.0",
- "spdx-license-ids": "^3.0.0"
- }
- },
- "node_modules/npm/node_modules/validate-npm-package-name": {
- "version": "6.0.0",
- "inBundle": true,
- "license": "ISC",
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/walk-up-path": {
- "version": "4.0.0",
- "inBundle": true,
- "license": "ISC",
- "engines": {
- "node": "20 || >=22"
- }
- },
- "node_modules/npm/node_modules/which": {
- "version": "5.0.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "isexe": "^3.1.1"
- },
- "bin": {
- "node-which": "bin/which.js"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/which/node_modules/isexe": {
- "version": "3.1.1",
- "inBundle": true,
- "license": "ISC",
- "engines": {
- "node": ">=16"
- }
- },
- "node_modules/npm/node_modules/wrap-ansi": {
- "version": "8.1.0",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^6.1.0",
- "string-width": "^5.0.1",
- "strip-ansi": "^7.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
- }
- },
- "node_modules/npm/node_modules/wrap-ansi-cjs": {
- "name": "wrap-ansi",
- "version": "7.0.0",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
- }
- },
- "node_modules/npm/node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
- "version": "4.3.0",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/npm/node_modules/wrap-ansi/node_modules/ansi-regex": {
- "version": "6.1.0",
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-regex?sponsor=1"
- }
- },
- "node_modules/npm/node_modules/wrap-ansi/node_modules/emoji-regex": {
- "version": "9.2.2",
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/npm/node_modules/wrap-ansi/node_modules/string-width": {
- "version": "5.1.2",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "eastasianwidth": "^0.2.0",
- "emoji-regex": "^9.2.2",
- "strip-ansi": "^7.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/npm/node_modules/wrap-ansi/node_modules/strip-ansi": {
- "version": "7.1.0",
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^6.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/strip-ansi?sponsor=1"
- }
- },
- "node_modules/npm/node_modules/write-file-atomic": {
- "version": "6.0.0",
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "imurmurhash": "^0.1.4",
- "signal-exit": "^4.0.1"
- },
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/npm/node_modules/yallist": {
- "version": "4.0.0",
- "inBundle": true,
- "license": "ISC"
- },
- "node_modules/npmlog": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz",
- "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==",
- "deprecated": "This package is no longer supported.",
- "license": "ISC",
- "dependencies": {
- "are-we-there-yet": "^2.0.0",
- "console-control-strings": "^1.1.0",
- "gauge": "^3.0.0",
- "set-blocking": "^2.0.0"
- }
- },
- "node_modules/object-assign": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/object-hash": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
- "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
- "license": "MIT",
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/object-inspect": {
- "version": "1.13.4",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
- "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/on-finished": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
- "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
- "license": "MIT",
- "dependencies": {
- "ee-first": "1.1.1"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
- "license": "ISC",
- "dependencies": {
- "wrappy": "1"
- }
- },
- "node_modules/one-time": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz",
- "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==",
- "license": "MIT",
- "dependencies": {
- "fn.name": "1.x.x"
- }
- },
- "node_modules/onetime": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
- "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "mimic-fn": "^2.1.0"
- },
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/optionator": {
- "version": "0.9.4",
- "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
- "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "deep-is": "^0.1.3",
- "fast-levenshtein": "^2.0.6",
- "levn": "^0.4.1",
- "prelude-ls": "^1.2.1",
- "type-check": "^0.4.0",
- "word-wrap": "^1.2.5"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/os-homedir": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
- "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/os-tmpdir": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
- "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/osenv": {
- "version": "0.1.5",
- "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
- "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
- "deprecated": "This package is no longer supported.",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "os-homedir": "^1.0.0",
- "os-tmpdir": "^1.0.0"
- }
- },
- "node_modules/p-limit": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
- "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "yocto-queue": "^0.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/p-locate": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
- "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "p-limit": "^3.0.2"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/p-map": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
- "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "aggregate-error": "^3.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/p-try": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
- "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/pac-proxy-agent": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.1.0.tgz",
- "integrity": "sha512-Z5FnLVVZSnX7WjBg0mhDtydeRZ1xMcATZThjySQUHqr+0ksP8kqaw23fNKkaaN/Z8gwLUs/W7xdl0I75eP2Xyw==",
- "license": "MIT",
- "dependencies": {
- "@tootallnate/quickjs-emscripten": "^0.23.0",
- "agent-base": "^7.1.2",
- "debug": "^4.3.4",
- "get-uri": "^6.0.1",
- "http-proxy-agent": "^7.0.0",
- "https-proxy-agent": "^7.0.6",
- "pac-resolver": "^7.0.1",
- "socks-proxy-agent": "^8.0.5"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/pac-proxy-agent/node_modules/agent-base": {
- "version": "7.1.3",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
- "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==",
- "license": "MIT",
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/pac-proxy-agent/node_modules/https-proxy-agent": {
- "version": "7.0.6",
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
- "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
- "license": "MIT",
- "dependencies": {
- "agent-base": "^7.1.2",
- "debug": "4"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/pac-resolver": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz",
- "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==",
- "license": "MIT",
- "dependencies": {
- "degenerator": "^5.0.0",
- "netmask": "^2.0.2"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/parent-module": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
- "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
- "license": "MIT",
- "dependencies": {
- "callsites": "^3.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/parse-json": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
- "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.0.0",
- "error-ex": "^1.3.1",
- "json-parse-even-better-errors": "^2.3.0",
- "lines-and-columns": "^1.1.6"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/parseurl": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
- "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/path-is-absolute": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/path-key": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
- "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/path-parse": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
- "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/path-to-regexp": {
- "version": "0.1.12",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
- "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
- "license": "MIT"
- },
- "node_modules/pend": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
- "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
- "license": "MIT"
- },
- "node_modules/picocolors": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
- "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
- "license": "ISC"
- },
- "node_modules/picomatch": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
- "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/pirates": {
- "version": "4.0.6",
- "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz",
- "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/pkg-dir": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
- "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "find-up": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/pkg-dir/node_modules/find-up": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
- "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "locate-path": "^5.0.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/pkg-dir/node_modules/locate-path": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
- "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "p-locate": "^4.1.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/pkg-dir/node_modules/p-limit": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
- "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "p-try": "^2.0.0"
- },
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/pkg-dir/node_modules/p-locate": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
- "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "p-limit": "^2.2.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/prebuild-install": {
- "version": "7.1.3",
- "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz",
- "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==",
- "license": "MIT",
- "dependencies": {
- "detect-libc": "^2.0.0",
- "expand-template": "^2.0.3",
- "github-from-package": "0.0.0",
- "minimist": "^1.2.3",
- "mkdirp-classic": "^0.5.3",
- "napi-build-utils": "^2.0.0",
- "node-abi": "^3.3.0",
- "pump": "^3.0.0",
- "rc": "^1.2.7",
- "simple-get": "^4.0.0",
- "tar-fs": "^2.0.0",
- "tunnel-agent": "^0.6.0"
- },
- "bin": {
- "prebuild-install": "bin.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/prelude-ls": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
- "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/prettier": {
- "version": "3.4.2",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz",
- "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "prettier": "bin/prettier.cjs"
- },
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/prettier/prettier?sponsor=1"
- }
- },
- "node_modules/pretty-format": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
- "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/schemas": "^29.6.3",
- "ansi-styles": "^5.0.0",
- "react-is": "^18.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/pretty-format/node_modules/ansi-styles": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/progress": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
- "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
- "license": "MIT",
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/promise-inflight": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
- "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==",
- "license": "ISC",
- "optional": true
- },
- "node_modules/promise-retry": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz",
- "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==",
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "err-code": "^2.0.2",
- "retry": "^0.12.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/prompts": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
- "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "kleur": "^3.0.3",
- "sisteransi": "^1.0.5"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/protobufjs": {
- "version": "7.4.0",
- "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz",
- "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==",
- "hasInstallScript": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "@protobufjs/aspromise": "^1.1.2",
- "@protobufjs/base64": "^1.1.2",
- "@protobufjs/codegen": "^2.0.4",
- "@protobufjs/eventemitter": "^1.1.0",
- "@protobufjs/fetch": "^1.1.0",
- "@protobufjs/float": "^1.0.2",
- "@protobufjs/inquire": "^1.1.0",
- "@protobufjs/path": "^1.1.2",
- "@protobufjs/pool": "^1.1.0",
- "@protobufjs/utf8": "^1.1.0",
- "@types/node": ">=13.7.0",
- "long": "^5.0.0"
- },
- "engines": {
- "node": ">=12.0.0"
- }
- },
- "node_modules/proxy-addr": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
- "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
- "license": "MIT",
- "dependencies": {
- "forwarded": "0.2.0",
- "ipaddr.js": "1.9.1"
- },
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/proxy-addr/node_modules/ipaddr.js": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
- "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/proxy-agent": {
- "version": "6.5.0",
- "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz",
- "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==",
- "license": "MIT",
- "dependencies": {
- "agent-base": "^7.1.2",
- "debug": "^4.3.4",
- "http-proxy-agent": "^7.0.1",
- "https-proxy-agent": "^7.0.6",
- "lru-cache": "^7.14.1",
- "pac-proxy-agent": "^7.1.0",
- "proxy-from-env": "^1.1.0",
- "socks-proxy-agent": "^8.0.5"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/proxy-agent/node_modules/agent-base": {
- "version": "7.1.3",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
- "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==",
- "license": "MIT",
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/proxy-agent/node_modules/https-proxy-agent": {
- "version": "7.0.6",
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
- "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
- "license": "MIT",
- "dependencies": {
- "agent-base": "^7.1.2",
- "debug": "4"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/proxy-agent/node_modules/lru-cache": {
- "version": "7.18.3",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
- "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
- "license": "ISC",
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/proxy-from-env": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
- "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
- "license": "MIT"
- },
- "node_modules/pstree.remy": {
- "version": "1.1.8",
- "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
- "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/pump": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz",
- "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==",
- "license": "MIT",
- "dependencies": {
- "end-of-stream": "^1.1.0",
- "once": "^1.3.1"
- }
- },
- "node_modules/punycode": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
- "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/puppeteer": {
- "version": "24.2.0",
- "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-24.2.0.tgz",
- "integrity": "sha512-z8vv7zPEgrilIbOo3WNvM+2mXMnyM9f4z6zdrB88Fzeuo43Oupmjrzk3EpuvuCtyK0A7Lsllfx7Z+4BvEEGJcQ==",
- "hasInstallScript": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@puppeteer/browsers": "2.7.1",
- "chromium-bidi": "1.2.0",
- "cosmiconfig": "^9.0.0",
- "devtools-protocol": "0.0.1402036",
- "puppeteer-core": "24.2.0",
- "typed-query-selector": "^2.12.0"
- },
- "bin": {
- "puppeteer": "lib/cjs/puppeteer/node/cli.js"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/puppeteer-core": {
- "version": "24.2.0",
- "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.2.0.tgz",
- "integrity": "sha512-e4A4/xqWdd4kcE6QVHYhJ+Qlx/+XpgjP4d8OwBx0DJoY/nkIRhSgYmKQnv7+XSs1ofBstalt+XPGrkaz4FoXOQ==",
- "license": "Apache-2.0",
- "dependencies": {
- "@puppeteer/browsers": "2.7.1",
- "chromium-bidi": "1.2.0",
- "debug": "^4.4.0",
- "devtools-protocol": "0.0.1402036",
- "typed-query-selector": "^2.12.0",
- "ws": "^8.18.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/pure-rand": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz",
- "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==",
- "dev": true,
- "funding": [
- {
- "type": "individual",
- "url": "https://github.com/sponsors/dubzzz"
- },
- {
- "type": "opencollective",
- "url": "https://opencollective.com/fast-check"
- }
- ],
- "license": "MIT"
- },
- "node_modules/qs": {
- "version": "6.13.0",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
- "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
- "license": "BSD-3-Clause",
- "dependencies": {
- "side-channel": "^1.0.6"
- },
- "engines": {
- "node": ">=0.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/queue-microtask": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
- "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT"
- },
- "node_modules/range-parser": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
- "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/raw-body": {
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
- "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
- "license": "MIT",
- "dependencies": {
- "bytes": "3.1.2",
- "http-errors": "2.0.0",
- "iconv-lite": "0.4.24",
- "unpipe": "1.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/rc": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
- "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
- "license": "(BSD-2-Clause OR MIT OR Apache-2.0)",
- "dependencies": {
- "deep-extend": "^0.6.0",
- "ini": "~1.3.0",
- "minimist": "^1.2.0",
- "strip-json-comments": "~2.0.1"
- },
- "bin": {
- "rc": "cli.js"
- }
- },
- "node_modules/rc/node_modules/ini": {
- "version": "1.3.8",
- "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
- "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
- "license": "ISC"
- },
- "node_modules/rc/node_modules/strip-json-comments": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
- "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/react-is": {
- "version": "18.3.1",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
- "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/read-installed": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/read-installed/-/read-installed-4.0.3.tgz",
- "integrity": "sha512-O03wg/IYuV/VtnK2h/KXEt9VIbMUFbk3ERG0Iu4FhLZw0EP0T9znqrYDGn6ncbEsXUFaUjiVAWXHzxwt3lhRPQ==",
- "deprecated": "This package is no longer supported.",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "debuglog": "^1.0.1",
- "read-package-json": "^2.0.0",
- "readdir-scoped-modules": "^1.0.0",
- "semver": "2 || 3 || 4 || 5",
- "slide": "~1.1.3",
- "util-extend": "^1.0.1"
- },
- "optionalDependencies": {
- "graceful-fs": "^4.1.2"
- }
- },
- "node_modules/read-installed/node_modules/semver": {
- "version": "5.7.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
- "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
- "dev": true,
- "license": "ISC",
- "bin": {
- "semver": "bin/semver"
- }
- },
- "node_modules/read-package-json": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-2.1.2.tgz",
- "integrity": "sha512-D1KmuLQr6ZSJS0tW8hf3WGpRlwszJOXZ3E8Yd/DNRaM5d+1wVRZdHlpGBLAuovjr28LbWvjpWkBHMxpRGGjzNA==",
- "deprecated": "This package is no longer supported. Please use @npmcli/package-json instead.",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "glob": "^7.1.1",
- "json-parse-even-better-errors": "^2.3.0",
- "normalize-package-data": "^2.0.0",
- "npm-normalize-package-bin": "^1.0.0"
- }
- },
- "node_modules/readable-stream": {
- "version": "3.6.2",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
- "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
- "license": "MIT",
- "dependencies": {
- "inherits": "^2.0.3",
- "string_decoder": "^1.1.1",
- "util-deprecate": "^1.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/readdir-scoped-modules": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz",
- "integrity": "sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw==",
- "deprecated": "This functionality has been moved to @npmcli/fs",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "debuglog": "^1.0.1",
- "dezalgo": "^1.0.0",
- "graceful-fs": "^4.1.2",
- "once": "^1.3.0"
- }
- },
- "node_modules/readdirp": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.1.tgz",
- "integrity": "sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==",
- "license": "MIT",
- "engines": {
- "node": ">= 14.18.0"
- },
- "funding": {
- "type": "individual",
- "url": "https://paulmillr.com/funding/"
- }
- },
- "node_modules/rechoir": {
- "version": "0.8.0",
- "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz",
- "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "resolve": "^1.20.0"
- },
- "engines": {
- "node": ">= 10.13.0"
- }
- },
- "node_modules/regexp-tree": {
- "version": "0.1.27",
- "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz",
- "integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "regexp-tree": "bin/regexp-tree"
- }
- },
- "node_modules/require-directory": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
- "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/require-from-string": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
- "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/resolve": {
- "version": "1.22.10",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
- "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-core-module": "^2.16.0",
- "path-parse": "^1.0.7",
- "supports-preserve-symlinks-flag": "^1.0.0"
- },
- "bin": {
- "resolve": "bin/resolve"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/resolve-cwd": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
- "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "resolve-from": "^5.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/resolve-cwd/node_modules/resolve-from": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
- "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/resolve-from": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
- "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/resolve-pkg-maps": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
- "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
- "dev": true,
- "license": "MIT",
- "funding": {
- "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
- }
- },
- "node_modules/resolve.exports": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz",
- "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/retry": {
- "version": "0.12.0",
- "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
- "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==",
- "license": "MIT",
- "optional": true,
- "engines": {
- "node": ">= 4"
- }
- },
- "node_modules/reusify": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
- "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "iojs": ">=1.0.0",
- "node": ">=0.10.0"
- }
- },
- "node_modules/rimraf": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "deprecated": "Rimraf versions prior to v4 are no longer supported",
- "license": "ISC",
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/run-parallel": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
- "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "queue-microtask": "^1.2.2"
- }
- },
- "node_modules/safe-buffer": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
- "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT"
- },
- "node_modules/safe-regex": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz",
- "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "regexp-tree": "~0.1.1"
- }
- },
- "node_modules/safe-stable-stringify": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz",
- "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==",
- "license": "MIT",
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/safer-buffer": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
- "license": "MIT"
- },
- "node_modules/semver": {
- "version": "7.7.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
- "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/send": {
- "version": "0.19.0",
- "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
- "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
- "license": "MIT",
- "dependencies": {
- "debug": "2.6.9",
- "depd": "2.0.0",
- "destroy": "1.2.0",
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "etag": "~1.8.1",
- "fresh": "0.5.2",
- "http-errors": "2.0.0",
- "mime": "1.6.0",
- "ms": "2.1.3",
- "on-finished": "2.4.1",
- "range-parser": "~1.2.1",
- "statuses": "2.0.1"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/send/node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "license": "MIT",
- "dependencies": {
- "ms": "2.0.0"
- }
- },
- "node_modules/send/node_modules/debug/node_modules/ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
- "license": "MIT"
- },
- "node_modules/send/node_modules/encodeurl": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
- "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/serve-static": {
- "version": "1.16.2",
- "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz",
- "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==",
- "license": "MIT",
- "dependencies": {
- "encodeurl": "~2.0.0",
- "escape-html": "~1.0.3",
- "parseurl": "~1.3.3",
- "send": "0.19.0"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/set-blocking": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
- "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
- "license": "ISC"
- },
- "node_modules/setprototypeof": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
- "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
- "license": "ISC"
- },
- "node_modules/shebang-command": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
- "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "shebang-regex": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/shebang-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
- "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/side-channel": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
- "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "object-inspect": "^1.13.3",
- "side-channel-list": "^1.0.0",
- "side-channel-map": "^1.0.1",
- "side-channel-weakmap": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/side-channel-list": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
- "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "object-inspect": "^1.13.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/side-channel-map": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
- "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.2",
- "es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.5",
- "object-inspect": "^1.13.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/side-channel-weakmap": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
- "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.2",
- "es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.5",
- "object-inspect": "^1.13.3",
- "side-channel-map": "^1.0.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/signal-exit": {
- "version": "3.0.7",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
- "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
- "license": "ISC"
- },
- "node_modules/simple-concat": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
- "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT"
- },
- "node_modules/simple-get": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
- "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "decompress-response": "^6.0.0",
- "once": "^1.3.1",
- "simple-concat": "^1.0.0"
- }
- },
- "node_modules/simple-swizzle": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
- "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
- "license": "MIT",
- "dependencies": {
- "is-arrayish": "^0.3.1"
- }
- },
- "node_modules/simple-swizzle/node_modules/is-arrayish": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
- "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==",
- "license": "MIT"
- },
- "node_modules/simple-update-notifier": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz",
- "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "semver": "^7.5.3"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/sisteransi": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
- "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/slash": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
- "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/slide": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz",
- "integrity": "sha512-NwrtjCg+lZoqhFU8fOwl4ay2ei8PaqCBOUV3/ektPY9trO1yQ1oXEfmHAhKArUVUr/hOHvy5f6AdP17dCM0zMw==",
- "dev": true,
- "license": "ISC",
- "engines": {
- "node": "*"
- }
- },
- "node_modules/smart-buffer": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
- "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
- "license": "MIT",
- "engines": {
- "node": ">= 6.0.0",
- "npm": ">= 3.0.0"
- }
- },
- "node_modules/socks": {
- "version": "2.8.3",
- "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz",
- "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==",
- "license": "MIT",
- "dependencies": {
- "ip-address": "^9.0.5",
- "smart-buffer": "^4.2.0"
- },
- "engines": {
- "node": ">= 10.0.0",
- "npm": ">= 3.0.0"
- }
- },
- "node_modules/socks-proxy-agent": {
- "version": "8.0.5",
- "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz",
- "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==",
- "license": "MIT",
- "dependencies": {
- "agent-base": "^7.1.2",
- "debug": "^4.3.4",
- "socks": "^2.8.3"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/socks-proxy-agent/node_modules/agent-base": {
- "version": "7.1.3",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
- "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==",
- "license": "MIT",
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "devOptional": true,
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/source-map-support": {
- "version": "0.5.13",
- "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz",
- "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "buffer-from": "^1.0.0",
- "source-map": "^0.6.0"
- }
- },
- "node_modules/spdx-compare": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/spdx-compare/-/spdx-compare-1.0.0.tgz",
- "integrity": "sha512-C1mDZOX0hnu0ep9dfmuoi03+eOdDoz2yvK79RxbcrVEG1NO1Ph35yW102DHWKN4pk80nwCgeMmSY5L25VE4D9A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "array-find-index": "^1.0.2",
- "spdx-expression-parse": "^3.0.0",
- "spdx-ranges": "^2.0.0"
- }
- },
- "node_modules/spdx-correct": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
- "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "spdx-expression-parse": "^3.0.0",
- "spdx-license-ids": "^3.0.0"
- }
- },
- "node_modules/spdx-exceptions": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz",
- "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==",
- "dev": true,
- "license": "CC-BY-3.0"
- },
- "node_modules/spdx-expression-parse": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
- "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "spdx-exceptions": "^2.1.0",
- "spdx-license-ids": "^3.0.0"
- }
- },
- "node_modules/spdx-license-ids": {
- "version": "3.0.21",
- "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz",
- "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==",
- "dev": true,
- "license": "CC0-1.0"
- },
- "node_modules/spdx-ranges": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/spdx-ranges/-/spdx-ranges-2.1.1.tgz",
- "integrity": "sha512-mcdpQFV7UDAgLpXEE/jOMqvK4LBoO0uTQg0uvXUewmEFhpiZx5yJSZITHB8w1ZahKdhfZqP5GPEOKLyEq5p8XA==",
- "dev": true,
- "license": "(MIT AND CC-BY-3.0)"
- },
- "node_modules/spdx-satisfies": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/spdx-satisfies/-/spdx-satisfies-4.0.1.tgz",
- "integrity": "sha512-WVzZ/cXAzoNmjCWiEluEA3BjHp5tiUmmhn9MK+X0tBbR9sOqtC6UQwmgCNrAIZvNlMuBUYAaHYfb2oqlF9SwKA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "spdx-compare": "^1.0.0",
- "spdx-expression-parse": "^3.0.0",
- "spdx-ranges": "^2.0.0"
- }
- },
- "node_modules/split-ca": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/split-ca/-/split-ca-1.0.1.tgz",
- "integrity": "sha512-Q5thBSxp5t8WPTTJQS59LrGqOZqOsrhDGDVm8azCqIBjSBd7nd9o2PM+mDulQQkh8h//4U6hFZnc/mul8t5pWQ==",
- "license": "ISC"
- },
- "node_modules/sprintf-js": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz",
- "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==",
- "license": "BSD-3-Clause"
- },
- "node_modules/sqlite3": {
- "version": "5.1.7",
- "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.7.tgz",
- "integrity": "sha512-GGIyOiFaG+TUra3JIfkI/zGP8yZYLPQ0pl1bH+ODjiX57sPhrLU5sQJn1y9bDKZUFYkX1crlrPfSYt0BKKdkog==",
- "hasInstallScript": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "bindings": "^1.5.0",
- "node-addon-api": "^7.0.0",
- "prebuild-install": "^7.1.1",
- "tar": "^6.1.11"
- },
- "optionalDependencies": {
- "node-gyp": "8.x"
- },
- "peerDependencies": {
- "node-gyp": "8.x"
- },
- "peerDependenciesMeta": {
- "node-gyp": {
- "optional": true
- }
- }
- },
- "node_modules/sqlite3/node_modules/node-addon-api": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
- "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
- "license": "MIT"
- },
- "node_modules/ssh2": {
- "version": "1.16.0",
- "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.16.0.tgz",
- "integrity": "sha512-r1X4KsBGedJqo7h8F5c4Ybpcr5RjyP+aWIG007uBPRjmdQWfEiVLzSK71Zji1B9sKxwaCvD8y8cwSkYrlLiRRg==",
- "hasInstallScript": true,
- "dependencies": {
- "asn1": "^0.2.6",
- "bcrypt-pbkdf": "^1.0.2"
- },
- "engines": {
- "node": ">=10.16.0"
- },
- "optionalDependencies": {
- "cpu-features": "~0.0.10",
- "nan": "^2.20.0"
- }
- },
- "node_modules/ssri": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
- "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==",
- "license": "ISC",
- "optional": true,
- "dependencies": {
- "minipass": "^3.1.1"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/stack-trace": {
- "version": "0.0.10",
- "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
- "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==",
- "license": "MIT",
- "engines": {
- "node": "*"
- }
- },
- "node_modules/stack-utils": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
- "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "escape-string-regexp": "^2.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/stack-utils/node_modules/escape-string-regexp": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
- "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/statuses": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
- "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/streamx": {
- "version": "2.22.0",
- "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.22.0.tgz",
- "integrity": "sha512-sLh1evHOzBy/iWRiR6d1zRcLao4gGZr3C1kzNz4fopCOKJb6xD9ub8Mpi9Mr1R6id5o43S+d93fI48UC5uM9aw==",
- "license": "MIT",
- "dependencies": {
- "fast-fifo": "^1.3.2",
- "text-decoder": "^1.1.0"
- },
- "optionalDependencies": {
- "bare-events": "^2.2.0"
- }
- },
- "node_modules/string_decoder": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
- "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
- "license": "MIT",
- "dependencies": {
- "safe-buffer": "~5.2.0"
- }
- },
- "node_modules/string-length": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
- "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "char-regex": "^1.0.2",
- "strip-ansi": "^6.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "license": "MIT",
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/strip-bom": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
- "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/strip-final-newline": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
- "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/strip-json-comments": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
- "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/superagent": {
- "version": "9.0.2",
- "resolved": "https://registry.npmjs.org/superagent/-/superagent-9.0.2.tgz",
- "integrity": "sha512-xuW7dzkUpcJq7QnhOsnNUgtYp3xRwpt2F7abdRYIpCsAt0hhUqia0EdxyXZQQpNmGtsCzYHryaKSV3q3GJnq7w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "component-emitter": "^1.3.0",
- "cookiejar": "^2.1.4",
- "debug": "^4.3.4",
- "fast-safe-stringify": "^2.1.1",
- "form-data": "^4.0.0",
- "formidable": "^3.5.1",
- "methods": "^1.1.2",
- "mime": "2.6.0",
- "qs": "^6.11.0"
- },
- "engines": {
- "node": ">=14.18.0"
- }
- },
- "node_modules/superagent/node_modules/mime": {
- "version": "2.6.0",
- "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
- "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "mime": "cli.js"
- },
- "engines": {
- "node": ">=4.0.0"
- }
- },
- "node_modules/supertest": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/supertest/-/supertest-7.0.0.tgz",
- "integrity": "sha512-qlsr7fIC0lSddmA3tzojvzubYxvlGtzumcdHgPwbFWMISQwL22MhM2Y3LNt+6w9Yyx7559VW5ab70dgphm8qQA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "methods": "^1.1.2",
- "superagent": "^9.0.1"
- },
- "engines": {
- "node": ">=14.18.0"
- }
- },
- "node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/supports-preserve-symlinks-flag": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
- "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/swagger-ui-dist": {
- "version": "5.18.3",
- "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.18.3.tgz",
- "integrity": "sha512-G33HFW0iFNStfY2x6QXO2JYVMrFruc8AZRX0U/L71aA7WeWfX2E5Nm8E/tsipSZJeIZZbSjUDeynLK/wcuNWIw==",
- "license": "Apache-2.0",
- "dependencies": {
- "@scarf/scarf": "=1.4.0"
- }
- },
- "node_modules/swagger-ui-express": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-5.0.1.tgz",
- "integrity": "sha512-SrNU3RiBGTLLmFU8GIJdOdanJTl4TOmT27tt3bWWHppqYmAZ6IDuEuBvMU6nZq0zLEe6b/1rACXCgLZqO6ZfrA==",
- "license": "MIT",
- "dependencies": {
- "swagger-ui-dist": ">=5.0.0"
- },
- "engines": {
- "node": ">= v0.10.32"
- },
- "peerDependencies": {
- "express": ">=4.0.0 || >=5.0.0-beta"
- }
- },
- "node_modules/tapable": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
- "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/tar": {
- "version": "6.2.1",
- "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
- "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
- "license": "ISC",
- "dependencies": {
- "chownr": "^2.0.0",
- "fs-minipass": "^2.0.0",
- "minipass": "^5.0.0",
- "minizlib": "^2.1.1",
- "mkdirp": "^1.0.3",
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/tar-fs": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.1.tgz",
- "integrity": "sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA==",
- "license": "MIT",
- "dependencies": {
- "chownr": "^1.1.1",
- "mkdirp-classic": "^0.5.2",
- "pump": "^3.0.0",
- "tar-stream": "^2.0.0"
- }
- },
- "node_modules/tar-fs/node_modules/chownr": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
- "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
- "license": "ISC"
- },
- "node_modules/tar-stream": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
- "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
- "license": "MIT",
- "dependencies": {
- "bl": "^4.0.3",
- "end-of-stream": "^1.4.1",
- "fs-constants": "^1.0.0",
- "inherits": "^2.0.3",
- "readable-stream": "^3.1.1"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/tar/node_modules/minipass": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
- "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
- "license": "ISC",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/tar/node_modules/mkdirp": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
- "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
- "license": "MIT",
- "bin": {
- "mkdirp": "bin/cmd.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/tar/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "license": "ISC"
- },
- "node_modules/teamcity-service-messages": {
- "version": "0.1.14",
- "resolved": "https://registry.npmjs.org/teamcity-service-messages/-/teamcity-service-messages-0.1.14.tgz",
- "integrity": "sha512-29aQwaHqm8RMX74u2o/h1KbMLP89FjNiMxD9wbF2BbWOnbM+q+d1sCEC+MqCc4QW3NJykn77OMpTFw/xTHIc0w==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/test-exclude": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
- "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "@istanbuljs/schema": "^0.1.2",
- "glob": "^7.1.4",
- "minimatch": "^3.0.4"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/test-exclude/node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/test-exclude/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/text-decoder": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz",
- "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==",
- "license": "Apache-2.0",
- "dependencies": {
- "b4a": "^1.6.4"
- }
- },
- "node_modules/text-hex": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
- "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==",
- "license": "MIT"
- },
- "node_modules/tmpl": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
- "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
- "dev": true,
- "license": "BSD-3-Clause"
- },
- "node_modules/to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-number": "^7.0.0"
- },
- "engines": {
- "node": ">=8.0"
- }
- },
- "node_modules/toidentifier": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
- "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
- "license": "MIT",
- "engines": {
- "node": ">=0.6"
- }
- },
- "node_modules/touch": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz",
- "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==",
- "dev": true,
- "license": "ISC",
- "bin": {
- "nodetouch": "bin/nodetouch.js"
- }
- },
- "node_modules/tr46": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
- "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
- "license": "MIT"
- },
- "node_modules/treeify": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz",
- "integrity": "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.6"
- }
- },
- "node_modules/triple-beam": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz",
- "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==",
- "license": "MIT",
- "engines": {
- "node": ">= 14.0.0"
- }
- },
- "node_modules/ts-api-utils": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.1.tgz",
- "integrity": "sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18.12"
- },
- "peerDependencies": {
- "typescript": ">=4.8.4"
- }
- },
- "node_modules/ts-jest": {
- "version": "29.2.5",
- "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.2.5.tgz",
- "integrity": "sha512-KD8zB2aAZrcKIdGk4OwpJggeLcH1FgrICqDSROWqlnJXGCXK4Mn6FcdK2B6670Xr73lHMG1kHw8R87A0ecZ+vA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "bs-logger": "^0.2.6",
- "ejs": "^3.1.10",
- "fast-json-stable-stringify": "^2.1.0",
- "jest-util": "^29.0.0",
- "json5": "^2.2.3",
- "lodash.memoize": "^4.1.2",
- "make-error": "^1.3.6",
- "semver": "^7.6.3",
- "yargs-parser": "^21.1.1"
- },
- "bin": {
- "ts-jest": "cli.js"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0"
- },
- "peerDependencies": {
- "@babel/core": ">=7.0.0-beta.0 <8",
- "@jest/transform": "^29.0.0",
- "@jest/types": "^29.0.0",
- "babel-jest": "^29.0.0",
- "jest": "^29.0.0",
- "typescript": ">=4.3 <6"
- },
- "peerDependenciesMeta": {
- "@babel/core": {
- "optional": true
- },
- "@jest/transform": {
- "optional": true
- },
- "@jest/types": {
- "optional": true
- },
- "babel-jest": {
- "optional": true
- },
- "esbuild": {
- "optional": true
- }
- }
- },
- "node_modules/ts-node": {
- "version": "10.9.2",
- "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
- "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@cspotcode/source-map-support": "^0.8.0",
- "@tsconfig/node10": "^1.0.7",
- "@tsconfig/node12": "^1.0.7",
- "@tsconfig/node14": "^1.0.0",
- "@tsconfig/node16": "^1.0.2",
- "acorn": "^8.4.1",
- "acorn-walk": "^8.1.1",
- "arg": "^4.1.0",
- "create-require": "^1.1.0",
- "diff": "^4.0.1",
- "make-error": "^1.1.1",
- "v8-compile-cache-lib": "^3.0.1",
- "yn": "3.1.1"
- },
- "bin": {
- "ts-node": "dist/bin.js",
- "ts-node-cwd": "dist/bin-cwd.js",
- "ts-node-esm": "dist/bin-esm.js",
- "ts-node-script": "dist/bin-script.js",
- "ts-node-transpile-only": "dist/bin-transpile.js",
- "ts-script": "dist/bin-script-deprecated.js"
- },
- "peerDependencies": {
- "@swc/core": ">=1.2.50",
- "@swc/wasm": ">=1.2.50",
- "@types/node": "*",
- "typescript": ">=2.7"
- },
- "peerDependenciesMeta": {
- "@swc/core": {
- "optional": true
- },
- "@swc/wasm": {
- "optional": true
- }
- }
- },
- "node_modules/tsconfig-paths": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz",
- "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "json5": "^2.2.2",
- "minimist": "^1.2.6",
- "strip-bom": "^3.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/tsconfig-paths-webpack-plugin": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.2.0.tgz",
- "integrity": "sha512-zbem3rfRS8BgeNK50Zz5SIQgXzLafiHjOwUAvk/38/o1jHn/V5QAgVUcz884or7WYcPaH3N2CIfUc2u0ul7UcA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "chalk": "^4.1.0",
- "enhanced-resolve": "^5.7.0",
- "tapable": "^2.2.1",
- "tsconfig-paths": "^4.1.2"
- },
- "engines": {
- "node": ">=10.13.0"
- }
- },
- "node_modules/tsconfig-paths/node_modules/strip-bom": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
- "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/tslib": {
- "version": "2.8.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
- "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
- "license": "0BSD"
- },
- "node_modules/tsx": {
- "version": "4.19.2",
- "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.2.tgz",
- "integrity": "sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "esbuild": "~0.23.0",
- "get-tsconfig": "^4.7.5"
- },
- "bin": {
- "tsx": "dist/cli.mjs"
- },
- "engines": {
- "node": ">=18.0.0"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.3"
- }
- },
- "node_modules/tunnel-agent": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
- "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
- "license": "Apache-2.0",
- "dependencies": {
- "safe-buffer": "^5.0.1"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/tweetnacl": {
- "version": "0.14.5",
- "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
- "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==",
- "license": "Unlicense"
- },
- "node_modules/type-check": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
- "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "prelude-ls": "^1.2.1"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/type-detect": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
- "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/type-fest": {
- "version": "0.21.3",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
- "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
- "dev": true,
- "license": "(MIT OR CC0-1.0)",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/type-is": {
- "version": "1.6.18",
- "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
- "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
- "license": "MIT",
- "dependencies": {
- "media-typer": "0.3.0",
- "mime-types": "~2.1.24"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/typed-query-selector": {
- "version": "2.12.0",
- "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.0.tgz",
- "integrity": "sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg==",
- "license": "MIT"
- },
- "node_modules/typescript": {
- "version": "5.7.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz",
- "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==",
- "devOptional": true,
- "license": "Apache-2.0",
- "peer": true,
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
- },
- "engines": {
- "node": ">=14.17"
- }
- },
- "node_modules/typescript-eslint": {
- "version": "8.23.0",
- "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.23.0.tgz",
- "integrity": "sha512-/LBRo3HrXr5LxmrdYSOCvoAMm7p2jNizNfbIpCgvG4HMsnoprRUOce/+8VJ9BDYWW68rqIENE/haVLWPeFZBVQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/eslint-plugin": "8.23.0",
- "@typescript-eslint/parser": "8.23.0",
- "@typescript-eslint/utils": "8.23.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^8.57.0 || ^9.0.0",
- "typescript": ">=4.8.4 <5.8.0"
- }
- },
- "node_modules/uglify-js": {
- "version": "3.19.3",
- "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz",
- "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==",
- "dev": true,
- "license": "BSD-2-Clause",
- "bin": {
- "uglifyjs": "bin/uglifyjs"
- },
- "engines": {
- "node": ">=0.8.0"
- }
- },
- "node_modules/undefsafe": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
- "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/undici-types": {
- "version": "6.20.0",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
- "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
- "license": "MIT"
- },
- "node_modules/unique-filename": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
- "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
- "license": "ISC",
- "optional": true,
- "dependencies": {
- "unique-slug": "^2.0.0"
- }
- },
- "node_modules/unique-slug": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz",
- "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==",
- "license": "ISC",
- "optional": true,
- "dependencies": {
- "imurmurhash": "^0.1.4"
- }
- },
- "node_modules/unpipe": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
- "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/update-browserslist-db": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz",
- "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/browserslist"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "escalade": "^3.2.0",
- "picocolors": "^1.1.1"
- },
- "bin": {
- "update-browserslist-db": "cli.js"
- },
- "peerDependencies": {
- "browserslist": ">= 4.21.0"
- }
- },
- "node_modules/uri-js": {
- "version": "4.4.1",
- "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
- "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "punycode": "^2.1.0"
- }
- },
- "node_modules/util-deprecate": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
- "license": "MIT"
- },
- "node_modules/util-extend": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/util-extend/-/util-extend-1.0.3.tgz",
- "integrity": "sha512-mLs5zAK+ctllYBj+iAQvlDCwoxU/WDOUaJkcFudeiAX6OajC6BKXJUa9a+tbtkC11dz2Ufb7h0lyvIOVn4LADA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/utils-merge": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
- "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4.0"
- }
- },
- "node_modules/uuid": {
- "version": "10.0.0",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz",
- "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==",
- "funding": [
- "https://github.com/sponsors/broofa",
- "https://github.com/sponsors/ctavan"
- ],
- "license": "MIT",
- "bin": {
- "uuid": "dist/bin/uuid"
- }
- },
- "node_modules/v8-compile-cache-lib": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
- "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/v8-to-istanbul": {
- "version": "9.3.0",
- "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz",
- "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "@jridgewell/trace-mapping": "^0.3.12",
- "@types/istanbul-lib-coverage": "^2.0.1",
- "convert-source-map": "^2.0.0"
- },
- "engines": {
- "node": ">=10.12.0"
- }
- },
- "node_modules/validate-npm-package-license": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
- "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "spdx-correct": "^3.0.0",
- "spdx-expression-parse": "^3.0.0"
- }
- },
- "node_modules/vary": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
- "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/walker": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
- "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "makeerror": "1.0.12"
- }
- },
- "node_modules/watskeburt": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/watskeburt/-/watskeburt-4.2.2.tgz",
- "integrity": "sha512-AOCg1UYxWpiHW1tUwqpJau8vzarZYTtzl2uu99UptBmbzx6kOzCGMfRLF6KIRX4PYekmryn89MzxlRNkL66YyA==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "watskeburt": "dist/run-cli.js"
- },
- "engines": {
- "node": "^18||>=20"
- }
- },
- "node_modules/webidl-conversions": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
- "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
- "license": "BSD-2-Clause"
- },
- "node_modules/whatwg-url": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
- "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
- "license": "MIT",
- "dependencies": {
- "tr46": "~0.0.3",
- "webidl-conversions": "^3.0.0"
- }
- },
- "node_modules/which": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
- "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
- "devOptional": true,
- "license": "ISC",
- "dependencies": {
- "isexe": "^2.0.0"
- },
- "bin": {
- "node-which": "bin/node-which"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/wide-align": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
- "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
- "license": "ISC",
- "dependencies": {
- "string-width": "^1.0.2 || 2 || 3 || 4"
- }
- },
- "node_modules/winston": {
- "version": "3.17.0",
- "resolved": "https://registry.npmjs.org/winston/-/winston-3.17.0.tgz",
- "integrity": "sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==",
- "license": "MIT",
- "dependencies": {
- "@colors/colors": "^1.6.0",
- "@dabh/diagnostics": "^2.0.2",
- "async": "^3.2.3",
- "is-stream": "^2.0.0",
- "logform": "^2.7.0",
- "one-time": "^1.0.0",
- "readable-stream": "^3.4.0",
- "safe-stable-stringify": "^2.3.1",
- "stack-trace": "0.0.x",
- "triple-beam": "^1.3.0",
- "winston-transport": "^4.9.0"
- },
- "engines": {
- "node": ">= 12.0.0"
- }
- },
- "node_modules/winston-daily-rotate-file": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/winston-daily-rotate-file/-/winston-daily-rotate-file-5.0.0.tgz",
- "integrity": "sha512-JDjiXXkM5qvwY06733vf09I2wnMXpZEhxEVOSPenZMii+g7pcDcTBt2MRugnoi8BwVSuCT2jfRXBUy+n1Zz/Yw==",
- "license": "MIT",
- "dependencies": {
- "file-stream-rotator": "^0.6.1",
- "object-hash": "^3.0.0",
- "triple-beam": "^1.4.1",
- "winston-transport": "^4.7.0"
- },
- "engines": {
- "node": ">=8"
- },
- "peerDependencies": {
- "winston": "^3"
- }
- },
- "node_modules/winston-transport": {
- "version": "4.9.0",
- "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.9.0.tgz",
- "integrity": "sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==",
- "license": "MIT",
- "dependencies": {
- "logform": "^2.7.0",
- "readable-stream": "^3.6.2",
- "triple-beam": "^1.3.0"
- },
- "engines": {
- "node": ">= 12.0.0"
- }
- },
- "node_modules/word-wrap": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
- "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/wrap-ansi": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
- "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
- }
- },
- "node_modules/wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
- "license": "ISC"
- },
- "node_modules/write-file-atomic": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz",
- "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "imurmurhash": "^0.1.4",
- "signal-exit": "^3.0.7"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
- }
- },
- "node_modules/ws": {
- "version": "8.18.0",
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
- "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
- "license": "MIT",
- "engines": {
- "node": ">=10.0.0"
- },
- "peerDependencies": {
- "bufferutil": "^4.0.1",
- "utf-8-validate": ">=5.0.2"
- },
- "peerDependenciesMeta": {
- "bufferutil": {
- "optional": true
- },
- "utf-8-validate": {
- "optional": true
- }
- }
- },
- "node_modules/y18n": {
- "version": "5.0.8",
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
- "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
- "license": "ISC",
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/yallist": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
- "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/yaml": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz",
- "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==",
- "license": "ISC",
- "bin": {
- "yaml": "bin.mjs"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/yamljs": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/yamljs/-/yamljs-0.3.0.tgz",
- "integrity": "sha512-C/FsVVhht4iPQYXOInoxUM/1ELSf9EsgKH34FofQOp6hwCPrW4vG4w5++TED3xRUo8gD7l0P1J1dLlDYzODsTQ==",
- "license": "MIT",
- "dependencies": {
- "argparse": "^1.0.7",
- "glob": "^7.0.5"
- },
- "bin": {
- "json2yaml": "bin/json2yaml",
- "yaml2json": "bin/yaml2json"
- }
- },
- "node_modules/yamljs/node_modules/argparse": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
- "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
- "license": "MIT",
- "dependencies": {
- "sprintf-js": "~1.0.2"
- }
- },
- "node_modules/yamljs/node_modules/sprintf-js": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
- "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
- "license": "BSD-3-Clause"
- },
- "node_modules/yargs": {
- "version": "17.7.2",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
- "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
- "license": "MIT",
- "dependencies": {
- "cliui": "^8.0.1",
- "escalade": "^3.1.1",
- "get-caller-file": "^2.0.5",
- "require-directory": "^2.1.1",
- "string-width": "^4.2.3",
- "y18n": "^5.0.5",
- "yargs-parser": "^21.1.1"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/yargs-parser": {
- "version": "21.1.1",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
- "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
- "license": "ISC",
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/yauzl": {
- "version": "2.10.0",
- "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
- "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
- "license": "MIT",
- "dependencies": {
- "buffer-crc32": "~0.2.3",
- "fd-slicer": "~1.1.0"
- }
- },
- "node_modules/yn": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
- "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/yocto-queue": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
- "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/zod": {
- "version": "3.24.1",
- "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.1.tgz",
- "integrity": "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/colinhacks"
- }
- }
- }
-}
diff --git a/package.json b/package.json
index c48ee738..06509479 100644
--- a/package.json
+++ b/package.json
@@ -1,123 +1,45 @@
{
"name": "dockstatapi",
- "repository": "git@github.com:Its4Nik/dockstatapi.git",
- "version": "2.0.1",
- "description": "API for docker hosts using dockerode",
- "main": "src/server.ts",
+ "author": {
+ "email": "info@itsnik.de",
+ "name": "ItsNik",
+ "url": "https://github.com/Its4Nik"
+ },
+ "license": "CC BY-NC 4.0",
+ "contributors": [],
+ "description": "DockStatAPI is an API backend featuring plugins and more for DockStat",
+ "version": "2.1.0",
"scripts": {
- "test": "NODE_ENV=testing jest -w 1 --forceExit",
- "test:silent": "NODE_ENV=testing jest -w 1 --forceExit --silent",
- "local-env-file": "bash ./src/misc/createEnvDev.sh",
- "start": "npm run local-env-file && NODE_ENV=production tsx src/server.ts",
- "start:build": "npm run local-env-file -d && npm run build && NODE_ENV=production node dist/src/src/server.js",
- "dev": "npm run local-env-file && NODE_ENV=development nodemon",
- "dev:socket": "docker compose -f docker/docker-compose.dev.yaml up -d && npm run local-env-file && NODE_ENV=development nodemon ; docker compose -f docker/docker-compose.dev.yaml down",
- "dev:trace": "npm run local-env-file && NODE_ENV=development nodemon --trace-uncaught --trace-warnings",
- "dep": "bash ./src/misc/dependencyGraphs/createDependencyGraph.sh",
- "dep:remove": "bash ./src/misc/removeUnusedDeps.sh && npm run dep",
- "build": "tsc",
- "build:mini": "tsc && bash ./src/misc/minifyDist.sh --build-only",
- "build:docker": "docker build . -t \"dockstatapi:local\" -f ./docker/Dockerfile-dev",
- "build:docker:prod": "docker build . -t \"dockstatapi:local\" -f ./docker/Dockerfile-base",
- "mini": "bash ./src/misc/minifyDist.sh",
- "docker": "docker compose -f docker/docker-compose.yaml up -d && bash ./src/misc/.tmux.sh; docker compose -f docker/docker-compose.yaml down",
- "docker:build": "npm run build:docker && npm run docker",
- "docker:build:prod": "npm run build:docker:prod && npm run docker",
- "prettier": "prettier -c ./__tests__/*.spec.ts --parser typescript --write && prettier -c ./src/**/*.ts --parser typescript --write && prettier -c ./.github/workflows/*.yaml --parser yaml --write && prettier -c ./**/*.md --parser markdown --write && prettier -c ./**/*.json --parser json --write",
- "lint": "eslint",
- "lint:fix": "eslint --fix",
- "license": "bash ./src/misc/credits.sh",
- "finish": "npm run local-env-file && npm run license && npm run prettier && npm run lint"
+ "start": "cross-env NODE_ENV=production LOG_LEVEL=info bun run src/index.ts",
+ "start:linux": "NODE_ENV=production LOG_LEVEL=info bun run src/index.ts",
+ "dev": "docker compose -f docker/docker-compose.dev.yaml up -d && cross-env NODE_ENV=dev bun run --watch src/index.ts",
+ "dev:clean": "bun dev ; echo '\nExiting...' ; bun clean",
+ "build": "bun build --target bun src/index.ts --outdir ./dist",
+ "clean": "bun run clean:win || bun run clean:lin",
+ "clean:win": "node -e \"process.exit(process.platform === 'win32' ? 0 : 1)\" && cmd /c del /Q dockstatapi.db* && echo 'success'",
+ "clean:lin": "node -e \"process.exit(process.platform !== 'win32' ? 0 : 1)\" && rm -f dockstatapi.db* && echo 'success'"
},
- "keywords": [],
- "author": "Its4Nik",
- "license": "BSD 3-Clause License",
"dependencies": {
- "bcrypt": "^5.1.1",
- "chokidar": "^4.0.1",
- "cors": "^2.8.5",
- "cytoscape": "^3.30.4",
- "docker-compose": "^1.1.0",
- "dockerode": "^4.0.2",
- "express": "^4.21.1",
- "express-rate-limit": "^7.4.1",
- "https": "^1.0.0",
- "i": "^0.3.7",
- "ipaddr.js": "^2.2.0",
- "nodemailer": "^6.9.16",
- "npm": "^11.0.0",
- "puppeteer": "^24.0.0",
- "sqlite3": "^5.1.7",
- "swagger-ui-express": "^5.0.1",
- "winston": "^3.15.0",
- "winston-daily-rotate-file": "^5.0.0",
- "yamljs": "^0.3.0"
+ "@elysiajs/static": "^1.2.0",
+ "@elysiajs/swagger": "^1.2.2",
+ "chalk": "^5.4.1",
+ "docker-compose": "^1.1.1",
+ "dockerode": "^4.0.4",
+ "elysia": "latest",
+ "split2": "^4.2.0",
+ "winston": "^3.17.0",
+ "winston-transport": "^4.9.0",
+ "yaml": "^2.7.0"
},
"devDependencies": {
- "@eslint/js": "^9.17.0",
- "@types/bcrypt": "^5.0.2",
- "@types/cors": "^2.8.17",
- "@types/cytoscape": "^3.21.8",
- "@types/dockerode": "^3.3.31",
- "@types/express": "^5.0.0",
- "@types/express-handlebars": "^5.3.1",
- "@types/jest": "^29.5.14",
- "@types/node": "^22.9.0",
- "@types/node-fetch": "^2.6.12",
- "@types/nodemailer": "^6.4.17",
- "@types/supertest": "^6.0.2",
- "@types/supports-color": "^8.1.3",
- "@types/swagger-jsdoc": "^6.0.4",
- "@types/swagger-ui-express": "^4.1.7",
- "@types/ws": "^8.5.14",
- "@types/yamljs": "^0.2.34",
- "@typescript-eslint/eslint-plugin": "^8.18.2",
- "@typescript-eslint/parser": "^8.18.2",
- "dependency-cruiser": "^16.5.0",
- "eslint": "^9.17.0",
- "globals": "^15.14.0",
- "jest": "^29.7.0",
- "license-checker": "^25.0.1",
- "nodemon": "^3.1.7",
- "prettier": "^3.4.2",
- "supertest": "^7.0.0",
- "ts-jest": "^29.2.5",
- "ts-node": "^10.9.2",
- "tsx": "^4.19.2",
- "typescript-eslint": "^8.18.2",
- "uglify-js": "^3.19.3"
- },
- "engines": {
- "npm": ">=10.8.2"
+ "@types/dockerode": "^3.3.34",
+ "@types/split2": "^4.2.3",
+ "bun-types": "latest",
+ "cross-env": "^7.0.3",
+ "wrap-ansi": "^9.0.0"
},
- "jest": {
- "preset": "ts-jest",
- "testMatch": [
- "**/__tests__/**/*.(test|spec).ts"
- ],
- "testEnvironment": "node",
- "transform": {
- "^.+\\.(ts|tsx)$": "ts-jest"
- },
- "moduleFileExtensions": [
- "ts",
- "tsx",
- "js",
- "jsx",
- "json",
- "node"
- ],
- "coveragePathIgnorePatterns": [
- "/node_modules/"
- ],
- "moduleNameMapper": {
- "^@/(.*)$": "src/$1"
- },
- "transformIgnorePatterns": [
- "/node_modules/"
- ],
- "testPathIgnorePatterns": [
- "util"
- ]
- }
-}
+ "module": "src/index.js",
+ "trustedDependencies": [
+ "protobufjs"
+ ]
+}
\ No newline at end of file
diff --git a/public/404.html b/public/404.html
new file mode 100644
index 00000000..39b107d4
--- /dev/null
+++ b/public/404.html
@@ -0,0 +1,99 @@
+
+
+
+
+
+
+ 404 - Page Not Found
+
+
+
+
+
+
+
404
+
+ Oops! The page you're looking for doesn't exist.
+
+
+ Swagger
+ GitHub
+
+
+
+
+
\ No newline at end of file
diff --git a/.github/DockStat.png b/public/DockStat.png
similarity index 100%
rename from .github/DockStat.png
rename to public/DockStat.png
diff --git a/src/config/db.ts b/src/config/db.ts
deleted file mode 100644
index 5ed4d6a0..00000000
--- a/src/config/db.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import sqlite3 from "sqlite3";
-import logger from "../utils/logger";
-
-const dbPath: string = "./src/data/database.db";
-
-const db: sqlite3.Database = new sqlite3.Database(dbPath, (error: unknown) => {
- if (error as Error) {
- logger.error("Error opening database:", (error as Error).message);
- } else {
- db.run(
- `CREATE TABLE IF NOT EXISTS data (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- info TEXT NOT NULL,
- timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
- )`,
- () => {
- logger.info("Database created / checked successfully, table is ready.");
- },
- );
- }
-});
-
-export default db;
diff --git a/src/config/hostsystem.ts b/src/config/hostsystem.ts
deleted file mode 100644
index 87928a8e..00000000
--- a/src/config/hostsystem.ts
+++ /dev/null
@@ -1,93 +0,0 @@
-import {
- RUNNING_IN_DOCKER,
- VERSION,
- HA_MASTER,
- HA_UNSAFE,
- TRUSTED_PROXIES,
- LOG_LEVEL,
-} from "./variables";
-import fs from "fs";
-import logger from "../utils/logger";
-import os from "os";
-import { atomicWrite } from "../utils/atomicWrite";
-
-const userConf = "./src/data/user.conf";
-const inDocker: boolean = RUNNING_IN_DOCKER == "true";
-const version: string = VERSION || "unknown";
-const masterNode: string = HA_MASTER === "true" ? "✓" : "✗";
-const unsafeSync: string = HA_UNSAFE === "true" ? "✓" : "✗";
-
-let trustedProxies: string = "";
-
-if (TRUSTED_PROXIES) {
- trustedProxies = TRUSTED_PROXIES;
-} else {
- trustedProxies = "✗";
-}
-
-function writeUserConf(port: number) {
- let previousConfig = null;
- let shouldRewriteConfig = false;
-
- const installationDetails = {
- installedAt: new Date().toISOString(),
- backendVersion: version,
- inDocker: inDocker,
- installedBy: os.userInfo().username,
- platform: os.platform(),
- arch: os.arch(),
- };
-
- if (fs.existsSync(userConf)) {
- try {
- previousConfig = JSON.parse(fs.readFileSync(userConf, "utf-8"));
- if (previousConfig.backendVersion !== version) {
- shouldRewriteConfig = true;
- logger.debug(
- "Version change detected. Rewriting configuration file...",
- );
- } else {
- logger.debug("No version change detected. Skipping re-initialization.");
- }
- } catch (error) {
- logger.error(
- "Error reading the configuration file. Rewriting it...",
- error,
- );
- shouldRewriteConfig = true;
- }
- } else {
- logger.debug("Configuration file not found. Creating a new one...");
- shouldRewriteConfig = true;
- }
-
- if (shouldRewriteConfig) {
- atomicWrite(userConf, JSON.stringify(installationDetails, null, 2));
- logger.debug("Configuration file created/updated:", userConf);
- }
-
- const startDetails = {
- startedAt: new Date().toISOString(),
- backendVersion: version,
- };
-
- logger.info("-----------------------------------------");
- logger.info(`Starting at : ${startDetails.startedAt}`);
- logger.info(`Running env : ${process.env.NODE_ENV}`);
- logger.info(`Version : ${startDetails.backendVersion}`);
- logger.info(`Docker : ${installationDetails.inDocker}`);
- logger.info(`Running as : ${installationDetails.installedBy}`);
- logger.info(`Platform : ${installationDetails.platform}`);
- logger.info(`Arch : ${installationDetails.arch}`);
- logger.info(`Master node : ${masterNode}`);
- logger.info(`Unsafe sync : ${unsafeSync}`);
- logger.info(`Proxies : ${trustedProxies}`);
- logger.info(`Log Level : ${LOG_LEVEL}`);
- logger.info(`Server : http://localhost:${port}`);
- if (process.env.NODE_ENV !== "production") {
- logger.info(`Swagger-UI : http://localhost:${port}/api-docs`);
- }
- logger.info("-----------------------------------------");
-}
-
-export default writeUserConf;
diff --git a/src/config/initFiles.ts b/src/config/initFiles.ts
deleted file mode 100644
index 7524907c..00000000
--- a/src/config/initFiles.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import { existsSync } from "fs";
-import logger from "../utils/logger";
-import { atomicWrite } from "../utils/atomicWrite";
-
-const files = [
- { path: "./src/data/highAvailability.json", content: "{}" },
- {
- path: "./src/data/password.json",
- content: JSON.stringify(
- {
- hash: "",
- salt: "",
- },
- null,
- 2,
- ),
- },
- { path: "./src/data/states.json", content: "{}" },
- {
- path: "./src/data/template.json",
- content: JSON.stringify(
- { text: "{{name}} is {{state}} on {{hostName}}" },
- null,
- 2,
- ),
- },
- { path: "./src/data/frontendConfiguration.json", content: "[]" },
- { path: "./src/data/usePassword.txt", content: "false" },
-];
-
-function initFiles(): void {
- files.forEach(({ path: filePath, content }) => {
- if (!existsSync(filePath)) {
- atomicWrite(filePath, content);
- logger.info(`Created: ${filePath}`);
- } else {
- logger.debug(`Skipped (already exists): ${filePath}`);
- }
- });
-}
-
-export default initFiles;
diff --git a/src/config/stacks.ts b/src/config/stacks.ts
deleted file mode 100644
index def75dcb..00000000
--- a/src/config/stacks.ts
+++ /dev/null
@@ -1,260 +0,0 @@
-import logger from "../utils/logger";
-import fs from "fs";
-import path from "path";
-import YAML from "yamljs";
-import { DockerComposeFile } from "../typings/dockerCompose";
-import { dockerStackProperty, dockerStackEnv } from "../typings/dockerStackEnv";
-import { stackConfig } from "../typings/stackConfig";
-import { validate } from "../handlers/stack";
-import { atomicWrite } from "../utils/atomicWrite";
-import { AUTOMATIC_ENVIRONMENT_FILE_MANAGEMENT } from "./variables";
-
-const nameRegex = /^[A-Za-z0-9_-]+$/;
-const stackRootFolder = "./stacks";
-const configFilePath = `${stackRootFolder}/.config.json`;
-
-async function getStackCompose(name: string) {
- try {
- await validate(name);
- const stackCompose = `${stackRootFolder}/${name}/docker-compose.yaml`;
-
- return YAML.parse(fs.readFileSync(stackCompose, "utf-8"));
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg);
- throw new Error(errorMsg);
- }
-}
-
-async function getStackConfig(): Promise {
- try {
- return fs.readFileSync(configFilePath, "utf-8");
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg);
- throw new Error(errorMsg);
- }
-}
-
-async function createStack(
- name: string,
- content: DockerComposeFile,
- override: boolean,
-) {
- try {
- if (!name) {
- const errorMsg = "Name required";
- logger.error(errorMsg);
- throw new Error(errorMsg);
- }
-
- if (!nameRegex.test(name)) {
- const errorMsg = "Name does not match [A-Za-z0-9_-]";
- logger.error(errorMsg);
- throw new Error(errorMsg);
- }
-
- if (!content) {
- const errorMsg = "Data for this stack is required";
- logger.error(errorMsg);
- throw new Error(errorMsg);
- }
-
- const stackFolderPath = `${stackRootFolder}/${name}`;
-
- if (!fs.existsSync(stackFolderPath)) {
- fs.mkdirSync(stackFolderPath, { recursive: true });
- logger.debug(`Created stack folder at ${stackFolderPath}`);
- }
-
- updateConfigFile(name);
-
- let yamlContent = "";
- let environmentFileData: dockerStackEnv = { environment: [] };
- if (AUTOMATIC_ENVIRONMENT_FILE_MANAGEMENT == "true" && override == false) {
- logger.debug("AEFM is activated");
- const { cleanCompose, envSchema } = extractAndRemoveEnv(content);
- yamlContent = YAML.stringify(cleanCompose, 10, 2);
- environmentFileData = envSchema;
-
- await writeEnvFile(name, environmentFileData);
- } else {
- yamlContent = YAML.stringify(content, 10, 2);
- }
-
- const filePath = `${stackFolderPath}/docker-compose.yaml`;
- atomicWrite(filePath, yamlContent);
- logger.debug(`Stack content written to ${filePath}`);
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg);
- throw new Error(errorMsg);
- }
-}
-
-function updateConfigFile(stackName: string) {
- try {
- let config: stackConfig = { stacks: [] };
- if (fs.existsSync(configFilePath)) {
- const configData = fs.readFileSync(configFilePath, "utf-8");
- config = JSON.parse(configData);
- }
-
- const stacks = config.stacks || [];
-
- if (!stacks.includes(stackName)) {
- stacks.push(stackName);
- }
-
- const updatedConfig = { stacks };
- atomicWrite(configFilePath, JSON.stringify(updatedConfig, null, 2));
- logger.debug(`Updated .config.json with stack name: ${stackName}`);
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(`Error updating .config.json: ${errorMsg}`);
- throw new Error(errorMsg);
- }
-}
-
-async function writeEnvFile(
- name: string,
- data: dockerStackEnv,
-): Promise {
- try {
- await validate(name);
-
- if (!nameRegex.test(name)) {
- const sanitizedStackName = name.replace(/\n|\r/g, "");
- const errorMsg = `Invalid stack name: ${sanitizedStackName}`;
- logger.error(errorMsg);
- return false;
- }
-
- const dockerEnvPath = path.resolve(stackRootFolder, name, "docker.env");
- const dockerEnvPathBak = path.resolve(
- stackRootFolder,
- name,
- ".docker.env.bak",
- );
-
- if (
- !dockerEnvPath.startsWith(path.resolve(stackRootFolder)) ||
- !dockerEnvPathBak.startsWith(path.resolve(stackRootFolder))
- ) {
- const sanitizedStackName = name.replace(/\n|\r/g, "");
- const errorMsg = `Path traversal attempt detected: ${sanitizedStackName}`;
- logger.error(errorMsg);
- return false;
- }
-
- const variableNames = data.environment.map(({ name }) => name);
- const duplicateVars = variableNames.filter(
- (item, index) => variableNames.indexOf(item) !== index,
- );
-
- if (duplicateVars.length > 0) {
- const duplicatesList = duplicateVars.join(", ");
- const sanitizedDuplicatesList = duplicatesList.replace(/\n|\r/g, "");
- const errorMsg = `Duplicate environment variables detected: ${sanitizedDuplicatesList}`;
- logger.error(errorMsg);
- return false;
- }
-
- const envFileContent = data.environment
- .map(({ name, value }) => `${name}="${value}"`)
- .join("\n");
-
- if (fs.existsSync(dockerEnvPath)) {
- logger.debug("Creating a local backup");
- const previousData = fs.readFileSync(dockerEnvPath);
- atomicWrite(dockerEnvPathBak, previousData);
- }
-
- atomicWrite(dockerEnvPath, envFileContent);
- return true;
- } catch (error: unknown) {
- const errorMsg = (
- error instanceof Error ? error.message : String(error)
- ).replace(/\n|\r/g, "");
- logger.error(errorMsg);
- throw new Error(errorMsg);
- }
-}
-
-async function getEnvFile(name: string) {
- await validate(name);
- const dockerEnvPath = path.resolve(stackRootFolder, name, "docker.env");
- if (!dockerEnvPath.startsWith(path.resolve(stackRootFolder))) {
- throw new Error("Invalid path");
- }
-
- if (fs.existsSync(dockerEnvPath)) {
- const data = fs.readFileSync(dockerEnvPath, "utf-8");
-
- const environment: dockerStackProperty[] = data
- .split("\n")
- .filter((line) => line.trim() !== "" && line.includes("="))
- .map((line) => {
- const [name, ...valueParts] = line.split("=");
- const value = valueParts.join("=").replace(/^"|"$/g, "");
- return { name: name.trim(), value: value.trim() };
- });
-
- return { environment };
- } else {
- return null;
- }
-}
-
-function extractAndRemoveEnv(data: DockerComposeFile): {
- cleanCompose: DockerComposeFile;
- envSchema: dockerStackEnv;
-} {
- const environment: dockerStackProperty[] = [];
- const envCount: Record = {};
-
- for (const [, service] of Object.entries(data.services)) {
- if (service.environment) {
- for (const key of Object.keys(service.environment)) {
- envCount[key] = (envCount[key] || 0) + 1;
- }
- }
- }
-
- for (const [, service] of Object.entries(data.services)) {
- if (service.environment) {
- const remainingEnvironment: Record = {};
-
- for (const [key, value] of Object.entries(service.environment)) {
- if (envCount[key] === 1) {
- environment.push({ name: key, value });
- } else {
- remainingEnvironment[key] = value;
- }
- }
-
- service.environment = remainingEnvironment;
-
- if (Object.keys(service.environment).length === 0) {
- delete service.environment;
- }
- }
-
- if (!service.env_file) {
- service.env_file = ["./docker.env"];
- }
- }
-
- return {
- cleanCompose: data,
- envSchema: { environment },
- };
-}
-
-export {
- createStack,
- getStackConfig,
- getStackCompose,
- writeEnvFile,
- getEnvFile,
-};
diff --git a/src/config/swagger.yaml b/src/config/swagger.yaml
deleted file mode 100644
index 2230f73b..00000000
--- a/src/config/swagger.yaml
+++ /dev/null
@@ -1,2084 +0,0 @@
-openapi: "3.0.0"
-
-security:
- - passwordAuth: []
-
-info:
- title: "DockStatAPI"
- version: "2.0.1"
- externalDocs:
- description: DockStat(API) Wiki
- url: https://outline.itsnik.de/s/dockstat
- license:
- name: BSD-3-Clause
- url: https://github.com/Its4Nik/dockstatapi/tree/main?tab=BSD-3-Clause-1-ov-file#readme
- contact:
- email: info@itsnik.de
- description: |-
- 
-
- # Pipelines
-
- [](https://github.com/Its4Nik/dockstatapi/actions/workflows/build-image.yml)
- [](https://github.com/Its4Nik/dockstatapi/actions/workflows/validation.yml)
-
- # Feature List:
-
- - Swagger API Documentation
- - Database (Keeps data for 24 hours max)
- - Advanced authentication using hashes and salt
- - `http` API to configure the backend
- - Multi-arch docker builds (using buildx github action)
- - Advanced security through middlewares: rate-limiting and authentication
- - Multi Arch Docker builds through docker buildx
- - High Availability using single master and unlimited worker nodes!
-
- # 🔗 DockStatAPI v2 Documentation
-
- _⚠️ = Deprecation warning_
-
- - [Introduction](https://outline.itsnik.de/s/dockstat)
-
- - [DockstatAPI v2](https://outline.itsnik.de/s/dockstat/doc/dockstatapi-v2-XRMDKRqMIg)
-
- - [API reference](https://outline.itsnik.de/s/dockstat/doc/api-reference-1PTxqx1MQ6)
- - [How dependency graphs are made](https://outline.itsnik.de/s/dockstat/doc/how-the-dependecy-graphs-are-made-svuZbEHH9g)
-
- - [DockStat v1](https://outline.itsnik.de/s/dockstat/doc/dockstat-v1-zVaFS4zROI)
-
- - [⚠️ Customisation](https://outline.itsnik.de/s/dockstat/doc/customization-PiBz4OpQIZ)
- - [⚠️ Themes](https://outline.itsnik.de/s/dockstat/doc/themes-BFhN6ZBbYx)
- - [⚠️ Installation](https://outline.itsnik.de/s/dockstat/doc/installation-DaO99bB86q)
-
- - [⚠️ DockStatAPI v1](https://outline.itsnik.de/s/dockstat/doc/dockstatapi-v1-jLcVCfPNmS)
- - [⚠️ Integrations](https://outline.itsnik.de/s/dockstat/doc/integrations-Agq1oL6HxF)
- - [⚠️ Backend API reference](https://outline.itsnik.de/s/dockstat/doc/backend-api-reference-YzcBbDvY33)
-
-tags:
- - name: Authentication
- description: Routes to setup / configure authentication
-
- - name: Configuration
- description: Configuring the backend
-
- - name: Database queries
- description: Queries made against the SQLite database
-
- - name: "Frontend Configuration"
- description: Backend routes to configure the integrated "frontend service"
-
- - name: Miscellaneous
- description: Some "random" routes which still can be useful
-
- - name: High availability
- description: High availability routes, mainly used by HA sync
-
- - name: Notification Service
- description: Routes to configure the notification service
-
- - name: Stacks
- description: Management of the Stack module
-
-servers:
- - url: http://localhost:9876
- description: "Your DockStatAPI instance"
-
-paths:
- # ------------------------------
- # Authentication setup:
- /auth/enable:
- post:
- tags:
- - "Authentication"
- summary: Enable authentication for every route
- operationId: enableAuth
- parameters:
- - name: password
- in: query
- required: true
- explode: true
- schema:
- type: string
- default: super-secret
- responses:
- "200":
- description: Success - Successfully enabled authentication
- content:
- application/json:
- schema:
- type: object
- properties:
- status:
- type: string
- example: "success"
- message:
- type: string
- example: "Authentication enabled successfully"
-
- "403":
- description: Error - Password is required / Authentication is already enabled
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
- /auth/disable:
- post:
- tags:
- - "Authentication"
- summary: Disable authentication for every route
- operationId: disableAuth
- parameters:
- - name: password
- in: query
- required: true
- explode: true
- schema:
- type: string
- default: super-secret
- responses:
- "200":
- description: Succes - Succesfully disabled authentication
- content:
- application/json:
- schema:
- type: object
- properties:
- status:
- type: string
- example: "success"
- message:
- type: string
- example: "Authentication disabled successfully"
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
- # ------------------------------
- # Database queries:
- /data/latest:
- get:
- tags:
- - "Database queries"
- summary: Fetched the last added entry from the Database and provides it via a JSON output
- operationId: getLatestData
- responses:
- "200":
- description: Succes - Successfully fetched the database
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/ServerContainers"
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "404":
- description: Error - No entries found inside database
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
- /data/all:
- get:
- tags:
- - "Database queries"
- summary: Provides all database entries with an index starting from 0
- operationId: getAllData
- responses:
- "200":
- description: Succes - Successfully fetched the database
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/IndexedServerContainers"
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "404":
- description: Error - No entries found inside database
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
- /data/clear:
- delete:
- tags:
- - "Database queries"
- summary: Deletes all database entries
- operationId: dataClear
- responses:
- "200":
- description: Succes - Successfully cleared the database
- content:
- application/json:
- schema:
- type: object
- properties:
- status:
- type: string
- example: "success"
- message:
- type: string
- example: "Successfully cleared the database"
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
- # ------------------------------
- # Configuration:
- /api/hosts:
- get:
- tags:
- - "Configuration"
- summary: Retrieves the configured name of all added Hosts
- operationId: getHosts
- responses:
- "200":
- description: Succes - Successfully fetched all configured hosts
- content:
- application/json:
- schema:
- type: array
- example: '[ "Host-1", "Host-2" ]'
-
- "400":
- description: Error - No hosts defined, please add a host via /conf/addHost
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
- /api/host/{hostName}/stats:
- get:
- tags:
- - "Configuration"
- summary: Shows general information about the target host, like dockeer engine version
- operationId: getHostInfo
- parameters:
- - name: hostName
- in: path
- description: Hostname of the target host
- required: true
- schema:
- type: string
- responses:
- "200":
- description: Succes - Successfully fetched info about target host
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/HostInfo"
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "404":
- description: Error - No Host found
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
- /api/system:
- get:
- tags:
- - "Configuration"
- summary: Fetched the installation details of this DockStatAPI instance
- operationId: getSystem
- responses:
- "200":
- description: Succes - Fetched system configuration
- content:
- application/json:
- schema:
- type: object
- properties:
- installedAt:
- type: string
- format: date-time
- example: "2024-12-25T19:20:02.418Z"
- backendVersion:
- type: string
- example: "2.0.1"
- inDocker:
- type: boolean
- example: false
- installedBy:
- type: string
- example: "user"
- platform:
- type: string
- example: "linux"
- arch:
- type: string
- example: "x64"
- "400":
- description: Error - Received empty configuration
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
- /api/config:
- get:
- tags:
- - "Configuration"
- summary: Retrieves information about the configured hosts
- operationId: getConfig
- responses:
- "200":
- description: Succes - Fetched system configuration
- content:
- application/json:
- schema:
- type: object
- properties:
- hosts:
- type: array
- items:
- type: object
- properties:
- name:
- type: string
- example: "Host-1"
- url:
- type: string
- example: "192.168.2.12"
- port:
- type: string
- example: "2375"
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
- /api/frontend-config:
- get:
- tags:
- - "Configuration"
- summary: Fetches the "Frontend Configuration" => Used in the DockStat frontend
- operationId: getFrontendConfig
- responses:
- "200":
- description: Succes - Fetched "Frontend Configuration"
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/FrontendConfig"
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
- /api/current-schedule:
- get:
- tags:
- - "Configuration"
- summary: Shows the current configured schedule (for fetching data) in seconds
- operationId: getSchedule
- responses:
- "200":
- description: Succes - Fetched schedule
- content:
- application/json:
- schema:
- type: object
- properties:
- interval:
- type: integer
- example: 600
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
- /api/status:
- get:
- tags:
- - "Miscellaneous"
- summary: Pings all hosts to check reachability
- operationId: getStatus
- responses:
- "200":
- description: Succes - Gathered Status
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/ApiStatus"
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
- /api/containers:
- get:
- tags:
- - "Miscellaneous"
- summary: Fetched all container data directly from the host without reading from the database
- operationId: getContainers
- responses:
- "200":
- description: Succes - Fetched all container statistics
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/ServerContainers"
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
- # ------------------------------
- # High availability:
- /ha/config:
- get:
- tags:
- - "High availability"
- summary: Get the current high availability config
- operationId: getHaConfig
- responses:
- "200":
- description: Succes - Fetched high availability config
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/HaConfig"
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
-
- /ha/sync:
- post:
- tags:
- - "High availability"
- deprecated: true
- summary: This route is not deprecated, but only used by the high availability feature
- operationId: syncHa
- responses:
- "200":
- description: Succes - Synchronized successfully
- "400":
- description: Error - `files` object is missing or invalid
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
-
- /ha/prepare-sync:
- get:
- tags:
- - "High availability"
- deprecated: true
- summary: This route is not deprecated, but only used by the high availability feature
- operationId: syncPrepare
- responses:
- "200":
- description: Succes - Prepared all files for syncing
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
-
- # ------------------------------
- # Notification Service:
- /notification-service/get-template:
- get:
- tags:
- - "Notification Service"
- summary: Fetches the current template for the notification service
- operationId: getNsTemplate
- responses:
- "200":
- description: Success - Fetched notification template
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/Notification-Template"
- "400":
- description: Error - Error while reading file (see server logs)
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
- /notification-service/set-template:
- post:
- tags:
- - "Notification Service"
- - "Configuration"
- summary: Update the current notification template
- operationId: setNsTemplate
- requestBody:
- required: true
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/Notification-Template"
- responses:
- "200":
- description: Success - Template updated successfully
- content:
- application/json:
- schema:
- type: object
- properties:
- status:
- type: string
- example: "success"
- message:
- type: string
- example: "Template updated successfully."
- "400":
- description: Error - Invalid input format. Expected JSON with a 'text' field
- content:
- application/json:
- schema:
- type: object
- properties:
- status:
- type: string
- example: "error"
- message:
- type: string
- example: "Invalid input format. Expected JSON with a 'text' field"
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
- /notification-service/test/{type}/{containerId}:
- post:
- tags:
- - "Notification Service"
- summary: Test a specific type of notification using real data
- operationId: testNs
- parameters:
- - in: path
- name: type
- required: true
- schema:
- type: string
- description: The desired notification to test
-
- - in: path
- name: containerId
- required: true
- schema:
- type: string
- description: A real container ID is needed to test templating functionality
- responses:
- "200":
- description: Success - Sent test notification
- content:
- application/json:
- schema:
- type: object
- properties:
- status:
- type: string
- example: "success"
- message:
- type: string
- example: "Sent test notification"
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
- # ------------------------------
- # Configuration:
- /conf/addHost:
- put:
- tags:
- - "Configuration"
- summary: Adds a new host to the configuration and starts querying it
- operationId: addHost
- parameters:
- - name: name
- in: query
- required: true
- description: A name for the new host
- - name: url
- in: query
- required: true
- description: The target IP or dns entry
- - name: port
- in: query
- required: true
- description: The targets port on which Docker-Socket-Proxy runs
- responses:
- "200":
- description: Success - Host added successfully
- content:
- application/json:
- schema:
- type: object
- properties:
- status:
- type: string
- example: "success"
- message:
- type: string
- example: "Host added successfully"
- "400":
- description: Error - Name, Port, and URL are required
- content:
- application/json:
- schema:
- type: object
- properties:
- status:
- type: string
- example: "error"
- message:
- type: string
- example: "Name, Port, and URL are required"
- "401":
- description: Host already exists
- content:
- application/json:
- schema:
- type: object
- properties:
- status:
- type: string
- example: "error"
- message:
- type: string
- example: "Host already exists"
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
- /conf/removeHost:
- delete:
- tags:
- - "Configuration"
- summary: Removes an host from the config
- operationId: removeHost
- parameters:
- - name: hostName
- in: query
- required: true
- description: "The name of the to-be-removed-Host"
- responses:
- "200":
- description: Success - Host removed successfully
- content:
- application/json:
- schema:
- type: object
- properties:
- status:
- type: string
- example: "success"
- message:
- type: string
- example: "Host removed successfully"
- "401":
- description: Error - Host name is required
- content:
- application/json:
- schema:
- type: object
- properties:
- status:
- type: string
- example: "error"
- message:
- type: string
- example: "Host name is required"
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "404":
- description: Error - Host not found
- content:
- application/json:
- schema:
- type: object
- properties:
- status:
- type: string
- example: "error"
- message:
- type: string
- example: "Host not found"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
- /conf/scheduler:
- tags:
- - "Configuration"
- summary: Adjust the scheduler timing
- operationId: adjustSchedule
- parameters:
- - name: interval
- in: query
- required: true
- description: "Adjust the schedule timing (in seconds)"
- responses:
- "200":
- description: Success - Timing updated
- content:
- application/json:
- schema:
- type: object
- properties:
- status:
- type: string
- example: "success"
- message:
- type: string
- example: "Updated interval"
- "401":
- description: Error - Interval must be between 5 minutes and 6 hours
- content:
- application/json:
- schema:
- type: object
- properties:
- status:
- type: string
- example: "error"
- message:
- type: string
- example: "Interval must be between 5 minutes and 6 hours."
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
- # ------------------------------
- # Frontend routes:
- /frontend/show/{containerName}:
- post:
- tags:
- - "Frontend Configuration"
- operationId: frShowCon
- summary: Set `hide` to false for the specified container
- parameters:
- - name: containerName
- in: path
- schema:
- type: string
- required: true
- description: The name of the container to unhide
- responses:
- "200":
- description: Success - now showing the container
- content:
- application/json:
- schema:
- type: object
- properties:
- status:
- type: string
- example: "success"
- message:
- type: string
- example: "Container unhidden successfully."
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
- /frontend/hide/{containerName}:
- delete:
- tags:
- - "Frontend Configuration"
- operationId: frHideCon
- summary: Set `hide` to true for the specified container
- parameters:
- - name: containerName
- in: path
- schema:
- type: string
- required: true
- description: The name of the container to unhide
- responses:
- "200":
- description: Success - now hiding the container
- content:
- application/json:
- schema:
- type: object
- properties:
- status:
- type: string
- example: "success"
- message:
- type: string
- example: "Hid container succesfully"
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
- /frontend/tag/{containerName}/{tag}:
- post:
- tags:
- - "Frontend Configuration"
- operationId: frTagCon
- summary: Add a tag to the tag array for the specified container
- parameters:
- - name: containerName
- in: path
- schema:
- type: string
- required: true
- description: The name of the container to add a tag to
- - name: tag
- in: path
- schema:
- type: string
- required: true
- description: The name of the tag to add
- responses:
- "200":
- description: Success - Tag added successfully
- content:
- application/json:
- schema:
- type: object
- properties:
- status:
- type: string
- example: "success"
- message:
- type: string
- example: "Tag added successfully."
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
- /frontend/remove-tag/{containerName}/{tag}:
- delete:
- tags:
- - "Frontend Configuration"
- operationId: frRmTagCon
- summary: Remove the specified tag from the tag array for the specified container
- parameters:
- - name: containerName
- in: path
- schema:
- type: string
- required: true
- description: The name of the container to remove a tag from
- - name: tag
- in: path
- schema:
- type: string
- required: true
- description: The name of the tag to remove
- responses:
- "200":
- description: Success - Tag removed successfully
- content:
- application/json:
- schema:
- type: object
- properties:
- status:
- type: string
- example: "success"
- message:
- type: string
- example: "Tag removed successfully."
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
- /frontend/pin/{containerName}:
- post:
- tags:
- - "Frontend Configuration"
- operationId: frPinCon
- summary: Set `pinned` to true for the specified container
- parameters:
- - name: containerName
- in: path
- schema:
- type: string
- required: true
- description: The name of the container to pin
- responses:
- "200":
- description: Success - Container pinned successfully
- content:
- application/json:
- schema:
- type: object
- properties:
- status:
- type: string
- example: "success"
- message:
- type: string
- example: "Container pinned successfully."
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
- /frontend/unpin/{containerName}:
- delete:
- tags:
- - "Frontend Configuration"
- operationId: frRmPinCon
- summary: Set `pinned` to false for the specified container
- parameters:
- - name: containerName
- in: path
- schema:
- type: string
- required: true
- description: The name of the container to unpin
- responses:
- "200":
- description: Success - Container unpinned successfully
- content:
- application/json:
- schema:
- type: object
- properties:
- status:
- type: string
- example: "success"
- message:
- type: string
- example: "Container unpinned successfully."
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
- /frontend/add-link/{containerName}/{link}:
- post:
- tags:
- - "Frontend Configuration"
- operationId: frAddLinkCon
- summary: Add a link to the specified container
- parameters:
- - name: containerName
- in: path
- schema:
- type: string
- required: true
- description: The name of the container to add a link to
- - name: link
- in: path
- schema:
- type: URI
- required: true
- allowReserved: false
- description: The URI of the link (please use Uniform Resource Identifier format)
- responses:
- "200":
- description: Success - Link added to container successfully
- content:
- application/json:
- schema:
- type: object
- properties:
- status:
- type: string
- example: "success"
- message:
- type: string
- example: "Link added successfully."
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
- /frontend/remove-link/{containerName}:
- delete:
- tags:
- - "Frontend Configuration"
- operationId: frRmLinkCon
- summary: Remove a link to the specified container
- parameters:
- - name: containerName
- in: path
- schema:
- type: string
- required: true
- description: The name of the container to remove a link from
- responses:
- "200":
- description: Success - Link removed from container successfully
- content:
- application/json:
- schema:
- type: object
- properties:
- status:
- type: string
- example: "success"
- message:
- type: string
- example: "Link removed successfully."
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
- /frontend/add-icon/{containerName}/{icon}/{useCustomIcon}:
- post:
- tags:
- - "Frontend Configuration"
- operationId: frAddIcon
- summary: Add an icon (path) to the specified container
- parameters:
- - name: containerName
- in: path
- schema:
- type: string
- required: true
- description: The name of the container to add an icon to
- - name: icon
- in: path
- schema:
- type: string
- required: true
- description: The name of the icon file
- - name: useCustomIcon
- in: path
- schema:
- type: boolean
- required: false
- description: If the icon is a custom icon or not
- responses:
- "200":
- description: Success - Icon added to container successfully
- content:
- application/json:
- schema:
- type: object
- properties:
- status:
- type: string
- example: "success"
- message:
- type: string
- example: "Icon added successfully."
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
- /frontend/remove-icon/{containerName}:
- delete:
- tags:
- - "Frontend Configuration"
- operationId: frRmIcon
- summary: Remove an icon from the specified container
- parameters:
- - name: containerName
- in: path
- schema:
- type: string
- required: true
- description: The name of the container to remove an icon from
- responses:
- "200":
- description: Success - Icon removed from container successfully
- content:
- application/json:
- schema:
- type: object
- properties:
- status:
- type: string
- example: "success"
- message:
- type: string
- example: "Icon removed successfully."
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
- # ------------------------------
- # Stack management
- /stacks/create/{name}:
- post:
- tags:
- - "Stacks"
- operationId: createStack
- summary: Creates a docker-compose file inside the stack name directory
- requestBody:
- required: true
- content:
- application/json:
- schema:
- type: string
- description: Your docker-compose.yaml contents
- parameters:
- - name: name
- in: path
- schema:
- type: string
- required: true
- description: The name of the stack
- responses:
- "200":
- description: Success - Stack created
- content:
- application/json:
- schema:
- type: object
- properties:
- status:
- type: string
- example: "success"
- message:
- type: string
- example: "Stack created"
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
- /stacks/start/{name}:
- post:
- tags:
- - "Stacks"
- operationId: startStack
- summary: Starts the defined stack
- parameters:
- - name: name
- in: path
- schema:
- type: string
- required: true
- description: The name of the stack
- responses:
- "200":
- description: Success - Stack started
- content:
- application/json:
- schema:
- type: object
- properties:
- status:
- type: string
- example: "success"
- message:
- type: string
- example: "Stack created"
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
- /stacks/stop/{name}:
- post:
- tags:
- - "Stacks"
- operationId: stopStack
- summary: Stops the defined stack
- parameters:
- - name: name
- in: path
- schema:
- type: string
- required: true
- description: The name of the stack
- responses:
- "200":
- description: Success - Stack stopped
- content:
- application/json:
- schema:
- type: object
- properties:
- status:
- type: string
- example: "success"
- message:
- type: string
- example: "Stack stopped"
-
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
- /stacks/get/{name}:
- get:
- tags:
- - "Stacks"
- operationId: getStack
- summary: Get the docker-compose.yaml (as JSON) from the defined stack
- parameters:
- - name: name
- in: path
- schema:
- type: string
- required: true
- description: The name of the stack
- responses:
- "200":
- description: Success - Stack fetched
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
- /stacks/set-env/{name}:
- post:
- tags:
- - "Stacks"
- operationId: setStackEnv
- summary: Set the docker.env (as JSON) from the defined stack
- requestBody:
- required: true
- content:
- application/json:
- schema:
- type: string
- description: Your docker.env contents
- parameters:
- - name: override
- in: query
- required: false
- description: Whether to override (true) the automatic environment file management (boolean value)
- - name: name
- in: path
- schema:
- type: string
- required: true
- description: The name of the stack
- responses:
- "200":
- description: Success - Stack environment set
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
- /stacks/get-env/{name}:
- get:
- tags:
- - "Stacks"
- operationId: getStackEnv
- summary: Get the docker.env (as JSON) from the defined stack
- parameters:
- - name: name
- in: path
- schema:
- type: string
- required: true
- description: The name of the stack
- responses:
- "200":
- description: Success - Stack config fetched
- "403":
- description: Error - Password is required
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/403"
- "500":
- description: Error - Critical Error, please see the server's logs
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/500"
- "503":
- description: Error - The high-availability lock is currently active, please try again later
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/503"
-
-# ------------------------------
-components:
- securitySchemes:
- passwordAuth:
- type: apiKey
- in: header
- name: x-password
- description: Password required for authentication
-
- schemas:
- Notification-Template:
- type: object
- properties:
- text:
- type: string
- example: "{{container}} on {{host}} is {{state}}"
-
- IndexedServerContainers:
- type: object
- properties:
- "0":
- type: object
- properties:
- Host-1:
- type: array
- items:
- $ref: "#/components/schemas/Container"
- additionalProperties: false
-
- ServerContainers:
- type: object
- properties:
- Host-1:
- type: array
- items:
- $ref: "#/components/schemas/Container"
- additionalProperties: false
-
- Container:
- type: object
- properties:
- name:
- type: string
- description: The name of the container.
- example: "Container-1"
- id:
- type: string
- description: The unique identifier of the container.
- example: "a84ca83bb0e7f8c24fe472b9164d40a4bae518ece8369e6776f722b81dd65bcf"
- hostName:
- type: string
- description: The hostname of the server.
- example: "Host-1"
- state:
- type: string
- description: The current state of the container.
- example: "running"
- cpu_usage:
- type: number
- description: The CPU usage of the container in arbitrary units.
- example: 625185.1851851852
- mem_usage:
- type: integer
- description: Memory usage in bytes.
- example: 359899136
- mem_limit:
- type: integer
- description: Memory limit in bytes.
- example: 8127893504
- net_rx:
- type: integer
- description: Total network received in bytes.
- example: 11004185462
- net_tx:
- type: integer
- description: Total network transmitted in bytes.
- example: 9950013623
- current_net_rx:
- type: integer
- description: Current network received in bytes.
- example: 11004185462
- current_net_tx:
- type: integer
- description: Current network transmitted in bytes.
- example: 9950013623
- networkMode:
- type: string
- description: The network mode of the container.
- example: "docker_default"
-
- HostInfo:
- type: object
- properties:
- hostName:
- type: string
- example: "Host-1"
- info:
- type: object
- properties:
- ID:
- type: string
- format: uuid
- example: "32b5fad9-9b12-48b0-9ce7-178f2886ad60"
- Containers:
- type: integer
- example: 8
- ContainersRunning:
- type: integer
- example: 8
- ContainersPaused:
- type: integer
- example: 0
- ContainersStopped:
- type: integer
- example: 0
- Images:
- type: integer
- example: 7
- OperatingSystem:
- type: string
- example: "Ubuntu 24.04 LTS"
- KernelVersion:
- type: string
- example: "6.8.0-38-generic"
- Architecture:
- type: string
- example: "x86_64"
- MemTotal:
- type: integer
- example: 8127893504
- NCPU:
- type: integer
- example: 4
- version:
- type: object
- properties:
- Components:
- type: object
- properties:
- Engine:
- type: string
- example: "27.1.1"
- containerd:
- type: string
- example: "1.7.19"
- runc:
- type: string
- example: "1.7.19"
- docker-init:
- type: string
- example: "0.19.0"
-
- Frontend:
- type: object
- properties:
- name:
- type: string
- description: The name of the container
- hidden:
- type: boolean
- description: Whether the container is hidden
- tags:
- type: array
- items:
- type: string
- description: List of tags associated with the container
- link:
- type: string
- format: uri
- description: A link associated with the container
- icon:
- type: string
- description: Icon for the container
- pinned:
- type: boolean
- description: Whether the container is pinned
- required:
- - name
-
- FrontendConfig:
- type: array
- items:
- $ref: "#/components/schemas/Frontend"
-
- ApiStatus:
- type: object
- properties:
- ApiReachable:
- type: boolean
- description: Whether the API is reachable
- online:
- type: object
- description: Status of individual services keyed by their names
- properties:
- Host-1:
- type: boolean
- Host-2:
- type: boolean
- required:
- - ApiReachable
- - online
-
- HaConfig:
- type: object
- properties:
- active:
- type: boolean
- description: Whether High availability is active or nots
- master:
- type: boolean
- description: Whether this node is the master node
- nodes:
- type: array
- items:
- type: string
- format: hostname
- description: List of nodes in the cluster, specified by hostname or IP with port
- required:
- - active
- - master
- - nodes
-
- 401:
- type: object
- properties:
- status:
- type: string
- example: "error"
- message:
- type: string
- example: "Invalid password"
-
- 403:
- type: object
- properties:
- status:
- type: string
- example: "denied"
- message:
- type: string
- example: "Password required"
-
- 500:
- type: object
- properties:
- status:
- type: string
- example: "critical"
- message:
- type: string
- example: "Please see the server logs for more info"
-
- 503:
- type: object
- properties:
- status:
- type: string
- example: "error"
- message:
- type: string
- example: "Service unavailable. The high-availability lock is currently active. Please try again later."
diff --git a/src/config/swaggerConfig.ts b/src/config/swaggerConfig.ts
deleted file mode 100644
index 39c074a6..00000000
--- a/src/config/swaggerConfig.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { SwaggerOptions } from "swagger-ui-express";
-import { css } from "./swaggerTheme";
-
-export const options: SwaggerOptions = {
- swaggerOptions: {
- tryItOutEnabled: true,
- },
- customCss: css,
- explorer: false,
-};
diff --git a/src/config/swaggerTheme.ts b/src/config/swaggerTheme.ts
deleted file mode 100644
index d8a879c9..00000000
--- a/src/config/swaggerTheme.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-export const css = `
-
-.swagger-ui .topbar {
- display: none
-}
-`;
diff --git a/src/config/variables.ts b/src/config/variables.ts
deleted file mode 100644
index 37c67a23..00000000
--- a/src/config/variables.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import vars from "../data/variables.json";
-
-export const {
- VERSION,
- RUNNING_IN_DOCKER,
- TRUSTED_PROXIES,
- HA_MASTER,
- HA_MASTER_IP,
- HA_NODE,
- HA_UNSAFE,
- DISCORD_WEBHOOK_URL,
- EMAIL_SENDER,
- EMAIL_RECIPIENT,
- EMAIL_PASSWORD,
- EMAIL_SERVICE,
- PUSHBULLET_ACCESS_TOKEN,
- PUSHOVER_USER_KEY,
- PUSHOVER_API_TOKEN,
- SLACK_WEBHOOK_URL,
- TELEGRAM_BOT_TOKEN,
- TELEGRAM_CHAT_ID,
- WHATSAPP_API_URL,
- WHATSAPP_RECIPIENT,
- AUTOMATIC_ENVIRONMENT_FILE_MANAGEMENT,
- LOG_LEVEL,
-} = vars;
diff --git a/src/controllers/auth.ts b/src/controllers/auth.ts
deleted file mode 100644
index 905e39c9..00000000
--- a/src/controllers/auth.ts
+++ /dev/null
@@ -1,64 +0,0 @@
-import fs from "fs/promises";
-import logger from "../utils/logger";
-const passwordFile: string = "./src/data/password.json";
-const passwordBool: string = "./src/data/usePassword.txt";
-
-async function authEnabled(): Promise {
- let isAuthEnabled: boolean = false;
- let data: string = "";
- try {
- data = await fs.readFile(passwordBool, "utf8");
- isAuthEnabled = data.trim() === "true";
- return isAuthEnabled;
- } catch (error: unknown) {
- logger.error("Error reading file: ", error as Error);
- return isAuthEnabled;
- }
-}
-
-async function readPasswordFile() {
- let data: string = "";
- try {
- data = await fs.readFile(passwordFile, "utf8");
- return data;
- } catch (error: unknown) {
- logger.error("Could not read saved password: ", error as Error);
- return data;
- }
-}
-
-async function writePasswordFile(passwordData: string) {
- try {
- await fs.writeFile(passwordFile, passwordData);
- setTrue();
- logger.debug("Authentication enabled");
- return "Authentication enabled";
- } catch (error: unknown) {
- logger.error("Error writing password file:", error as Error);
- return error;
- }
-}
-
-async function setTrue() {
- try {
- await fs.writeFile(passwordBool, "true", "utf8");
- logger.info(`Enabled authentication`);
- return;
- } catch (error: unknown) {
- logger.error("Error writing to the file:", error as Error);
- return;
- }
-}
-
-async function setFalse() {
- try {
- await fs.writeFile(passwordBool, "false", "utf8");
- logger.info(`Disabled authentication`);
- return;
- } catch (error: unknown) {
- logger.error("Error writing to the file:", error as Error);
- return;
- }
-}
-
-export { authEnabled, readPasswordFile, writePasswordFile, setFalse };
diff --git a/src/controllers/containerController.ts b/src/controllers/containerController.ts
deleted file mode 100644
index 2883dad9..00000000
--- a/src/controllers/containerController.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import { getDockerClient } from "../utils/dockerClient";
-import logger from "../utils/logger";
-import { Request, Response } from "express";
-import { createResponseHandler } from "../handlers/response";
-
-const getContainers = async (req: Request, res: Response): Promise => {
- const ResponseHandler = createResponseHandler(res);
- const host: string = (req.query.host as string) || "local";
-
- logger.info(`Fetching containers from host: ${host}`);
-
- try {
- const docker = getDockerClient(host);
- const containers = await docker.listContainers();
-
- return ResponseHandler.rawData(
- containers,
- `Fetched containers from ${host}`,
- );
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
-};
-
-const getContainerStats = async (
- containerID: string,
- containerHost: string,
- res: Response,
-): Promise => {
- logger.info(
- `Fetching stats for container: ${containerID} from host: ${containerHost}`,
- );
- const ResponseHandler = createResponseHandler(res);
-
- try {
- const docker = getDockerClient(containerHost);
- const container = docker.getContainer(containerID);
- const stats = await container.stats({ stream: false });
-
- return ResponseHandler.rawData(
- stats,
- `Successfully fetched stats for container: ${containerID} from host: ${containerHost}`,
- );
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
-};
-
-export default {
- getContainers,
- getContainerStats,
-};
diff --git a/src/controllers/databaseMigration.ts b/src/controllers/databaseMigration.ts
deleted file mode 100644
index 45f88d12..00000000
--- a/src/controllers/databaseMigration.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import db from "../config/db";
-import logger from "../utils/logger";
-
-function clearOldEntries(): void {
- const twentyFourHoursAgo: number = Date.now() - 24 * 60 * 60 * 1000;
-
- db.run(
- `DELETE FROM data WHERE createdAt < ?`,
- [twentyFourHoursAgo],
- (err: Error | null) => {
- if (err) {
- logger.error("Error deleting old entries:", err.message);
- throw new Error("Database cleanup failed");
- }
- logger.info("Old entries cleared successfully");
- },
- );
-}
-
-export default clearOldEntries;
diff --git a/src/controllers/fetchData.ts b/src/controllers/fetchData.ts
deleted file mode 100644
index 06e52a93..00000000
--- a/src/controllers/fetchData.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-import db from "../config/db";
-import { fetchAllContainers } from "../utils/containerService";
-import logger from "../utils/logger";
-import fs from "fs";
-import { atomicWrite } from "../utils/atomicWrite";
-const filePath = "./src/data/states.json";
-
-let previousState: { [key: string]: string } = {};
-
-interface Container {
- name: string;
- id: string;
- state: string;
- hostName: string;
-}
-
-interface AllContainerData {
- [host: string]: Container[] | { error: string };
-}
-
-const fetchData = async (): Promise => {
- try {
- const allContainerData: AllContainerData =
- (await fetchAllContainers()) || {};
-
- db.run(
- `INSERT INTO data (info) VALUES (?)`,
- [JSON.stringify(allContainerData)],
- function (error) {
- if (error) {
- logger.error("Error inserting data:", error);
- return;
- }
- logger.info(`Data inserted with ID: ${this.lastID}`);
- },
- );
-
- const containerStatus: AllContainerData = {};
-
- Object.keys(allContainerData).forEach((host) => {
- const containers = allContainerData[host];
-
- // Handle if the containers are an array, otherwise handle the error
- if (Array.isArray(containers)) {
- containerStatus[host] = containers.map((container: Container) => ({
- name: container.name,
- id: container.id,
- state: container.state,
- hostName: container.hostName,
- }));
- } else {
- // If there's an error, handle it separately
- containerStatus[host] = { error: "Error fetching containers" };
- }
- });
-
- if (fs.existsSync(filePath)) {
- const fileData = fs.readFileSync(filePath, "utf8");
- previousState = fileData ? JSON.parse(fileData) : {};
- }
-
- // Compare previous and current state
- if (JSON.stringify(previousState) !== JSON.stringify(containerStatus)) {
- atomicWrite(filePath, JSON.stringify(containerStatus, null, 2));
- logger.info(`Container states saved to ${filePath}`);
- // TODO: Add logic + notification levels per service
- } else {
- logger.info("No state change detected, notifications not triggered.");
- }
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg);
- }
-};
-
-export default fetchData;
diff --git a/src/controllers/frontendConfiguration.ts b/src/controllers/frontendConfiguration.ts
deleted file mode 100644
index ed4e59dd..00000000
--- a/src/controllers/frontendConfiguration.ts
+++ /dev/null
@@ -1,297 +0,0 @@
-import fs from "fs";
-import logger from "../utils/logger";
-const dataPath: string = "./src/data/frontendConfiguration.json";
-const expression: string =
- "https?://(www.)?[-a-zA-Z0-9@:%._+~#=]{1,256}.[a-zA-Z0-9()]{1,6}([-a-zA-Z0-9()@:%_+.~#?&//=]*)";
-const regex = new RegExp(expression);
-import { FrontendConfig } from "../typings/frontendConfig";
-
-///////////////////////////////////////////////////////////////
-// Hide Containers:
-async function hideContainer(containerName: string) {
- try {
- const data = await readData();
- const containerIndex = data.findIndex(
- (container) => container.name === containerName,
- );
-
- if (containerIndex !== -1) {
- data[containerIndex].hidden = true;
- await saveData(data);
- } else {
- data.push({ name: containerName, hidden: true });
- await saveData(data);
- }
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg);
- }
-}
-
-async function unhideContainer(containerName: string) {
- try {
- const data = await readData();
- const containerIndex = data.findIndex(
- (container) => container.name === containerName,
- );
-
- if (containerIndex !== -1) {
- delete data[containerIndex].hidden;
- await saveData(data);
- cleanupData();
- }
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg);
- }
-}
-
-///////////////////////////////////////////////////////////////
-// Tag containers
-async function addTagToContainer(containerName: string, tag: string) {
- try {
- const data = await readData();
- const containerIndex = data.findIndex(
- (container) => container.name === containerName,
- );
-
- if (containerIndex !== -1) {
- if (!data[containerIndex].tags) {
- data[containerIndex].tags = [];
- }
- data[containerIndex].tags.push(tag);
- await saveData(data);
- } else {
- data.push({ name: containerName, tags: [tag] });
- await saveData(data);
- }
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg);
- }
-}
-
-async function removeTagFromContainer(containerName: string, tag: string) {
- try {
- const data = await readData();
- const containerIndex = data.findIndex(
- (container) => container.name === containerName,
- );
-
- if (containerIndex !== -1 && data[containerIndex].tags) {
- data[containerIndex].tags = data[containerIndex].tags.filter(
- (t) => t !== tag,
- );
- await saveData(data);
- cleanupData();
- }
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg);
- }
-}
-
-///////////////////////////////////////////////////////////////
-// Pin containers
-async function pinContainer(containerName: string) {
- try {
- const data = await readData();
- const containerIndex = data.findIndex(
- (container) => container.name === containerName,
- );
-
- if (containerIndex !== -1) {
- data[containerIndex].pinned = true;
- await saveData(data);
- } else {
- data.push({ name: containerName, pinned: true });
- await saveData(data);
- }
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg);
- }
-}
-
-async function unpinContainer(containerName: string) {
- try {
- const data = await readData();
- const containerIndex = data.findIndex(
- (container) => container.name === containerName,
- );
-
- if (containerIndex !== -1) {
- delete data[containerIndex].pinned;
- await saveData(data);
- cleanupData();
- }
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg);
- }
-}
-
-///////////////////////////////////////////////////////////////
-// Add/remove link from containers
-async function setLink(containerName: string, link: string) {
- if (link.match(regex)) {
- try {
- const data = await readData();
- const containerIndex = data.findIndex(
- (container) => container.name === containerName,
- );
-
- if (containerIndex !== -1) {
- data[containerIndex].link = `${link}`;
- await saveData(data);
- } else {
- data.push({ name: containerName, link: `${link}` });
- await saveData(data);
- }
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg);
- }
- } else {
- logger.error(`Provided link is not valid: ${link}`);
- throw new Error(`Provided link is not valid: ${link}`);
- }
-}
-
-async function removeLink(containerName: string) {
- try {
- const data = await readData();
- const containerIndex = data.findIndex(
- (container) => container.name === containerName,
- );
-
- if (containerIndex !== -1) {
- delete data[containerIndex].link;
- await saveData(data);
- cleanupData();
- }
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg);
- }
-}
-
-///////////////////////////////////////////////////////////////
-// Add/remove icon from containers
-async function setIcon(containerName: string, icon: string, custom: boolean) {
- try {
- const data = await readData();
- const containerIndex: number = data.findIndex(
- (container) => container.name === containerName,
- );
-
- if (custom === true) {
- if (containerIndex !== -1) {
- data[containerIndex].icon = `custom/${icon}`;
- await saveData(data);
- } else {
- data.push({ name: containerName, icon: `custom/${icon}` });
- await saveData(data);
- }
- } else if (containerIndex !== -1) {
- data[containerIndex].icon = `${icon}`;
- await saveData(data);
- } else {
- data.push({ name: containerName, icon: `${icon}` });
- await saveData(data);
- }
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg);
- }
-}
-
-async function removeIcon(containerName: string) {
- try {
- const data = await readData();
- const containerIndex = data.findIndex(
- (container) => container.name === containerName,
- );
-
- if (containerIndex !== -1) {
- delete data[containerIndex].icon;
- await saveData(data);
- cleanupData();
- }
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg);
- }
-}
-
-///////////////////////////////////////////////////////////////
-// Data specific functionss
-async function readData() {
- try {
- const data: FrontendConfig = JSON.parse(
- await fs.promises.readFile(dataPath, "utf-8"),
- );
- return data;
- } catch (error: unknown) {
- console.error(`Error while reading ${dataPath}: ${error as Error}`);
- if (error as Error) {
- await saveData([]);
- return [];
- } else {
- throw error;
- }
- }
-}
-
-async function saveData(data: FrontendConfig) {
- try {
- await fs.promises.writeFile(
- dataPath,
- JSON.stringify(data, null, 2),
- "utf-8",
- );
- logger.info("Succesfully wrote to file");
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg);
- }
-}
-
-async function cleanupData() {
- try {
- const data = await readData();
- let cleanedData: FrontendConfig = [];
-
- if (data && Array.isArray(data)) {
- cleanedData = data.filter((container) => {
- // Filter out containers with empty "tags" or containers with only one property (name)
- if (
- container.tags &&
- Array.isArray(container.tags) &&
- container.tags.length === 0
- ) {
- delete container.tags;
- }
- return Object.keys(container).length > 1;
- });
- }
-
- await saveData(cleanedData);
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg);
- }
-}
-
-export {
- hideContainer,
- unhideContainer,
- addTagToContainer,
- removeTagFromContainer,
- pinContainer,
- unpinContainer,
- setLink,
- removeLink,
- setIcon,
- removeIcon,
-};
diff --git a/src/controllers/highAvailability.ts b/src/controllers/highAvailability.ts
deleted file mode 100644
index 45db9d7b..00000000
--- a/src/controllers/highAvailability.ts
+++ /dev/null
@@ -1,285 +0,0 @@
-import logger from "../utils/logger";
-import fs from "fs";
-import chokidar from "chokidar";
-import path from "path";
-import { promisify } from "util";
-import {
- HA_UNSAFE,
- HA_MASTER,
- HA_MASTER_IP,
- HA_NODE,
-} from "../config/variables";
-import { atomicWrite } from "../utils/atomicWrite";
-import { HighAvailabilityConfig, HaNodeConfig, NodeCache } from "../typings/ha";
-
-const sleep = promisify(setTimeout);
-
-const haMasterPath: string = "./src/data/highAvailability.json";
-const haNodePath: string = "./src/data/haNode.json";
-const nodeCachePath: string = "./src/data/nodeCache.json";
-const useUnsafeConnection: boolean = JSON.parse(HA_UNSAFE || "false");
-const lockFilePath: string = "./src/data/ha.lock";
-
-const configFiles: string[] = [
- "./src/data/dockerConfig.json",
- "./src/data/states.json",
- "./src/data/template.json",
- "./src/data/frontendConfiguration.json",
- "./src/data/nodeCache.json",
- "./src/data/usePassword.txt",
- "./src/data/password.json",
-];
-
-const MAX_RETRIES = 10;
-const BASE_DELAY_MS = 100;
-
-async function acquireLock(): Promise {
- let retryCount = 0;
-
- while (fs.existsSync(lockFilePath)) {
- if (retryCount >= MAX_RETRIES) {
- throw new Error(
- "Failed to acquire lock: maximum retry attempts exceeded",
- );
- }
-
- const backoffMs = BASE_DELAY_MS * Math.pow(2, retryCount);
- const jitter = Math.random() * 0.3 * backoffMs;
- const delayMs = backoffMs + jitter;
-
- logger.warn(
- `Lock file exists, waiting ${Math.round(delayMs)}ms before retry ${retryCount + 1}/${MAX_RETRIES}...`,
- );
- await sleep(delayMs);
- retryCount++;
- }
-
- try {
- atomicWrite(lockFilePath, "locked", { exclusive: true });
- logger.debug("Lock acquired.");
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg);
- }
-}
-
-async function releaseLock(): Promise {
- try {
- if (fs.existsSync(lockFilePath)) {
- await fs.promises.unlink(lockFilePath);
- logger.debug("Lock released.");
- }
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg);
- }
-}
-
-async function writeConfig(
- data: HighAvailabilityConfig | NodeCache | HaNodeConfig,
- filePath: string,
-): Promise {
- await acquireLock();
- try {
- logger.debug(`Writing ${filePath}`);
- const dirPath: string = path.dirname(filePath);
- await fs.promises.mkdir(dirPath, { recursive: true });
-
- const jsonData = JSON.stringify(data, null, 2);
- await fs.promises.writeFile(filePath, jsonData);
-
- logger.debug(`${filePath} has been written.`);
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg);
- } finally {
- await releaseLock();
- }
-}
-
-async function readConfig(): Promise {
- await acquireLock();
- try {
- logger.debug("Reading HA-Config");
- const data: HighAvailabilityConfig = JSON.parse(
- fs.readFileSync(haMasterPath, "utf-8"),
- );
- return data;
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg);
- return null;
- } finally {
- await releaseLock();
- }
-}
-
-async function prepareFilesForSync(): Promise> {
- const fileData: Record = {};
- try {
- for (const filePath of configFiles) {
- const content = await fs.promises.readFile(filePath, "utf-8");
- fileData[filePath] = content;
- }
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg);
- }
- return fileData;
-}
-
-async function checkApiReachable(node: string): Promise {
- const nodeUrl =
- useUnsafeConnection === true
- ? `http://${node}/api/status`
- : `https://${node}/api/status`;
-
- logger.info(`Checking node (${nodeUrl}) reachability`);
-
- try {
- const response = await fetch(nodeUrl);
- if (!response.ok) {
- logger.error(`Failed to reach node ${node}. Status: ${response.status}`);
- return false;
- }
-
- const data = await response.json();
- if (data.ApiReachable as boolean) {
- logger.info(`Node ${node} is reachable.`);
- return true;
- } else {
- logger.error(`Node ${node} is not reachable. ApiReachable: false`);
- return false;
- }
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg);
- return false;
- }
-}
-
-async function synchronizeFilesWithNodes(): Promise {
- const haConfig = await readConfig();
-
- if (!haConfig || !haConfig.master || haConfig.nodes.length === 0) {
- logger.warn("No slave nodes to synchronize with.");
- return;
- }
-
- const files = await prepareFilesForSync();
-
- for (const node of haConfig.nodes) {
- if (!(await checkApiReachable(node))) {
- logger.warn(
- `Skipping file sync with ${node} due to connectivity issues.`,
- );
- continue; // Skip synchronization if the node is unreachable
- }
-
- const nodeUrl =
- useUnsafeConnection === true
- ? `http://${node}/ha/sync`
- : `https://${node}/ha/sync`;
-
- logger.info(`Synchronizing files with node: ${node}`);
-
- const response = await fetch(nodeUrl, {
- method: "POST",
- headers: { "Content-Type": "application/json" },
- body: JSON.stringify({ files }),
- });
-
- if (response.ok) {
- logger.info(`Files synchronized successfully with node: ${node}`);
- } else {
- logger.error(
- `Failed to synchronize files with node ${node}. Status: ${response.status}`,
- );
- }
- }
-}
-
-function monitorConfigFiles(): void {
- const watcher = chokidar.watch(configFiles, { persistent: true });
-
- watcher
- .on("change", async (filePath) => {
- logger.info(`File changed: ${filePath}. Initiating synchronization.`);
- await synchronizeFilesWithNodes();
- })
- .on("error", (error) => {
- logger.error(`Error watching files: ${(error as Error).message}`);
- });
-
- logger.info("Started monitoring configuration files for changes.");
-}
-
-async function startMasterNode() {
- if (HA_MASTER == "true") {
- if (!HA_MASTER_IP) {
- logger.error(
- "Master's IP is not set, please set the HA_MASTER_IP variable (example: 10.0.0.4:9876)",
- );
- } else {
- const haNodeConfig: HaNodeConfig = {
- master: HA_MASTER_IP,
- };
- const haConfig: HighAvailabilityConfig = {
- active: true,
- master: true,
- nodes: HA_NODE ? HA_NODE.split(",").map((node) => node.trim()) : [],
- };
-
- const nodeCache: NodeCache = HA_NODE
- ? HA_NODE.split(",").reduce((cache, node, index) => {
- const [ip, port] = node.trim().split(":");
- if (ip && port) {
- cache[`node-${index + 1}`] = { ip, port: parseInt(port, 10) };
- }
- return cache;
- }, {} as NodeCache)
- : {};
-
- logger.debug("Writing HA-Config(s)");
- await writeConfig(haConfig, haMasterPath);
- await writeConfig(haNodeConfig, haNodePath);
- await writeConfig(nodeCache, nodeCachePath);
-
- logger.info("Running startup sync...");
- await synchronizeFilesWithNodes();
- logger.info("Watching config files in ./data");
- monitorConfigFiles();
- }
- } else {
- logger.info("This is a slave node");
- }
-}
-
-async function ensureFileExists(
- filePath: string,
- content: string,
-): Promise {
- await acquireLock();
- try {
- const dirPath = path.dirname(filePath);
- await fs.promises.mkdir(dirPath, { recursive: true });
- await fs.promises.writeFile(filePath, content, { flag: "w" });
- logger.info(`File updated: ${filePath}`);
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg);
- } finally {
- await releaseLock();
- }
-}
-
-export {
- HighAvailabilityConfig,
- writeConfig,
- readConfig,
- prepareFilesForSync,
- synchronizeFilesWithNodes,
- monitorConfigFiles,
- startMasterNode,
- ensureFileExists,
-};
diff --git a/src/controllers/notificationController.ts b/src/controllers/notificationController.ts
deleted file mode 100644
index 0ece9553..00000000
--- a/src/controllers/notificationController.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-import notify from "../utils/notifications/_notify";
-import logger from "../utils/logger";
-import {
- DISCORD_WEBHOOK_URL,
- EMAIL_SENDER,
- EMAIL_RECIPIENT,
- EMAIL_PASSWORD,
- EMAIL_SERVICE,
- PUSHBULLET_ACCESS_TOKEN,
- PUSHOVER_USER_KEY,
- PUSHOVER_API_TOKEN,
- SLACK_WEBHOOK_URL,
- TELEGRAM_BOT_TOKEN,
- TELEGRAM_CHAT_ID,
- WHATSAPP_API_URL,
- WHATSAPP_RECIPIENT,
-} from "../config/variables";
-
-const notificationTypes = {
- discord: !!DISCORD_WEBHOOK_URL,
- email: !!(EMAIL_SENDER && EMAIL_RECIPIENT && EMAIL_PASSWORD && EMAIL_SERVICE),
- pushbullet: !!PUSHBULLET_ACCESS_TOKEN,
- pushover: !!(PUSHOVER_API_TOKEN && PUSHOVER_USER_KEY),
- slack: !!SLACK_WEBHOOK_URL,
- telegram: !!(TELEGRAM_BOT_TOKEN && TELEGRAM_CHAT_ID),
- whatsapp: !!(WHATSAPP_API_URL && WHATSAPP_RECIPIENT),
-};
-
-async function sendNotification(containerId: string) {
- if (notificationTypes.discord) {
- logger.debug(`Sending notification via discord (${containerId})`);
- notify("discord", containerId);
- }
- if (notificationTypes.email) {
- logger.debug(`Sending notification via E-Mail (${containerId})`);
- notify("email", containerId);
- }
- if (notificationTypes.pushbullet) {
- logger.debug(`Sending notification via Pushbullet (${containerId})`);
- notify("pushbullet", containerId);
- }
- if (notificationTypes.pushover) {
- logger.debug(`Sending notification via Pushover (${containerId})`);
- notify("pushover", containerId);
- }
- if (notificationTypes.slack) {
- logger.debug(`Sending notification via Slack (${containerId})`);
- notify("slack", containerId);
- }
- if (notificationTypes.telegram) {
- logger.debug(`Sending notification via Telegram (${containerId})`);
- notify("slack", containerId);
- }
- if (notificationTypes.whatsapp) {
- logger.debug(`Sending notification via Pushbullet (${containerId})`);
- notify("whatsapp", containerId);
- }
-}
-
-export default sendNotification;
diff --git a/src/controllers/proxy.ts b/src/controllers/proxy.ts
deleted file mode 100644
index c091590a..00000000
--- a/src/controllers/proxy.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { Application } from "express";
-import logger from "../utils/logger";
-import { TRUSTED_PROXIES } from "../config/variables";
-
-export default function trustedProxies(app: Application) {
- const trusted: string = TRUSTED_PROXIES;
-
- if (!trusted) {
- logger.warn(
- "No trusted Proxy configured, if ran behind a proxy please configure it according to the docs",
- );
- } else {
- app.set("trust proxy", trusted);
- }
-}
diff --git a/src/controllers/scheduler.ts b/src/controllers/scheduler.ts
deleted file mode 100644
index db450d95..00000000
--- a/src/controllers/scheduler.ts
+++ /dev/null
@@ -1,91 +0,0 @@
-import fetchData from "./fetchData";
-import logger from "../utils/logger";
-import db from "../config/db";
-const regex = /(\d{1,5})([smh])/g;
-
-let fetchInterval = 5 * 60 * 1000; // Fetch data every 5 minutes by default
-const cleanupInterval = 24 * 60 * 60 * 1000; // every 24hrs
-let intervalId: NodeJS.Timeout;
-
-const scheduleFetch = () => {
- try {
- fetchData();
- cleanupOldEntries();
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg);
- }
-
- intervalId = setInterval(() => {
- logger.info(
- `Fetching data at interval of ${fetchInterval / 1000} seconds.`,
- );
- fetchData();
- }, fetchInterval);
-
- setInterval(() => {
- cleanupOldEntries();
- }, cleanupInterval);
-
- logger.info(`Data fetching scheduled every ${fetchInterval / 1000} seconds.`);
- logger.info("Old entries cleanup scheduled every 24 hours.");
-
- // Additional 20-second interval to log process exit listeners, if any
- setInterval(() => {
- const exitListeners = process.listeners("exit");
-
- if (exitListeners.length > 0) {
- logger.info(`Exit listeners detected: ${exitListeners}`);
- }
- }, 20000);
-};
-
-const setFetchInterval = (newInterval: number) => {
- if (intervalId) {
- clearInterval(intervalId);
- logger.info("Cleared existing fetch interval.");
- }
- fetchInterval = newInterval;
- scheduleFetch();
- logger.info(`Fetch interval updated to ${fetchInterval / 1000} seconds.`);
-};
-
-const parseInterval = (interval: string) => {
- const timeUnits: { [key: string]: number } = {
- s: 1000,
- m: 60 * 1000,
- h: 60 * 60 * 1000,
- };
-
- let totalMilliseconds = 0;
- let match;
-
- while ((match = regex.exec(interval))) {
- const value = parseInt(match[1], 10);
- const unit = match[2];
- totalMilliseconds += value * timeUnits[unit];
- }
-
- return totalMilliseconds;
-};
-
-const getCurrentSchedule = () => {
- return {
- interval: fetchInterval / 1000,
- };
-};
-
-const cleanupOldEntries = async () => {
- const twentyFourHoursAgo = new Date(
- Date.now() - 24 * 60 * 60 * 1000,
- ).toISOString();
- try {
- db.run("DELETE FROM data WHERE timestamp < ?", twentyFourHoursAgo, Error);
- logger.info("Old entries cleared from the database.");
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg);
- }
-};
-
-export { scheduleFetch, setFetchInterval, parseInterval, getCurrentSchedule };
diff --git a/src/core/database/helper.ts b/src/core/database/helper.ts
new file mode 100644
index 00000000..3bea0446
--- /dev/null
+++ b/src/core/database/helper.ts
@@ -0,0 +1,17 @@
+import { logger } from "../utils/logger";
+
+export function executeDbOperation(
+ label: string,
+ operation: () => T,
+ validate?: () => void
+): T {
+ const startTime = Date.now();
+ logger.debug(`__task__ __db__ ${label} �3`);
+ if (validate) {
+ validate();
+ }
+ const result = operation();
+ const duration = Date.now() - startTime;
+ logger.debug(`__task__ __db__ ${label} �4f (${duration}ms)`);
+ return result;
+}
\ No newline at end of file
diff --git a/src/core/database/repository.ts b/src/core/database/repository.ts
new file mode 100644
index 00000000..56543cf2
--- /dev/null
+++ b/src/core/database/repository.ts
@@ -0,0 +1,565 @@
+import { executeDbOperation } from "./helper";
+import Database from "bun:sqlite";
+import { logger } from "~/core/utils/logger";
+import { relayController } from "~/core/docker/relay-controller";
+import type { DockerHost, HostStats } from "~/typings/docker";
+import type { stacks_config } from "~/typings/database";
+
+const db = new Database("dockstatapi.db");
+db.exec("PRAGMA journal_mode = WAL;");
+
+export const dbFunctions = {
+ init() {
+ const startTime = Date.now();
+ db.exec(`
+ CREATE TABLE IF NOT EXISTS backend_log_entries (
+ timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
+ level TEXT,
+ message TEXT,
+ file TEXT,
+ line NUMBER
+ );
+
+ CREATE TABLE IF NOT EXISTS stacks_config (
+ name TEXT PRIMARY KEY,
+ version INTEGER,
+ custom BOOLEAN,
+ source TEXT,
+ container_count INTEGER,
+ stack_prefix TEXT,
+ automatic_reboot_on_error BOOLEAN,
+ image_updates BOOLEAN
+ );
+
+ CREATE TABLE IF NOT EXISTS docker_hosts (
+ name TEXT,
+ url TEXT,
+ secure BOOLEAN
+ );
+
+ CREATE TABLE IF NOT EXISTS host_stats (
+ hostId TEXT PRIMARY KEY,
+ dockerVersion TEXT,
+ apiVersion TEXT,
+ os TEXT,
+ architecture TEXT,
+ totalMemory INTEGER,
+ totalCPU INTEGER,
+ labels TEXT,
+ containers INTEGER,
+ containersRunning INTEGER,
+ containersStopped INTEGER,
+ containersPaused INTEGER,
+ images INTEGER
+ );
+
+ CREATE TABLE IF NOT EXISTS container_stats (
+ id TEXT,
+ hostId TEXT,
+ name TEXT,
+ image TEXT,
+ status TEXT,
+ state TEXT,
+ cpu_usage FLOAT,
+ memory_usage FLOAT,
+ timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
+ );
+
+ CREATE TABLE IF NOT EXISTS config (
+ polling_rate NUMBER,
+ keep_data_for NUMBER,
+ fetching_interval NUMBER
+ );
+ `);
+
+ logger.info("Starting server...");
+
+
+ /*
+ * Default values:
+ * - Websocket polling interval 5 seconds
+ * - Data retention value for the database (logs and container stats) 7 days
+ * - Data fetcher for the Database: 5 minutes
+ */
+ const configRow = db
+ .prepare(`SELECT COUNT(*) AS count FROM config`)
+ .get() as { count: number };
+ if (configRow.count === 0) {
+ logger.debug("Initializing default config");
+ const stmt = db.prepare(
+ `
+ INSERT INTO config (polling_rate, keep_data_for, fetching_interval) VALUES (5, 7, 5)
+ `,
+ );
+ stmt.run();
+ }
+
+ const hostRow = db
+ .prepare(`SELECT COUNT(*) AS count FROM docker_hosts WHERE name = ?`)
+ .get("Localhost") as { count: number };
+ if (hostRow.count === 0) {
+ logger.debug("Initializing default docker host (Localhost)");
+ const stmt = db.prepare(
+ `
+ INSERT INTO docker_hosts (name, url, secure) VALUES (?, ?, ?)
+ `,
+ );
+ stmt.run("Localhost", "localhost:2375", false);
+ }
+ logger.debug("__task__ __db__ Initializing Database ⏳")
+ const duration = Date.now() - startTime;
+ logger.debug(`__task__ __db__ Initializing Database ✔️ (${duration}ms)`);
+ },
+
+ addDockerHost(hostId: string, url: string, secure: boolean) {
+ return executeDbOperation(
+ "Add Docker Host",
+ () => {
+ const stmt = db.prepare(`
+ INSERT INTO docker_hosts (name, url, secure)
+ VALUES (?, ?, ?)
+ `);
+ return stmt.run(hostId, url, secure);
+ },
+ () => {
+ if (
+ typeof hostId !== "string" ||
+ typeof url !== "string" ||
+ typeof secure !== "boolean"
+ ) {
+ logger.error("Invalid parameter types for addDockerHost");
+ throw new TypeError("Invalid parameter types for addDockerHost");
+ }
+ }
+ );
+ },
+
+ getDockerHosts(): DockerHost[] {
+ return executeDbOperation(
+ "Get Docker Hosts",
+ () => {
+ const stmt = db.prepare(`
+ SELECT name, url, secure
+ FROM docker_hosts
+ ORDER BY name DESC
+ `);
+ const data = stmt.all();
+ return data as DockerHost[];
+ },
+ () => { }
+ );
+ },
+
+ addLogEntry: (
+ level: string,
+ message: string,
+ file_name: string,
+ line: number,
+ ) => {
+ if (
+ typeof level !== "string" ||
+ typeof message !== "string" ||
+ typeof file_name !== "string" ||
+ typeof line !== "number"
+ ) {
+ logger.crit("Invalid parameter types for addLogEntry");
+ throw new TypeError("Invalid parameter types for addLogEntry");
+ }
+
+ const stmt = db.prepare(`
+ INSERT INTO backend_log_entries (level, message, file, line)
+ VALUES (?, ?, ?, ?)
+ `);
+ return stmt.run(level, message, file_name, line);
+ },
+
+ getAllLogs() {
+ return executeDbOperation(
+ "Get All Logs",
+ () => {
+ const stmt = db.prepare(`
+ SELECT timestamp, level, message, file, line
+ FROM backend_log_entries
+ ORDER BY timestamp DESC
+ `);
+ const data = stmt.all();
+ return data;
+ },
+ () => { }
+ );
+ },
+
+ getLogsByLevel(level: string) {
+ return executeDbOperation(
+ "Get Logs By Level",
+ () => {
+ const stmt = db.prepare(`
+ SELECT timestamp, level, message, file, line
+ FROM backend_log_entries
+ WHERE level = ?
+ ORDER BY timestamp DESC
+ `);
+ const data = stmt.all(level);
+ return data;
+ },
+ () => {
+ if (typeof level !== "string") {
+ logger.error("Level parameter must be a string");
+ throw new TypeError("Level parameter must be a string");
+ }
+ }
+ );
+ },
+
+ updateDockerHost(name: string, url: string, secure: boolean) {
+ return executeDbOperation(
+ "Update Docker Host",
+ () => {
+ const stmt = db.prepare(`
+ UPDATE docker_hosts
+ SET url = ?, secure = ?
+ WHERE name = ?
+ `);
+ const data = stmt.run(url, secure, name);
+ return data;
+ },
+ () => {
+ if (
+ typeof name !== "string" ||
+ typeof url !== "string" ||
+ typeof secure !== "boolean"
+ ) {
+ logger.error("Invalid parameter types for updateDockerHost");
+ throw new TypeError("Invalid parameter types for updateDockerHost");
+ }
+ }
+ );
+ },
+
+ deleteDockerHost(name: string) {
+ return executeDbOperation(
+ "Delete Docker Host",
+ () => {
+ const stmt = db.prepare(`
+ DELETE FROM docker_hosts
+ WHERE name = ?
+ `);
+ const data = stmt.run(name);
+ return data;
+ },
+ () => {
+ if (typeof name !== "string") {
+ logger.error("Invalid parameter type for deleteDockerHost");
+ throw new TypeError("Name parameter must be a string");
+ }
+ }
+ );
+ },
+
+ clearAllLogs() {
+ return executeDbOperation(
+ "Clear All Logs",
+ () => {
+ const stmt = db.prepare(`
+ DELETE FROM backend_log_entries
+ `);
+ const data = stmt.run();
+ return data;
+ },
+ () => { }
+ );
+ },
+
+ clearLogsByLevel(level: string) {
+ return executeDbOperation(
+ "Clear Logs By Level",
+ () => {
+ const stmt = db.prepare(`
+ DELETE FROM backend_log_entries
+ WHERE level = ?
+ `);
+ const data = stmt.run(level);
+ return data;
+ },
+ () => {
+ if (typeof level !== "string") {
+ logger.error("Invalid parameter type for clearLogsByLevel");
+ throw new TypeError("Level parameter must be a string");
+ }
+ }
+ );
+ },
+
+ updateConfig(
+ polling_rate: number,
+ fetching_interval: number,
+ keep_data_for: number
+ ) {
+ return executeDbOperation(
+ "Update Config",
+ () => {
+ const stmt = db.prepare(`
+ UPDATE config
+ SET polling_rate = ?,
+ fetching_interval = ?,
+ keep_data_for = ?
+ `);
+ const data = stmt.run(polling_rate, fetching_interval, keep_data_for);
+ return data;
+ },
+ () => {
+ if (
+ typeof polling_rate !== "number" ||
+ typeof fetching_interval !== "number" ||
+ typeof keep_data_for !== "number"
+ ) {
+ logger.error("Invalid parameter types for updateConfig");
+ throw new TypeError("Invalid parameter types for updateConfig");
+ }
+ }
+ );
+ },
+
+ getConfig() {
+ return executeDbOperation(
+ "Get Config",
+ () => {
+ const stmt = db.prepare(`
+ SELECT polling_rate, keep_data_for, fetching_interval
+ FROM config
+ `);
+ const data = stmt.all();
+ return data;
+ },
+ () => { }
+ );
+ },
+
+ deleteOldData(days: number) {
+ return executeDbOperation(
+ "Delete Old Data",
+ () => {
+ const deleteContainerStmt = db.prepare(`
+ DELETE FROM container_stats
+ WHERE timestamp < datetime('now', '-' || ? || ' days')
+ `);
+ deleteContainerStmt.run(days);
+
+ const deleteLogsStmt = db.prepare(`
+ DELETE FROM backend_log_entries
+ WHERE timestamp < datetime('now', '-' || ? || ' days')
+ `);
+ deleteLogsStmt.run(days);
+ },
+ () => {
+ if (typeof days !== "number") {
+ logger.error("Invalid parameter type for deleteOldData");
+ throw new TypeError("Days parameter must be a number");
+ }
+ }
+ );
+ },
+
+ addContainerStats(
+ id: string,
+ hostId: string,
+ name: string,
+ image: string,
+ status: string,
+ state: string,
+ cpu_usage: number,
+ memory_usage: number
+ ) {
+ return executeDbOperation(
+ "Add Container Stats",
+ () => {
+ const stmt = db.prepare(`
+ INSERT INTO container_stats (id, hostId, name, image, status, state, cpu_usage, memory_usage)
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
+ `);
+ const data = stmt.run(
+ id,
+ hostId,
+ name,
+ image,
+ status,
+ state,
+ cpu_usage,
+ memory_usage
+ );
+ return data;
+ },
+ () => {
+ if (
+ typeof id !== "string" ||
+ typeof hostId !== "string" ||
+ typeof name !== "string" ||
+ typeof image !== "string" ||
+ typeof status !== "string" ||
+ typeof state !== "string" ||
+ typeof cpu_usage !== "number" ||
+ typeof memory_usage !== "number"
+ ) {
+ logger.error("Invalid parameter types for addContainerStats");
+ throw new TypeError("Invalid parameter types for addContainerStats");
+ }
+ }
+ );
+ },
+
+ updateHostStats(stats: HostStats) {
+ return executeDbOperation(
+ "Update Host Stats",
+ () => {
+ const labelsJson = JSON.stringify(stats.labels);
+ const stmt = db.prepare(`
+ INSERT INTO host_stats (
+ hostId,
+ dockerVersion,
+ apiVersion,
+ os,
+ architecture,
+ totalMemory,
+ totalCPU,
+ labels,
+ containers,
+ containersRunning,
+ containersStopped,
+ containersPaused,
+ images
+ )
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+ ON CONFLICT(hostId) DO UPDATE SET
+ dockerVersion = excluded.dockerVersion,
+ apiVersion = excluded.apiVersion,
+ os = excluded.os,
+ architecture = excluded.architecture,
+ totalMemory = excluded.totalMemory,
+ totalCPU = excluded.totalCPU,
+ labels = excluded.labels,
+ containers = excluded.containers,
+ containersRunning = excluded.containersRunning,
+ containersStopped = excluded.containersStopped,
+ containersPaused = excluded.containersPaused,
+ images = excluded.images;
+ `);
+ const data = stmt.run(
+ stats.hostId,
+ stats.dockerVersion,
+ stats.apiVersion,
+ stats.os,
+ stats.architecture,
+ stats.totalMemory,
+ stats.totalCPU,
+ labelsJson,
+ stats.containers,
+ stats.containersRunning,
+ stats.containersStopped,
+ stats.containersPaused,
+ stats.images
+ );
+ return data;
+ },
+ () => { }
+ );
+ },
+
+ addStack(stack_config: stacks_config) {
+ return executeDbOperation(
+ "Add Stack Config",
+ () => {
+ const stmt = db.prepare(`
+ INSERT INTO stacks_config (
+ name,
+ version,
+ custom,
+ source,
+ container_count,
+ stack_prefix,
+ automatic_reboot_on_error,
+ image_updates
+ )
+ VALUES(?, ?, ?, ?, ?, ?, ?, ?)
+ `);
+ const data = stmt.run(
+ stack_config.name,
+ stack_config.version,
+ stack_config.custom,
+ stack_config.source,
+ stack_config.container_count,
+ stack_config.stack_prefix,
+ stack_config.automatic_reboot_on_error,
+ stack_config.image_updates
+ );
+ relayController.stackAdded();
+ return data;
+ },
+ () => { }
+ );
+ },
+
+ getStacks() {
+ return executeDbOperation(
+ "Get Stacks",
+ () => {
+ const stmt = db.prepare(`
+ SELECT name, version, custom, source, container_count, stack_prefix, automatic_reboot_on_error, image_updates
+ FROM stacks_config
+ ORDER BY name DESC
+ `);
+ const data = stmt.all();
+ return data;
+ },
+ () => { }
+ );
+ },
+
+ deleteStack(name: string) {
+ return executeDbOperation(
+ "Delete Stack",
+ () => {
+ const stmt = db.prepare(`
+ DELETE FROM stacks_config
+ WHERE name = ?;
+ `);
+ const data = stmt.run(name);
+ relayController.stackDeleted();
+ return data;
+ },
+ () => { }
+ );
+ },
+
+ updateStack(stack_config: stacks_config) {
+ return executeDbOperation(
+ "Update Stack",
+ () => {
+ const stmt = db.prepare(`
+ UPDATE stacks_config
+ SET
+ version = ?,
+ custom = ?,
+ source = ?,
+ container_count = ?,
+ stack_prefix = ?,
+ automatic_reboot_on_error = ?,
+ image_updates = ?
+ WHERE name = ?;
+ `);
+ const data = stmt.run(
+ stack_config.version,
+ stack_config.custom,
+ stack_config.source,
+ stack_config.container_count,
+ stack_config.stack_prefix,
+ stack_config.automatic_reboot_on_error,
+ stack_config.image_updates,
+ stack_config.name
+ );
+ relayController.stackUpdated();
+ return data;
+ },
+ () => { }
+ );
+ }
+};
diff --git a/src/core/docker/client.ts b/src/core/docker/client.ts
new file mode 100644
index 00000000..ee0d7147
--- /dev/null
+++ b/src/core/docker/client.ts
@@ -0,0 +1,61 @@
+import type { DockerHost } from "~/typings/docker";
+import Docker from "dockerode";
+import { logger } from "~/core/utils/logger";
+
+async function fileExists(path: string): Promise {
+ try {
+ return await Bun.file(path).exists();
+ } catch (error) {
+ return false;
+ }
+}
+
+export const getDockerClient = (host: DockerHost): Docker => {
+ try {
+ const inputUrl = host.url.includes("://") ? host.url : `${host.secure ? "https" : "http"}://${host.url}`;
+ const parsedUrl = new URL(inputUrl);
+ const hostAddress = parsedUrl.hostname;
+ let port = parsedUrl.port ? parseInt(parsedUrl.port) : (host.secure ? 2376 : 2375);
+
+ if (isNaN(port) || port < 1 || port > 65535) {
+ throw new Error("Invalid port number in Docker host URL");
+ }
+
+ return new Docker({
+ protocol: host.secure ? "https" : "http",
+ host: hostAddress,
+ port,
+ version: "v1.41",
+ // TODO: Add TLS configuration if needed
+ });
+ } catch (error) {
+ logger.error("Invalid Docker host URL configuration:", error);
+ throw new Error("Invalid Docker host configuration");
+ }
+};
+
+export const stackClient = async (): Promise => {
+ const socketPath = "/var/run/docker.sock";
+ try {
+ if (!(await fileExists(socketPath))) {
+ throw new Error("Docker socket not found at " + socketPath);
+ }
+
+ const docker = new Docker({
+ socketPath
+ });
+
+ const pingTimeout = 2000;
+ await Promise.race([
+ docker.ping(),
+ new Promise((_, reject) =>
+ setTimeout(() => reject(new Error("Ping timed out")), pingTimeout)
+ )
+ ]);
+
+ return docker;
+ } catch (error) {
+ logger.error(`Could not create Docker client for "${socketPath}" - ${error}`);
+ throw new Error("Failed to create Docker client for local Docker socket");
+ }
+};
diff --git a/src/core/docker/relay-controller.ts b/src/core/docker/relay-controller.ts
new file mode 100644
index 00000000..db8b6bb5
--- /dev/null
+++ b/src/core/docker/relay-controller.ts
@@ -0,0 +1,13 @@
+// Import any function here, when any of the specifies functions is detected, it will run said function
+
+export const relayController = {
+ stackAdded() {
+
+ },
+ stackDeleted() {
+
+ },
+ stackUpdated() {
+
+ }
+}
\ No newline at end of file
diff --git a/src/core/docker/scheduler.ts b/src/core/docker/scheduler.ts
new file mode 100644
index 00000000..e4adf9ce
--- /dev/null
+++ b/src/core/docker/scheduler.ts
@@ -0,0 +1,115 @@
+import storeContainerData from "~/core/docker/store-container-stats";
+import { dbFunctions } from "~/core/database/repository";
+import { config } from "~/typings/database";
+import { logger } from "~/core/utils/logger";
+import storeHostData from "~/core/docker//store-host-stats";
+
+function convertFromMinToMs(minutes: number): number {
+ return minutes * 60 * 1000;
+}
+
+async function initialRun(
+ scheduleName: string,
+ scheduleFunction: Promise | void,
+ isAsync: boolean,
+) {
+ try {
+ if (isAsync) {
+ await scheduleFunction;
+ } else {
+ scheduleFunction;
+ }
+ logger.info(`Startup run success for: ${scheduleName}`);
+ } catch (error) {
+ logger.error(`Startup run failed for ${scheduleName}, ${error as string}`);
+ }
+}
+
+async function setSchedules() {
+ try {
+ const rawConfigData: unknown[] = dbFunctions.getConfig();
+ const configData = rawConfigData[0];
+
+ if (
+ !configData ||
+ typeof (configData as config).keep_data_for !== "number" ||
+ typeof (configData as config).fetching_interval !== "number"
+ ) {
+ logger.error("Invalid configuration data:", configData);
+ throw new Error("Invalid configuration data");
+ }
+
+ const { keep_data_for, fetching_interval } = configData as config;
+
+ if (keep_data_for === undefined) {
+ const errMsg = "keep_data_for is undefined";
+ logger.error(errMsg);
+ throw new Error(errMsg);
+ }
+
+ if (fetching_interval === undefined) {
+ const errMsg = "fetching_interval is undefined";
+ logger.error(errMsg);
+ throw new Error(errMsg);
+ }
+
+ logger.info(
+ `Scheduling: Fetching container statistics every ${fetching_interval} minutes`,
+ );
+
+ logger.info(
+ `Scheduling: Updating host statistics every ${fetching_interval} minutes`,
+ );
+
+ logger.info(
+ `Scheduling: Cleaning up Database every hour and deleting data older then ${keep_data_for} days`,
+ );
+
+ // Schedule container data fetching
+ await initialRun("storeContainerData", storeContainerData(), true);
+ setInterval(async () => {
+ try {
+ logger.info("Task Start: Fetching container data.");
+ await storeContainerData();
+ logger.info("Task End: Container data fetched successfully.");
+ } catch (error) {
+ logger.error("Error in fetching container data:", error);
+ }
+ }, convertFromMinToMs(fetching_interval));
+
+ // Schedule Host statistics updates
+ await initialRun("storeHostData", storeHostData(), true);
+ setInterval(async () => {
+ try {
+ logger.info("Task Start: Updating host stats.");
+ await storeHostData();
+ logger.info("Task End: Updating host stats successfully.");
+ } catch (error) {
+ logger.error("Error in updating host stats:", error);
+ }
+ }, convertFromMinToMs(fetching_interval));
+
+ // Schedule database cleanup
+ await initialRun(
+ "dbFunctions.deleteOldData",
+ dbFunctions.deleteOldData(keep_data_for),
+ false,
+ );
+ setInterval(() => {
+ try {
+ logger.info("Task Start: Cleaning up old database data.");
+ dbFunctions.deleteOldData(keep_data_for);
+ logger.info("Task End: Database cleanup completed.");
+ } catch (error) {
+ logger.error("Error in database cleanup task:", error);
+ }
+ }, convertFromMinToMs(60));
+
+ logger.info("Schedules have been set successfully.");
+ } catch (error) {
+ logger.error("Error setting schedules:", error);
+ throw error;
+ }
+}
+
+export { setSchedules };
diff --git a/src/core/docker/store-container-stats.ts b/src/core/docker/store-container-stats.ts
new file mode 100644
index 00000000..e64f31bc
--- /dev/null
+++ b/src/core/docker/store-container-stats.ts
@@ -0,0 +1,96 @@
+import { getDockerClient } from "~/core/docker/client";
+import { dbFunctions } from "~/core/database/repository";
+import Docker from "dockerode";
+import {
+ calculateCpuPercent,
+ calculateMemoryUsage,
+} from "~/core/utils/calculations";
+
+async function storeContainerData() {
+ try {
+ const hosts = dbFunctions.getDockerHosts();
+
+ // Process each host concurrently and wait for them all to finish
+ await Promise.all(
+ hosts.map(async (host) => {
+ const docker = getDockerClient(host);
+
+ // Test the connection with a ping
+ try {
+ await docker.ping();
+ } catch (error) {
+ const errMsg = error instanceof Error ? error.message : String(error);
+ throw new Error(
+ `Failed to ping docker host "${host.name}": ${errMsg}`,
+ );
+ }
+
+ let containers;
+ try {
+ containers = await docker.listContainers({ all: true });
+ } catch (error) {
+ const errMsg = error instanceof Error ? error.message : String(error);
+ throw new Error(
+ `Failed to list containers on host "${host.name}": ${errMsg}`,
+ );
+ }
+
+ // Process each container concurrently
+ await Promise.all(
+ containers.map(async (containerInfo) => {
+ const containerName = containerInfo.Names[0].replace(/^\//, "");
+ try {
+ const container = docker.getContainer(containerInfo.Id);
+
+ const stats: Docker.ContainerStats = await new Promise(
+ (resolve, reject) => {
+ container.stats({ stream: false }, (error, stats) => {
+ if (error) {
+ const errMsg =
+ error instanceof Error ? error.message : String(error);
+ return reject(
+ new Error(
+ `Failed to get stats for container "${containerName}" (ID: ${containerInfo.Id}) on host "${host.name}": ${errMsg}`,
+ ),
+ );
+ }
+ if (!stats) {
+ return reject(
+ new Error(
+ `No stats returned for container "${containerName}" (ID: ${containerInfo.Id}) on host "${host.name}".`,
+ ),
+ );
+ }
+ resolve(stats);
+ });
+ },
+ );
+
+ dbFunctions.addContainerStats(
+ containerInfo.Id,
+ host.name,
+ containerName,
+ containerInfo.Image,
+ containerInfo.Status,
+ containerInfo.State,
+ calculateCpuPercent(stats),
+ calculateMemoryUsage(stats),
+ );
+ } catch (error) {
+ const errMsg =
+ error instanceof Error ? error.message : String(error);
+ throw new Error(
+ `Error processing container "${containerName}" (ID: ${containerInfo.Id}) on host "${host.name}": ${errMsg}`,
+ );
+ }
+ }),
+ );
+ }),
+ );
+ } catch (error) {
+ const errMsg = error instanceof Error ? error.message : String(error);
+ throw new Error(`Failed to store container data: ${errMsg}`);
+ }
+}
+
+export default storeContainerData;
diff --git a/src/core/docker/store-host-stats.ts b/src/core/docker/store-host-stats.ts
new file mode 100644
index 00000000..f8cd3527
--- /dev/null
+++ b/src/core/docker/store-host-stats.ts
@@ -0,0 +1,68 @@
+import { logger } from "~/core/utils/logger";
+import { dbFunctions } from "~/core/database/repository";
+import { DockerHost, HostStats } from "~/typings/docker";
+import { getDockerClient } from "~/core/docker/client";
+import { DockerInfo } from "~/typings/dockerode";
+
+async function storeHostData() {
+ try {
+ const hosts = dbFunctions.getDockerHosts() as DockerHost[];
+
+ await Promise.all(
+ hosts.map(async (host) => {
+ const docker = getDockerClient(host);
+
+ try {
+ await docker.ping();
+ } catch (error) {
+ const errMsg = error instanceof Error ? error.message : String(error);
+ throw new Error(
+ `Failed to ping docker host "${host.name}": ${errMsg}`,
+ );
+ }
+
+ let hostStats: DockerInfo;
+ let stats: HostStats;
+ try {
+ hostStats = await docker.info();
+ } catch (error) {
+ const errMsg = error instanceof Error ? error.message : String(error);
+ throw new Error(
+ `Failed to fetch stats for host "${host.name}": ${errMsg}`,
+ );
+ }
+
+ try {
+ const stats: HostStats = {
+ hostId: host.name,
+ dockerVersion: hostStats.ServerVersion,
+ apiVersion: hostStats.Driver,
+ os: hostStats.OperatingSystem,
+ architecture: hostStats.Architecture,
+ totalMemory: hostStats.MemTotal,
+ totalCPU: hostStats.NCPU,
+ labels: hostStats.Labels,
+ images: hostStats.Images,
+ containers: hostStats.Containers,
+ containersPaused: hostStats.ContainersPaused,
+ containersRunning: hostStats.ContainersRunning,
+ containersStopped: hostStats.ContainersStopped,
+ };
+
+ dbFunctions.updateHostStats(stats);
+ } catch (error) {
+ const errMsg = error instanceof Error ? error.message : String(error);
+ throw new Error(
+ `Failed to store stats for host "${host.name}": ${errMsg}`,
+ );
+ }
+ }),
+ );
+ } catch (error) {
+ const errMsg = error instanceof Error ? error.message : String(error);
+ logger.error(`storeHostData failed: ${errMsg}`);
+ throw new Error(`Failed to store host data: ${errMsg}`);
+ }
+}
+
+export default storeHostData;
diff --git a/src/core/plugins/loader.ts b/src/core/plugins/loader.ts
new file mode 100644
index 00000000..db77bedd
--- /dev/null
+++ b/src/core/plugins/loader.ts
@@ -0,0 +1,38 @@
+import { pluginManager } from "./plugin-manager";
+import path from "path";
+import fs from "fs";
+import { logger } from "../utils/logger";
+import { checkFileForChangeMe } from "../utils/change-me-checker";
+
+export async function loadPlugins(pluginDir: string) {
+ const pluginPath = path.join(process.cwd(), pluginDir);
+
+ logger.debug(`Loading plugins (${pluginPath})`);
+ if (!fs.existsSync(pluginPath)) {
+ return;
+ }
+
+ let pluginCount = 0;
+ const files = fs.readdirSync(pluginPath);
+
+ for (const file of files) {
+ if (!file.endsWith(".plugin.ts")) {
+ continue
+ };
+
+ const absolutePath = path.join(pluginPath, file);
+ try {
+ await checkFileForChangeMe(absolutePath);
+ const module = await import(absolutePath);
+ const plugin = module.default;
+ pluginManager.register(plugin);
+ pluginCount++;
+ } catch (error) {
+ logger.error(
+ `Error while importing plugin ${absolutePath}: ${error as string}`,
+ );
+ }
+ }
+
+ logger.info(`Registered ${pluginCount} plugin(s)`);
+}
diff --git a/src/core/plugins/plugin-actions.ts b/src/core/plugins/plugin-actions.ts
new file mode 100644
index 00000000..0b2f9357
--- /dev/null
+++ b/src/core/plugins/plugin-actions.ts
@@ -0,0 +1,10 @@
+import { pluginManager } from "./plugin-manager";
+
+export const pluginAction = {
+ containerStart(containerInfo: any) {
+ pluginManager.handleContainerStart(containerInfo);
+ },
+ metricsReceived(metrics: any) {
+ pluginManager.handleMetrics(metrics);
+ },
+};
diff --git a/src/core/plugins/plugin-manager.ts b/src/core/plugins/plugin-manager.ts
new file mode 100644
index 00000000..614604af
--- /dev/null
+++ b/src/core/plugins/plugin-manager.ts
@@ -0,0 +1,98 @@
+import { EventEmitter } from "events";
+import { logger } from "../utils/logger";
+import type { Plugin } from "~/typings/plugin";
+import type { ContainerInfo, HostStats } from "~/typings/docker";
+
+export class PluginManager extends EventEmitter {
+ private plugins: Map = new Map();
+
+ register(plugin: Plugin) {
+ try {
+ this.plugins.set(plugin.name, plugin);
+ logger.debug(`Registered plugin: ${plugin.name}`);
+ } catch (error) {
+ logger.error(
+ `Registering plugin ${plugin.name} failed: ${error as string}`,
+ );
+ }
+ }
+
+ unregister(name: string) {
+ this.plugins.delete(name);
+ }
+
+ // Trigger plugin flows:
+ handleContainerStop(containerInfo: ContainerInfo) {
+ this.plugins.forEach((plugin) => {
+ plugin.onContainerStop?.(containerInfo);
+ });
+ }
+
+ handleContainerExit(containerInfo: ContainerInfo) {
+ this.plugins.forEach((plugin) => {
+ plugin.onContainerExit?.(containerInfo);
+ });
+ }
+
+ handleContainerCreate(containerInfo: ContainerInfo) {
+ this.plugins.forEach((plugin) => {
+ plugin.onContainerCreate?.(containerInfo);
+ });
+ }
+
+ handleContainerDestroy(containerInfo: ContainerInfo) {
+ this.plugins.forEach((plugin) => {
+ plugin.onContainerDestroy?.(containerInfo);
+ });
+ }
+
+ handleContainerPause(containerInfo: ContainerInfo) {
+ this.plugins.forEach((plugin) => {
+ plugin.onContainerPause?.(containerInfo);
+ });
+ }
+
+ handleContainerUnpause(containerInfo: ContainerInfo) {
+ this.plugins.forEach((plugin) => {
+ plugin.onContainerUnpause?.(containerInfo);
+ });
+ }
+
+ handleContainerRestart(containerInfo: ContainerInfo) {
+ this.plugins.forEach((plugin) => {
+ plugin.onContainerRestart?.(containerInfo);
+ });
+ }
+
+ handleContainerUpdate(containerInfo: ContainerInfo) {
+ this.plugins.forEach((plugin) => {
+ plugin.onContainerUpdate?.(containerInfo);
+ });
+ }
+
+ handleContainerRename(containerInfo: ContainerInfo) {
+ this.plugins.forEach((plugin) => {
+ plugin.onContainerRename?.(containerInfo);
+ });
+ }
+
+ handleContainerHealthStatus(containerInfo: ContainerInfo) {
+ this.plugins.forEach((plugin) => {
+ plugin.onContainerHealthStatus?.(containerInfo);
+ });
+ }
+
+ handleHostUnreachable(HostStats: HostStats) {
+ this.plugins.forEach((plugin) => {
+ plugin.onHostUnreachable?.(HostStats);
+ });
+ }
+
+ handleHostReachableAgain(HostStats: HostStats) {
+ this.plugins.forEach((plugin) => {
+ plugin.onHostReachableAgain?.(HostStats);
+ });
+ }
+}
+
+export const pluginManager = new PluginManager();
diff --git a/src/core/stacks/controller.ts b/src/core/stacks/controller.ts
new file mode 100644
index 00000000..2ff5edb9
--- /dev/null
+++ b/src/core/stacks/controller.ts
@@ -0,0 +1,134 @@
+import { dbFunctions } from "../database/repository";
+import YAML from "yaml";
+import { logger } from "../utils/logger";
+import DockerCompose from "docker-compose";
+import type { Stack, ComposeSpec } from "~/typings/docker-compose";
+import type { stacks_config } from "~/typings/database";
+
+async function getStackPath(stack: Stack): Promise {
+ const stackName = stack.name.trim().replace(/\s+/g, "_");
+ return `stacks/${stackName}`;
+}
+
+async function createStackYAML(compose_spec: Stack): Promise {
+ const yaml = YAML.stringify(compose_spec.compose_spec);
+ const stackPath = await getStackPath(compose_spec);
+ await Bun.write(`${stackPath}/docker-compose.yaml`, yaml, { createPath: true });
+}
+
+export async function deployStack(
+ stack: ComposeSpec,
+ name: string,
+ version: number,
+ source: string,
+ automatic_reboot_on_error: boolean,
+ isCustom: boolean,
+ image_updates: boolean,
+ stack_prefix?: string
+): Promise {
+ try {
+ logger.debug(`Deploying Stack: ${JSON.stringify(stack)}`)
+
+ const serviceCount = stack.services
+ ? Object.keys(stack.services).length
+ : 0;
+
+ const resolvedPrefix = stack_prefix ?? "";
+
+ const stack_config: stacks_config = {
+ name: name,
+ version: version,
+ source,
+ stack_prefix: resolvedPrefix,
+ automatic_reboot_on_error,
+ container_count: serviceCount,
+ custom: isCustom,
+ image_updates,
+ };
+
+ if (!stack.name) {
+ logger.debug(`${JSON.stringify(stack)}`)
+ throw new Error("Stack name needed")
+ }
+
+ dbFunctions.addStack(stack_config);
+
+ const stackYaml: Stack = {
+ name: name,
+ source: source,
+ version: version,
+ compose_spec: stack,
+ }
+ await createStackYAML(stackYaml);
+ const stackPath = await getStackPath(stackYaml);
+ await DockerCompose.upAll({ cwd: stackPath });
+ } catch (error: any) {
+ throw new Error(`Error while deploying Stack: ${error.message || error}`);
+ }
+}
+
+export async function stopStack(stack_name: string): Promise {
+ try {
+ const stack = {
+ name: stack_name
+ }
+ const stackPath = await getStackPath(stack as Stack);
+ await DockerCompose.downAll({ cwd: stackPath });
+ } catch (error: any) {
+ throw new Error(`Error while stopping stack "${stack_name}": ${error.message || error}`);
+ }
+}
+
+export async function startStack(stack_name: string): Promise {
+ try {
+ const stack = {
+ name: stack_name
+ }
+ const stackPath = await getStackPath(stack as Stack);
+ await DockerCompose.upAll({ cwd: stackPath });
+ } catch (error: any) {
+ throw new Error(`Error while starting stack "${stack_name}": ${error.message || error}`);
+ }
+}
+
+export async function pullStackImages(stack_name: string): Promise {
+ try {
+ const stack = {
+ name: stack_name
+ }
+ const stackPath = await getStackPath(stack as Stack);
+ await DockerCompose.pullAll({ cwd: stackPath });
+ } catch (error: any) {
+ throw new Error(`Error while pulling images for stack "${stack_name}": ${error.message || error}`);
+ }
+}
+
+export async function restartStack(stack_name: string): Promise {
+ try {
+ const stack = {
+ name: stack_name
+ }
+ const stackPath = await getStackPath(stack as Stack);
+ await DockerCompose.restartAll({ cwd: stackPath });
+ } catch (error: any) {
+ throw new Error(`Error while restarting stack "${stack_name}": ${error.message || error}`);
+ }
+}
+
+export async function getStackStatus(stack_name: string): Promise {
+ try {
+ logger.debug("Retrieving status for Stack:", stack_name);
+ const stackYaml = { name: stack_name };
+ const stackPath = await getStackPath(stackYaml as Stack);
+ const rawStatus = await DockerCompose.ps({ cwd: stackPath });
+
+ return rawStatus.data.services.reduce((acc: any, service: any) => {
+ acc[(service.name)] = service.state;
+ return acc;
+ }, {});
+
+ } catch (error: any) {
+ throw new Error(`Error while retrieving status for stack "${stack_name}": ${error.message || error}`);
+ }
+}
+
diff --git a/src/core/utils/calculations.ts b/src/core/utils/calculations.ts
new file mode 100644
index 00000000..3ead3a6d
--- /dev/null
+++ b/src/core/utils/calculations.ts
@@ -0,0 +1,16 @@
+import type Docker from "dockerode";
+
+const calculateCpuPercent = (stats: Docker.ContainerStats): number => {
+ const cpuDelta =
+ stats.cpu_stats.cpu_usage.total_usage -
+ stats.precpu_stats.cpu_usage.total_usage;
+ const systemDelta =
+ stats.cpu_stats.system_cpu_usage - stats.precpu_stats.system_cpu_usage;
+ return (cpuDelta / systemDelta) * 100;
+};
+
+const calculateMemoryUsage = (stats: Docker.ContainerStats): number => {
+ return (stats.memory_stats.usage / stats.memory_stats.limit) * 100;
+};
+
+export { calculateCpuPercent, calculateMemoryUsage };
diff --git a/src/core/utils/change-me-checker.ts b/src/core/utils/change-me-checker.ts
new file mode 100644
index 00000000..fa19520b
--- /dev/null
+++ b/src/core/utils/change-me-checker.ts
@@ -0,0 +1,16 @@
+import { readFile } from "fs/promises";
+import { logger } from "~/core/utils/logger";
+
+export async function checkFileForChangeMe(filePath: string) {
+ const regex = /change[\W_]*me/i;
+ let content = "";
+ try {
+ content = await readFile(filePath, "utf-8");
+ } catch (error) {
+ logger.error("Error reading file:", error);
+ }
+
+ if (regex.test(content)) {
+ throw new Error(`Error: The file contains 'CHANGE_ME'. Please update it.`);
+ }
+}
diff --git a/src/core/utils/logger.ts b/src/core/utils/logger.ts
new file mode 100644
index 00000000..b35aeeae
--- /dev/null
+++ b/src/core/utils/logger.ts
@@ -0,0 +1,113 @@
+import { createLogger, format, transports } from "winston";
+import path from "path";
+import chalk, { ChalkInstance } from "chalk";
+import { dbFunctions } from "../database/repository";
+import wrapAnsi from "wrap-ansi";
+
+// Change to false here if dont want the spacing on a wrapped line
+const padNewlines: boolean = true;
+
+const fileLineFormat = format((info) => {
+ try {
+ const stack = new Error().stack?.split("\n");
+ if (stack) {
+ for (let i = 2; i < stack.length; i++) {
+ const line = stack[i].trim();
+ // Exclude lines from node_modules or the current file
+ if (!line.includes("node_modules") && !line.includes(path.basename(__filename))) {
+ const matches = line.match(/\(?(.+):(\d+):(\d+)\)?$/);
+ if (matches) {
+ info.file = path.basename(matches[1]);
+ info.line = parseInt(matches[2], 10);
+ break;
+ }
+ }
+ }
+ }
+ } catch (err) {
+ // Ignore errors during stack trace extraction
+ }
+ return info;
+});
+
+const formatTerminalMessage = (message: string, prefixLength: number) => {
+ const maxWidth = process.stdout.columns || 80;
+ const wrapWidth = maxWidth - prefixLength - 15;
+
+ if (padNewlines) {
+ const wrapped = wrapAnsi(chalk.gray(message), wrapWidth, {
+ trim: true,
+ hard: true,
+ });
+
+ return wrapped
+ .split("\n")
+ .map((line, i) => (i === 0 ? line : " ".repeat(prefixLength) + line))
+ .join("\n");
+ }
+ return message;
+};
+
+export const logger = createLogger({
+ level: process.env.LOG_LEVEL || 'debug',
+ format: format.combine(
+ format.timestamp({ format: "DD/MM HH:mm:ss" }),
+ fileLineFormat(),
+ format.printf(({ timestamp, level, message, file, line }) => {
+
+ const levelColors: Record = {
+ error: chalk.red.bold,
+ warn: chalk.yellow.bold,
+ info: chalk.green.bold,
+ debug: chalk.blue.bold,
+ verbose: chalk.cyan.bold,
+ silly: chalk.magenta.bold,
+ task: chalk.cyan.bold
+ };
+
+ if ((message as string).startsWith("__task__")) {
+ message = (message as string).replaceAll("__task__", "").trimStart();
+ level = "task"
+ if ((message as string).startsWith("__db__")) {
+ message = (message as string).replaceAll("__db__", "").trimStart();
+ message = `${chalk.magenta("DB")} ${message}`
+ }
+ }
+
+ const paddedLevel = level.toUpperCase().padEnd(5);
+ const coloredLevel = (levelColors[level] || chalk.white)(paddedLevel);
+ const coloredContext = chalk.cyan(`${file as string}:${line as number}`);
+ const coloredTimestamp = chalk.yellow(timestamp);
+
+ if (process.env.NODE_ENV !== "dev") {
+ return `${coloredLevel} [ ${coloredTimestamp} ] - ${chalk.gray(
+ message
+ )} - [ ${coloredContext} ]`;
+ }
+
+ const prefix = `${paddedLevel} [ ${timestamp} ] - `;
+ const prefixLength = prefix.length;
+ const formattedMessage = formatTerminalMessage(
+ message as string,
+ prefixLength
+ );
+ const ansiRegex = /\x1B\[[0-?9;]*[mG]/g;
+
+ try {
+ dbFunctions.addLogEntry(
+ (level as string).replace(ansiRegex, ''),
+ (message as string).replace(ansiRegex, ''),
+ (file as string).replace(ansiRegex, ''),
+ line as number
+ );
+ } catch (error) {
+ // Use console.error to avoid recursive logging
+ console.error(`Error inserting log into DB: ${String(error)}`);
+ process.abort()
+ }
+
+ return `${coloredLevel} [ ${coloredTimestamp} ] - ${formattedMessage} - [ ${coloredContext} ]`;
+ })
+ ),
+ transports: [new transports.Console()],
+});
diff --git a/src/core/utils/package-json.ts b/src/core/utils/package-json.ts
new file mode 100644
index 00000000..3872d561
--- /dev/null
+++ b/src/core/utils/package-json.ts
@@ -0,0 +1,18 @@
+import packageJson from "~/../package.json";
+const { version, description, license, contributors, dependencies, devDependencies } = packageJson;
+
+const authorName = packageJson.author.name;
+const authorEmail = packageJson.author.email;
+const authorWebsite = packageJson.author.url;
+
+export {
+ version,
+ description,
+ authorName,
+ authorEmail,
+ authorWebsite,
+ license,
+ contributors,
+ dependencies,
+ devDependencies,
+};
diff --git a/src/core/utils/respone-handler.ts b/src/core/utils/respone-handler.ts
new file mode 100644
index 00000000..93e0cdbe
--- /dev/null
+++ b/src/core/utils/respone-handler.ts
@@ -0,0 +1,46 @@
+import { logger } from "~/core/utils/logger";
+import type { HTTPHeaders } from "elysia/dist/types";
+import type { ElysiaCookie } from "elysia/dist/cookies";
+import type { StatusMap } from "elysia";
+
+interface set {
+ headers: HTTPHeaders;
+ status?: number | keyof StatusMap;
+ redirect?: string;
+ cookie?: Record;
+}
+
+export const responseHandler = {
+ error(
+ set: set,
+ error: string,
+ response_message: string,
+ error_code?: number,
+ ) {
+ set.status = error_code || 500;
+ logger.error(`${response_message} - ${error}`);
+ return { error: `${response_message}` };
+ },
+
+ ok(set: set, response_message: string) {
+ set.status = 200;
+ logger.debug(response_message);
+ return { success: true };
+ },
+
+ simple_error(set: set, response_massage: string, status_code?: number) {
+ set.status = status_code || 502;
+ logger.warn(response_massage);
+ return { error: response_massage };
+ },
+
+ reject(set: set, reject: any, response_message: string, error?: string) {
+ set.status = 501;
+ if (error) {
+ logger.error(`${response_message} - ${error}`);
+ } else {
+ logger.error(response_message);
+ }
+ return reject(new Error(response_message));
+ },
+};
diff --git a/src/data/frontendConfiguration.json b/src/data/frontendConfiguration.json
deleted file mode 100644
index 0637a088..00000000
--- a/src/data/frontendConfiguration.json
+++ /dev/null
@@ -1 +0,0 @@
-[]
\ No newline at end of file
diff --git a/src/data/template.json b/src/data/template.json
deleted file mode 100644
index 75e12f22..00000000
--- a/src/data/template.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "text": "{{name}} is {{state}} on {{hostName}}"
-}
diff --git a/src/data/usePassword.txt b/src/data/usePassword.txt
deleted file mode 100644
index 02e4a84d..00000000
--- a/src/data/usePassword.txt
+++ /dev/null
@@ -1 +0,0 @@
-false
\ No newline at end of file
diff --git a/src/handlers/api.ts b/src/handlers/api.ts
deleted file mode 100644
index fa7f1f7e..00000000
--- a/src/handlers/api.ts
+++ /dev/null
@@ -1,142 +0,0 @@
-import extractRelevantData from "../utils/extractHostData";
-import { Request, Response } from "express";
-import { getDockerClient } from "../utils/dockerClient";
-import { fetchAllContainers } from "../utils/containerService";
-import { getCurrentSchedule } from "../controllers/scheduler";
-import fs from "fs";
-import checkReachability from "../utils/connectionChecker";
-const configPath = "./src/data/dockerConfig.json";
-const userConf = "./src/data/user.conf";
-import { dockerConfig } from "../typings/dockerConfig";
-import { createResponseHandler } from "./response";
-
-class ApiHandler {
- private req: Request;
- private res: Response;
-
- constructor(req: Request, res: Response) {
- this.req = req;
- this.res = res;
- }
-
- hosts() {
- const ResponseHandler = createResponseHandler(this.res);
- try {
- const rawData = fs.readFileSync(configPath, "utf-8");
- const config: dockerConfig = JSON.parse(rawData);
-
- if (!config.hosts) {
- return ResponseHandler.error("No hosts defined in configuration.", 400);
- }
-
- const hosts = config.hosts.map((host) => host.name);
- return ResponseHandler.rawData(hosts, "Fetched data for all hosts");
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
- }
-
- system() {
- const ResponseHandler = createResponseHandler(this.res);
- try {
- const rawData = fs.readFileSync(userConf, "utf8");
- const config = JSON.parse(rawData);
-
- if (!config) {
- return ResponseHandler.error("Received empty configuration", 400);
- }
-
- return ResponseHandler.rawData(config, "Fetched system configuration");
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
- }
-
- async hostStats(hostName: string) {
- const ResponseHandler = createResponseHandler(this.res);
- try {
- const docker = getDockerClient(hostName);
- const info = await docker.info();
- const version = await docker.version();
- const relevantData = extractRelevantData({ hostName, info, version });
-
- if (!relevantData) {
- ResponseHandler.error("No host found", 404);
- }
-
- return ResponseHandler.rawData(relevantData, "Fetched Host stats");
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
- }
-
- async containers() {
- const ResponseHandler = createResponseHandler(this.res);
- try {
- const allContainerData = await fetchAllContainers();
- return ResponseHandler.rawData(
- allContainerData,
- "Fetched all containers across all hosts",
- );
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
- }
-
- async config() {
- const ResponseHandler = createResponseHandler(this.res);
- try {
- const rawData = fs.readFileSync(configPath);
- const data = JSON.parse(rawData.toString());
- return ResponseHandler.rawData(data, "Fetched config");
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
- }
-
- currentSchedule() {
- const ResponseHandler = createResponseHandler(this.res);
- try {
- const currentSchedule = getCurrentSchedule();
- return ResponseHandler.rawData(
- currentSchedule,
- "Fetched current schedule",
- );
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
- }
-
- async status() {
- const ResponseHandler = createResponseHandler(this.res);
- try {
- const data = await checkReachability();
- return ResponseHandler.rawData(data, "Fetched Status");
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
- }
-
- frontendConfig() {
- const configPath: string = "./src/data/frontendConfiguration.json";
- const ResponseHandler = createResponseHandler(this.res);
- try {
- const rawData = fs.readFileSync(configPath);
- const data = JSON.parse(rawData.toString());
- return ResponseHandler.rawData(data, "Fetched frontend configuration");
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
- }
-}
-
-export const createApiHandler = (req: Request, res: Response) =>
- new ApiHandler(req, res);
diff --git a/src/handlers/auth.ts b/src/handlers/auth.ts
deleted file mode 100644
index 4dfbd3fb..00000000
--- a/src/handlers/auth.ts
+++ /dev/null
@@ -1,72 +0,0 @@
-import { Request, Response } from "express";
-import {
- authEnabled,
- readPasswordFile,
- writePasswordFile,
- setFalse,
-} from "../controllers/auth";
-import { createResponseHandler } from "./response";
-import bcrypt from "bcrypt";
-
-const saltRounds: number = 10;
-
-class AuthenticationHandler {
- private req: Request;
- private res: Response;
-
- constructor(req: Request, res: Response) {
- this.req = req;
- this.res = res;
- }
-
- async enable(password: string) {
- const ResponseHandler = createResponseHandler(this.res);
- try {
- if (await authEnabled()) {
- return ResponseHandler.denied(
- "Password Authentication is already enabled, please deactivate it first",
- );
- }
-
- if (!password) {
- return ResponseHandler.denied("Password is required");
- }
-
- const salt = await bcrypt.genSalt(saltRounds);
- const hash = await bcrypt.hash(password, salt);
-
- const passwordData = { hash, salt };
- writePasswordFile(JSON.stringify(passwordData));
-
- return ResponseHandler.ok("Authentication enabled successfully");
- } catch (error) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
- }
-
- async disable(password: string) {
- const ResponseHandler = createResponseHandler(this.res);
- try {
- if (!password) {
- return ResponseHandler.denied("Password is required");
- }
-
- const storedData = JSON.parse(await readPasswordFile());
- const isPasswordValid = await bcrypt.compare(password, storedData.hash);
-
- if (!isPasswordValid) {
- return ResponseHandler.error("Invalid password", 401);
- }
-
- await setFalse();
- return ResponseHandler.ok("Authentication disabled successfully");
- } catch (error) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
- }
-}
-
-export const createAuthenticationHandler = (req: Request, res: Response) =>
- new AuthenticationHandler(req, res);
diff --git a/src/handlers/conf.ts b/src/handlers/conf.ts
deleted file mode 100644
index b49dd2a5..00000000
--- a/src/handlers/conf.ts
+++ /dev/null
@@ -1,98 +0,0 @@
-import { setFetchInterval, parseInterval } from "../controllers/scheduler";
-import { Request, Response } from "express";
-import fs from "fs";
-import { createResponseHandler } from "./response";
-import { target, dockerConfig } from "../typings/dockerConfig";
-const configPath: string = "./src/data/dockerConfig.json";
-
-class ConfHandler {
- private req: Request;
- private res: Response;
-
- constructor(req: Request, res: Response) {
- this.req = req;
- this.res = res;
- }
-
- addHost(req: Request) {
- const ResponseHandler = createResponseHandler(this.res);
-
- try {
- const { name, url, port } = req.query as unknown as target;
- if (!name || !url || !port) {
- return ResponseHandler.error("Name, Port, and URL are required.", 400);
- }
-
- const config: dockerConfig = JSON.parse(
- fs.readFileSync(configPath, "utf-8"),
- );
-
- if (config.hosts.some((host) => host.name === name)) {
- return ResponseHandler.error("Host already exists.", 422);
- }
-
- config.hosts.push({ name, url, port });
- fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
-
- return ResponseHandler.ok("Host added successfully.");
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
- }
-
- removeHost(req: Request) {
- const ResponseHandler = createResponseHandler(this.res);
- try {
- const hostName = req.query.hostName as string;
-
- if (!hostName) {
- return ResponseHandler.error("Host name is required.", 401);
- }
-
- const currentState = fs.readFileSync(configPath, "utf-8");
- const config: dockerConfig = JSON.parse(currentState);
-
- const hostIndex = config.hosts.findIndex(
- (host) => host.name === hostName,
- );
-
- if (hostIndex === -1) {
- return ResponseHandler.error("Host not found.", 404);
- }
-
- config.hosts.splice(hostIndex, 1);
-
- fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
-
- return ResponseHandler.ok("Host removed successfully.");
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
- }
-
- scheduler(req: Request) {
- const ResponseHandler = createResponseHandler(this.res);
- try {
- const interval = req.query.interval as string;
- const newInterval = parseInterval(interval);
-
- if (newInterval < 5 * 60 * 1000 || newInterval > 6 * 60 * 60 * 1000) {
- return ResponseHandler.error(
- "Interval must be between 5 minutes and 6 hours.",
- 401,
- );
- }
-
- setFetchInterval(newInterval);
- return ResponseHandler.ok("Updated interval");
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
- }
-}
-
-export const createConfHandler = (req: Request, res: Response) =>
- new ConfHandler(req, res);
diff --git a/src/handlers/data.ts b/src/handlers/data.ts
deleted file mode 100644
index 5d3bf41c..00000000
--- a/src/handlers/data.ts
+++ /dev/null
@@ -1,123 +0,0 @@
-import { Response, Request } from "express";
-import db from "../config/db";
-import { Table, DataRow } from "../typings/table";
-import { createResponseHandler } from "./response";
-import logger from "../utils/logger";
-
-function formatRows(rows: DataRow[]): Record {
- return rows.reduce(
- (
- acc: Record,
- row,
- index: number,
- ): Record => {
- acc[index] = JSON.parse(row.info);
- return acc;
- },
- {},
- );
-}
-
-class DatabaseHandler {
- private req: Request;
- private res: Response;
-
- constructor(req: Request, res: Response) {
- this.req = req;
- this.res = res;
- }
-
- latest() {
- const ResponseHandler = createResponseHandler(this.res);
- db.get(
- "SELECT info FROM data ORDER BY timestamp DESC LIMIT 1",
- (error: unknown, row: Partial> | undefined) => {
- if (error) {
- return ResponseHandler.critical(error as string);
- }
-
- if (!row || !row.info) {
- return ResponseHandler.error(
- "No data available for /data/latest",
- 404,
- );
- }
-
- try {
- return ResponseHandler.rawData(
- JSON.parse(row.info),
- "Read latest data",
- );
- } catch (error: unknown) {
- const errorMsg =
- error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
- },
- );
- }
-
- latestRaw(): Promise {
- return new Promise((resolve, reject) => {
- logger.debug("Reading DB");
- db.get(
- "SELECT info FROM data ORDER BY timestamp DESC LIMIT 1",
- (error: unknown, row: Partial> | undefined) => {
- if (error) {
- return reject(`Database query error: ${error}`);
- }
-
- if (!row || !row.info) {
- return reject("No data available for /data/latest");
- }
-
- try {
- logger.info("Read latest data");
- const parsedData = JSON.parse(row.info);
- logger.debug("Parsed data:", parsedData);
- resolve(parsedData);
- } catch (error: unknown) {
- const errorMsg =
- error instanceof Error ? error.message : String(error);
- reject(`Error parsing data: ${errorMsg}`);
- }
- },
- );
- });
- }
-
- all() {
- const ResponseHandler = createResponseHandler(this.res);
- const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString();
-
- db.all(
- "SELECT info FROM data WHERE timestamp >= ?",
- [oneDayAgo],
- (error: unknown, rows: Pick[] | undefined) => {
- if (error) {
- return ResponseHandler.critical(error as string);
- }
-
- if (!rows || rows.length === 0) {
- return ResponseHandler.error("No data available", 404);
- }
-
- return ResponseHandler.rawData(formatRows(rows), "Read database");
- },
- );
- }
-
- clear() {
- const ResponseHandler = createResponseHandler(this.res);
- db.run("DELETE FROM data", (error: unknown) => {
- if (error) {
- return ResponseHandler.critical(error as string);
- }
-
- return ResponseHandler.ok("Database cleared successfully");
- });
- }
-}
-
-export const createDatabaseHandler = (req: Request, res: Response) =>
- new DatabaseHandler(req, res);
diff --git a/src/handlers/frontend.ts b/src/handlers/frontend.ts
deleted file mode 100644
index 6b2edc55..00000000
--- a/src/handlers/frontend.ts
+++ /dev/null
@@ -1,138 +0,0 @@
-import { Request, Response } from "express";
-import { createResponseHandler } from "./response";
-import {
- hideContainer,
- unhideContainer,
- addTagToContainer,
- removeTagFromContainer,
- pinContainer,
- unpinContainer,
- setLink,
- removeLink,
- setIcon,
- removeIcon,
-} from "../controllers/frontendConfiguration";
-
-class FrontendHandler {
- private req: Request;
- private res: Response;
-
- constructor(req: Request, res: Response) {
- this.req = req;
- this.res = res;
- }
-
- async show(containerName: string) {
- const ResponseHandler = createResponseHandler(this.res);
- try {
- await unhideContainer(containerName);
- return ResponseHandler.ok("Container unhidden successfully.");
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
- }
-
- async hide(containerName: string) {
- const ResponseHandler = createResponseHandler(this.res);
- try {
- await hideContainer(containerName);
- return ResponseHandler.ok("Hid container succesfully");
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
- }
-
- async addTag(containerName: string, tag: string) {
- const ResponseHandler = createResponseHandler(this.res);
- try {
- await addTagToContainer(containerName, tag);
- return ResponseHandler.ok("Tag added successfully.");
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
- }
-
- async removeTag(containerName: string, tag: string) {
- const ResponseHandler = createResponseHandler(this.res);
- try {
- await removeTagFromContainer(containerName, tag);
- ResponseHandler.ok("Tag removed successfully.");
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
- }
-
- async pin(containerName: string) {
- const ResponseHandler = createResponseHandler(this.res);
- try {
- await pinContainer(containerName);
- return ResponseHandler.ok("Container pinned successfully.");
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
- }
-
- async unPin(containerName: string) {
- const ResponseHandler = createResponseHandler(this.res);
- try {
- await unpinContainer(containerName);
- return ResponseHandler.ok("Container unpinned successfully.");
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
- }
-
- async addLink(containerName: string, link: string) {
- const ResponseHandler = createResponseHandler(this.res);
- try {
- await setLink(containerName, link);
- return ResponseHandler.ok("Link added successfully.");
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
- }
-
- async removeLink(containerName: string) {
- const ResponseHandler = createResponseHandler(this.res);
- try {
- await removeLink(containerName);
- return ResponseHandler.ok("Removed link succesfully");
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
- }
-
- async addIcon(containerName: string, icon: string, useCustomIcon: string) {
- const ResponseHandler = createResponseHandler(this.res);
- const iconBool = useCustomIcon === "true";
- try {
- await setIcon(containerName, icon, iconBool);
- return ResponseHandler.ok("Icon added successfully.");
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
- }
-
- async removeIcon(containerName: string) {
- const ResponseHandler = createResponseHandler(this.res);
- try {
- await removeIcon(containerName);
- return ResponseHandler.ok("Icon removed successfully.");
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
- }
-}
-
-export const createFrontendHandler = (req: Request, res: Response) =>
- new FrontendHandler(req, res);
diff --git a/src/handlers/graph.ts b/src/handlers/graph.ts
deleted file mode 100644
index 12e05724..00000000
--- a/src/handlers/graph.ts
+++ /dev/null
@@ -1,82 +0,0 @@
-import cytoscape from "cytoscape";
-import logger from "../utils/logger";
-import { AllContainerData, ContainerData } from "./../typings/dockerConfig";
-import { atomicWrite } from "../utils/atomicWrite";
-
-const CACHE_DIR_JSON = "./src/data/graph.json";
-
-async function generateGraphJSON(
- allContainerData: AllContainerData,
-): Promise {
- try {
- logger.info("generateGraphJSON >>> Starting generation");
-
- const graphData = {
- nodes: [] as cytoscape.ElementDefinition[],
- edges: [] as cytoscape.ElementDefinition[],
- };
-
- for (const [hostName, containers] of Object.entries(allContainerData)) {
- if ("error" in containers) {
- graphData.nodes.push({
- data: {
- id: hostName,
- label: `Host: ${hostName} Error: ${containers.error}`,
- type: "server",
- error: true,
- },
- });
- } else {
- const containerList = containers as ContainerData[];
-
- // Host node with container count and metadata
- graphData.nodes.push({
- data: {
- id: hostName,
- label: `${hostName}\n${containerList.length} Containers`,
- type: "server",
- hostName,
- containerCount: containerList.length,
- },
- });
-
- for (const container of containerList) {
- const { id, ...otherContainerProps } = container;
-
- graphData.nodes.push({
- data: {
- id: id,
- label: `${container.name}\n${container.state.toUpperCase()}`,
- type: "container",
- ...otherContainerProps,
- },
- });
-
- // Edge between host and container
- graphData.edges.push({
- data: {
- id: `${hostName}-${container.id}`,
- source: hostName,
- target: container.id,
- connectionType: "host-container",
- },
- });
- }
- }
- }
-
- atomicWrite(CACHE_DIR_JSON, JSON.stringify(graphData, null, 2));
- logger.info("generateGraphJSON <<< JSON file generated successfully");
- return true;
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg);
- return false;
- }
-}
-
-function getGraphFilePath() {
- return { json: CACHE_DIR_JSON };
-}
-
-export { generateGraphJSON, getGraphFilePath };
diff --git a/src/handlers/ha.ts b/src/handlers/ha.ts
deleted file mode 100644
index 16c9ae19..00000000
--- a/src/handlers/ha.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-import { Request, Response } from "express";
-import logger from "../utils/logger";
-import {
- readConfig,
- prepareFilesForSync,
- ensureFileExists,
-} from "../controllers/highAvailability";
-import { createResponseHandler } from "./response";
-
-class HaHandler {
- private req: Request;
- private res: Response;
-
- constructor(req: Request, res: Response) {
- this.req = req;
- this.res = res;
- }
-
- async config() {
- const ResponseHandler = createResponseHandler(this.res);
- try {
- const data = await readConfig();
- return ResponseHandler.rawData(data, "Fetched HA-Config");
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
- }
-
- async sync(req: Request) {
- const ResponseHandler = createResponseHandler(this.res);
- try {
- const { files } = req.body;
- logger.info("Received synchronization request from master node.");
- if (!files || typeof files !== "object") {
- return ResponseHandler.error(
- "Invalid request: 'files' object is missing or invalid.",
- 400,
- );
- }
-
- for (const [filePath, content] of Object.entries(files)) {
- await ensureFileExists(filePath, content as string);
- }
-
- return ResponseHandler.ok("Synchronization completed successfully.");
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
- }
-
- async prepare() {
- const ResponseHandler = createResponseHandler(this.res);
- try {
- logger.info("Preparing files for synchronization.");
- const fileData = await prepareFilesForSync();
- return ResponseHandler.rawData(
- fileData,
- "Done preparing files for synchronization",
- );
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
- }
-}
-
-export const createHaHandler = (req: Request, res: Response) =>
- new HaHandler(req, res);
diff --git a/src/handlers/notification.ts b/src/handlers/notification.ts
deleted file mode 100644
index 9c10a599..00000000
--- a/src/handlers/notification.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-import { Request, Response } from "express";
-import fs from "fs";
-import notify from "../utils/notifications/_notify";
-const dataTemplate = "./src/data/template.json";
-import { TemplateData } from "../typings/template";
-import { createResponseHandler } from "./response";
-
-function isTemplateData(data: TemplateData): data is TemplateData {
- return (
- data !== null && typeof data === "object" && typeof data.text === "string"
- );
-}
-
-class NotificationHandler {
- private req: Request;
- private res: Response;
-
- constructor(req: Request, res: Response) {
- this.req = req;
- this.res = res;
- }
-
- getTemplate() {
- const ResponseHandler = createResponseHandler(this.res);
- try {
- fs.readFile(dataTemplate, "utf-8", (error: unknown, data) => {
- if (error) {
- return ResponseHandler.error(error as string, 400);
- }
- return ResponseHandler.rawData(
- JSON.parse(data),
- "Fetched notification template",
- );
- });
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
- }
-
- setTemplate(req: Request) {
- const ResponseHandler = createResponseHandler(this.res);
- const newTemplate: TemplateData = req.body;
-
- try {
- if (!isTemplateData(newTemplate)) {
- return ResponseHandler.error(
- "Invalid input format. Expected JSON with a 'text' field.",
- 400,
- );
- }
-
- fs.writeFileSync(dataTemplate, JSON.stringify(newTemplate, null, 2));
- return ResponseHandler.ok("Template updated successfully.");
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
- }
-
- async test(req: Request) {
- const { type, containerId } = req.params;
- const ResponseHandler = createResponseHandler(this.res);
-
- try {
- await notify(type, containerId);
- return ResponseHandler.ok("Sent test notification");
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
- }
-}
-
-export const createNotificationHandler = (req: Request, res: Response) =>
- new NotificationHandler(req, res);
diff --git a/src/handlers/response.ts b/src/handlers/response.ts
deleted file mode 100644
index ee062102..00000000
--- a/src/handlers/response.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import { Response } from "express";
-import logger from "../utils/logger";
-
-class ResponseHandler {
- private res: Response;
-
- constructor(res: Response) {
- this.res = res;
- }
-
- rawData(data: unknown, message: string) {
- logger.info(message);
- this.res.status(200).json(data);
- }
-
- ok(message: string) {
- logger.info(message);
- this.res.status(200).json({ status: "success", message });
- }
-
- denied(message: string) {
- logger.warn(message);
- this.res.status(403).json({ status: "denied", message });
- }
-
- error(message: string, code: number) {
- logger.error(`Code: ${code} - ${message}`);
- this.res.status(code).json({ status: "error", message });
- }
-
- critical(log: string) {
- logger.error(log.replace(/\n|\r/g, ""));
- this.res.status(500).json({
- status: "critical",
- message: "Please see the server logs for more info",
- });
- }
-}
-
-export const createResponseHandler = (res: Response) =>
- new ResponseHandler(res);
diff --git a/src/handlers/stack.ts b/src/handlers/stack.ts
deleted file mode 100644
index 0f15e166..00000000
--- a/src/handlers/stack.ts
+++ /dev/null
@@ -1,168 +0,0 @@
-import { Response, Request } from "express";
-import {
- createStack,
- getStackConfig,
- getStackCompose,
- writeEnvFile,
- getEnvFile,
-} from "../config/stacks";
-import { DockerComposeFile } from "../typings/dockerCompose";
-import logger from "../utils/logger";
-import * as compose from "docker-compose";
-import { createResponseHandler } from "./response";
-import { stackConfig } from "../typings/stackConfig";
-import { dockerStackEnv } from "../typings/dockerStackEnv";
-import path from "path";
-
-const PROJECT_ROOT = path.resolve(__dirname, "../..");
-
-export async function validate(name: string): Promise {
- const config: stackConfig = JSON.parse(await getStackConfig());
- if (!config.stacks.find((element) => element === name)) {
- throw new Error("Stack not found");
- }
-
- return true;
-}
-
-async function composeAction(option: string, name: string): Promise {
- const composeFile: string = path.join(PROJECT_ROOT, `stacks/${name}`);
- try {
- switch (option) {
- case "start": {
- await compose.upAll({ cwd: composeFile, log: false });
- break;
- }
- case "stop": {
- await compose.downAll({ cwd: composeFile, log: false });
- break;
- }
- default:
- throw new Error(`Invalid option: ${option}`);
- }
- } catch (err) {
- let errorMessage: string;
- const portAllocated: string = "port is already allocated";
-
- if (err instanceof Error) {
- errorMessage = err.message;
- } else if (typeof err === "object" && err !== null) {
- errorMessage = JSON.stringify(err);
- } else {
- errorMessage = String(err);
- }
-
- if (errorMessage.search(portAllocated)) {
- logger.error("Port(s) already allocated");
- }
- throw new Error(errorMessage);
- }
-}
-
-class StackHandler {
- private req: Request;
- private res: Response;
-
- constructor(req: Request, res: Response) {
- this.req = req;
- this.res = res;
- }
-
- async createStack(req: Request, res: Response) {
- const ResponseHandler = createResponseHandler(res);
- try {
- const name: string = req.params.name;
- const content: DockerComposeFile = req.body;
- let override = false;
- override = req.query.override == "true";
-
- await createStack(name, content, override);
- return ResponseHandler.ok("Stack created");
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
- }
-
- async start(req: Request, res: Response) {
- const ResponseHandler = createResponseHandler(res);
- try {
- const name: string = req.params.name;
- await validate(name);
- await composeAction("start", name);
- return ResponseHandler.ok("Stack started");
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
- }
-
- async stop(req: Request, res: Response) {
- const ResponseHandler = createResponseHandler(res);
- try {
- const name: string = req.params.name;
- await validate(name);
- await composeAction("stop", name);
- return ResponseHandler.ok("Stack stopped");
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
- }
-
- async stackCompose(req: Request, res: Response) {
- const ResponseHandler = createResponseHandler(res);
- try {
- const { name } = req.params;
- return ResponseHandler.rawData(
- await getStackCompose(name),
- "Stack compose fetched",
- );
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg.replace(/\n|\r/g, ""));
- throw new Error(errorMsg);
- }
- }
-
- async setStackEnv(req: Request, res: Response) {
- const ResponseHandler = createResponseHandler(res);
- try {
- const data: dockerStackEnv = req.body;
- const name: string = req.params.name;
- if (await writeEnvFile(name, data)) {
- return ResponseHandler.ok("Wrote docker.env");
- } else {
- return ResponseHandler.critical(
- "Something went wrong while writing the env File!",
- );
- }
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg.replace(/\n|\r/g, ""));
- throw new Error(errorMsg);
- }
- }
-
- async getStackEnv(req: Request, res: Response) {
- const ResponseHandler = createResponseHandler(res);
- try {
- const name: string = req.params.name;
- const data = await getEnvFile(name);
- if (data == null) {
- return ResponseHandler.error(
- "No environment file found for this Stack!",
- 404,
- );
- }
- return ResponseHandler.rawData(data, "Read docker.env");
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg.replace(/\n|\r/g, ""));
- throw new Error(errorMsg);
- }
- }
-}
-
-export const createStackHandler = (req: Request, res: Response) =>
- new StackHandler(req, res);
diff --git a/src/index.ts b/src/index.ts
new file mode 100644
index 00000000..a2dfb814
--- /dev/null
+++ b/src/index.ts
@@ -0,0 +1,87 @@
+import { swagger } from "@elysiajs/swagger";
+import { Elysia } from "elysia";
+import { dbFunctions } from "~/core/database/repository";
+import { loadPlugins } from "~/core/plugins/loader";
+import { logger } from "~/core/utils/logger";
+import { dockerRoutes } from "~/routes/docker-manager";
+import { dockerStatsRoutes } from "~/routes/docker-stats";
+import { backendLogs } from "~/routes/logs";
+import { dockerWebsocketRoutes } from "~/routes/docker-websocket";
+import { stackRoutes } from "./routes/stacks";
+import { apiConfigRoutes } from "~/routes/api-config";
+import { setSchedules } from "~/core/docker/scheduler";
+import staticPlugin from "@elysiajs/static";
+
+console.log("")
+dbFunctions.init();
+
+const DockStatAPI = new Elysia()
+ .use(staticPlugin())
+ .use(
+ swagger({
+ documentation: {
+ info: {
+ title: "DockStatAPI",
+ version: "2.1.0",
+ description: "Docker monitoring API with plugin support",
+ },
+ tags: [
+ {
+ name: "Statistics",
+ description:
+ "All endpoints for fetching statistics of hosts / containers",
+ },
+ {
+ name: "Management",
+ description: "Various endpoints for managing DockStatAPI",
+ },
+ {
+ name: "Stacks",
+ description: "DockStat's Stack functionality",
+ },
+ {
+ name: "Utils",
+ description: "Various utilities which might be useful",
+ },
+ ],
+ },
+ }),
+ )
+ .use(dockerRoutes)
+ .use(dockerStatsRoutes)
+ .use(backendLogs)
+ .use(dockerWebsocketRoutes)
+ .use(apiConfigRoutes)
+ .use(stackRoutes)
+ .get("/health", () => ({ status: "healthy" }), { tags: ["Utils"] })
+ .onError(({ code, set }) => {
+ if (code === 'NOT_FOUND') {
+ logger.warn("Unknown route, showing error page!")
+ set.status = 404
+ set.headers['Content-Type'] = 'text/html'
+ return Bun.file('public/404.html')
+ }
+ });
+
+async function startServer() {
+ try {
+ await loadPlugins("./src/plugins");
+ DockStatAPI.listen(3000, ({ hostname, port }) => {
+ console.log("----- [ ############## ]")
+ logger.info(`DockStatAPI is running at http://${hostname}:${port}`);
+ logger.info(
+ `Swagger API Documentation available at http://${hostname}:${port}/swagger`,
+ );
+ });
+ } catch (error) {
+ logger.error("Failed to start server:", error);
+ process.exit(1);
+ }
+}
+
+await setSchedules();
+await startServer();
+
+logger.info("Started server");
+console.log("----- [ ############## ]")
+
diff --git a/src/init.ts b/src/init.ts
deleted file mode 100644
index 188542f6..00000000
--- a/src/init.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-import express, { Request, Response, NextFunction } from "express";
-import process from "node:process";
-import swaggerDocs from "./utils/swaggerDocs";
-import auth from "./routes/auth/routes";
-import data from "./routes/data/routes";
-import frontend from "./routes/frontendController/routes";
-import api from "./routes/getter/routes";
-import notificationService from "./routes/notifications/routes";
-import conf from "./routes/setter/routes";
-import graph from "./routes/graphs/routes";
-import authMiddleware from "./middleware/authMiddleware";
-import ha from "./routes/highavailability/routes";
-import trustedProxies from "./controllers/proxy";
-import { limiter } from "./middleware/rateLimiter";
-import { scheduleFetch } from "./controllers/scheduler";
-import { Server } from 'http';
-import cors from "cors";
-import { setupWebSocket } from "./utils/webSocket";
-import stacks from "./routes/stack/routes";
-import { blockWhileLocked } from "./middleware/checkLock";
-import logger from "./utils/logger";
-import initFiles from "./config/initFiles";
-
-const LAB = [limiter, authMiddleware, blockWhileLocked];
-
-const initializeApp = (app: express.Application, server: Server): void => {
- initFiles();
-
- try {
- logger.debug("Starting Websocket server, with these endpoints:");
- logger.debug("ws://localhost:9876/wss/container-data")
- logger.debug("ws://localhost:9876/wss/server-logs")
- setupWebSocket(server);
- } catch (error: unknown) {
- logger.error("Error starting WebSocket: ", error)
- }
-
- app.use(cors());
- app.use(express.json());
-
- if (process.env.NODE_ENV !== "production") {
- app.use("/api-docs", (req: Request, res: Response, next: NextFunction) =>
- next(),
- );
- app.get("/", (req: Request, res: Response) => {
- res.redirect("/api-docs");
- });
- swaggerDocs(app);
- }
-
- trustedProxies(app);
- scheduleFetch();
-
- app.use("/api", LAB, api);
- app.use("/conf", LAB, conf);
- app.use("/auth", LAB, auth);
- app.use("/data", LAB, data);
- app.use("/frontend", LAB, frontend);
- app.use("/graph", LAB, graph);
- app.use("/notification-service", LAB, notificationService);
- app.use("/stacks", LAB, stacks);
- app.use("/ha", limiter, authMiddleware, ha);
-
- process.on("exit", (code: number) => {
- logger.warn(`Server exiting (Code: ${code})`);
- });
-};
-
-export default initializeApp;
diff --git a/src/middleware/authMiddleware.ts b/src/middleware/authMiddleware.ts
deleted file mode 100644
index 414b2762..00000000
--- a/src/middleware/authMiddleware.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import bcrypt from "bcrypt";
-import { Request, Response, NextFunction } from "express";
-import logger from "../utils/logger";
-import { rateLimitedReadFile } from "../utils/rateLimitFS";
-import { createResponseHandler } from "../handlers/response";
-const passwordFile = "./src/data/password.json";
-const passwordBool = "./src/data/usePassword.txt";
-
-async function authMiddleware(
- req: Request,
- res: Response,
- next: NextFunction,
-): Promise {
- const ResponseHandler = createResponseHandler(res);
- try {
- const authStatusData = await rateLimitedReadFile(passwordBool);
- const isAuthEnabled = authStatusData.trim() === "true";
-
- if (!isAuthEnabled) {
- logger.warn("You are not using authentication, please enable it.");
- logger.debug("Authentication disabled, skipping login process...");
- return next();
- }
-
- const providedPassword = req.headers["x-password"];
- if (!providedPassword) {
- ResponseHandler.denied("Password required");
- return;
- }
-
- const passwordData = await rateLimitedReadFile(passwordFile);
- const storedData = JSON.parse(passwordData);
-
- const passwordMatch = await bcrypt.compare(
- providedPassword as string,
- storedData.hash,
- );
- if (!passwordMatch) {
- ResponseHandler.error("Invalid Password", 402);
- return;
- }
-
- logger.debug("Authentication succesfull");
- next();
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
-}
-
-export default authMiddleware;
diff --git a/src/middleware/checkLock.ts b/src/middleware/checkLock.ts
deleted file mode 100644
index c01540fe..00000000
--- a/src/middleware/checkLock.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { Request, Response, NextFunction } from "express";
-import { rateLimitedExistsSync } from "../utils/rateLimitFS";
-import { createResponseHandler } from "../handlers/response";
-
-const lockFilePath = "./src/data/ha.lock";
-
-export async function blockWhileLocked(
- req: Request,
- res: Response,
- next: NextFunction,
-): Promise {
- const ResponseHandler = createResponseHandler(res);
- if (await rateLimitedExistsSync(lockFilePath)) {
- ResponseHandler.error(
- "Service unavailable. The high-availability lock is currently active. Please try again later.",
- 503,
- );
- } else {
- next();
- }
-}
diff --git a/src/middleware/rateLimiter.ts b/src/middleware/rateLimiter.ts
deleted file mode 100644
index dc64af25..00000000
--- a/src/middleware/rateLimiter.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import rateLimit from "express-rate-limit";
-
-export const limiter = rateLimit({
- windowMs: 5 * 60 * 1000, // 5 minutes
- limit: 300, // Limit each IP to 300 requests per `window` (here, per 5 minutes)
- standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers
- legacyHeaders: false, // Disable the `X-RateLimit-*` headers
-});
diff --git a/src/misc/.tmux.sh b/src/misc/.tmux.sh
deleted file mode 100644
index a929a1a3..00000000
--- a/src/misc/.tmux.sh
+++ /dev/null
@@ -1 +0,0 @@
-[ -z "$TMUX" ] && tmux new-session -d -s docker 'docker compose -f docker/docker-compose.yaml logs -f master' \; rename-window 'master' \; new-window 'docker compose -f docker/docker-compose.yaml logs -f slave' \; rename-window 'slave' \; new-window 'docker compose -f docker/docker-compose.yaml logs -f test-socket-proxy' \; rename-window 'proxy' \; attach-session || echo 'Already inside a tmux session. Exiting.'
diff --git a/src/misc/createEnvDev.sh b/src/misc/createEnvDev.sh
deleted file mode 100755
index 1f231aa6..00000000
--- a/src/misc/createEnvDev.sh
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/bin/bash
-
-# Version
-VERSION="$(cat ./package.json | grep version | cut -d '"' -f 4)"
-
-# Automatic Stack environment management
-AUTOMATIC_ENVIRONMENT_FILE_MANAGEMENT="${AUTOMATIC_ENVIRONMENT_FILE_MANAGEMENT:-true}"
-
-# Docker
-if grep -q '/docker' /proc/1/cgroup 2>/dev/null || [ -f /.dockerenv ]; then
- RUNNING_IN_DOCKER="true"
-else
- RUNNING_IN_DOCKER="false"
-fi
-
-# Default dev log level
-LOG_LEVEL="${LOG_LEVEL:-debug}"
-
-echo -n "\
-{
- \"VERSION\": \"${VERSION}\",
- \"RUNNING_IN_DOCKER\": \"${RUNNING_IN_DOCKER}\",
- \"TRUSTED_PROXIES\": \"${TRUSTED_PROXIES}\",
- \"HA_MASTER\": \"${HA_MASTER}\",
- \"HA_MASTER_IP\": \"${HA_MASTER_IP}\",
- \"HA_NODE\": \"${HA_NODE}\",
- \"HA_UNSAFE\": \"${HA_UNSAFE}\",
- \"DISCORD_WEBHOOK_URL\": \"${DISCORD_WEBHOOK_URL}\",
- \"EMAIL_SENDER\": \"${EMAIL_SENDER}\",
- \"EMAIL_RECIPIENT\": \"${EMAIL_RECIPIENT}\",
- \"EMAIL_PASSWORD\": \"${EMAIL_PASSWORD}\",
- \"EMAIL_SERVICE\": \"${EMAIL_SERVICE}\",
- \"PUSHBULLET_ACCESS_TOKEN\": \"${PUSHBULLET_ACCESS_TOKEN}\",
- \"PUSHOVER_USER_KEY\": \"${PUSHOVER_USER_KEY}\",
- \"PUSHOVER_API_TOKEN\": \"${PUSHOVER_API_TOKEN}\",
- \"SLACK_WEBHOOK_URL\": \"${SLACK_WEBHOOK_URL}\",
- \"TELEGRAM_BOT_TOKEN\": \"${TELEGRAM_BOT_TOKEN}\",
- \"TELEGRAM_CHAT_ID\": \"${TELEGRAM_CHAT_ID}\",
- \"WHATSAPP_API_URL\": \"${WHATSAPP_API_URL}\",
- \"WHATSAPP_RECIPIENT\": \"${WHATSAPP_RECIPIENT}\",
- \"AUTOMATIC_ENVIRONMENT_FILE_MANAGEMENT\": \"${AUTOMATIC_ENVIRONMENT_FILE_MANAGEMENT}\",
- \"LOG_LEVEL\": \"${LOG_LEVEL}\"
-} \
-" > ./src/data/variables.json || exit 1
diff --git a/src/misc/createEnvFile.sh b/src/misc/createEnvFile.sh
deleted file mode 100755
index 0fbd15de..00000000
--- a/src/misc/createEnvFile.sh
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/bin/bash
-
-# Version
-VERSION="$(cat ./package.json | grep version | cut -d '"' -f 4)"
-
-# Automatic Stack environment management
-AUTOMATIC_ENVIRONMENT_FILE_MANAGEMENT="${AUTOMATIC_ENVIRONMENT_FILE_MANAGEMENT:-true}"
-
-# Docker
-if grep -q '/docker' /proc/1/cgroup 2>/dev/null || [ -f /.dockerenv ]; then
- RUNNING_IN_DOCKER="true"
-else
- RUNNING_IN_DOCKER="false"
-fi
-
-# Default log level
-LOG_LEVEL="${LOG_LEVEL:-info}"
-
-echo -n "\
-{
- \"VERSION\": \"${VERSION}\",
- \"RUNNING_IN_DOCKER\": \"${RUNNING_IN_DOCKER}\",
- \"TRUSTED_PROXIES\": \"${TRUSTED_PROXIES}\",
- \"HA_MASTER\": \"${HA_MASTER}\",
- \"HA_MASTER_IP\": \"${HA_MASTER_IP}\",
- \"HA_NODE\": \"${HA_NODE}\",
- \"HA_UNSAFE\": \"${HA_UNSAFE}\",
- \"DISCORD_WEBHOOK_URL\": \"${DISCORD_WEBHOOK_URL}\",
- \"EMAIL_SENDER\": \"${EMAIL_SENDER}\",
- \"EMAIL_RECIPIENT\": \"${EMAIL_RECIPIENT}\",
- \"EMAIL_PASSWORD\": \"${EMAIL_PASSWORD}\",
- \"EMAIL_SERVICE\": \"${EMAIL_SERVICE}\",
- \"PUSHBULLET_ACCESS_TOKEN\": \"${PUSHBULLET_ACCESS_TOKEN}\",
- \"PUSHOVER_USER_KEY\": \"${PUSHOVER_USER_KEY}\",
- \"PUSHOVER_API_TOKEN\": \"${PUSHOVER_API_TOKEN}\",
- \"SLACK_WEBHOOK_URL\": \"${SLACK_WEBHOOK_URL}\",
- \"TELEGRAM_BOT_TOKEN\": \"${TELEGRAM_BOT_TOKEN}\",
- \"TELEGRAM_CHAT_ID\": \"${TELEGRAM_CHAT_ID}\",
- \"WHATSAPP_API_URL\": \"${WHATSAPP_API_URL}\",
- \"WHATSAPP_RECIPIENT\": \"${WHATSAPP_RECIPIENT}\",
- \"AUTOMATIC_ENVIRONMENT_FILE_MANAGEMENT\": \"${AUTOMATIC_ENVIRONMENT_FILE_MANAGEMENT}\",
- \"LOG_LEVEL\": \"${LOG_LEVEL}\"
-} \
-" > /api/src/data/variables.json || exit 1
diff --git a/src/misc/credits.sh b/src/misc/credits.sh
deleted file mode 100755
index 3db14f64..00000000
--- a/src/misc/credits.sh
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/bash
-
-if ! command -v jq 2>&1 >/dev/null
-then
- echo "ERROR: jq could not be found"
- exit 1
-fi
-
-
-LICENSE_JSON=$(npx license-checker \
- --exclude 'MIT, MIT-0, MIT OR X11, BSD, ISC, Unlicense, CC0-1.0, Python-2.0: 1' \
- --json)
-
-{
- echo -e "# CREDITS\n"
- echo -e "This file shows all npm packages used in DockStatAPI (also Dev packages)\n"
-} > CREDITS.md
-
-jq -r '
- to_entries |
- group_by(.value.licenses)[] |
- "### License: \(.[0].value.licenses)\n\n" +
- "| Name | Repository | Publisher |\n|------|-------------|-----------|\n" +
- (map(
- "| \(.key) | \(.value.repository // "N/A") | \(.value.publisher // "N/A") |"
- ) | join("\n")) + "\n\n"
-' <<< "$LICENSE_JSON" >> CREDITS.md
-
-echo "Markdown file with license information has been created: CREDITS.md"
diff --git a/src/misc/dependencyGraphs/.dependency-cruiser.cjs b/src/misc/dependencyGraphs/.dependency-cruiser.cjs
deleted file mode 100644
index d734a682..00000000
--- a/src/misc/dependencyGraphs/.dependency-cruiser.cjs
+++ /dev/null
@@ -1,359 +0,0 @@
-/** @type {import('dependency-cruiser').IConfiguration} */
-module.exports = {
- forbidden: [
- {
- name: "no-circular",
- severity: "warn",
- comment:
- "This dependency is part of a circular relationship. You might want to revise " +
- "your solution (i.e. use dependency inversion, make sure the modules have a single responsibility) ",
- from: {},
- to: {
- circular: true,
- },
- },
- {
- name: "no-orphans",
- comment:
- "This is an orphan module - it's likely not used (anymore?). Either use it or " +
- "remove it. If it's logical this module is an orphan (i.e. it's a config file), " +
- "add an exception for it in your dependency-cruiser configuration. By default " +
- "this rule does not scrutinize dot-files (e.g. .eslintrc.js), TypeScript declaration " +
- "files (.d.ts), tsconfig.json and some of the babel and webpack configs.",
- severity: "warn",
- from: {
- orphan: true,
- pathNot: [
- "(^|/)[.][^/]+[.](?:js|cjs|mjs|ts|cts|mts|json)$", // dot files
- "[.]d[.]ts$", // TypeScript declaration files
- "(^|/)tsconfig[.]json$", // TypeScript config
- "(^|/)(?:babel|webpack)[.]config[.](?:js|cjs|mjs|ts|cts|mts|json)$", // other configs
- ],
- },
- to: {},
- },
- {
- name: "no-deprecated-core",
- comment:
- "A module depends on a node core module that has been deprecated. Find an alternative - these are " +
- "bound to exist - node doesn't deprecate lightly.",
- severity: "warn",
- from: {},
- to: {
- dependencyTypes: ["core"],
- path: [
- "^v8/tools/codemap$",
- "^v8/tools/consarray$",
- "^v8/tools/csvparser$",
- "^v8/tools/logreader$",
- "^v8/tools/profile_view$",
- "^v8/tools/profile$",
- "^v8/tools/SourceMap$",
- "^v8/tools/splaytree$",
- "^v8/tools/tickprocessor-driver$",
- "^v8/tools/tickprocessor$",
- "^node-inspect/lib/_inspect$",
- "^node-inspect/lib/internal/inspect_client$",
- "^node-inspect/lib/internal/inspect_repl$",
- "^async_hooks$",
- "^punycode$",
- "^domain$",
- "^constants$",
- "^sys$",
- "^_linklist$",
- "^_stream_wrap$",
- ],
- },
- },
- {
- name: "not-to-deprecated",
- comment:
- "This module uses a (version of an) npm module that has been deprecated. Either upgrade to a later " +
- "version of that module, or find an alternative. Deprecated modules are a security risk.",
- severity: "warn",
- from: {},
- to: {
- dependencyTypes: ["deprecated"],
- },
- },
- {
- name: "no-non-package-json",
- severity: "error",
- comment:
- "This module depends on an npm package that isn't in the 'dependencies' section of your package.json. " +
- "That's problematic as the package either (1) won't be available on live (2 - worse) will be " +
- "available on live with an non-guaranteed version. Fix it by adding the package to the dependencies " +
- "in your package.json.",
- from: {},
- to: {
- dependencyTypes: ["npm-no-pkg", "npm-unknown"],
- },
- },
- {
- name: "not-to-unresolvable",
- comment:
- "This module depends on a module that cannot be found ('resolved to disk'). If it's an npm " +
- "module: add it to your package.json. In all other cases you likely already know what to do.",
- severity: "error",
- from: {},
- to: {
- couldNotResolve: true,
- },
- },
- {
- name: "no-duplicate-dep-types",
- comment:
- "Likely this module depends on an external ('npm') package that occurs more than once " +
- "in your package.json i.e. bot as a devDependencies and in dependencies. This will cause " +
- "maintenance problems later on.",
- severity: "warn",
- from: {},
- to: {
- moreThanOneDependencyType: true,
- // as it's pretty common to have a type import be a type only import
- // _and_ (e.g.) a devDependency - don't consider type-only dependency
- // types for this rule
- dependencyTypesNot: ["type-only"],
- },
- },
-
- /* rules you might want to tweak for your specific situation: */
-
- {
- name: "not-to-spec",
- comment:
- "This module depends on a spec (test) file. The sole responsibility of a spec file is to test code. " +
- "If there's something in a spec that's of use to other modules, it doesn't have that single " +
- "responsibility anymore. Factor it out into (e.g.) a separate utility/ helper or a mock.",
- severity: "error",
- from: {},
- to: {
- path: "[.](?:spec|test)[.](?:js|mjs|cjs|jsx|ts|mts|cts|tsx)$",
- },
- },
- {
- name: "not-to-dev-dep",
- severity: "error",
- comment:
- "This module depends on an npm package from the 'devDependencies' section of your " +
- "package.json. It looks like something that ships to production, though. To prevent problems " +
- "with npm packages that aren't there on production declare it (only!) in the 'dependencies'" +
- "section of your package.json. If this module is development only - add it to the " +
- "from.pathNot re of the not-to-dev-dep rule in the dependency-cruiser configuration",
- from: {
- path: "^(./)",
- pathNot: "[.](?:spec|test)[.](?:js|mjs|cjs|jsx|ts|mts|cts|tsx)$",
- },
- to: {
- dependencyTypes: ["npm-dev"],
- // type only dependencies are not a problem as they don't end up in the
- // production code or are ignored by the runtime.
- dependencyTypesNot: ["type-only"],
- pathNot: ["node_modules/@types/"],
- },
- },
- {
- name: "optional-deps-used",
- severity: "info",
- comment:
- "This module depends on an npm package that is declared as an optional dependency " +
- "in your package.json. As this makes sense in limited situations only, it's flagged here. " +
- "If you're using an optional dependency here by design - add an exception to your" +
- "dependency-cruiser configuration.",
- from: {},
- to: {
- dependencyTypes: ["npm-optional"],
- },
- },
- {
- name: "peer-deps-used",
- comment:
- "This module depends on an npm package that is declared as a peer dependency " +
- "in your package.json. This makes sense if your package is e.g. a plugin, but in " +
- "other cases - maybe not so much. If the use of a peer dependency is intentional " +
- "add an exception to your dependency-cruiser configuration.",
- severity: "warn",
- from: {},
- to: {
- dependencyTypes: ["npm-peer"],
- },
- },
- ],
- options: {
- /* Which modules not to follow further when encountered */
- doNotFollow: {
- /* path: an array of regular expressions in strings to match against */
- path: ["../node_modules"],
- },
-
- /* Which modules to exclude */
- // exclude : {
- // /* path: an array of regular expressions in strings to match against */
- // path: '',
- // },
-
- /* Which modules to exclusively include (array of regular expressions in strings)
- dependency-cruiser will skip everything not matching this pattern
- */
- // includeOnly : [''],
-
- /* List of module systems to cruise.
- When left out dependency-cruiser will fall back to the list of _all_
- module systems it knows of. It's the default because it's the safe option
- It might come at a performance penalty, though.
- moduleSystems: ['amd', 'cjs', 'es6', 'tsd']
-
- As in practice only commonjs ('cjs') and ecmascript modules ('es6')
- are widely used, you can limit the moduleSystems to those.
- */
-
- // moduleSystems: ['cjs', 'es6'],
-
- /* prefix for links in html and svg output (e.g. 'https://github.com/you/yourrepo/blob/main/'
- to open it on your online repo or `vscode://file/${process.cwd()}/` to
- open it in visual studio code),
- */
- // prefix: `vscode://file/${process.cwd()}/`,
-
- /* false (the default): ignore dependencies that only exist before typescript-to-javascript compilation
- true: also detect dependencies that only exist before typescript-to-javascript compilation
- "specify": for each dependency identify whether it only exists before compilation or also after
- */
- // tsPreCompilationDeps: false,
-
- /* list of extensions to scan that aren't javascript or compile-to-javascript.
- Empty by default. Only put extensions in here that you want to take into
- account that are _not_ parsable.
- */
- // extraExtensionsToScan: [".json", ".jpg", ".png", ".svg", ".webp"],
-
- /* if true combines the package.jsons found from the module up to the base
- folder the cruise is initiated from. Useful for how (some) mono-repos
- manage dependencies & dependency definitions.
- */
- // combinedDependencies: false,
-
- /* if true leave symlinks untouched, otherwise use the realpath */
- // preserveSymlinks: false,
-
- /* TypeScript project file ('tsconfig.json') to use for
- (1) compilation and
- (2) resolution (e.g. with the paths property)
-
- The (optional) fileName attribute specifies which file to take (relative to
- dependency-cruiser's current working directory). When not provided
- defaults to './tsconfig.json'.
- */
- //tsConfig: {
- //fileName: "../tsconfig.json",
- //},
-
- /* Webpack configuration to use to get resolve options from.
-
- The (optional) fileName attribute specifies which file to take (relative
- to dependency-cruiser's current working directory. When not provided defaults
- to './webpack.conf.js'.
-
- The (optional) `env` and `arguments` attributes contain the parameters
- to be passed if your webpack config is a function and takes them (see
- webpack documentation for details)
- */
- // webpackConfig: {
- // fileName: 'webpack.config.js',
- // env: {},
- // arguments: {}
- // },
-
- /* Babel config ('.babelrc', '.babelrc.json', '.babelrc.json5', ...) to use
- for compilation
- */
- // babelConfig: {
- // fileName: '.babelrc',
- // },
-
- /* List of strings you have in use in addition to cjs/ es6 requires
- & imports to declare module dependencies. Use this e.g. if you've
- re-declared require, use a require-wrapper or use window.require as
- a hack.
- */
- // exoticRequireStrings: [],
-
- /* options to pass on to enhanced-resolve, the package dependency-cruiser
- uses to resolve module references to disk. The values below should be
- suitable for most situations
-
- If you use webpack: you can also set these in webpack.conf.js. The set
- there will override the ones specified here.
- */
- enhancedResolveOptions: {
- /* What to consider as an 'exports' field in package.jsons */
- exportsFields: ["exports"],
- /* List of conditions to check for in the exports field.
- Only works when the 'exportsFields' array is non-empty.
- */
- conditionNames: ["import", "require", "node", "default", "types"],
- /*
- The extensions, by default are the same as the ones dependency-cruiser
- can access (run `npx depcruise --info` to see which ones that are in
- _your_ environment). If that list is larger than you need you can pass
- the extensions you actually use (e.g. ["", ".jsx"]). This can speed
- up module resolution, which is the most expensive step.
- */
- extensions: ["", ".jsx", ".ts", ".tsx"],
- /* What to consider a 'main' field in package.json */
- mainFields: ["module", "main", "types", "typings"],
- /*
- A list of alias fields in package.jsons
- See [this specification](https://github.com/defunctzombie/package-browser-field-spec) and
- the webpack [resolve.alias](https://webpack.js.org/configuration/resolve/#resolvealiasfields)
- documentation
-
- Defaults to an empty array (= don't use alias fields).
- */
- // aliasFields: ["browser"],
- },
- reporterOptions: {
- dot: {
- /* pattern of modules that can be consolidated in the detailed
- graphical dependency graph. The default pattern in this configuration
- collapses everything in node_modules to one folder deep so you see
- the external modules, but their innards.
- */
- collapsePattern: "node_modules/(?:@[^/]+/[^/]+|[^/]+)",
-
- /* Options to tweak the appearance of your graph.See
- https://github.com/sverweij/dependency-cruiser/blob/main/doc/options-reference.md#reporteroptions
- for details and some examples. If you don't specify a theme
- dependency-cruiser falls back to a built-in one.
- */
- theme: {
- graph: {
- /* splines: "ortho" gives straight lines, but is slow on big graphs
- splines: "true" gives bezier curves (fast, not as nice as ortho)
- */
- ortho: "true",
- },
- },
- },
- archi: {
- /* pattern of modules that can be consolidated in the high level
- graphical dependency graph. If you use the high level graphical
- dependency graph reporter (`archi`) you probably want to tweak
- this collapsePattern to your situation.
- */
- collapsePattern:
- "^(?:packages|src|lib(s?)|app(s?)|bin|test(s?)|spec(s?))/[^/]+|node_modules/(?:@[^/]+/[^/]+|[^/]+)",
-
- /* Options to tweak the appearance of your graph. If you don't specify a
- theme for 'archi' dependency-cruiser will use the one specified in the
- dot section above and otherwise use the default one.
- */
- // theme: { },
- },
- text: {
- highlightFocused: true,
- },
- },
- },
-};
-// generated: dependency-cruiser@16.5.0 on 2024-11-08T20:57:37.261Z
diff --git a/src/misc/dependencyGraphs/createDependencyGraph.sh b/src/misc/dependencyGraphs/createDependencyGraph.sh
deleted file mode 100755
index 5fe007aa..00000000
--- a/src/misc/dependencyGraphs/createDependencyGraph.sh
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/bin/bash
-TMP=$(mktemp)
-IGNORE="node_modules|logger|.dependency-cruiser|path|fs|os|https|net|process|util"
-
-cat ./src/init.ts | grep "./routes" | awk '{print $2,$4}' > $TMP
-
-spawn_worker(){
- local line="$1"
- local target_route="$(echo "$line" | cut -d '"' -f2 | sed 's|^./routes|./src/routes|').ts"
- local route=$(echo "$line" | awk '{print $1}')
-
- echo -e "\nRoute: $route \n${target_route}"
-
- test=true depcruise \
- -c ./src/misc/dependencyGraphs/.dependency-cruiser.cjs \
- -p cli-feedback \
- -T mermaid \
- -x "$IGNORE" \
- -f ./src/misc/dependencyGraphs/mermaid-${route}.txt \
- ${target_route} || exit 1
-}
-
-while read line; do
- spawn_worker "$line" &
-done < <(cat $TMP)
-
-npx depcruise \
- -c ./src/misc/dependencyGraphs/.dependency-cruiser.cjs \
- -p cli-feedback \
- -T mermaid \
- -x "$IGNORE" \
- -f ./src/misc/dependencyGraphs/mermaid-all.txt \
- ./src/server.ts || exit 1
-
-wait
-
-find ./src/misc/dependencyGraphs -type f -name "*.txt" -exec sed -i 's/flowchart LR/flowchart TB/g' {} +
-
-echo -e "\n========\n\n DONE\n\n========"
-
-exit 0
diff --git a/src/misc/dependencyGraphs/mermaid-all.txt b/src/misc/dependencyGraphs/mermaid-all.txt
deleted file mode 100644
index 1cb2ebe8..00000000
--- a/src/misc/dependencyGraphs/mermaid-all.txt
+++ /dev/null
@@ -1,113 +0,0 @@
-flowchart TB
-
-subgraph 0["src"]
-1["server.ts"]
-2["init.ts"]
-subgraph 3["config"]
-4["initFiles.ts"]
-7["variables.ts"]
-B["db.ts"]
-end
-subgraph 5["controllers"]
-6["proxy.ts"]
-A["scheduler.ts"]
-C["fetchData.ts"]
-N["auth.ts"]
-U["frontendConfiguration.ts"]
-14["highAvailability.ts"]
-end
-subgraph 8["data"]
-9["variables.json"]
-end
-subgraph D["middleware"]
-E["authMiddleware.ts"]
-H["checkLock.ts"]
-I["rateLimiter.ts"]
-end
-subgraph F["handlers"]
-G["response.ts"]
-M["auth.ts"]
-Q["data.ts"]
-T["frontend.ts"]
-X["api.ts"]
-10["graph.ts"]
-13["ha.ts"]
-19["notification.ts"]
-1C["conf.ts"]
-end
-subgraph J["routes"]
-subgraph K["auth"]
-L["routes.ts"]
-end
-subgraph O["data"]
-P["routes.ts"]
-end
-subgraph R["frontendController"]
-S["routes.ts"]
-end
-subgraph V["getter"]
-W["routes.ts"]
-end
-subgraph Y["graphs"]
-Z["routes.ts"]
-end
-subgraph 11["highavailability"]
-12["routes.ts"]
-end
-subgraph 17["notifications"]
-18["routes.ts"]
-end
-subgraph 1A["setter"]
-1B["routes.ts"]
-end
-end
-subgraph 15["typings"]
-16["ha.ts"]
-end
-end
-1-->2
-2-->4
-2-->6
-2-->A
-2-->E
-2-->H
-2-->I
-2-->L
-2-->P
-2-->S
-2-->W
-2-->Z
-2-->12
-2-->18
-2-->1B
-6-->7
-7-->9
-A-->B
-A-->C
-C-->B
-E-->G
-H-->G
-L-->M
-M-->N
-M-->G
-P-->Q
-Q-->B
-Q-->G
-S-->T
-T-->U
-T-->G
-W-->X
-X-->A
-X-->G
-Z-->10
-Z-->G
-12-->13
-13-->14
-13-->G
-14-->7
-14-->16
-18-->19
-19-->G
-1B-->1C
-1C-->A
-1C-->G
diff --git a/src/misc/dependencyGraphs/mermaid-api.txt b/src/misc/dependencyGraphs/mermaid-api.txt
deleted file mode 100644
index 3cb4811e..00000000
--- a/src/misc/dependencyGraphs/mermaid-api.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-flowchart TB
-
-subgraph 0["src"]
-subgraph 1["routes"]
-subgraph 2["getter"]
-3["routes.ts"]
-end
-end
-subgraph 4["handlers"]
-5["api.ts"]
-B["response.ts"]
-end
-subgraph 6["controllers"]
-7["scheduler.ts"]
-A["fetchData.ts"]
-end
-subgraph 8["config"]
-9["db.ts"]
-end
-end
-3-->5
-5-->7
-5-->B
-7-->9
-7-->A
-A-->9
diff --git a/src/misc/dependencyGraphs/mermaid-auth.txt b/src/misc/dependencyGraphs/mermaid-auth.txt
deleted file mode 100644
index 336ddedb..00000000
--- a/src/misc/dependencyGraphs/mermaid-auth.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-flowchart TB
-
-subgraph 0["src"]
-subgraph 1["routes"]
-subgraph 2["auth"]
-3["routes.ts"]
-end
-end
-subgraph 4["handlers"]
-5["auth.ts"]
-8["response.ts"]
-end
-subgraph 6["controllers"]
-7["auth.ts"]
-end
-end
-3-->5
-5-->7
-5-->8
diff --git a/src/misc/dependencyGraphs/mermaid-conf.txt b/src/misc/dependencyGraphs/mermaid-conf.txt
deleted file mode 100644
index 370dd892..00000000
--- a/src/misc/dependencyGraphs/mermaid-conf.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-flowchart TB
-
-subgraph 0["src"]
-subgraph 1["routes"]
-subgraph 2["setter"]
-3["routes.ts"]
-end
-end
-subgraph 4["handlers"]
-5["conf.ts"]
-B["response.ts"]
-end
-subgraph 6["controllers"]
-7["scheduler.ts"]
-A["fetchData.ts"]
-end
-subgraph 8["config"]
-9["db.ts"]
-end
-end
-3-->5
-5-->7
-5-->B
-7-->9
-7-->A
-A-->9
diff --git a/src/misc/dependencyGraphs/mermaid-data.txt b/src/misc/dependencyGraphs/mermaid-data.txt
deleted file mode 100644
index 4aa6a133..00000000
--- a/src/misc/dependencyGraphs/mermaid-data.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-flowchart TB
-
-subgraph 0["src"]
-subgraph 1["routes"]
-subgraph 2["data"]
-3["routes.ts"]
-end
-end
-subgraph 4["handlers"]
-5["data.ts"]
-8["response.ts"]
-end
-subgraph 6["config"]
-7["db.ts"]
-end
-end
-3-->5
-5-->7
-5-->8
diff --git a/src/misc/dependencyGraphs/mermaid-frontend.txt b/src/misc/dependencyGraphs/mermaid-frontend.txt
deleted file mode 100644
index 8dde5ce9..00000000
--- a/src/misc/dependencyGraphs/mermaid-frontend.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-flowchart TB
-
-subgraph 0["src"]
-subgraph 1["routes"]
-subgraph 2["frontendController"]
-3["routes.ts"]
-end
-end
-subgraph 4["handlers"]
-5["frontend.ts"]
-8["response.ts"]
-end
-subgraph 6["controllers"]
-7["frontendConfiguration.ts"]
-end
-end
-3-->5
-5-->7
-5-->8
diff --git a/src/misc/dependencyGraphs/mermaid-graph.txt b/src/misc/dependencyGraphs/mermaid-graph.txt
deleted file mode 100644
index 34484535..00000000
--- a/src/misc/dependencyGraphs/mermaid-graph.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-flowchart TB
-
-subgraph 0["src"]
-subgraph 1["routes"]
-subgraph 2["graphs"]
-3["routes.ts"]
-end
-end
-subgraph 4["handlers"]
-5["graph.ts"]
-6["response.ts"]
-end
-end
-3-->5
-3-->6
diff --git a/src/misc/dependencyGraphs/mermaid-ha.txt b/src/misc/dependencyGraphs/mermaid-ha.txt
deleted file mode 100644
index 2c789f6c..00000000
--- a/src/misc/dependencyGraphs/mermaid-ha.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-flowchart TB
-
-subgraph 0["src"]
-subgraph 1["routes"]
-subgraph 2["highavailability"]
-3["routes.ts"]
-end
-end
-subgraph 4["handlers"]
-5["ha.ts"]
-E["response.ts"]
-end
-subgraph 6["controllers"]
-7["highAvailability.ts"]
-end
-subgraph 8["config"]
-9["variables.ts"]
-end
-subgraph A["data"]
-B["variables.json"]
-end
-subgraph C["typings"]
-D["ha.ts"]
-end
-end
-3-->5
-5-->7
-5-->E
-7-->9
-7-->D
-9-->B
diff --git a/src/misc/dependencyGraphs/mermaid-notificationService.txt b/src/misc/dependencyGraphs/mermaid-notificationService.txt
deleted file mode 100644
index 2bc9731c..00000000
--- a/src/misc/dependencyGraphs/mermaid-notificationService.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-flowchart TB
-
-subgraph 0["src"]
-subgraph 1["routes"]
-subgraph 2["notifications"]
-3["routes.ts"]
-end
-end
-subgraph 4["handlers"]
-5["notification.ts"]
-6["response.ts"]
-end
-end
-3-->5
-5-->6
diff --git a/src/misc/entrypoint.sh b/src/misc/entrypoint.sh
deleted file mode 100755
index b352ca75..00000000
--- a/src/misc/entrypoint.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/bin/bash
-
-VERSION="$(cat ./package.json | grep version | cut -d '"' -f 4)"
-
-if [[ "$1" = "--dev" ]]; then
- node_env="development"
-elif [[ "$1" = "--prod" ]]; then
- node_env="production"
-fi
-
-echo -e "
-\033[1;32mWelcome to\033[0m
-
-\033[1;34m###### ###### #### ### ### #### ######### ###### #########\033[0m
-\033[1;34m### ### ### ### ### ### ### ### ### ### ### ###\033[0m
-\033[1;34m### ### ### ### ### ###### #### ### ### ### ###\033[0m
-\033[1;34m### ### ### ### ### ### ### #### ### ############ ###\033[0m
-\033[1;34m### ### ### ### ### ### ### #### ### ### ### ###\033[0m
-\033[1;34m###### ###### #### ### ### #### ### ### ### ### \033[0m(\033[1;33mAPI - v${VERSION}\033[0m)
-
-\033[1;36mUseful links:\033[0m
-
-- Documentation: \033[1;32mhttps://outline.itsnik.de/s/dockstat\033[0m
-- GitHub (Frontend): \033[1;32mhttps://github.com/its4nik/dockstat\033[0m
-- GitHub (Backend): \033[1;32mhttps://github.com/its4nik/dockstatapi\033[0m
-
-\033[1;35mSummary:\033[0m
-
-DockStat and DockStatAPI are 2 fully OpenSource projects, DockStatAPI is a simple but extensible API which allows queries via a REST endpoint.
-
-"
-
-bash ./createEnvFile.sh
-
-NODE_ENV=${node_env} node src/server.js
diff --git a/src/misc/minifyDist.sh b/src/misc/minifyDist.sh
deleted file mode 100755
index 171ef095..00000000
--- a/src/misc/minifyDist.sh
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/bash
-
-dist="$(pwd)/dist"
-
-run_script() {
- npx uglifyjs --no-annotations --in-situ "$1" > /dev/null
- echo "✔️ Minified : $(basename "$1")"
-}
-
-if [ -d "$dist" ]; then
- echo "::: Dist directory exists."
-else
- echo "::: Dist does not exist... Running npx tsc"
- npx tsc
-fi
-
-max_jobs=$(nproc)
-job_count=0
-
-for file in $(find "$dist" -type f -name "*.js"); do
- run_script "$file" &
- ((job_count++))
-
- if ((job_count >= max_jobs)); then
- wait
- job_count=0
- fi
-done
-
-wait
-
-echo
-
-if [[ $1 == "--build-only" ]]; then
- exit 0
-fi
-
-node dist/server.js
diff --git a/src/misc/removeUnusedDeps.sh b/src/misc/removeUnusedDeps.sh
deleted file mode 100755
index 5e806df3..00000000
--- a/src/misc/removeUnusedDeps.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/bash
-
-echo "Creating unused dependency list"
-
-TMP="$(npx depcheck --ignores https,@typescript-eslint/eslint-plugin,@typescript-eslint/parser,license-checker,uglify-js,@types/supports-color,ipaddr.js,dependency-cruiser,tsx,@types/bcrypt,@types/express,@types/express-handlebars,@types/node,ts-node --quiet --oneline | tail -n 1 | tr -d '\n')"
-
-lines=$(echo -n "$TMP" | tr -s ' ' '\n' | wc -l)
-
-if ((lines == 0)); then
- echo "No unused dependencies."
-else
- echo
- echo "Removing these unused dependencies ($lines):"
- for entry in $TMP; do
- echo "$entry"
- done
- echo
-
-
- read -n 1 -p "Delete unused dependencies? (y/n) " input
- echo
-
- case $input in
- Y|y)
- COMMAND=$(echo "npm remove $TMP")
- $COMMAND
- exit 0
- ;;
- *)
- echo "Aborting"
- exit 1
- ;;
- esac
-fi
-
-exit 0
diff --git a/src/plugins/example.plugin.ts b/src/plugins/example.plugin.ts
new file mode 100644
index 00000000..a9ed6acc
--- /dev/null
+++ b/src/plugins/example.plugin.ts
@@ -0,0 +1,23 @@
+import type { Plugin } from "~/typings/plugin";
+import type { ContainerInfo } from "~/typings/docker";
+import type { HostStats } from "~/typings/docker";
+import { logger } from "~/core/utils/logger";
+
+const ExamplePlugin: Plugin = {
+ name: "Example Plugin",
+ async onContainerStart(containerInfo: ContainerInfo) {},
+ async onContainerStop(containerInfo: ContainerInfo) {},
+ async onContainerExit(containerInfo: ContainerInfo) {},
+ async onContainerCreate(containerInfo: ContainerInfo) {},
+ async onContainerDestroy(containerInfo: ContainerInfo) {},
+ async onContainerPause(containerInfo: ContainerInfo) {},
+ async onContainerUnpause(containerInfo: ContainerInfo) {},
+ async onContainerRestart(containerInfo: ContainerInfo) {},
+ async onContainerUpdate(containerInfo: ContainerInfo) {},
+ async onContainerRename(containerInfo: ContainerInfo) {},
+ async onContainerHealthStatus(containerInfo: ContainerInfo) {},
+ async onHostUnreachable(HostStats: HostStats) {},
+ async onHostReachableAgain(HostStats: HostStats) {},
+} satisfies Plugin;
+
+export default ExamplePlugin;
diff --git a/src/plugins/telegram.plugin.ts b/src/plugins/telegram.plugin.ts
new file mode 100644
index 00000000..cf7c376d
--- /dev/null
+++ b/src/plugins/telegram.plugin.ts
@@ -0,0 +1,34 @@
+import type { Plugin } from "~/typings/plugin";
+import type { ContainerInfo } from "~/typings/docker";
+import { logger } from "~/core/utils/logger";
+
+const TELEGRAM_BOT_TOKEN = "CHANGE_ME"; // Replace with your bot token
+const TELEGRAM_CHAT_ID = "CHANGE_ME"; // Replace with your chat ID
+
+const TelegramNotificationPlugin: Plugin = {
+ name: "Telegram Notification Plugin",
+ async onContainerStart(containerInfo: ContainerInfo) {
+ const message = `Container Started: ${containerInfo.name} on ${containerInfo.hostId}`;
+ try {
+ const response = await fetch(
+ `https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage`,
+ {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({
+ chat_id: TELEGRAM_CHAT_ID,
+ text: message,
+ }),
+ },
+ );
+ if (!response.ok) {
+ logger.error(`HTTP error ${response.status}`);
+ }
+ logger.info("Telegram notification sent.");
+ } catch (error) {
+ logger.error("Failed to send Telegram notification", error as string);
+ }
+ },
+} satisfies Plugin;
+
+export default TelegramNotificationPlugin;
diff --git a/src/routes/api-config.ts b/src/routes/api-config.ts
new file mode 100644
index 00000000..e6185517
--- /dev/null
+++ b/src/routes/api-config.ts
@@ -0,0 +1,96 @@
+import { Elysia, t } from "elysia";
+import { dbFunctions } from "~/core/database/repository";
+import { logger } from "~/core/utils/logger";
+import { responseHandler } from "~/core/utils/respone-handler";
+import { config } from "~/typings/database";
+import {
+ version,
+ authorEmail,
+ authorName,
+ authorWebsite,
+ contributors,
+ dependencies,
+ description,
+ devDependencies,
+ license,
+} from "~/core/utils/package-json";
+
+export const apiConfigRoutes = new Elysia({ prefix: "/config" })
+ .get(
+ "/get",
+ async ({ set }) => {
+ try {
+ const data = dbFunctions.getConfig() as config[];
+ const distinct = data[0];
+ set.status = 200;
+ set.headers["Content-Type"] = "application/json";
+ logger.debug("Fetched backend config");
+ return distinct;
+ } catch (error) {
+ return responseHandler.error(
+ set,
+ "Error getting the DockStatAPI config",
+ error as string,
+ );
+ }
+ },
+ {
+ tags: ["Management"],
+ },
+ )
+ .post(
+ "/update",
+ async ({ set, body }) => {
+ try {
+ const { polling_rate, fetching_interval, keep_data_for } = body;
+ set.headers["Content-Type"] = "application/json";
+ dbFunctions.updateConfig(
+ polling_rate,
+ fetching_interval,
+ keep_data_for,
+ );
+ return responseHandler.ok(set, "Updated DockStatAPI config");
+ } catch (error) {
+ return responseHandler.error(
+ set,
+ "Error updating the DockStatAPI config",
+ error as string,
+ );
+ }
+ },
+ {
+ body: t.Object({
+ polling_rate: t.Number(),
+ fetching_interval: t.Number(),
+ keep_data_for: t.Number(),
+ }),
+ tags: ["Management"],
+ },
+ )
+ .get("/package", async ({ set }) => {
+ try {
+ logger.debug("Fetching package.json");
+ return {
+ version: version,
+ description: description,
+ license: license,
+ authorName: authorName,
+ authorEmail: authorEmail,
+ authorWebsite: authorWebsite,
+ contributors: contributors,
+ dependencies: dependencies,
+ devDependencies: devDependencies,
+ };
+
+ } catch (error) {
+ return responseHandler.error(
+ set,
+ error as string,
+ "Error while reading package.json",
+ );
+ }
+ },
+ {
+ tags: ["Management"],
+ },
+ );
diff --git a/src/routes/auth/routes.ts b/src/routes/auth/routes.ts
deleted file mode 100644
index 03549bfa..00000000
--- a/src/routes/auth/routes.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { Router, Request, Response } from "express";
-import { createAuthenticationHandler } from "../../handlers/auth";
-
-const router = Router();
-
-router.post("/enable", async (req: Request, res: Response): Promise => {
- const password = req.query.password as string;
- const handler = createAuthenticationHandler(req, res);
- await handler.enable(password);
-});
-
-router.post("/disable", async (req: Request, res: Response): Promise => {
- const password = req.query.password as string;
- const handler = createAuthenticationHandler(req, res);
- await handler.disable(password);
-});
-
-export default router;
diff --git a/src/routes/data/routes.ts b/src/routes/data/routes.ts
deleted file mode 100644
index 93c4610b..00000000
--- a/src/routes/data/routes.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import express, { Request, Response } from "express";
-const router = express.Router();
-import { createDatabaseHandler } from "../../handlers/data";
-
-router.get("/latest", (req: Request, res: Response) => {
- const DatabaseHandler = createDatabaseHandler(req, res);
- return DatabaseHandler.latest();
-});
-
-router.get("/all", (req: Request, res: Response) => {
- const DatabaseHandler = createDatabaseHandler(req, res);
- return DatabaseHandler.all();
-});
-
-router.delete("/clear", (req: Request, res: Response) => {
- const DatabaseHandler = createDatabaseHandler(req, res);
- return DatabaseHandler.clear();
-});
-
-export default router;
diff --git a/src/routes/docker-manager.ts b/src/routes/docker-manager.ts
new file mode 100644
index 00000000..eb53fdb9
--- /dev/null
+++ b/src/routes/docker-manager.ts
@@ -0,0 +1,82 @@
+import { Elysia, t } from "elysia";
+import { dbFunctions } from "~/core/database/repository";
+import { logger } from "~/core/utils/logger";
+import { responseHandler } from "~/core/utils/respone-handler";
+
+export const dockerRoutes = new Elysia({ prefix: "/docker-config" })
+ .post(
+ "/add-host",
+ async ({ set, body }) => {
+ try {
+ const { name, url, secure } = body;
+ set.headers["Content-Type"] = "application/json";
+ dbFunctions.addDockerHost(name, url, secure);
+ return responseHandler.ok(set, `Added docker host (${name})`);
+ } catch (error: unknown) {
+ return responseHandler.error(
+ set,
+ "Error adding docker Host",
+ error as string,
+ );
+ }
+ },
+ {
+ detail: {
+ tags: ["Management"],
+ },
+ body: t.Object({
+ name: t.String(),
+ url: t.String(),
+ secure: t.Boolean(),
+ }),
+ },
+ )
+
+ .post(
+ "/update-host",
+ async ({ set, body }) => {
+ try {
+ const { name, url, secure } = body;
+ dbFunctions.updateDockerHost(name, url, secure);
+ } catch (error) {
+ return responseHandler.error(
+ set,
+ error as string,
+ "Failed to update host",
+ );
+ }
+ },
+ {
+ detail: {
+ tags: ["Management"],
+ },
+ body: t.Object({
+ name: t.String(),
+ url: t.String(),
+ secure: t.Boolean(),
+ }),
+ },
+ )
+
+ .get(
+ "/hosts",
+ async ({ set }) => {
+ try {
+ const dockerHosts = dbFunctions.getDockerHosts();
+ set.headers["Content-Type"] = "application/json";
+ logger.debug("Retrieved docker hosts");
+ return dockerHosts;
+ } catch (error) {
+ return responseHandler.error(
+ set,
+ error as string,
+ "Failed to retrieve hosts",
+ );
+ }
+ },
+ {
+ detail: {
+ tags: ["Management"],
+ },
+ },
+ );
diff --git a/src/routes/docker-stats.ts b/src/routes/docker-stats.ts
new file mode 100644
index 00000000..d85bfc1f
--- /dev/null
+++ b/src/routes/docker-stats.ts
@@ -0,0 +1,157 @@
+import Docker from "dockerode";
+import { Elysia } from "elysia";
+import { dbFunctions } from "~/core/database/repository";
+import { getDockerClient } from "~/core/docker/client";
+import {
+ calculateCpuPercent,
+ calculateMemoryUsage,
+} from "~/core/utils/calculations";
+import { logger } from "~/core/utils/logger";
+import { responseHandler } from "~/core/utils/respone-handler";
+import type { ContainerInfo, DockerHost, HostStats } from "~/typings/docker";
+import type { DockerInfo } from "~/typings/dockerode";
+
+export const dockerStatsRoutes = new Elysia({ prefix: "/docker" })
+ .get(
+ "/containers",
+ async ({ set }) => {
+ try {
+ const hosts = dbFunctions.getDockerHosts() as DockerHost[];
+ const containers: ContainerInfo[] = [];
+
+ await Promise.all(
+ hosts.map(async (host) => {
+ try {
+ const docker = getDockerClient(host);
+ try {
+ await docker.ping();
+ } catch (pingError) {
+ return responseHandler.error(
+ set,
+ pingError as string,
+ "Docker host connection failed",
+ );
+ }
+
+ const hostContainers = await docker.listContainers({ all: true });
+
+ await Promise.all(
+ hostContainers.map(async (containerInfo) => {
+ try {
+ const container = docker.getContainer(containerInfo.Id);
+ const stats = await new Promise(
+ (resolve, reject) => {
+ container.stats({ stream: false }, (error, stats) => {
+ if (error) {
+ return responseHandler.reject(
+ set,
+ reject,
+ "An error occurred",
+ error,
+ );
+ }
+ if (!stats) {
+ return responseHandler.reject(
+ set,
+ reject,
+ "No stats available",
+ );
+ }
+ resolve(stats);
+ });
+ },
+ );
+
+ containers.push({
+ id: containerInfo.Id,
+ hostId: host.name,
+ name: containerInfo.Names[0].replace(/^\//, ""),
+ image: containerInfo.Image,
+ status: containerInfo.Status,
+ state: containerInfo.State,
+ cpuUsage: calculateCpuPercent(stats),
+ memoryUsage: calculateMemoryUsage(stats),
+ });
+ } catch (containerError) {
+ logger.error(
+ "Error fetching container stats,",
+ containerError,
+ );
+ }
+ }),
+ );
+ logger.debug(`Fetched stats for ${host.name}`);
+ } catch (hostError) {
+ logger.error("Error fetching containers for host,", hostError);
+ }
+ }),
+ );
+
+ set.headers["Content-Type"] = "application/json";
+ logger.debug("Fetched all containers across all hosts");
+ return { containers };
+ } catch (error) {
+ return responseHandler.error(
+ set,
+ error as string,
+ "Failed to retrieve containers",
+ );
+ }
+ },
+ {
+ detail: {
+ tags: ["Statistics"],
+ },
+ },
+ )
+
+ .get(
+ "/hosts/:id",
+ async ({ params, set }) => {
+ try {
+ const hosts = dbFunctions.getDockerHosts() as DockerHost[];
+ const host = hosts.find((h) => h.name === params.id);
+
+ if (!host) {
+ return responseHandler.simple_error(
+ set,
+ `Host (${params.id}) not found`,
+ );
+ }
+
+ const docker = getDockerClient(host);
+ const info: DockerInfo = await docker.info();
+
+ const config: HostStats = {
+ hostId: host.name,
+ dockerVersion: info.ServerVersion,
+ apiVersion: info.Driver,
+ os: info.OperatingSystem,
+ architecture: info.Architecture,
+ totalMemory: info.MemTotal,
+ totalCPU: info.NCPU,
+ labels: info.Labels,
+ images: info.Images,
+ containers: info.Containers,
+ containersPaused: info.ContainersPaused,
+ containersRunning: info.ContainersRunning,
+ containersStopped: info.ContainersStopped,
+ };
+
+ set.headers["Content-Type"] = "application/json";
+ logger.debug(`Fetched config for ${host.name}`);
+ return config;
+ } catch (error) {
+ return responseHandler.error(
+ set,
+ error as string,
+ "Failed to retrieve host config",
+ );
+ }
+ },
+ {
+ detail: {
+ tags: ["Statistics"],
+ },
+ },
+ );
diff --git a/src/routes/docker-websocket.ts b/src/routes/docker-websocket.ts
new file mode 100644
index 00000000..43c8038a
--- /dev/null
+++ b/src/routes/docker-websocket.ts
@@ -0,0 +1,240 @@
+import type { StatusMap } from "elysia";
+import { Elysia } from "elysia";
+import type { HTTPHeaders } from "elysia/dist/types";
+import { dbFunctions } from "~/core/database/repository";
+import { getDockerClient } from "~/core/docker/client";
+import {
+ calculateCpuPercent,
+ calculateMemoryUsage,
+} from "~/core/utils/calculations";
+import { logger } from "~/core/utils/logger";
+import { responseHandler } from "~/core/utils/respone-handler";
+import type { DockerHost } from "~/typings/docker";
+import split2 from "split2";
+import type { Readable } from "stream";
+import type { streams } from "~/typings/websocket";
+
+interface ExtendedWebSocket extends WebSocket {
+ isOpen: boolean;
+ streams: any[];
+ heartbeat: NodeJS.Timeout | null;
+}
+
+const set: { headers: HTTPHeaders; status?: number | keyof StatusMap } = {
+ headers: {},
+};
+
+export const dockerWebsocketRoutes = new Elysia({ prefix: "/docker" }).ws(
+ "/stats",
+ {
+ async open(socket) {
+ socket.send(JSON.stringify({ message: "Connection established" }));
+ let hosts: DockerHost[];
+
+ (socket as unknown as ExtendedWebSocket).isOpen = true;
+ (socket as unknown as ExtendedWebSocket).streams = [];
+ (socket as unknown as ExtendedWebSocket).heartbeat = null; // Add heartbeat reference
+
+ logger.info(`Opened WebSocket (${socket.id})`);
+
+ try {
+ hosts = dbFunctions.getDockerHosts();
+ logger.debug(
+ `Retrieved ${hosts.length} docker host(s) from the database`,
+ );
+ } catch (error: unknown) {
+ const errResponse = responseHandler.error(
+ set,
+ (error as Error).message,
+ "Failed to retrieve Docker hosts",
+ 500,
+ );
+ logger.error(
+ `Error retrieving Docker hosts: ${(error as Error).message}`,
+ );
+ socket.send(JSON.stringify(errResponse));
+ return;
+ }
+
+ // Add heartbeat using WebSocket protocol-level ping
+ (socket as any).heartbeat = setInterval(() => {
+ if (!(socket as unknown as ExtendedWebSocket).isOpen) {
+ clearInterval((socket as any).heartbeat);
+ return;
+ }
+ socket.ping(); // Use WebSocket protocol ping
+ }, 30000);
+
+ for (const host of hosts) {
+ if (!(socket as unknown as ExtendedWebSocket).isOpen) {
+ break
+ };
+
+ logger.debug(`Processing host: ${host.name}`);
+
+ try {
+ const docker = getDockerClient(host);
+ await docker.ping();
+ logger.debug(`Ping successful for host: ${host.name}`);
+ logger.debug(`Listing containers for host: ${host.name}`);
+ const containers = await docker.listContainers();
+ logger.debug(
+ `Found ${containers.length} container(s) on host ${host.name}`,
+ );
+
+ for (const containerInfo of containers) {
+ if (!(socket as unknown as ExtendedWebSocket).isOpen) {
+ break
+ };
+
+ logger.debug(
+ `Processing container ${containerInfo.Id} on host ${host.name}`,
+ );
+ const container = docker.getContainer(containerInfo.Id);
+ try {
+ logger.debug(
+ `Starting stats stream for container ${containerInfo.Id} on host ${host.name}`,
+ );
+ const statsStream = (await container.stats({
+ stream: true,
+ })) as Readable;
+ const splitStream = split2();
+
+ // Store both streams for cleanup
+ (socket as unknown as ExtendedWebSocket).streams.push({ statsStream, splitStream });
+
+ // Handle stream lifecycle
+ statsStream
+ .on("close", () => {
+ logger.debug(`Stats stream closed for ${containerInfo.Id}`);
+ splitStream.destroy();
+ })
+ .on("end", () => {
+ logger.debug(`Stats stream ended for ${containerInfo.Id}`);
+ splitStream.destroy();
+ });
+
+ statsStream
+ .pipe(splitStream)
+ .on("data", (line: string) => {
+ // 1 = OPEN state
+ if (socket.readyState !== 1) {
+ return
+ };
+ if (!line) {
+ return
+ };
+ try {
+ const stats = JSON.parse(line);
+ const cpuUsage = calculateCpuPercent(stats);
+ const memoryUsage = calculateMemoryUsage(stats);
+
+ const data = {
+ id: containerInfo.Id,
+ hostId: host.name,
+ name: containerInfo.Names[0].replace(/^\//, ""),
+ image: containerInfo.Image,
+ status: containerInfo.Status,
+ state: containerInfo.State,
+ cpuUsage,
+ memoryUsage,
+ };
+ socket.send(JSON.stringify(data));
+ } catch (parseErr: any) {
+ logger.error(
+ `Failed to parse stats for container ${containerInfo.Id} on host ${host.name}: ${parseErr.message}`,
+ );
+ }
+ })
+ .on("error", (err: Error) => {
+ logger.error(
+ `Stats stream error for container ${containerInfo.Id} on host ${host.name}: ${err.message}`,
+ );
+ if (socket.readyState === 1) {
+ socket.send(
+ JSON.stringify({
+ hostId: host.name,
+ containerId: containerInfo.Id,
+ error: `Stats stream error for container ${containerInfo.Id} on host ${host.name}`,
+ }),
+ );
+ }
+ statsStream.destroy();
+ });
+ } catch (streamErr: any) {
+ const errMsg = `Failed to start stats stream for container ${containerInfo.Id}`;
+ logger.error(
+ `Failed to start stats stream for container ${containerInfo.Id} on host ${host.name}: ${streamErr.message}`,
+ );
+ if (socket.readyState === 1) {
+ socket.send(
+ JSON.stringify({
+ hostId: host.name,
+ containerId: containerInfo.Id,
+ error: errMsg,
+ }),
+ );
+ }
+ }
+ }
+ } catch (err: any) {
+ logger.error(
+ `Failed to list containers for host ${host.name}: ${err.message}`,
+ );
+ const errResponse = responseHandler.error(
+ set,
+ err.message,
+ `Failed to list containers for host ${host.name}`,
+ 500,
+ );
+ if (socket.readyState === 1) {
+ socket.send(
+ JSON.stringify({
+ hostId: host.name,
+ error: errResponse.error,
+ }),
+ );
+ }
+ }
+ }
+ },
+
+ message(_, message) {
+ if (message === "pong") {
+ return
+ };
+ },
+
+ close(socket, code, reason) {
+ logger.info(`Closing SplitStream and WebSocket (${socket.id})`);
+ const wasOpen = (socket as unknown as ExtendedWebSocket).isOpen;
+ (socket as unknown as ExtendedWebSocket).isOpen = false;
+
+ // Immediate heartbeat cleanup
+ clearInterval((socket as any).heartbeat);
+
+ // Force-close streams using destructor pattern
+ const streams: streams[] = (socket as unknown as ExtendedWebSocket).streams || [];
+ streams.forEach(({ statsStream, splitStream }) => {
+ try {
+ // Immediate pipeline breakdown
+ statsStream.unpipe(splitStream);
+ statsStream.destroy(new Error("WebSocket closed"));
+ splitStream.destroy(new Error("WebSocket closed"));
+
+ // Remove all potential listeners
+ statsStream.removeAllListeners();
+ splitStream.removeAllListeners();
+ } catch (err) {
+ logger.error(`Stream cleanup error: ${err}`);
+ }
+ });
+
+ if (wasOpen) {
+ logger.info(
+ `Closed WebSocket (${socket.id}) - Code: ${code} - Reason: ${reason}`,
+ );
+ }
+ },
+ },
+);
diff --git a/src/routes/frontendController/routes.ts b/src/routes/frontendController/routes.ts
deleted file mode 100644
index 723afa47..00000000
--- a/src/routes/frontendController/routes.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-import express from "express";
-const router = express.Router();
-import { createFrontendHandler } from "../../handlers/frontend";
-
-router.post("/show/:containerName", async (req, res) => {
- const FrontendHandler = createFrontendHandler(req, res);
- const containerName = req.params.containerName;
- return FrontendHandler.show(containerName);
-});
-
-router.post("/tag/:containerName/:tag", async (req, res) => {
- const { containerName, tag } = req.params;
- const FrontendHandler = createFrontendHandler(req, res);
- return FrontendHandler.addTag(containerName, tag);
-});
-
-router.post("/pin/:containerName", async (req, res) => {
- const { containerName } = req.params;
- const FrontendHandler = createFrontendHandler(req, res);
- return FrontendHandler.pin(containerName);
-});
-
-router.post("/add-link/:containerName/:link", async (req, res) => {
- const { containerName, link } = req.params;
- const FrontendHandler = createFrontendHandler(req, res);
- return FrontendHandler.addLink(containerName, link);
-});
-
-router.post(
- "/add-icon/:containerName/:icon/:useCustomIcon",
- async (req, res) => {
- const { containerName, icon, useCustomIcon } = req.params;
- const FrontendHandler = createFrontendHandler(req, res);
- return FrontendHandler.addIcon(containerName, icon, useCustomIcon);
- },
-);
-
-/*
- ____ _____ _ _____ _____ _____
-| _ \| ____| | | ____|_ _| ____|
-| | | | _| | | | _| | | | _|
-| |_| | |___| |___| |___ | | | |___
-|____/|_____|_____|_____| |_| |_____|
-*/
-
-router.delete("/hide/:containerName", async (req, res) => {
- const { containerName } = req.params;
- const FrontendHandler = createFrontendHandler(req, res);
- return FrontendHandler.hide(containerName);
-});
-
-router.delete("/remove-tag/:containerName/:tag", async (req, res) => {
- const { containerName, tag } = req.params;
- const FrontendHandler = createFrontendHandler(req, res);
- return FrontendHandler.removeTag(containerName, tag);
-});
-
-router.delete("/unpin/:containerName", async (req, res) => {
- const { containerName } = req.params;
- const FrontendHandler = createFrontendHandler(req, res);
- return FrontendHandler.unPin(containerName);
-});
-
-router.delete("/remove-link/:containerName", async (req, res) => {
- const { containerName } = req.params;
- const FrontendHandler = createFrontendHandler(req, res);
- return FrontendHandler.removeLink(containerName);
-});
-
-router.delete("/remove-icon/:containerName", async (req, res) => {
- const { containerName } = req.params;
- const FrontendHandler = createFrontendHandler(req, res);
- return FrontendHandler.removeIcon(containerName);
-});
-
-export default router;
diff --git a/src/routes/getter/routes.ts b/src/routes/getter/routes.ts
deleted file mode 100644
index d08ae511..00000000
--- a/src/routes/getter/routes.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import { Router, Request, Response } from "express";
-import { createApiHandler } from "../../handlers/api";
-const router = Router();
-
-router.get("/hosts", (req: Request, res: Response) => {
- const ApiHandler = createApiHandler(req, res);
- return ApiHandler.hosts();
-});
-
-router.get("/system", (req: Request, res: Response) => {
- const ApiHandler = createApiHandler(req, res);
- return ApiHandler.system();
-});
-
-router.get("/host/:hostName/stats", async (req: Request, res: Response) => {
- const { hostName } = req.params;
- const ApiHandler = createApiHandler(req, res);
- return ApiHandler.hostStats(hostName);
-});
-
-router.get("/containers", async (req: Request, res: Response) => {
- const ApiHandler = createApiHandler(req, res);
- return ApiHandler.containers();
-});
-
-router.get("/config", async (req: Request, res: Response) => {
- const ApiHandler = createApiHandler(req, res);
- return ApiHandler.config();
-});
-
-router.get("/current-schedule", (req: Request, res: Response) => {
- const ApiHandler = createApiHandler(req, res);
- return ApiHandler.currentSchedule();
-});
-
-router.get("/status", async (req: Request, res: Response) => {
- const ApiHandler = createApiHandler(req, res);
- return ApiHandler.status();
-});
-
-router.get("/frontend-config", (req: Request, res: Response) => {
- const ApiHandler = createApiHandler(req, res);
- return ApiHandler.frontendConfig();
-});
-
-export default router;
diff --git a/src/routes/graphs/routes.ts b/src/routes/graphs/routes.ts
deleted file mode 100644
index fcaa7983..00000000
--- a/src/routes/graphs/routes.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { Request, Response, Router } from "express";
-import { createResponseHandler } from "../../handlers/response";
-import path from "path";
-import { rateLimitedReadFile } from "../../utils/rateLimitFS";
-const router = Router();
-
-router.get("/json", async (req: Request, res: Response) => {
- const ResponseHandler = createResponseHandler(res);
- try {
- const data = await rateLimitedReadFile(
- path.join(__dirname, "/../../.." + "/src/data/graph.json"),
- );
- return ResponseHandler.rawData(data, "Graph JSON fetched");
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- return ResponseHandler.critical(errorMsg);
- }
-});
-
-export default router;
diff --git a/src/routes/highavailability/routes.ts b/src/routes/highavailability/routes.ts
deleted file mode 100644
index d4adc466..00000000
--- a/src/routes/highavailability/routes.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import { Router, Request, Response } from "express";
-import { SyncRequestBody } from "../../typings/syncRequestBody";
-import { createHaHandler } from "../../handlers/ha";
-const router = Router();
-
-router.get("/config", async (req: Request, res: Response) => {
- const HaHandler = createHaHandler(req, res);
- return HaHandler.config();
-});
-
-router.post(
- "/sync",
- async (
- req: Request<{}, {}, SyncRequestBody>, // eslint-disable-line
- res: Response,
- ): Promise => {
- const HaHandler = createHaHandler(req, res);
- return HaHandler.sync(req);
- },
-);
-
-router.get("/prepare-sync", async (req: Request, res: Response) => {
- const HaHandler = createHaHandler(req, res);
- return HaHandler.prepare();
-});
-
-export default router;
diff --git a/src/routes/logs.ts b/src/routes/logs.ts
new file mode 100644
index 00000000..a8cae1c5
--- /dev/null
+++ b/src/routes/logs.ts
@@ -0,0 +1,88 @@
+import { Elysia } from "elysia";
+import { dbFunctions } from "~/core/database/repository";
+import { logger } from "~/core/utils/logger";
+
+export const backendLogs = new Elysia({ prefix: "/logs" })
+ .get(
+ "/",
+ async ({ set }) => {
+ try {
+ const logs = dbFunctions.getAllLogs();
+ set.headers["Content-Type"] = "application/json";
+ logger.debug(`Retrieved all logs`);
+ return logs;
+ } catch (error) {
+ set.status = 500;
+ logger.error("Failed to retrieve logs,", error);
+ return { error: "Failed to retrieve logs" };
+ }
+ },
+ {
+ detail: {
+ tags: ["Management"],
+ },
+ },
+ )
+
+ .get(
+ "/:level",
+ async ({ params: { level }, set }) => {
+ try {
+ const logs = dbFunctions.getLogsByLevel(level);
+ set.headers["Content-Type"] = "application/json";
+ logger.debug(`Retrieved logs (level: ${level})`);
+ return logs;
+ } catch (error) {
+ set.status = 500;
+ logger.error("Failed to retrieve logs");
+ return { error: "Failed to retrieve logs" };
+ }
+ },
+ {
+ detail: {
+ tags: ["Management"],
+ },
+ },
+ )
+
+ .delete(
+ "/",
+ async ({ set }) => {
+ try {
+ set.status = 200;
+ set.headers["Content-Type"] = "application/json";
+ dbFunctions.clearAllLogs();
+ return { success: true };
+ } catch (error) {
+ set.status = 500;
+ logger.error("Could not delete all logs,", error);
+ return { error: "Could not delete all logs" };
+ }
+ },
+ {
+ detail: {
+ tags: ["Management"],
+ },
+ },
+ )
+
+ .delete(
+ "/:level",
+ async ({ params: { level }, set }) => {
+ try {
+ dbFunctions.clearLogsByLevel(level);
+ set.headers["Content-Type"] = "application/json";
+ logger.debug(`Cleared all logs with level: ${level}`);
+ return { success: true };
+ } catch (error) {
+ set.status = 500;
+ logger.error("Could not clear logs with level", level, ",", error);
+ return { error: "Failed to retrieve logs" };
+ }
+ },
+ {
+ detail: {
+ tags: ["Management"],
+ },
+ },
+ );
diff --git a/src/routes/notifications/routes.ts b/src/routes/notifications/routes.ts
deleted file mode 100644
index 13b754bd..00000000
--- a/src/routes/notifications/routes.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { Request, Response, Router } from "express";
-import { createNotificationHandler } from "../../handlers/notification";
-const router = Router();
-
-router.get("/get-template", (req: Request, res: Response) => {
- const NotificationHandler = createNotificationHandler(req, res);
- return NotificationHandler.getTemplate();
-});
-
-router.post("/set-template", (req: Request, res: Response): void => {
- const NotificationHandler = createNotificationHandler(req, res);
- return NotificationHandler.setTemplate(req);
-});
-
-router.post("/test/:type/:containerId", async (req: Request, res: Response) => {
- const NotificationHandler = createNotificationHandler(req, res);
- NotificationHandler.test(req);
-});
-
-export default router;
diff --git a/src/routes/setter/routes.ts b/src/routes/setter/routes.ts
deleted file mode 100644
index 16150293..00000000
--- a/src/routes/setter/routes.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import express, { Router, Request, Response } from "express";
-const router: Router = express.Router();
-import { createConfHandler } from "../../handlers/conf";
-
-router.put("/addHost", async (req: Request, res: Response): Promise => {
- const ConfHandler = createConfHandler(req, res);
- return ConfHandler.addHost(req);
-});
-
-router.delete("/removeHost", (req: Request, res: Response): void => {
- const ConfHandler = createConfHandler(req, res);
- return ConfHandler.removeHost(req);
-});
-
-router.put("/scheduler", (req: Request, res: Response) => {
- const ConfHandler = createConfHandler(req, res);
- return ConfHandler.scheduler(req);
-});
-
-export default router;
diff --git a/src/routes/stack/routes.ts b/src/routes/stack/routes.ts
deleted file mode 100644
index 8f9b9ae8..00000000
--- a/src/routes/stack/routes.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import express, { Router, Request, Response } from "express";
-const router: Router = express.Router();
-import { createStackHandler } from "../../handlers/stack";
-
-router.post("/create/:name", async (req: Request, res: Response) => {
- const StackHandler = createStackHandler(req, res);
- return StackHandler.createStack(req, res);
-});
-
-router.post("/start/:name", async (req: Request, res: Response) => {
- const StackHandler = createStackHandler(req, res);
- return StackHandler.start(req, res);
-});
-
-router.post("/stop/:name", async (req: Request, res: Response) => {
- const StackHandler = createStackHandler(req, res);
- return StackHandler.stop(req, res);
-});
-
-router.get("/get/:name", async (req: Request, res: Response) => {
- const StackHandler = createStackHandler(req, res);
- return await StackHandler.stackCompose(req, res);
-});
-
-router.post("/set-env/:name", async (req: Request, res: Response) => {
- const StackHandler = createStackHandler(req, res);
- return await StackHandler.setStackEnv(req, res);
-});
-
-router.get("/get-env/:name", async (req: Request, res: Response) => {
- const StackHandler = createStackHandler(req, res);
- return await StackHandler.getStackEnv(req, res);
-});
-
-export default router;
diff --git a/src/routes/stacks.ts b/src/routes/stacks.ts
new file mode 100644
index 00000000..600dec55
--- /dev/null
+++ b/src/routes/stacks.ts
@@ -0,0 +1,239 @@
+import { Elysia, error, t } from "elysia";
+import { responseHandler } from "~/core/utils/respone-handler";
+import {
+ deployStack,
+ stopStack,
+ pullStackImages,
+ restartStack,
+ getStackStatus,
+ startStack
+} from "~/core/stacks/controller";
+import { dbFunctions } from "~/core/database/repository";
+import { logger } from "~/core/utils/logger";
+
+export const stackRoutes = new Elysia({ prefix: "/stacks" })
+ .post(
+ "/deploy",
+ async ({ set, body }) => {
+ try {
+ const isCustom = body.isCustom || false;
+
+
+ const image_updates = body.image_updates || false;
+
+
+ let missingParams: string[] = [];
+ if (!body.compose_spec) {
+ missingParams.push("compose_spec");
+ }
+ if (!body.automatic_reboot_on_error) {
+ missingParams.push("automatic_reboot_on_error");
+ }
+ if (!body.source) {
+ missingParams.push("source");
+ }
+ if (!body.name) {
+ missingParams.push("name");
+ }
+
+ if (missingParams.length > 0) {
+ const errMsg = `Missing values of: ${missingParams.join("; ")}`;
+ return responseHandler.error(set, errMsg, errMsg);
+ }
+
+ await deployStack(
+ body.compose_spec,
+ body.name,
+ body.version,
+ body.source,
+ body.automatic_reboot_on_error,
+ isCustom,
+ image_updates,
+ body.stack_prefix
+ );
+ logger.info(`Deployed Stack (${body.name})`)
+ return responseHandler.ok(
+ set,
+ `Stack ${body.name} deployed successfully`
+ );
+ } catch (error: any) {
+ return responseHandler.error(
+ set,
+ error.message || error,
+ "Error deploying stack"
+ );
+ }
+ },
+ {
+ detail: { tags: ["Stacks"] },
+ body: t.Object({
+ compose_spec: t.Any(),
+ name: t.String(),
+ version: t.Number(),
+ automatic_reboot_on_error: t.Boolean(),
+ isCustom: t.Boolean(),
+ image_updates: t.Boolean(),
+ source: t.String(),
+ stack_prefix: t.Optional(t.String()),
+ }),
+ }
+ )
+ .post(
+ "/start",
+ async ({ set, body }) => {
+ try {
+ if (!body.stack) {
+ throw new Error("Stack needed")
+ }
+ await startStack(body.stack);
+ logger.info(`Started Stack (${body.stack})`)
+ return responseHandler.ok(
+ set,
+ `Stack ${body.stack} started successfully`
+ );
+ } catch (error: any) {
+ return responseHandler.error(
+ set,
+ error.message || error,
+ "Error starting stack"
+ );
+ }
+ },
+ {
+ detail: { tags: ["Stacks"] },
+ body: t.Object({
+ stack: t.Any(),
+ }),
+ }
+ )
+ .post(
+ "/stop",
+ async ({ set, body }) => {
+ try {
+ if (!body.stack) {
+ throw new Error("Stack needed")
+ }
+ await stopStack(body.stack);
+ logger.info(`Stopped Stack (${body.stack})`)
+ return responseHandler.ok(
+ set,
+ `Stack ${body.stack} stopped successfully`
+ );
+ } catch (error: any) {
+ return responseHandler.error(
+ set,
+ error.message || error,
+ "Error stopping stack"
+ );
+ }
+ },
+ {
+ detail: { tags: ["Stacks"] },
+ body: t.Object({
+ stack: t.Any(),
+ }),
+ }
+ )
+ .post(
+ "/restart",
+ async ({ set, body }) => {
+ try {
+ if (!body.stack) {
+ throw new Error("Stack needed")
+ }
+ await restartStack(body.stack);
+ logger.info(`Restarted Stack (${body.stack})`)
+ return responseHandler.ok(
+ set,
+ `Stack ${body.stack} restarted successfully`
+ );
+ } catch (error: any) {
+ return responseHandler.error(
+ set,
+ error.message || error,
+ "Error restarting stack"
+ );
+ }
+ },
+ {
+ detail: { tags: ["Stacks"] },
+ body: t.Object({
+ stack: t.Any(),
+ }),
+ }
+ )
+ .post(
+ "/pull-images",
+ async ({ set, body }) => {
+ try {
+ if (!body.stack) {
+ throw new Error("Stack needed")
+ }
+ await pullStackImages(body.stack);
+ logger.info(`Pulled Stack images (${body.stack})`)
+ return responseHandler.ok(
+ set,
+ `Images for stack ${body.stack} pulled successfully`
+ );
+ } catch (error: any) {
+ return responseHandler.error(
+ set,
+ error.message || error,
+ "Error pulling images"
+ );
+ }
+ },
+ {
+ detail: { tags: ["Stacks"] },
+ body: t.Object({
+ stack: t.Any(),
+ }),
+ }
+ )
+ .get(
+ "/status",
+ async ({ set, query }) => {
+ try {
+ if (!query.stack_name) {
+ throw new Error("Stack needed")
+ }
+ logger.debug(query.stack_name)
+ const status = await getStackStatus(query.stack_name);
+ const res = responseHandler.ok(
+ set,
+ `Stack ${query.stack_name} status retrieved successfully`
+ );
+ logger.info("Fetched Stack status")
+ return { ...res, status: status };
+ } catch (error: any) {
+ return responseHandler.error(
+ set,
+ error.message || error,
+ "Error getting stack status"
+ );
+ }
+ },
+ {
+ detail: { tags: ["Stacks"] },
+ query: t.Object({
+ stack_name: t.Any(),
+ }),
+ }
+ )
+ .get("/", async ({ set }) => {
+ try {
+ const stacks = dbFunctions.getStacks();
+ logger.info("Fetched Stacks")
+ return stacks;
+ } catch (error: any) {
+ return responseHandler.error(
+ set,
+ error.message || error,
+ "Error getting stacks"
+ );
+ }
+ },
+ {
+ detail: { tags: ["Stacks"] },
+ }
+ );
diff --git a/src/sample-variable.json b/src/sample-variable.json
deleted file mode 100644
index f507796b..00000000
--- a/src/sample-variable.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "VERSION": "",
- "RUNNING_IN_DOCKER": "",
- "TRUSTED_PROXIES": "",
- "HA_MASTER": "",
- "HA_MASTER_IP": "",
- "HA_NODE": "",
- "HA_UNSAFE": "",
- "DISCORD_WEBHOOK_URL": "",
- "EMAIL_SENDER": "",
- "EMAIL_RECIPIENT": "",
- "EMAIL_PASSWORD": "",
- "EMAIL_SERVICE": "",
- "PUSHBULLET_ACCESS_TOKEN": "",
- "PUSHOVER_USER_KEY": "",
- "PUSHOVER_API_TOKEN": "",
- "SLACK_WEBHOOK_URL": "",
- "TELEGRAM_BOT_TOKEN": "",
- "TELEGRAM_CHAT_ID": "",
- "WHATSAPP_API_URL": "",
- "WHATSAPP_RECIPIENT": "",
- "AUTOMATIC_ENVIRONMENT_FILE_MANAGEMENT": "true",
- "LOG_LEVEL": "info"
-}
diff --git a/src/server.ts b/src/server.ts
deleted file mode 100644
index edcb2ec5..00000000
--- a/src/server.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import express from "express";
-import initializeApp from "./init";
-import writeUserConf from "./config/hostsystem";
-import { startServer } from "./utils/startServer";
-import http from "http";
-
-const port: number = parseInt(process.env.PORT || "9876");
-const app = express();
-const server = http.createServer(app);
-
-initializeApp(app, server);
-
-if (process.env.NODE_ENV !== "testing") {
- writeUserConf(port);
- startServer(app, server, port);
-}
-
-export default app;
\ No newline at end of file
diff --git a/src/typings/atomicWrite.ts b/src/typings/atomicWrite.ts
deleted file mode 100644
index 1f4bfb4a..00000000
--- a/src/typings/atomicWrite.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-interface AtomicWriteOptions {
- mode?: number;
- exclusive?: boolean;
-}
-
-export { AtomicWriteOptions };
diff --git a/src/typings/database.ts b/src/typings/database.ts
new file mode 100644
index 00000000..3d95b353
--- /dev/null
+++ b/src/typings/database.ts
@@ -0,0 +1,25 @@
+interface backend_log_entries {
+ timestamp: string;
+ level: string;
+ message: string;
+ file: string;
+ line: number;
+}
+
+interface config {
+ polling_rate: number;
+ keep_data_for: number;
+ fetching_interval: number;
+}
+interface stacks_config {
+ name: string;
+ version: number;
+ custom: boolean;
+ source: string;
+ container_count: number;
+ stack_prefix: string;
+ automatic_reboot_on_error: boolean;
+ image_updates: boolean;
+}
+
+export type { backend_log_entries, config, stacks_config };
diff --git a/src/typings/docker-compose.ts b/src/typings/docker-compose.ts
new file mode 100644
index 00000000..a554c21c
--- /dev/null
+++ b/src/typings/docker-compose.ts
@@ -0,0 +1,393 @@
+export interface Stack {
+ compose_spec: ComposeSpec;
+ name: string
+ version: number;
+ source: string;
+}
+
+export interface ComposeSpec {
+ version?: string;
+ name?: string;
+ include?: Include[];
+ services?: { [key: string]: Service };
+ networks?: { [key: string]: Network };
+ volumes?: { [key: string]: Volume };
+ secrets?: { [key: string]: Secret };
+ configs?: { [key: string]: Config };
+ [key: `x-${string}`]: any;
+}
+
+type Include = string | { path: string | string[]; env_file?: string | string[]; project_directory?: string };
+
+interface Service {
+ develop?: Development | null;
+ deploy?: Deployment | null;
+ annotations?: ListOrDict;
+ attach?: boolean | string;
+ build?: string | {
+ context?: string;
+ dockerfile?: string;
+ dockerfile_inline?: string;
+ entitlements?: string[];
+ args?: ListOrDict;
+ ssh?: ListOrDict;
+ labels?: ListOrDict;
+ cache_from?: string[];
+ cache_to?: string[];
+ no_cache?: boolean | string;
+ additional_contexts?: ListOrDict;
+ network?: string;
+ pull?: boolean | string;
+ target?: string;
+ shm_size?: number | string;
+ extra_hosts?: ExtraHosts;
+ isolation?: string;
+ privileged?: boolean | string;
+ secrets?: ServiceConfigOrSecret[];
+ tags?: string[];
+ ulimits?: Ulimits;
+ platforms?: string[];
+ [key: `x-${string}`]: any;
+ };
+ blkio_config?: {
+ device_read_bps?: BlkioLimit[];
+ device_read_iops?: BlkioLimit[];
+ device_write_bps?: BlkioLimit[];
+ device_write_iops?: BlkioLimit[];
+ weight?: number | string;
+ weight_device?: BlkioWeight[];
+ };
+ cap_add?: string[];
+ cap_drop?: string[];
+ cgroup?: 'host' | 'private';
+ cgroup_parent?: string;
+ command?: Command;
+ configs?: ServiceConfigOrSecret[];
+ container_name?: string;
+ cpu_count?: string | number;
+ cpu_percent?: string | number;
+ cpu_shares?: number | string;
+ cpu_quota?: number | string;
+ cpu_period?: number | string;
+ cpu_rt_period?: number | string;
+ cpu_rt_runtime?: number | string;
+ cpus?: number | string;
+ cpuset?: string;
+ credential_spec?: {
+ config?: string;
+ file?: string;
+ registry?: string;
+ [key: `x-${string}`]: any;
+ };
+ depends_on?: string[] | {
+ [service: string]: {
+ condition: 'service_started' | 'service_healthy' | 'service_completed_successfully';
+ restart?: boolean | string;
+ required?: boolean;
+ [key: `x-${string}`]: any;
+ }
+ };
+ device_cgroup_rules?: string[];
+ devices?: (string | {
+ source: string;
+ target?: string;
+ permissions?: string;
+ [key: `x-${string}`]: any;
+ })[];
+ dns?: StringOrList;
+ dns_opt?: string[];
+ dns_search?: StringOrList;
+ domainname?: string;
+ entrypoint?: Command;
+ env_file?: EnvFile;
+ label_file?: string | string[];
+ environment?: ListOrDict;
+ expose?: (string | number)[];
+ extends?: string | { service: string; file?: string };
+ external_links?: string[];
+ extra_hosts?: ExtraHosts;
+ gpus?: 'all' | Array<{
+ capabilities?: string[];
+ count?: string | number;
+ device_ids?: string[];
+ driver?: string;
+ options?: ListOrDict;
+ [key: `x-${string}`]: any;
+ }>;
+ group_add?: (string | number)[];
+ healthcheck?: Healthcheck;
+ hostname?: string;
+ image?: string;
+ init?: boolean | string;
+ ipc?: string;
+ isolation?: string;
+ labels?: ListOrDict;
+ links?: string[];
+ logging?: {
+ driver?: string;
+ options?: { [key: string]: string | number | null };
+ [key: `x-${string}`]: any;
+ };
+ mac_address?: string;
+ mem_limit?: number | string;
+ mem_reservation?: string | number;
+ mem_swappiness?: number | string;
+ memswap_limit?: number | string;
+ network_mode?: string;
+ networks?: string[] | {
+ [network: string]: {
+ aliases?: string[];
+ ipv4_address?: string;
+ ipv6_address?: string;
+ link_local_ips?: string[];
+ mac_address?: string;
+ driver_opts?: { [key: string]: string | number };
+ priority?: number;
+ [key: `x-${string}`]: any;
+ } | null;
+ };
+ oom_kill_disable?: boolean | string;
+ oom_score_adj?: string | number;
+ pid?: string | null;
+ pids_limit?: number | string;
+ platform?: string;
+ ports?: (number | string | {
+ name?: string;
+ mode?: string;
+ host_ip?: string;
+ target?: number | string;
+ published?: string | number;
+ protocol?: string;
+ app_protocol?: string;
+ [key: `x-${string}`]: any;
+ })[];
+ post_start?: ServiceHook[];
+ pre_stop?: ServiceHook[];
+ privileged?: boolean | string;
+ profiles?: string[];
+ pull_policy?: 'always' | 'never' | 'if_not_present' | 'build' | 'missing';
+ read_only?: boolean | string;
+ restart?: string;
+ runtime?: string;
+ scale?: number | string;
+ security_opt?: string[];
+ shm_size?: number | string;
+ secrets?: ServiceConfigOrSecret[];
+ sysctls?: ListOrDict;
+ stdin_open?: boolean | string;
+ stop_grace_period?: string;
+ stop_signal?: string;
+ storage_opt?: object;
+ tmpfs?: StringOrList;
+ tty?: boolean | string;
+ ulimits?: Ulimits;
+ user?: string;
+ uts?: string;
+ userns_mode?: string;
+ volumes?: (string | {
+ type: string;
+ source?: string;
+ target?: string;
+ read_only?: boolean | string;
+ consistency?: string;
+ bind?: {
+ propagation?: string;
+ create_host_path?: boolean | string;
+ recursive?: 'enabled' | 'disabled' | 'writable' | 'readonly';
+ selinux?: 'z' | 'Z';
+ [key: `x-${string}`]: any;
+ };
+ volume?: {
+ nocopy?: boolean | string;
+ subpath?: string;
+ [key: `x-${string}`]: any;
+ };
+ tmpfs?: {
+ size?: number | string;
+ mode?: number | string;
+ [key: `x-${string}`]: any;
+ };
+ [key: `x-${string}`]: any;
+ })[];
+ volumes_from?: string[];
+ working_dir?: string;
+ [key: `x-${string}`]: any;
+}
+
+interface Healthcheck {
+ disable?: boolean | string;
+ interval?: string;
+ retries?: number | string;
+ test?: string | string[];
+ timeout?: string;
+ start_period?: string;
+ start_interval?: string;
+ [key: `x-${string}`]: any;
+}
+
+interface Development {
+ watch?: Array<{
+ path: string;
+ action: 'rebuild' | 'sync' | 'restart' | 'sync+restart' | 'sync+exec';
+ ignore?: string[];
+ target?: string;
+ exec?: ServiceHook;
+ [key: `x-${string}`]: any;
+ }>;
+ [key: `x-${string}`]: any;
+}
+
+interface Deployment {
+ mode?: string;
+ endpoint_mode?: string;
+ replicas?: number | string;
+ labels?: ListOrDict;
+ rollback_config?: {
+ parallelism?: number | string;
+ delay?: string;
+ failure_action?: string;
+ monitor?: string;
+ max_failure_ratio?: number | string;
+ order?: 'start-first' | 'stop-first';
+ [key: `x-${string}`]: any;
+ };
+ update_config?: {
+ parallelism?: number | string;
+ delay?: string;
+ failure_action?: string;
+ monitor?: string;
+ max_failure_ratio?: number | string;
+ order?: 'start-first' | 'stop-first';
+ [key: `x-${string}`]: any;
+ };
+ resources?: {
+ limits?: {
+ cpus?: number | string;
+ memory?: string;
+ pids?: number | string;
+ [key: `x-${string}`]: any;
+ };
+ reservations?: {
+ cpus?: number | string;
+ memory?: string;
+ generic_resources?: Array<{
+ discrete_resource_spec?: {
+ kind?: string;
+ value?: number | string;
+ [key: `x-${string}`]: any;
+ };
+ [key: `x-${string}`]: any;
+ }>;
+ devices?: Array<{
+ capabilities?: string[];
+ count?: string | number;
+ device_ids?: string[];
+ driver?: string;
+ options?: ListOrDict;
+ [key: `x-${string}`]: any;
+ }>;
+ [key: `x-${string}`]: any;
+ };
+ [key: `x-${string}`]: any;
+ };
+ restart_policy?: {
+ condition?: string;
+ delay?: string;
+ max_attempts?: number | string;
+ window?: string;
+ [key: `x-${string}`]: any;
+ };
+ placement?: {
+ constraints?: string[];
+ preferences?: Array<{
+ spread?: string;
+ [key: `x-${string}`]: any;
+ }>;
+ max_replicas_per_node?: number | string;
+ [key: `x-${string}`]: any;
+ };
+ [key: `x-${string}`]: any;
+}
+
+type Command = string | string[] | null;
+type EnvFile = string | Array;
+type StringOrList = string | string[];
+type ListOrDict = { [key: string]: string | number | boolean | null } | string[];
+type ExtraHosts = { [host: string]: string | string[] } | string[];
+interface BlkioLimit { path: string; rate: number | string; }
+interface BlkioWeight { path: string; weight: number | string; }
+type ServiceConfigOrSecret = string | {
+ source: string;
+ target?: string;
+ uid?: string;
+ gid?: string;
+ mode?: number | string;
+ [key: `x-${string}`]: any;
+};
+type Ulimits = { [key: string]: number | string | { hard: number | string; soft: number | string } };
+
+interface ServiceHook {
+ command?: Command;
+ user?: string;
+ privileged?: boolean | string;
+ working_dir?: string;
+ environment?: ListOrDict;
+ [key: `x-${string}`]: any;
+}
+
+interface Network {
+ name?: string;
+ driver?: string;
+ driver_opts?: { [key: string]: string | number };
+ ipam?: {
+ driver?: string;
+ config?: Array<{
+ subnet?: string;
+ ip_range?: string;
+ gateway?: string;
+ aux_addresses?: { [key: string]: string };
+ [key: `x-${string}`]: any;
+ }>;
+ options?: { [key: string]: string };
+ [key: `x-${string}`]: any;
+ };
+ external?: boolean | string | { name?: string;[key: `x-${string}`]: any };
+ internal?: boolean | string;
+ enable_ipv4?: boolean | string;
+ enable_ipv6?: boolean | string;
+ attachable?: boolean | string;
+ labels?: ListOrDict;
+ [key: `x-${string}`]: any;
+}
+
+interface Volume {
+ name?: string;
+ driver?: string;
+ driver_opts?: { [key: string]: string | number };
+ external?: boolean | string | { name?: string;[key: `x-${string}`]: any };
+ labels?: ListOrDict;
+ [key: `x-${string}`]: any;
+}
+
+interface Secret {
+ name?: string;
+ environment?: string;
+ file?: string;
+ external?: boolean | string | { name?: string;[key: string]: any };
+ labels?: ListOrDict;
+ driver?: string;
+ driver_opts?: { [key: string]: string | number };
+ template_driver?: string;
+ [key: `x-${string}`]: any;
+}
+
+interface Config {
+ name?: string;
+ content?: string;
+ environment?: string;
+ file?: string;
+ external?: boolean | string | { name?: string;[key: string]: any };
+ labels?: ListOrDict;
+ template_driver?: string;
+ [key: `x-${string}`]: any;
+}
\ No newline at end of file
diff --git a/src/typings/docker.ts b/src/typings/docker.ts
new file mode 100644
index 00000000..522762c2
--- /dev/null
+++ b/src/typings/docker.ts
@@ -0,0 +1,34 @@
+interface DockerHost {
+ name: string;
+ url: string;
+ secure: boolean;
+}
+
+interface ContainerInfo {
+ id: string;
+ hostId: string;
+ name: string;
+ image: string;
+ status: string;
+ state: string;
+ cpuUsage: number;
+ memoryUsage: number;
+}
+
+interface HostStats {
+ hostId: string;
+ dockerVersion: string;
+ apiVersion: string;
+ os: string;
+ architecture: string;
+ totalMemory: number;
+ totalCPU: number;
+ labels: string[];
+ containers: number;
+ containersRunning: number;
+ containersStopped: number;
+ containersPaused: number;
+ images: number;
+}
+
+export type { HostStats, ContainerInfo, DockerHost };
diff --git a/src/typings/dockerCompose.ts b/src/typings/dockerCompose.ts
deleted file mode 100644
index e30f7e0d..00000000
--- a/src/typings/dockerCompose.ts
+++ /dev/null
@@ -1,92 +0,0 @@
-export interface DockerComposeFile {
- services: Record;
- networks?: Record;
- volumes?: Record;
-}
-
-export interface ServiceDefinition {
- image?: string;
- build?: BuildDefinition;
- container_name?: string;
- command?: string | string[];
- environment?: Record;
- ports?: string[] | PortMapping[];
- volumes?: string[];
- networks?: string[];
- restart?: string;
- depends_on?: string[];
- deploy?: DeployDefinition;
- env_file?: string[];
-}
-
-export interface BuildDefinition {
- context: string;
- dockerfile?: string;
- args?: Record;
- cache_from?: string[];
- labels?: Record;
- target?: string;
-}
-
-export interface PortMapping {
- target: number;
- published: number;
- protocol?: "tcp" | "udp";
- mode?: "host" | "ingress";
-}
-
-export interface DeployDefinition {
- replicas?: number;
- resources?: ResourcesDefinition;
- restart_policy?: RestartPolicyDefinition;
- labels?: Record;
- update_config?: UpdateConfigDefinition;
-}
-
-export interface ResourcesDefinition {
- limits?: ResourceLimits;
- reservations?: ResourceReservations;
-}
-
-export interface ResourceLimits {
- cpus?: string;
- memory?: string;
-}
-
-export interface ResourceReservations {
- cpus?: string;
- memory?: string;
-}
-
-export interface RestartPolicyDefinition {
- condition?: "none" | "on-failure" | "any";
- delay?: string;
- max_attempts?: number;
- window?: string;
-}
-
-export interface UpdateConfigDefinition {
- parallelism?: number;
- delay?: string;
- failure_action?: "continue" | "pause";
- monitor?: string;
- max_failure_ratio?: number;
- order?: "start-first" | "stop-first";
-}
-
-export interface NetworkDefinition {
- driver?: string;
- driver_opts?: Record;
- attachable?: boolean;
- external?: boolean;
- internal?: boolean;
- labels?: Record;
-}
-
-export interface VolumeDefinition {
- driver?: string;
- driver_opts?: Record;
- external?: boolean;
- labels?: Record;
- name?: string;
-}
diff --git a/src/typings/dockerConfig.ts b/src/typings/dockerConfig.ts
deleted file mode 100644
index a1749d1f..00000000
--- a/src/typings/dockerConfig.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-interface target {
- name: string;
- url: string;
- port: number;
-}
-
-interface dockerConfig {
- hosts: target[];
-}
-
-interface HostConfig {
- name: string;
- [key: string]: string | number;
-}
-
-interface ContainerData {
- name: string;
- id: string;
- hostName: string;
- state: string;
- cpu_usage: number;
- mem_usage: number;
- mem_limit: number;
- net_rx: number;
- net_tx: number;
- current_net_rx: number;
- current_net_tx: number;
- networkMode: string;
-}
-
-interface AllContainerData {
- [hostName: string]: ContainerData[] | { error: string };
-}
-
-export { dockerConfig, target, ContainerData, AllContainerData, HostConfig };
diff --git a/src/typings/dockerStackEnv.ts b/src/typings/dockerStackEnv.ts
deleted file mode 100644
index c784b85d..00000000
--- a/src/typings/dockerStackEnv.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-interface dockerStackProperty {
- name: string;
- value: string;
-}
-
-interface dockerStackEnv {
- environment: dockerStackProperty[];
-}
-
-export { dockerStackEnv, dockerStackProperty };
diff --git a/src/typings/dockerode.ts b/src/typings/dockerode.ts
new file mode 100644
index 00000000..a4604337
--- /dev/null
+++ b/src/typings/dockerode.ts
@@ -0,0 +1,162 @@
+interface DockerInfo {
+ ID: string;
+ Containers: number;
+ ContainersRunning: number;
+ ContainersPaused: number;
+ ContainersStopped: number;
+ Images: number;
+ Driver: string;
+ DriverStatus: [string, string][];
+ DockerRootDir: string;
+ SystemStatus: [string, string][];
+ Plugins: {
+ Volume: string[];
+ Network: string[];
+ Authorization: string[];
+ Log: string[];
+ };
+ MemoryLimit: boolean;
+ SwapLimit: boolean;
+ KernelMemory: boolean;
+ CpuCfsPeriod: boolean;
+ CpuCfsQuota: boolean;
+ CPUShares: boolean;
+ CPUSet: boolean;
+ OomKillDisable: boolean;
+ IPv4Forwarding: boolean;
+ BridgeNfIptables: boolean;
+ BridgeNfIp6tables: boolean;
+ Debug: boolean;
+ NFd: number;
+ NGoroutines: number;
+ SystemTime: string;
+ LoggingDriver: string;
+ CgroupDriver: string;
+ NEventsListener: number;
+ KernelVersion: string;
+ OperatingSystem: string;
+ OSType: string;
+ Architecture: string;
+ NCPU: number;
+ MemTotal: number;
+ IndexServerAddress: string;
+ RegistryConfig: {
+ AllowNondistributableArtifactsCIDRs: string[];
+ AllowNondistributableArtifactsHostnames: string[];
+ InsecureRegistryCIDRs: string[];
+ IndexConfigs: Record<
+ string,
+ {
+ Name: string;
+ Mirrors: string[];
+ Secure: boolean;
+ Official: boolean;
+ }
+ >;
+ Mirrors: string[];
+ };
+ GenericResources: Array<
+ | { DiscreteResourceSpec: { Kind: string; Value: number } }
+ | { NamedResourceSpec: { Kind: string; Value: string } }
+ >;
+ HttpProxy: string;
+ HttpsProxy: string;
+ NoProxy: string;
+ Name: string;
+ Labels: string[];
+ ExperimentalBuild: boolean;
+ ServerVersion: string;
+ ClusterStore: string;
+ ClusterAdvertise: string;
+ Runtimes: Record<
+ string,
+ {
+ path: string;
+ runtimeArgs?: string[];
+ }
+ >;
+ DefaultRuntime: string;
+ Swarm: {
+ NodeID: string;
+ NodeAddr: string;
+ LocalNodeState: string;
+ ControlAvailable: boolean;
+ Error: string;
+ RemoteManagers: Array<{
+ NodeID: string;
+ Addr: string;
+ }>;
+ Nodes: number;
+ Managers: number;
+ Cluster: {
+ ID: string;
+ Version: {
+ Index: number;
+ };
+ CreatedAt: string;
+ UpdatedAt: string;
+ Spec: {
+ Name: string;
+ Labels: Record;
+ Orchestration: {
+ TaskHistoryRetentionLimit: number;
+ };
+ Raft: {
+ SnapshotInterval: number;
+ KeepOldSnapshots: number;
+ LogEntriesForSlowFollowers: number;
+ ElectionTick: number;
+ HeartbeatTick: number;
+ };
+ Dispatcher: {
+ HeartbeatPeriod: number;
+ };
+ CAConfig: {
+ NodeCertExpiry: number;
+ ExternalCAs: Array<{
+ Protocol: string;
+ URL: string;
+ Options: Record;
+ CACert: string;
+ }>;
+ SigningCACert: string;
+ SigningCAKey: string;
+ ForceRotate: number;
+ };
+ EncryptionConfig: {
+ AutoLockManagers: boolean;
+ };
+ TaskDefaults: {
+ LogDriver: {
+ Name: string;
+ Options: Record;
+ };
+ };
+ };
+ TLSInfo: {
+ TrustRoot: string;
+ CertIssuerSubject: string;
+ CertIssuerPublicKey: string;
+ };
+ RootRotationInProgress: boolean;
+ };
+ };
+ LiveRestoreEnabled: boolean;
+ Isolation: string;
+ InitBinary: string;
+ ContainerdCommit: {
+ ID: string;
+ Expected: string;
+ };
+ RuncCommit: {
+ ID: string;
+ Expected: string;
+ };
+ InitCommit: {
+ ID: string;
+ Expected: string;
+ };
+ SecurityOptions: string[];
+}
+
+export type { DockerInfo };
diff --git a/src/typings/frontendConfig.ts b/src/typings/frontendConfig.ts
deleted file mode 100644
index 6ce14979..00000000
--- a/src/typings/frontendConfig.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-interface Container {
- name: string;
- hidden?: boolean;
- tags?: string[];
- link?: string;
- icon?: string;
- pinned?: boolean;
-}
-
-type FrontendConfig = Container[];
-
-export { FrontendConfig };
diff --git a/src/typings/ha.ts b/src/typings/ha.ts
deleted file mode 100644
index f0352fc0..00000000
--- a/src/typings/ha.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-interface HighAvailabilityConfig {
- active: boolean;
- master: boolean;
- nodes: string[];
-}
-
-interface Node {
- ip: string;
- port: number;
-}
-
-interface HaNodeConfig {
- master: string;
-}
-
-interface NodeCache {
- [nodes: string]: Node;
-}
-
-export { HighAvailabilityConfig, Node, HaNodeConfig, NodeCache };
diff --git a/src/typings/hostData.ts b/src/typings/hostData.ts
deleted file mode 100644
index cf5a78da..00000000
--- a/src/typings/hostData.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-interface Component {
- Name: string;
- Version: string;
-}
-
-interface JsonData {
- hostName: string;
- info: {
- ID: string;
- Containers: number;
- ContainersRunning: number;
- ContainersPaused: number;
- ContainersStopped: number;
- Images: number;
- OperatingSystem: string;
- KernelVersion: string;
- Architecture: string;
- MemTotal: number;
- NCPU: number;
- };
- version: {
- Components: Component[];
- };
-}
-
-export { JsonData };
diff --git a/src/typings/plugin.ts b/src/typings/plugin.ts
new file mode 100644
index 00000000..9994ea67
--- /dev/null
+++ b/src/typings/plugin.ts
@@ -0,0 +1,25 @@
+import { ContainerInfo } from "~/typings/docker";
+import { HostStats } from "~/typings/docker";
+
+interface Plugin {
+ name: string;
+
+ // Container lifecycle hooks
+ onContainerStart?: (containerInfo: ContainerInfo) => void;
+ onContainerStop?: (containerInfo: ContainerInfo) => void;
+ onContainerExit?: (containerInfo: ContainerInfo) => void;
+ onContainerCreate?: (containerInfo: ContainerInfo) => void;
+ onContainerDestroy?: (containerInfo: ContainerInfo) => void;
+ onContainerPause?: (containerInfo: ContainerInfo) => void;
+ onContainerUnpause?: (containerInfo: ContainerInfo) => void;
+ onContainerRestart?: (containerInfo: ContainerInfo) => void;
+ onContainerUpdate?: (containerInfo: ContainerInfo) => void;
+ onContainerRename?: (containerInfo: ContainerInfo) => void;
+ onContainerHealthStatus?: (containerInfo: ContainerInfo) => void;
+
+ // Host lifecycle hooks
+ onHostUnreachable?: (HostStats: HostStats) => void;
+ onHostReachableAgain?: (HostStats: HostStats) => void;
+}
+
+export type { Plugin };
diff --git a/src/typings/response.ts b/src/typings/response.ts
deleted file mode 100644
index b122dfe2..00000000
--- a/src/typings/response.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-interface StatusResponse {
- ApiReachable: boolean;
- online: { [key: string]: boolean };
-}
-
-export { StatusResponse };
diff --git a/src/typings/stackConfig.ts b/src/typings/stackConfig.ts
deleted file mode 100644
index 45c72553..00000000
--- a/src/typings/stackConfig.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-interface stackConfig {
- stacks: string[];
-}
-
-export { stackConfig };
diff --git a/src/typings/states.ts b/src/typings/states.ts
deleted file mode 100644
index d5eed20b..00000000
--- a/src/typings/states.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-interface Container {
- name: string;
- id: string;
- state: string;
- hostName: string;
-}
-
-type ContainerStates = Container[];
-
-export { ContainerStates, Container };
diff --git a/src/typings/syncRequestBody.ts b/src/typings/syncRequestBody.ts
deleted file mode 100644
index 36fd70a4..00000000
--- a/src/typings/syncRequestBody.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-interface SyncRequestBody {
- files: Record;
-}
-
-export { SyncRequestBody };
diff --git a/src/typings/table.ts b/src/typings/table.ts
deleted file mode 100644
index cf0c18ab..00000000
--- a/src/typings/table.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-type Table = {
- id: number; // Primary key, auto-incremented
- info: string; // Non-null text field
- timestamp: string; // ISO 8601 formatted datetime string
-};
-
-interface DataRow {
- info: string;
-}
-
-export { Table, DataRow };
diff --git a/src/typings/template.ts b/src/typings/template.ts
deleted file mode 100644
index 71e0c8a3..00000000
--- a/src/typings/template.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-interface TemplateData {
- text: string;
-}
-
-export { TemplateData };
diff --git a/src/typings/websocket.ts b/src/typings/websocket.ts
new file mode 100644
index 00000000..a9712473
--- /dev/null
+++ b/src/typings/websocket.ts
@@ -0,0 +1,9 @@
+import type { Readable } from "stream";
+import type internal from "stream";
+
+interface streams {
+ statsStream: Readable;
+ splitStream: internal.Transform;
+}
+
+export { streams };
diff --git a/src/utils/assets/api-icon.svg b/src/utils/assets/api-icon.svg
deleted file mode 100644
index 5a4fdb7c..00000000
--- a/src/utils/assets/api-icon.svg
+++ /dev/null
@@ -1 +0,0 @@
- \
diff --git a/src/utils/assets/container-icon.svg b/src/utils/assets/container-icon.svg
deleted file mode 100644
index 15ed98c6..00000000
--- a/src/utils/assets/container-icon.svg
+++ /dev/null
@@ -1 +0,0 @@
- \
diff --git a/src/utils/assets/server-icon.svg b/src/utils/assets/server-icon.svg
deleted file mode 100644
index 31c92d4a..00000000
--- a/src/utils/assets/server-icon.svg
+++ /dev/null
@@ -1 +0,0 @@
- \
diff --git a/src/utils/atomicWrite.ts b/src/utils/atomicWrite.ts
deleted file mode 100644
index d279475e..00000000
--- a/src/utils/atomicWrite.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import fs from "fs";
-import logger from "./logger";
-import { AtomicWriteOptions } from "../typings/atomicWrite";
-
-export function atomicWrite(
- targetPath: string,
- data: object | string | Buffer | Record,
- options: AtomicWriteOptions = {},
-): void {
- const { mode = 0o600, exclusive = false } = options;
- const tempFile = `${targetPath}.tmp`;
-
- try {
- const writeData =
- typeof data === "object" && !(data instanceof Buffer)
- ? JSON.stringify(data, null, 2)
- : data;
-
- if (exclusive && fs.existsSync(targetPath)) {
- throw new Error(`File already exists: ${targetPath}`);
- }
-
- fs.writeFileSync(tempFile, writeData, { mode });
-
- fs.renameSync(tempFile, targetPath);
-
- logger.debug(`File successfully written to: ${targetPath}`);
- } catch (error: unknown) {
- if (fs.existsSync(tempFile)) fs.unlinkSync(tempFile);
- logger.error(
- `Failed to write file at ${targetPath}: ${(error as Error).message}`,
- );
- throw error;
- }
-}
diff --git a/src/utils/connectionChecker.ts b/src/utils/connectionChecker.ts
deleted file mode 100644
index 5a45505b..00000000
--- a/src/utils/connectionChecker.ts
+++ /dev/null
@@ -1,67 +0,0 @@
-import * as fs from "fs";
-import * as net from "net";
-import logger from "./logger";
-import { target } from "../typings/dockerConfig";
-import { StatusResponse } from "../typings/response";
-
-const filePath: string = "./src/data/dockerConfig.json";
-
-async function checkHostStatus(hosts: target[]): Promise {
- const results: { [key: string]: boolean } = {};
- for (const host of hosts) {
- const { name, url, port } = host;
-
- const isOnline = await checkPort(url, port);
-
- results[name] = !!isOnline;
-
- if (results[name] == true) {
- logger.debug(`${host.url}:${port} is online`);
- } else {
- logger.debug(`${host.url}:${port} is unreachable`);
- }
- }
-
- return {
- ApiReachable: true,
- online: results,
- };
-}
-
-function checkPort(host: string, port: number): Promise {
- return new Promise((resolve) => {
- const socket = new net.Socket();
- socket.setTimeout(3000);
-
- socket.on("connect", () => {
- socket.end();
- resolve(true);
- });
-
- socket.on("timeout", () => {
- socket.destroy();
- resolve(false);
- });
-
- socket.on("error", () => {
- socket.destroy();
- resolve(false);
- });
-
- socket.connect(port, host);
- });
-}
-
-async function checkReachability(): Promise {
- try {
- const data = fs.readFileSync(filePath, "utf-8");
- const parsedData = JSON.parse(data);
- const hosts: target[] = parsedData.hosts;
- return await checkHostStatus(hosts);
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg);
- }
-}
-
-export default checkReachability;
diff --git a/src/utils/containerService.ts b/src/utils/containerService.ts
deleted file mode 100644
index 0bb0a4e7..00000000
--- a/src/utils/containerService.ts
+++ /dev/null
@@ -1,173 +0,0 @@
-import logger from "./logger";
-import { ContainerInfo } from "dockerode";
-import { getDockerClient } from "./dockerClient";
-import fs from "fs";
-import { atomicWrite } from "./atomicWrite";
-const configPath = "./src/data/dockerConfig.json";
-import { AllContainerData, HostConfig } from "../typings/dockerConfig";
-import { generateGraphJSON } from "../handlers/graph";
-import { WebSocket } from "ws";
-
-export function loadConfig() {
- try {
- if (!fs.existsSync(configPath)) {
- logger.warn(
- `Config file not found. Creating an empty file at ${configPath}`,
- );
- atomicWrite(configPath, JSON.stringify({ hosts: [] }, null, 2));
- }
-
- const configData = fs.readFileSync(configPath, "utf-8");
- logger.debug("Loaded " + configPath);
- return JSON.parse(configData);
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg);
- return { hosts: [] };
- }
-}
-
-export async function fetchContainersForHost(hostName: string) {
- const config = loadConfig();
- const hostConfig = config.hosts.find((h: HostConfig) => h.name === hostName);
-
- if (!hostConfig) {
- throw new Error(`Host ${hostName} not found in configuration`);
- }
-
- try {
- const docker = getDockerClient(hostName);
- const containers: ContainerInfo[] = await docker.listContainers({
- all: true,
- });
-
- return await Promise.all(
- containers.map(async (container) => {
- try {
- const containerInstance = docker.getContainer(container.Id);
- const [containerInfo, containerStats] = await Promise.all([
- containerInstance.inspect(),
- containerInstance.stats({ stream: false }),
- ]);
-
- const cpuDelta =
- containerStats.cpu_stats.cpu_usage.total_usage -
- containerStats.precpu_stats.cpu_usage.total_usage;
- const systemCpuDelta =
- containerStats.cpu_stats.system_cpu_usage -
- containerStats.precpu_stats.system_cpu_usage;
- const cpuUsage =
- systemCpuDelta > 0
- ? (cpuDelta / systemCpuDelta) *
- containerStats.cpu_stats.online_cpus
- : 0;
-
- return {
- name: container.Names[0].replace("/", ""),
- id: container.Id,
- hostName,
- state: container.State,
- cpu_usage: cpuUsage,
- mem_usage: containerStats.memory_stats.usage,
- mem_limit: containerStats.memory_stats.limit,
- net_rx: containerStats.networks?.eth0?.rx_bytes || 0,
- net_tx: containerStats.networks?.eth0?.tx_bytes || 0,
- current_net_rx: containerStats.networks?.eth0?.rx_bytes || 0,
- current_net_tx: containerStats.networks?.eth0?.tx_bytes || 0,
- networkMode: containerInfo.HostConfig.NetworkMode || "unknown",
- };
- } catch (error) {
- logger.error(`Error processing container ${container.Id}: ${error}`);
- return {
- name: container.Names[0].replace("/", ""),
- id: container.Id,
- hostName,
- state: container.State,
- cpu_usage: 0,
- mem_usage: 0,
- mem_limit: 0,
- net_rx: 0,
- net_tx: 0,
- current_net_rx: 0,
- current_net_tx: 0,
- networkMode: "unknown",
- };
- }
- }),
- );
- } catch (error) {
- logger.error(`Error fetching containers for ${hostName}: ${error}`);
- throw error;
- }
-}
-
-export async function fetchAllContainers(): Promise {
- const config = loadConfig();
- const allContainerData: AllContainerData = {};
-
- await Promise.all(
- config.hosts.map(async (hostConfig: HostConfig) => {
- try {
- allContainerData[hostConfig.name] = await fetchContainersForHost(
- hostConfig.name,
- );
- } catch (error) {
- allContainerData[hostConfig.name] = {
- error: `Error fetching containers: ${error instanceof Error ? error.message : String(error)}`,
- };
- }
- }),
- );
-
- generateGraphJSON(allContainerData);
- return allContainerData;
-}
-
-export async function streamContainerData(ws: WebSocket, hostName: string) {
- try {
- const containers = await fetchContainersForHost(hostName);
- ws.send(JSON.stringify({ type: "containers", data: containers }));
-
- const docker = getDockerClient(hostName);
- const eventStream = await docker.getEvents();
-
- // eslint-disable-next-line
- if (!(eventStream instanceof require("stream").Readable)) {
- throw new Error("Failed to get valid event stream");
- }
-
- const handleData = (chunk: Buffer) => {
- ws.send(
- JSON.stringify({ type: "container-event", data: chunk.toString() }),
- );
- };
-
- const handleError = (err: Error) => {
- logger.error(`Event stream error for ${hostName}: ${err.message}`);
- ws.close();
- };
-
- eventStream.on("data", handleData).on("error", handleError);
-
- const closeHandler = () => {
- eventStream
- .removeListener("data", handleData)
- .removeListener("error", handleError)
- .removeListener("closed", handleError);
- logger.info(`Closed event stream for ${hostName}`);
- };
-
- ws.on("close", closeHandler);
- ws.on("error", closeHandler);
- } catch (error) {
- const message = error instanceof Error ? error.message : String(error);
- logger.error("Container data error:", message);
- ws.send(
- JSON.stringify({
- error: "Failed to fetch container data",
- details: message,
- }),
- );
- ws.close();
- }
-}
diff --git a/src/utils/dockerClient.ts b/src/utils/dockerClient.ts
deleted file mode 100644
index ff770888..00000000
--- a/src/utils/dockerClient.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import Docker from "dockerode";
-import fs from "fs";
-import logger from "./logger";
-import { dockerConfig, target } from "../typings/dockerConfig";
-
-function loadDockerConfig(): dockerConfig {
- const configPath = "./src/data/dockerConfig.json";
- try {
- const rawData = fs.readFileSync(configPath, "utf-8");
- logger.debug("Refreshed DockerConfig.json");
- return JSON.parse(rawData) as dockerConfig;
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg);
- throw new Error(errorMsg);
- }
-}
-
-function createDockerClient(hostConfig: target): Docker {
- logger.info(
- `Creating Docker client for host: ${hostConfig.url} on port: ${hostConfig.port || 2375}`,
- );
- return new Docker({
- host: hostConfig.url,
- port: hostConfig.port || 2375,
- protocol: "http",
- });
-}
-
-export const getDockerClient = (hostName: string): Docker => {
- logger.debug(`Getting Docker Client for ${hostName}`);
- const config = loadDockerConfig();
- const hostConfig = config.hosts.find((host) => host.name === hostName);
-
- if (!hostConfig) {
- const errorMsg = `Docker host ${hostName} not found in configuration`;
- logger.error(errorMsg);
- throw new Error(errorMsg);
- }
- return createDockerClient(hostConfig);
-};
diff --git a/src/utils/extractHostData.ts b/src/utils/extractHostData.ts
deleted file mode 100644
index 992f9638..00000000
--- a/src/utils/extractHostData.ts
+++ /dev/null
@@ -1,73 +0,0 @@
-import { JsonData } from "../typings/hostData";
-import logger from "./logger";
-
-type ComponentMap = Record;
-
-interface RelevantData {
- hostName: string;
- info: {
- ID: string;
- Containers: number;
- ContainersRunning: number;
- ContainersPaused: number;
- ContainersStopped: number;
- Images: number;
- OperatingSystem: string;
- KernelVersion: string;
- Architecture: string;
- MemTotal: number;
- NCPU: number;
- };
- version: {
- Components: ComponentMap;
- };
-}
-
-function processComponents(components: unknown): ComponentMap {
- try {
- if (!Array.isArray(components)) return {};
-
- return components.reduce((acc, component) => {
- if (
- typeof component === "object" &&
- component !== null &&
- "Name" in component &&
- "Version" in component
- ) {
- const { Name, Version } = component;
- if (typeof Name === "string" && typeof Version === "string") {
- acc[Name] = Version;
- }
- }
- return acc;
- }, {});
- } catch (error) {
- const errorMessage = error instanceof Error ? error.message : String(error);
- logger.error(`Error processing components: ${errorMessage}`);
- return {};
- }
-}
-
-export function extractRelevantData(jsonData: JsonData): RelevantData {
- return {
- hostName: jsonData.hostName,
- info: {
- ID: jsonData.info.ID,
- Containers: jsonData.info.Containers,
- ContainersRunning: jsonData.info.ContainersRunning,
- ContainersPaused: jsonData.info.ContainersPaused,
- ContainersStopped: jsonData.info.ContainersStopped,
- Images: jsonData.info.Images,
- OperatingSystem: jsonData.info.OperatingSystem,
- KernelVersion: jsonData.info.KernelVersion,
- Architecture: jsonData.info.Architecture,
- MemTotal: jsonData.info.MemTotal,
- NCPU: jsonData.info.NCPU,
- },
- version: {
- Components: processComponents(jsonData?.version?.Components),
- },
- };
-}
-
-export default extractRelevantData;
diff --git a/src/utils/logger.ts b/src/utils/logger.ts
deleted file mode 100644
index 2fd67bd5..00000000
--- a/src/utils/logger.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-import { createLogger, format, transports } from "winston";
-import DailyRotateFile from "winston-daily-rotate-file";
-import { LOG_LEVEL } from "../config/variables";
-
-const colors = {
- gray: "\x1b[90m",
- reset: "\x1b[0m",
- white: "\x1b[97m",
- red: "\x1b[31m",
- green: "\x1b[32m",
- yellow: "\x1b[33m",
- blue: "\x1b[34m",
-};
-
-function colorizeLogLevel(level: string, levelName: string) {
- switch (level) {
- case "info":
- return `${colors.green}${levelName}${colors.reset}`;
- case "debug":
- return `${colors.blue}${levelName}${colors.reset}`;
- case "error":
- return `${colors.red}${levelName}${colors.reset}`;
- case "warn":
- return `${colors.yellow}${levelName}${colors.reset}`;
- default:
- return `${colors.gray}UNKNOWN${colors.reset}`;
- }
-}
-
-// Filter out Exit listeners logs
-const filterLogs = format((info) => {
- if (
- typeof info.message === "string" &&
- info.message.includes("Exit listeners detected")
- ) {
- return false;
- }
- return info;
-});
-
-const logger = createLogger({
- level: LOG_LEVEL,
- format: format.combine(
- filterLogs(),
- format.timestamp({ format: "YYYY-MM-DD HH:mm:ss" }),
- ),
- transports: [
- new transports.Console({
- format: format.combine(
- format.printf((info) => {
- const level = info.level.toUpperCase().padEnd(5, " ");
- const timestamp = `${colors.gray}${info.timestamp}${colors.reset}`;
- const levelColorized = colorizeLogLevel(
- info.level.toLowerCase(),
- level,
- );
- const message = `${colors.white}${(info.message as string).replace(/\n|\r/g, "")}${colors.reset}`;
-
- return `${timestamp} ${levelColorized} : ${message}`;
- }),
- ),
- }),
- new DailyRotateFile({
- filename: "logs/app-%DATE%.log",
- datePattern: "YYYY-MM-DD",
- maxSize: "20m",
- maxFiles: "14d",
- zippedArchive: true,
- format: format.combine(
- format.printf((info) => {
- const level = info.level.toUpperCase().padEnd(5, " ");
- return `${info.timestamp} ${level} : ${info.message}`;
- }),
- ),
- }),
- ],
-});
-
-export default logger;
diff --git a/src/utils/notifications/_notify.ts b/src/utils/notifications/_notify.ts
deleted file mode 100644
index 49717f90..00000000
--- a/src/utils/notifications/_notify.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import logger from "../../utils/logger";
-import { telegramNotification } from "./telegram";
-import { slackNotification } from "./slack";
-import { discordNotification } from "./discord";
-import { emailNotification } from "./email";
-import { whatsappNotification } from "./whatsapp";
-import { pushbulletNotification } from "./pushbullet";
-import { pushoverNotification } from "./pushover";
-
-async function notify(type: string, containerId: string) {
- if (!containerId) {
- logger.error("Container ID is required.");
- throw new Error("Container ID is required.");
- }
-
- switch (type) {
- case "telegram":
- logger.debug("Sending Telegram notification...");
- await telegramNotification(containerId);
- break;
- case "slack":
- logger.debug("Sending Slack notification...");
- await slackNotification(containerId);
- break;
- case "discord":
- logger.debug("Sending Discord notification...");
- await discordNotification(containerId);
- break;
- case "email":
- logger.debug("Sending Email notification...");
- await emailNotification(containerId);
- break;
- case "whatsapp":
- logger.debug("Sending WhatsApp notification...");
- await whatsappNotification(containerId);
- break;
- case "pushbullet":
- logger.debug("Sending Pushbullet notification...");
- await pushbulletNotification(containerId);
- break;
- case "pushover":
- logger.debug("Sending Pushover notification...");
- await pushoverNotification(containerId);
- break;
- default:
- logger.error("Unknown notification type.");
- throw new Error("Unknown notification type.");
- }
-}
-
-export default notify;
diff --git a/src/utils/notifications/_template.ts b/src/utils/notifications/_template.ts
deleted file mode 100644
index fd5d71ed..00000000
--- a/src/utils/notifications/_template.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-import fs from "fs";
-import logger from "../logger";
-import { ContainerStates, Container } from "../../typings/states";
-
-const templatePath: string = "./src/data/template.json";
-const containersPath: string = "./src/data/states.json";
-
-interface Template {
- text: string;
-}
-
-function getTemplate(): Template | null {
- try {
- const data = fs.readFileSync(templatePath, "utf8");
- return JSON.parse(data);
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg);
- return null;
- }
-}
-
-function setTemplate(newTemplate: string): void {
- try {
- fs.writeFileSync(
- templatePath,
- JSON.stringify({ text: newTemplate }, null, 2),
- "utf8",
- );
- logger.debug("Template updated successfully");
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg);
- }
-}
-
-function renderTemplate(containerId: string): string | null {
- const template = getTemplate();
- if (!template) {
- logger.error("Template is missing or not a string");
- return null;
- }
-
- try {
- const data = fs.readFileSync(containersPath, "utf8");
- const containers = JSON.parse(data);
-
- let containerData: ContainerStates | null = null;
- for (const host in containers) {
- containerData = containers[host].find(
- (c: Container) => c.id === containerId,
- );
- if (containerData) {
- break;
- }
- }
-
- if (!containerData) {
- logger.error(`Container with ID ${containerId} not found`);
- return null;
- }
-
- // Substitute placeholders in the template with container data
- return Object.keys(containerData).reduce((text, key) => {
- const value = containerData[key as keyof ContainerStates];
- // Convert value to a string to avoid errors
- return text.replace(new RegExp(`{{${key}}}`, "g"), String(value));
- }, template.text);
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg);
- return null;
- }
-}
-
-export { getTemplate, setTemplate, renderTemplate };
diff --git a/src/utils/notifications/discord.ts b/src/utils/notifications/discord.ts
deleted file mode 100644
index d9be3a02..00000000
--- a/src/utils/notifications/discord.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-import * as https from "https";
-import logger from "../logger";
-import { renderTemplate } from "./_template";
-import { DISCORD_WEBHOOK_URL } from "../../config/variables";
-
-const discord_webhook_url: string = DISCORD_WEBHOOK_URL;
-
-export async function discordNotification(containerId: string): Promise {
- const discord_message: string | null = renderTemplate(containerId);
- if (!discord_message) {
- logger.error("Failed to create notification message.");
- return;
- }
-
- if (!discord_webhook_url) {
- logger.error("Discord webhook URL is not set.");
- return;
- }
-
- const postData = JSON.stringify({
- content: discord_message,
- });
-
- const url = new URL(discord_webhook_url);
-
- const options = {
- hostname: url.hostname,
- path: url.pathname,
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- "Content-Length": Buffer.byteLength(postData),
- },
- };
-
- const req = https.request(options, (res) => {
- let data = "";
-
- res.on("data", (chunk) => {
- data += chunk;
- });
-
- res.on("end", () => {
- if (res.statusCode !== 200) {
- logger.error(`Discord API error: ${data}`);
- }
- });
- });
-
- req.on("error", (error) => {
- logger.error("Error sending Discord message:", error);
- });
-
- req.write(postData);
- req.end();
-}
diff --git a/src/utils/notifications/email.ts b/src/utils/notifications/email.ts
deleted file mode 100644
index 62b37d3a..00000000
--- a/src/utils/notifications/email.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-import { SendMailOptions, createTransport } from "nodemailer";
-import logger from "../logger";
-import { renderTemplate } from "./_template";
-import {
- EMAIL_SENDER,
- EMAIL_SERVICE,
- EMAIL_PASSWORD,
- EMAIL_RECIPIENT,
-} from "../../config/variables";
-
-const email_sender: string = EMAIL_SENDER;
-const email_recipient: string = EMAIL_RECIPIENT;
-const email_password: string = EMAIL_PASSWORD;
-const email_service: string = EMAIL_SERVICE;
-
-export async function emailNotification(containerId: string) {
- // Validate email configuration parameters
- if (!email_sender || !email_recipient || !email_password || !email_service) {
- logger.error(
- "Email notification failed: Missing configuration parameters. " +
- "Please ensure EMAIL_SENDER, EMAIL_RECIPIENT, EMAIL_PASSWORD, and EMAIL_SERVICE are set in environment variables.",
- );
- return;
- }
-
- const email_message: string | null = renderTemplate(containerId);
- if (!email_message) {
- logger.error("Failed to create notification message.");
- return;
- }
-
- const transporter = createTransport({
- service: email_service,
- auth: {
- user: email_sender,
- pass: email_password,
- },
- });
-
- const mailOptions: SendMailOptions = {
- from: email_sender,
- to: email_recipient,
- subject: "DockStat",
- text: email_message,
- };
-
- try {
- await transporter.sendMail(mailOptions);
- } catch (error: unknown) {
- const errorMsg = error instanceof Error ? error.message : String(error);
- logger.error(errorMsg);
- }
-}
diff --git a/src/utils/notifications/pushbullet.ts b/src/utils/notifications/pushbullet.ts
deleted file mode 100644
index 811427a1..00000000
--- a/src/utils/notifications/pushbullet.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import * as https from "https";
-import logger from "../logger";
-import { renderTemplate } from "./_template";
-import { PUSHBULLET_ACCESS_TOKEN } from "../../config/variables";
-
-const pushbullet_access_token: string = PUSHBULLET_ACCESS_TOKEN;
-
-export async function pushbulletNotification(
- containerId: string,
-): Promise {
- const pushbullet_message: string | null = renderTemplate(containerId);
- if (!pushbullet_message) {
- logger.error("Failed to create notification message.");
- return;
- }
-
- if (!pushbullet_access_token) {
- logger.error("Pushbullet access token is not set.");
- return;
- }
-
- const postData = JSON.stringify({
- type: "note",
- title: "Container Notification",
- body: pushbullet_message,
- });
-
- const options = {
- hostname: "api.pushbullet.com",
- path: "/v2/pushes",
- method: "POST",
- headers: {
- "Access-Token": pushbullet_access_token,
- "Content-Type": "application/json",
- "Content-Length": Buffer.byteLength(postData),
- },
- };
-
- const req = https.request(options, (res) => {
- let data = "";
-
- res.on("data", (chunk) => {
- data += chunk;
- });
-
- res.on("end", () => {
- if (res.statusCode !== 200) {
- logger.error(`Pushbullet API error: ${data}`);
- }
- });
- });
-
- req.on("error", (error) => {
- logger.error("Error sending Pushbullet message:", error);
- });
-
- req.write(postData);
- req.end();
-}
diff --git a/src/utils/notifications/pushover.ts b/src/utils/notifications/pushover.ts
deleted file mode 100644
index aac71b3b..00000000
--- a/src/utils/notifications/pushover.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-import * as https from "https";
-import logger from "../logger";
-import { renderTemplate } from "./_template";
-import { PUSHOVER_USER_KEY, PUSHOVER_API_TOKEN } from "../../config/variables";
-
-const pushover_user_key: string = PUSHOVER_USER_KEY;
-const pushover_api_token: string = PUSHOVER_API_TOKEN;
-
-export async function pushoverNotification(containerId: string): Promise {
- const pushover_message: string | null = renderTemplate(containerId);
- if (!pushover_message) {
- logger.error("Failed to create notification message.");
- return;
- }
-
- if (!pushover_api_token || !pushover_user_key) {
- logger.error("Pushover API token or user key is not set.");
- return;
- }
-
- const postData = new URLSearchParams({
- token: pushover_api_token,
- user: pushover_user_key,
- message: pushover_message,
- }).toString();
-
- const options = {
- hostname: "api.pushover.net",
- path: "/1/messages.json",
- method: "POST",
- headers: {
- "Content-Type": "application/x-www-form-urlencoded",
- "Content-Length": Buffer.byteLength(postData),
- },
- };
-
- const req = https.request(options, (res) => {
- let data = "";
-
- res.on("data", (chunk) => {
- data += chunk;
- });
-
- res.on("end", () => {
- if (res.statusCode !== 200) {
- logger.error(`Pushover API error: ${data}`);
- }
- });
- });
-
- req.on("error", (error) => {
- logger.error("Error sending Pushover message:", error);
- });
-
- req.write(postData);
- req.end();
-}
diff --git a/src/utils/notifications/slack.ts b/src/utils/notifications/slack.ts
deleted file mode 100644
index e1e7216b..00000000
--- a/src/utils/notifications/slack.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-import * as https from "https";
-import logger from "../logger";
-import { renderTemplate } from "./_template";
-import { SLACK_WEBHOOK_URL } from "../../config/variables";
-
-const slack_webhook_url: string = SLACK_WEBHOOK_URL;
-
-export async function slackNotification(containerId: string): Promise {
- const slack_message: string | null = renderTemplate(containerId);
- if (!slack_message) {
- logger.error("Failed to create notification message.");
- return;
- }
-
- if (!slack_webhook_url) {
- logger.error("Slack webhook URL is not set.");
- return;
- }
-
- const postData = JSON.stringify({
- text: slack_message,
- });
-
- const url = new URL(slack_webhook_url);
-
- const options = {
- hostname: url.hostname,
- path: url.pathname,
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- "Content-Length": Buffer.byteLength(postData),
- },
- };
-
- const req = https.request(options, (res) => {
- let data = "";
-
- res.on("data", (chunk) => {
- data += chunk;
- });
-
- res.on("end", () => {
- if (res.statusCode !== 200) {
- logger.error(`Slack API error: ${data}`);
- }
- });
- });
-
- req.on("error", (error) => {
- logger.error("Error sending Slack message:", error);
- });
-
- req.write(postData);
- req.end();
-}
diff --git a/src/utils/notifications/telegram.ts b/src/utils/notifications/telegram.ts
deleted file mode 100644
index 440e0916..00000000
--- a/src/utils/notifications/telegram.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-import * as https from "https";
-import logger from "../logger";
-import { renderTemplate } from "./_template";
-import { TELEGRAM_BOT_TOKEN, TELEGRAM_CHAT_ID } from "../../config/variables";
-
-const telegram_bot_token: string = TELEGRAM_BOT_TOKEN;
-const telegram_chat_id: string = TELEGRAM_CHAT_ID;
-
-export async function telegramNotification(containerId: string): Promise {
- const telegram_message: string | null = renderTemplate(containerId);
- if (!telegram_message) {
- logger.error("Failed to create notification message.");
- return;
- }
-
- if (!telegram_bot_token || !telegram_chat_id) {
- logger.error("Telegram bot token or chat ID is not set.");
- return;
- }
-
- const postData = JSON.stringify({
- chat_id: telegram_chat_id,
- text: telegram_message,
- });
-
- const options = {
- hostname: "api.telegram.org",
- path: `/bot${telegram_bot_token}/sendMessage`,
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- "Content-Length": Buffer.byteLength(postData),
- },
- };
-
- const req = https.request(options, (res) => {
- let data = "";
-
- res.on("data", (chunk) => {
- data += chunk;
- });
-
- res.on("end", () => {
- if (res.statusCode !== 200) {
- logger.error(`Telegram API error: ${data}`);
- }
- });
- });
-
- req.on("error", (error) => {
- logger.error("Error sending message:", error);
- });
-
- req.write(postData);
- req.end();
-}
diff --git a/src/utils/notifications/whatsapp.ts b/src/utils/notifications/whatsapp.ts
deleted file mode 100644
index 1eb7575e..00000000
--- a/src/utils/notifications/whatsapp.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-import * as https from "https";
-import logger from "../logger";
-import { renderTemplate } from "./_template";
-import { WHATSAPP_API_URL, WHATSAPP_RECIPIENT } from "../../config/variables";
-
-const whatsapp_api_url: string = WHATSAPP_API_URL;
-const whatsapp_recipient: string = WHATSAPP_RECIPIENT;
-
-export async function whatsappNotification(containerId: string): Promise {
- const whatsapp_message: string | null = renderTemplate(containerId);
- if (!whatsapp_message) {
- logger.error("Failed to create notification message.");
- return;
- }
-
- if (!whatsapp_api_url || !whatsapp_recipient) {
- logger.error("WhatsApp API URL or recipient is not set.");
- return;
- }
-
- const postData = JSON.stringify({
- to: whatsapp_recipient,
- body: whatsapp_message,
- });
-
- const url = new URL(whatsapp_api_url);
-
- const options = {
- hostname: url.hostname,
- path: url.pathname,
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- "Content-Length": Buffer.byteLength(postData),
- },
- };
-
- const req = https.request(options, (res) => {
- let data = "";
-
- res.on("data", (chunk) => {
- data += chunk;
- });
-
- res.on("end", () => {
- if (res.statusCode !== 200) {
- logger.error(`WhatsApp API error: ${data}`);
- }
- });
- });
-
- req.on("error", (error) => {
- logger.error("Error sending WhatsApp message:", error);
- });
-
- req.write(postData);
- req.end();
-}
diff --git a/src/utils/rateLimitFS.ts b/src/utils/rateLimitFS.ts
deleted file mode 100644
index a8f0b42d..00000000
--- a/src/utils/rateLimitFS.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import { promises as fs, existsSync } from "fs";
-
-const delay = (ms: number): Promise =>
- new Promise((resolve) => setTimeout(resolve, ms));
-
-let lastOperationTime = 0;
-const rateLimitDuration = 500;
-
-export const rateLimitedReadFile = async (
- filePath: string,
- encoding: BufferEncoding = "utf8",
-): Promise => {
- const now = Date.now();
- const timeSinceLastOperation = now - lastOperationTime;
-
- if (timeSinceLastOperation < rateLimitDuration) {
- await delay(rateLimitDuration - timeSinceLastOperation);
- }
-
- lastOperationTime = Date.now();
- return fs.readFile(filePath, encoding);
-};
-
-export const rateLimitedExistsSync = async (
- filePath: string,
-): Promise => {
- const now = Date.now();
- const timeSinceLastOperation = now - lastOperationTime;
-
- if (timeSinceLastOperation < rateLimitDuration) {
- await delay(rateLimitDuration - timeSinceLastOperation);
- }
-
- lastOperationTime = Date.now();
- return existsSync(filePath);
-};
diff --git a/src/utils/startServer.ts b/src/utils/startServer.ts
deleted file mode 100644
index 52dcc256..00000000
--- a/src/utils/startServer.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { Express } from "express";
-import { Server } from "http";
-import { startMasterNode } from "../controllers/highAvailability";
-import writeUserConf from "../config/hostsystem";
-import initFiles from "../config/initFiles";
-
-export function startServer(app: Express, server: Server, port: number) {
- if (process.env.NODE_ENV === "testing") {
- writeUserConf(port);
- initFiles();
- }
-
- server.listen(port, () => {
- startMasterNode();
- });
-}
diff --git a/src/utils/swaggerDocs.ts b/src/utils/swaggerDocs.ts
deleted file mode 100644
index 7ed90d9d..00000000
--- a/src/utils/swaggerDocs.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import swaggerUi from "swagger-ui-express";
-import { options } from "../config/swaggerConfig";
-import yaml from "yamljs";
-import express from "express";
-import { SwaggerDefinition } from "swagger-jsdoc";
-
-const swaggerDocs = (app: express.Application) => {
- const swaggerYaml: SwaggerDefinition = yaml.load("./src/config/swagger.yaml");
- app.use("/api-docs", swaggerUi.serve, swaggerUi.setup(swaggerYaml, options));
-};
-
-export default swaggerDocs;
diff --git a/src/utils/webSocket.ts b/src/utils/webSocket.ts
deleted file mode 100644
index 66d1f74b..00000000
--- a/src/utils/webSocket.ts
+++ /dev/null
@@ -1,113 +0,0 @@
-import { Server } from "http";
-import { WebSocketServer, WebSocket } from "ws";
-import { URL } from "url";
-import fs from "fs";
-import logger from "./logger";
-import { streamContainerData } from "./containerService";
-
-export function setupWebSocket(server: Server) {
- const wss = new WebSocketServer({ noServer: true });
-
- server.on("upgrade", (req, socket, head) => {
- logger.debug(`Received upgrade request for URL: ${req.url}`);
- const baseURL = `http://${req.headers.host}/`;
- const requestURL = new URL(req.url || "", baseURL);
- const { pathname } = requestURL;
- logger.debug(`Parsed pathname: ${pathname}`);
-
- // Debug log to verify path handling
- logger.debug(`Handling upgrade for path: ${pathname}`);
-
- if (pathname === "/wss/container-data" || pathname === "/wss/server-logs") {
- wss.handleUpgrade(req, socket, head, (ws) => {
- wss.emit("connection", ws, req);
- });
- } else {
- logger.warn(`Rejected WebSocket connection to invalid path: ${pathname}`);
- socket.write("HTTP/1.1 404 Not Found\r\n\r\n");
- socket.destroy();
- }
- });
-
- server.on("error", (error) => {
- logger.error("HTTP server error:", error);
- });
-
- logger.debug("WebSocket server attached to HTTP server");
-
- wss.on("connection", (ws: WebSocket, req) => {
- const baseURL = `http://${req.headers.host}/`;
- const requestURL = new URL(req.url || "", baseURL);
- const { pathname } = requestURL;
-
- logger.info(`WebSocket connection established to ${pathname}`);
-
- const handleError = (error: string) => {
- ws.send(JSON.stringify({ error }));
- ws.close();
- };
-
- if (pathname === "/wss/container-data") {
- const hostName = requestURL.searchParams.get("host");
- if (!hostName) {
- handleError("Missing required host parameter");
- return;
- }
- streamContainerData(ws, hostName);
- } else if (pathname === "/wss/server-logs") {
- const logFiles = fs
- .readdirSync("logs/")
- .filter((file) => file.startsWith("app-"));
-
- if (logFiles.length === 0) {
- console.error("No log files found");
- return;
- }
-
- const sortedLogFiles = logFiles.sort((a, b) => {
- const dateA = a.match(/\d{4}-\d{2}-\d{2}/)?.[0] ?? "";
- const dateB = b.match(/\d{4}-\d{2}-\d{2}/)?.[0] ?? "";
-
- return dateB.localeCompare(dateA);
- });
-
- const logPath = "logs/" + sortedLogFiles[0];
-
- if (!fs.existsSync(logPath)) {
- handleError("Log file not found");
- logger.error(`Log file ${logPath} not found`);
- return;
- }
-
- // Read the initial content of the log file
- const history = fs.readFileSync(logPath, "utf-8");
- ws.send(JSON.stringify({ type: "log-history", data: history }));
-
- // Watch the log file for changes
- const watcher = fs.watchFile(
- logPath,
- { interval: 1000 },
- (curr, prev) => {
- if (curr.size > prev.size) {
- const stream = fs.createReadStream(logPath, {
- start: prev.size,
- end: curr.size - 1,
- encoding: "utf-8",
- });
-
- stream.on("data", (chunk) => {
- ws.send(JSON.stringify({ type: "log-update", data: chunk }));
- });
- }
- },
- );
-
- ws.on("close", () => {
- watcher.removeAllListeners();
- logger.info("Closed WebSocket connection for logs");
- });
- } else {
- handleError("Invalid WebSocket endpoint");
- }
- });
-}
diff --git a/tsconfig.json b/tsconfig.json
index c4f6f4c0..ab566ad1 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,17 +1,107 @@
{
"compilerOptions": {
- "resolveJsonModule": true,
- "target": "ES2020",
- "outDir": "dist/src",
- "module": "CommonJS",
- "moduleResolution": "node",
- "strict": true,
- "skipLibCheck": true,
- "forceConsistentCasingInFileNames": true,
- "esModuleInterop": true
- },
- "$schema": "https://json.schemastore.org/tsconfig",
- "display": "Recommended",
- "include": ["src/**/*", "**/*.d.ts", "__tests__/**/*"],
- "exclude": ["node_modules", "**/*.spec.ts"]
+ /* Visit https://aka.ms/tsconfig to read more about this file */
+
+ /* Projects */
+ // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
+ // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
+ // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
+ // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
+ // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
+ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
+
+ /* Language and Environment */
+ "target": "ES2021" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
+ // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
+ // "jsx": "preserve", /* Specify what JSX code is generated. */
+ // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
+ // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
+ // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
+ // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
+ // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
+ // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
+ // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
+ // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
+ // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
+
+ /* Modules */
+ "module": "ES2022" /* Specify what module code is generated. */,
+ // "rootDir": "./", /* Specify the root folder within your source files. */
+ "moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */,
+ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
+ "paths": {
+ "~/*": ["./src/*"]
+ } /* Specify a set of entries that re-map imports to additional lookup locations. */,
+ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
+ // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
+ "types": [
+ "bun-types"
+ ] /* Specify type package names to be included without being referenced in a source file. */,
+ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
+ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
+ "resolveJsonModule": true /* Enable importing .json files. */,
+ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */
+
+ /* JavaScript Support */
+ // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
+ // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
+ // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
+
+ /* Emit */
+ // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
+ // "declarationMap": true, /* Create sourcemaps for d.ts files. */
+ // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
+ // "sourceMap": true, /* Create source map files for emitted JavaScript files. */
+ // "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. */
+ // "outDir": "./", /* Specify an output folder for all emitted files. */
+ // "removeComments": true, /* Disable emitting comments. */
+ // "noEmit": true, /* Disable emitting files from a compilation. */
+ // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
+ // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
+ // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
+ // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
+ // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
+ // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
+ // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
+ // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
+ // "newLine": "crlf", /* Set the newline character for emitting files. */
+ // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
+ // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
+ // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
+ // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
+ // "declarationDir": "./", /* Specify the output directory for generated declaration files. */
+ // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
+
+ /* Interop Constraints */
+ // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
+ // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
+ "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
+ // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
+ "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
+
+ /* Type Checking */
+ "strict": true /* Enable all strict type-checking options. */,
+ // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
+ // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
+ // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
+ // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
+ // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
+ // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
+ // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
+ // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
+ // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
+ // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
+ // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
+ // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
+ // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
+ // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
+ // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
+ // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
+ // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
+ // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
+
+ /* Completeness */
+ // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
+ "skipLibCheck": true /* Skip type checking all .d.ts files. */
+ }
}