diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c1d53dd529..21215eabd8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -106,29 +106,6 @@ jobs: max_attempts: 3 command: sudo docker build --no-cache -f ./Probe/Dockerfile . - docker-build-telemetry: - runs-on: ubuntu-latest - env: - CI_PIPELINE_ID: ${{github.run_number}} - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Preinstall - uses: nick-fields/retry@v3 - with: - timeout_minutes: 10 - max_attempts: 3 - command: npm run prerun - - # build image probe api - - name: build docker image - uses: nick-fields/retry@v3 - with: - timeout_minutes: 45 - max_attempts: 3 - command: sudo docker build --no-cache -f ./Telemetry/Dockerfile . - docker-build-test-server: runs-on: ubuntu-latest env: diff --git a/.github/workflows/compile.yml b/.github/workflows/compile.yml index 31659b9128..dcf1444634 100644 --- a/.github/workflows/compile.yml +++ b/.github/workflows/compile.yml @@ -184,24 +184,6 @@ jobs: max_attempts: 3 command: cd Probe && npm install && npm run compile && npm run dep-check - compile-telemetry: - runs-on: ubuntu-latest - env: - CI_PIPELINE_ID: ${{github.run_number}} - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: latest - - run: cd Common && npm install - - name: Compile Telemetry - uses: nick-fields/retry@v3 - with: - timeout_minutes: 30 - max_attempts: 3 - command: cd Telemetry && npm install && npm run compile && npm run dep-check - - compile-status-page: runs-on: ubuntu-latest env: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 73b0977997..1f51c0e0f3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -569,88 +569,6 @@ jobs: --image test \ --tags "${SANITIZED_VERSION},enterprise-${SANITIZED_VERSION}" - telemetry-docker-image-build: - needs: [generate-build-number, read-version] - strategy: - matrix: - include: - - platform: linux/amd64 - runner: ubuntu-latest - - platform: linux/arm64 - runner: ubuntu-24.04-arm - runs-on: ${{ matrix.runner }} - steps: - - name: Free Disk Space (Ubuntu) - if: matrix.platform == 'linux/amd64' - uses: jlumbroso/free-disk-space@main - with: - tool-cache: false - android: true - dotnet: true - haskell: true - large-packages: true - docker-images: true - swap-storage: true - - - uses: actions/checkout@v4 - with: - ref: ${{ github.ref }} - - - uses: actions/setup-node@v4 - with: - node-version: latest - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Generate Dockerfile from Dockerfile.tpl - run: npm run prerun - - - name: Login to Docker Hub - run: | - echo "${{ secrets.DOCKERHUB_PASSWORD }}" | docker login --username "${{ secrets.DOCKERHUB_USERNAME }}" --password-stdin - - - name: Login to GitHub Container Registry - run: | - echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io --username "${{ github.repository_owner }}" --password-stdin - - - name: Build and push - run: | - bash ./Scripts/GHA/build_docker_images.sh \ - --image telemetry \ - --version "${{needs.read-version.outputs.major_minor}}" \ - --dockerfile ./Telemetry/Dockerfile \ - --context . \ - --platforms ${{ matrix.platform }} \ - --git-sha "${{ github.sha }}" - - telemetry-docker-image-merge: - needs: [telemetry-docker-image-build, read-version] - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - ref: ${{ github.ref }} - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Login to Docker Hub - run: | - echo "${{ secrets.DOCKERHUB_PASSWORD }}" | docker login --username "${{ secrets.DOCKERHUB_USERNAME }}" --password-stdin - - - name: Login to GitHub Container Registry - run: | - echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io --username "${{ github.repository_owner }}" --password-stdin - - - name: Merge multi-arch manifests - run: | - VERSION="${{needs.read-version.outputs.major_minor}}" - SANITIZED_VERSION="${VERSION//+/-}" - bash ./Scripts/GHA/merge_docker_manifests.sh \ - --image telemetry \ - --tags "${SANITIZED_VERSION},enterprise-${SANITIZED_VERSION}" - probe-docker-image-build: needs: [generate-build-number, read-version] strategy: @@ -992,7 +910,6 @@ jobs: - home-docker-image-merge - test-server-docker-image-merge - test-docker-image-merge - - telemetry-docker-image-merge - probe-docker-image-merge - app-docker-image-merge - ai-agent-docker-image-merge @@ -1008,7 +925,6 @@ jobs: "home", "test-server", "test", - "telemetry", "probe", "app", "ai-agent" @@ -1057,7 +973,7 @@ jobs: test-e2e-release-saas: runs-on: ubuntu-latest - needs: [telemetry-docker-image-merge, ai-agent-docker-image-merge, app-docker-image-merge, home-docker-image-merge, probe-docker-image-merge, test-docker-image-merge, test-server-docker-image-merge, publish-npm-packages, e2e-docker-image-merge, helm-chart-deploy, generate-build-number, read-version, nginx-docker-image-merge] + needs: [ai-agent-docker-image-merge, app-docker-image-merge, home-docker-image-merge, probe-docker-image-merge, test-docker-image-merge, test-server-docker-image-merge, publish-npm-packages, e2e-docker-image-merge, helm-chart-deploy, generate-build-number, read-version, nginx-docker-image-merge] env: CI_PIPELINE_ID: ${{github.run_number}} steps: @@ -1188,7 +1104,7 @@ jobs: test-e2e-release-self-hosted: runs-on: ubuntu-latest # After all the jobs runs - needs: [telemetry-docker-image-merge, ai-agent-docker-image-merge, app-docker-image-merge, home-docker-image-merge, probe-docker-image-merge, test-docker-image-merge, test-server-docker-image-merge, publish-npm-packages, e2e-docker-image-merge, helm-chart-deploy, generate-build-number, read-version, nginx-docker-image-merge] + needs: [ai-agent-docker-image-merge, app-docker-image-merge, home-docker-image-merge, probe-docker-image-merge, test-docker-image-merge, test-server-docker-image-merge, publish-npm-packages, e2e-docker-image-merge, helm-chart-deploy, generate-build-number, read-version, nginx-docker-image-merge] env: CI_PIPELINE_ID: ${{github.run_number}} steps: diff --git a/.github/workflows/test-release.yaml b/.github/workflows/test-release.yaml index b2f00f9739..8e698416f0 100644 --- a/.github/workflows/test-release.yaml +++ b/.github/workflows/test-release.yaml @@ -514,90 +514,6 @@ jobs: --image test \ --tags "${SANITIZED_VERSION},test,enterprise-${SANITIZED_VERSION},enterprise-test" - telemetry-docker-image-build: - needs: [read-version, generate-build-number] - strategy: - matrix: - include: - - platform: linux/amd64 - runner: ubuntu-latest - - platform: linux/arm64 - runner: ubuntu-24.04-arm - runs-on: ${{ matrix.runner }} - steps: - - name: Free Disk Space (Ubuntu) - if: matrix.platform == 'linux/amd64' - uses: jlumbroso/free-disk-space@main - with: - tool-cache: false - android: true - dotnet: true - haskell: true - large-packages: true - docker-images: true - swap-storage: true - - - uses: actions/checkout@v4 - with: - ref: ${{ github.ref }} - - - uses: actions/setup-node@v4 - with: - node-version: latest - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Generate Dockerfile from Dockerfile.tpl - run: npm run prerun - - - name: Login to Docker Hub - run: | - echo "${{ secrets.DOCKERHUB_PASSWORD }}" | docker login --username "${{ secrets.DOCKERHUB_USERNAME }}" --password-stdin - - - name: Login to GitHub Container Registry - run: | - echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io --username "${{ github.repository_owner }}" --password-stdin - - - name: Build and push - run: | - bash ./Scripts/GHA/build_docker_images.sh \ - --image telemetry \ - --version "${{needs.read-version.outputs.major_minor}}-test" \ - --dockerfile ./Telemetry/Dockerfile \ - --context . \ - --platforms ${{ matrix.platform }} \ - --git-sha "${{ github.sha }}" \ - --extra-tags test \ - --extra-enterprise-tags enterprise-test - - telemetry-docker-image-merge: - needs: [telemetry-docker-image-build, read-version] - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - ref: ${{ github.ref }} - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Login to Docker Hub - run: | - echo "${{ secrets.DOCKERHUB_PASSWORD }}" | docker login --username "${{ secrets.DOCKERHUB_USERNAME }}" --password-stdin - - - name: Login to GitHub Container Registry - run: | - echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io --username "${{ github.repository_owner }}" --password-stdin - - - name: Merge multi-arch manifests - run: | - VERSION="${{needs.read-version.outputs.major_minor}}-test" - SANITIZED_VERSION="${VERSION//+/-}" - bash ./Scripts/GHA/merge_docker_manifests.sh \ - --image telemetry \ - --tags "${SANITIZED_VERSION},test,enterprise-${SANITIZED_VERSION},enterprise-test" - probe-docker-image-build: needs: [read-version, generate-build-number] strategy: @@ -867,7 +783,7 @@ jobs: test-helm-chart: runs-on: ubuntu-latest - needs: [infrastructure-agent-deploy, publish-terraform-provider, telemetry-docker-image-merge, home-docker-image-merge, test-server-docker-image-merge, test-docker-image-merge, probe-docker-image-merge, app-docker-image-merge, ai-agent-docker-image-merge, nginx-docker-image-merge, e2e-docker-image-merge] + needs: [infrastructure-agent-deploy, publish-terraform-provider, home-docker-image-merge, test-server-docker-image-merge, test-docker-image-merge, probe-docker-image-merge, app-docker-image-merge, ai-agent-docker-image-merge, nginx-docker-image-merge, e2e-docker-image-merge] env: CI_PIPELINE_ID: ${{github.run_number}} steps: diff --git a/.github/workflows/test.telemetry.yaml b/.github/workflows/test.telemetry.yaml deleted file mode 100644 index 05253a0bdd..0000000000 --- a/.github/workflows/test.telemetry.yaml +++ /dev/null @@ -1,22 +0,0 @@ -name: Telemetry Test - -on: - pull_request: - push: - branches-ignore: - - 'hotfix-*' # excludes hotfix branches - - 'release' - -jobs: - test: - runs-on: ubuntu-latest - env: - CI_PIPELINE_ID: ${{github.run_number}} - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: latest - - run: cd Common && npm install - - run: cd Telemetry && npm install && npm run test - diff --git a/Telemetry/API/Fluent.ts b/App/FeatureSet/Telemetry/API/Fluent.ts similarity index 100% rename from Telemetry/API/Fluent.ts rename to App/FeatureSet/Telemetry/API/Fluent.ts diff --git a/Telemetry/API/IncomingRequestIngest/IncomingRequest.ts b/App/FeatureSet/Telemetry/API/IncomingRequestIngest/IncomingRequest.ts similarity index 100% rename from Telemetry/API/IncomingRequestIngest/IncomingRequest.ts rename to App/FeatureSet/Telemetry/API/IncomingRequestIngest/IncomingRequest.ts diff --git a/Telemetry/API/Metrics.ts b/App/FeatureSet/Telemetry/API/Metrics.ts similarity index 100% rename from Telemetry/API/Metrics.ts rename to App/FeatureSet/Telemetry/API/Metrics.ts diff --git a/Telemetry/API/OTelIngest.ts b/App/FeatureSet/Telemetry/API/OTelIngest.ts similarity index 100% rename from Telemetry/API/OTelIngest.ts rename to App/FeatureSet/Telemetry/API/OTelIngest.ts diff --git a/Telemetry/API/ProbeIngest/IncomingEmail.ts b/App/FeatureSet/Telemetry/API/ProbeIngest/IncomingEmail.ts similarity index 100% rename from Telemetry/API/ProbeIngest/IncomingEmail.ts rename to App/FeatureSet/Telemetry/API/ProbeIngest/IncomingEmail.ts diff --git a/Telemetry/API/ProbeIngest/Monitor.ts b/App/FeatureSet/Telemetry/API/ProbeIngest/Monitor.ts similarity index 100% rename from Telemetry/API/ProbeIngest/Monitor.ts rename to App/FeatureSet/Telemetry/API/ProbeIngest/Monitor.ts diff --git a/Telemetry/API/ProbeIngest/Probe.ts b/App/FeatureSet/Telemetry/API/ProbeIngest/Probe.ts similarity index 100% rename from Telemetry/API/ProbeIngest/Probe.ts rename to App/FeatureSet/Telemetry/API/ProbeIngest/Probe.ts diff --git a/Telemetry/API/ProbeIngest/Register.ts b/App/FeatureSet/Telemetry/API/ProbeIngest/Register.ts similarity index 100% rename from Telemetry/API/ProbeIngest/Register.ts rename to App/FeatureSet/Telemetry/API/ProbeIngest/Register.ts diff --git a/Telemetry/API/Pyroscope.ts b/App/FeatureSet/Telemetry/API/Pyroscope.ts similarity index 100% rename from Telemetry/API/Pyroscope.ts rename to App/FeatureSet/Telemetry/API/Pyroscope.ts diff --git a/Telemetry/API/ServerMonitorIngest/ServerMonitor.ts b/App/FeatureSet/Telemetry/API/ServerMonitorIngest/ServerMonitor.ts similarity index 100% rename from Telemetry/API/ServerMonitorIngest/ServerMonitor.ts rename to App/FeatureSet/Telemetry/API/ServerMonitorIngest/ServerMonitor.ts diff --git a/Telemetry/API/Syslog.ts b/App/FeatureSet/Telemetry/API/Syslog.ts similarity index 100% rename from Telemetry/API/Syslog.ts rename to App/FeatureSet/Telemetry/API/Syslog.ts diff --git a/Telemetry/Config.ts b/App/FeatureSet/Telemetry/Config.ts similarity index 100% rename from Telemetry/Config.ts rename to App/FeatureSet/Telemetry/Config.ts diff --git a/Telemetry/GrpcServer.ts b/App/FeatureSet/Telemetry/GrpcServer.ts similarity index 100% rename from Telemetry/GrpcServer.ts rename to App/FeatureSet/Telemetry/GrpcServer.ts diff --git a/App/FeatureSet/Telemetry/Index.ts b/App/FeatureSet/Telemetry/Index.ts new file mode 100644 index 0000000000..3cc680d1f2 --- /dev/null +++ b/App/FeatureSet/Telemetry/Index.ts @@ -0,0 +1,77 @@ +import OTelIngestAPI from "./API/OTelIngest"; +import MetricsAPI from "./API/Metrics"; +import SyslogAPI from "./API/Syslog"; +import FluentAPI from "./API/Fluent"; +import PyroscopeAPI from "./API/Pyroscope"; +// ProbeIngest routes +import ProbeIngestRegisterAPI from "./API/ProbeIngest/Register"; +import ProbeIngestMonitorAPI from "./API/ProbeIngest/Monitor"; +import ProbeIngestAPI from "./API/ProbeIngest/Probe"; +import IncomingEmailAPI from "./API/ProbeIngest/IncomingEmail"; +// ServerMonitorIngest routes +import ServerMonitorAPI from "./API/ServerMonitorIngest/ServerMonitor"; +// IncomingRequestIngest routes +import IncomingRequestAPI from "./API/IncomingRequestIngest/IncomingRequest"; + +import "./Jobs/TelemetryIngest/ProcessTelemetry"; +import { TELEMETRY_CONCURRENCY } from "./Config"; +import { startGrpcServer } from "./GrpcServer"; + +import FeatureSet from "Common/Server/Types/FeatureSet"; +import Express, { ExpressApplication } from "Common/Server/Utils/Express"; +import logger from "Common/Server/Utils/Logger"; + +const app: ExpressApplication = Express.getExpressApp(); + +const TELEMETRY_PREFIXES: Array = ["/telemetry", "/"]; + +// Existing telemetry routes +app.use(TELEMETRY_PREFIXES, OTelIngestAPI); +app.use(TELEMETRY_PREFIXES, MetricsAPI); +app.use(TELEMETRY_PREFIXES, SyslogAPI); +app.use(TELEMETRY_PREFIXES, FluentAPI); +app.use(TELEMETRY_PREFIXES, PyroscopeAPI); + +/* + * ProbeIngest routes under ["/probe-ingest", "/ingestor", "/"] + * "/ingestor" is used for backward compatibility because probes are already deployed with this path in client environments. + */ +const PROBE_INGEST_PREFIXES: Array = [ + "/probe-ingest", + "/ingestor", + "/", +]; +app.use(PROBE_INGEST_PREFIXES, ProbeIngestRegisterAPI); +app.use(PROBE_INGEST_PREFIXES, ProbeIngestMonitorAPI); +app.use(PROBE_INGEST_PREFIXES, ProbeIngestAPI); +app.use(["/probe-ingest", "/"], IncomingEmailAPI); + +// ServerMonitorIngest routes under ["/server-monitor-ingest", "/"] +const SERVER_MONITOR_PREFIXES: Array = ["/server-monitor-ingest", "/"]; +app.use(SERVER_MONITOR_PREFIXES, ServerMonitorAPI); + +// IncomingRequestIngest routes under ["/incoming-request-ingest", "/"] +const INCOMING_REQUEST_PREFIXES: Array = [ + "/incoming-request-ingest", + "/", +]; +app.use(INCOMING_REQUEST_PREFIXES, IncomingRequestAPI); + +const TelemetryFeatureSet: FeatureSet = { + init: async (): Promise => { + try { + logger.info( + `Telemetry Service - Queue concurrency: ${TELEMETRY_CONCURRENCY}`, + ); + + // Start gRPC OTLP server on port 4317 + startGrpcServer(); + } catch (err) { + logger.error("Telemetry FeatureSet Init Failed:"); + logger.error(err); + throw err; + } + }, +}; + +export default TelemetryFeatureSet; diff --git a/Telemetry/Jobs/IncomingRequestIngest/ProcessIncomingRequestIngest.ts b/App/FeatureSet/Telemetry/Jobs/IncomingRequestIngest/ProcessIncomingRequestIngest.ts similarity index 100% rename from Telemetry/Jobs/IncomingRequestIngest/ProcessIncomingRequestIngest.ts rename to App/FeatureSet/Telemetry/Jobs/IncomingRequestIngest/ProcessIncomingRequestIngest.ts diff --git a/Telemetry/Jobs/ProbeIngest/ProcessProbeIngest.ts b/App/FeatureSet/Telemetry/Jobs/ProbeIngest/ProcessProbeIngest.ts similarity index 100% rename from Telemetry/Jobs/ProbeIngest/ProcessProbeIngest.ts rename to App/FeatureSet/Telemetry/Jobs/ProbeIngest/ProcessProbeIngest.ts diff --git a/Telemetry/Jobs/ServerMonitorIngest/ProcessServerMonitorIngest.ts b/App/FeatureSet/Telemetry/Jobs/ServerMonitorIngest/ProcessServerMonitorIngest.ts similarity index 100% rename from Telemetry/Jobs/ServerMonitorIngest/ProcessServerMonitorIngest.ts rename to App/FeatureSet/Telemetry/Jobs/ServerMonitorIngest/ProcessServerMonitorIngest.ts diff --git a/Telemetry/Jobs/TelemetryIngest/ProcessTelemetry.ts b/App/FeatureSet/Telemetry/Jobs/TelemetryIngest/ProcessTelemetry.ts similarity index 100% rename from Telemetry/Jobs/TelemetryIngest/ProcessTelemetry.ts rename to App/FeatureSet/Telemetry/Jobs/TelemetryIngest/ProcessTelemetry.ts diff --git a/Telemetry/Middleware/OtelRequestMiddleware.ts b/App/FeatureSet/Telemetry/Middleware/OtelRequestMiddleware.ts similarity index 100% rename from Telemetry/Middleware/OtelRequestMiddleware.ts rename to App/FeatureSet/Telemetry/Middleware/OtelRequestMiddleware.ts diff --git a/Telemetry/Middleware/ProbeAuthorization.ts b/App/FeatureSet/Telemetry/Middleware/ProbeAuthorization.ts similarity index 100% rename from Telemetry/Middleware/ProbeAuthorization.ts rename to App/FeatureSet/Telemetry/Middleware/ProbeAuthorization.ts diff --git a/Telemetry/ProtoFiles/OTel/v1/common.proto b/App/FeatureSet/Telemetry/ProtoFiles/OTel/v1/common.proto similarity index 100% rename from Telemetry/ProtoFiles/OTel/v1/common.proto rename to App/FeatureSet/Telemetry/ProtoFiles/OTel/v1/common.proto diff --git a/Telemetry/ProtoFiles/OTel/v1/logs.proto b/App/FeatureSet/Telemetry/ProtoFiles/OTel/v1/logs.proto similarity index 100% rename from Telemetry/ProtoFiles/OTel/v1/logs.proto rename to App/FeatureSet/Telemetry/ProtoFiles/OTel/v1/logs.proto diff --git a/Telemetry/ProtoFiles/OTel/v1/logs_service.proto b/App/FeatureSet/Telemetry/ProtoFiles/OTel/v1/logs_service.proto similarity index 100% rename from Telemetry/ProtoFiles/OTel/v1/logs_service.proto rename to App/FeatureSet/Telemetry/ProtoFiles/OTel/v1/logs_service.proto diff --git a/Telemetry/ProtoFiles/OTel/v1/metrics.proto b/App/FeatureSet/Telemetry/ProtoFiles/OTel/v1/metrics.proto similarity index 100% rename from Telemetry/ProtoFiles/OTel/v1/metrics.proto rename to App/FeatureSet/Telemetry/ProtoFiles/OTel/v1/metrics.proto diff --git a/Telemetry/ProtoFiles/OTel/v1/metrics_service.proto b/App/FeatureSet/Telemetry/ProtoFiles/OTel/v1/metrics_service.proto similarity index 100% rename from Telemetry/ProtoFiles/OTel/v1/metrics_service.proto rename to App/FeatureSet/Telemetry/ProtoFiles/OTel/v1/metrics_service.proto diff --git a/Telemetry/ProtoFiles/OTel/v1/profiles.proto b/App/FeatureSet/Telemetry/ProtoFiles/OTel/v1/profiles.proto similarity index 100% rename from Telemetry/ProtoFiles/OTel/v1/profiles.proto rename to App/FeatureSet/Telemetry/ProtoFiles/OTel/v1/profiles.proto diff --git a/Telemetry/ProtoFiles/OTel/v1/profiles_service.proto b/App/FeatureSet/Telemetry/ProtoFiles/OTel/v1/profiles_service.proto similarity index 100% rename from Telemetry/ProtoFiles/OTel/v1/profiles_service.proto rename to App/FeatureSet/Telemetry/ProtoFiles/OTel/v1/profiles_service.proto diff --git a/Telemetry/ProtoFiles/OTel/v1/resource.proto b/App/FeatureSet/Telemetry/ProtoFiles/OTel/v1/resource.proto similarity index 100% rename from Telemetry/ProtoFiles/OTel/v1/resource.proto rename to App/FeatureSet/Telemetry/ProtoFiles/OTel/v1/resource.proto diff --git a/Telemetry/ProtoFiles/OTel/v1/trace_service.proto b/App/FeatureSet/Telemetry/ProtoFiles/OTel/v1/trace_service.proto similarity index 100% rename from Telemetry/ProtoFiles/OTel/v1/trace_service.proto rename to App/FeatureSet/Telemetry/ProtoFiles/OTel/v1/trace_service.proto diff --git a/Telemetry/ProtoFiles/OTel/v1/traces.proto b/App/FeatureSet/Telemetry/ProtoFiles/OTel/v1/traces.proto similarity index 100% rename from Telemetry/ProtoFiles/OTel/v1/traces.proto rename to App/FeatureSet/Telemetry/ProtoFiles/OTel/v1/traces.proto diff --git a/Telemetry/ProtoFiles/pprof/profile.proto b/App/FeatureSet/Telemetry/ProtoFiles/pprof/profile.proto similarity index 100% rename from Telemetry/ProtoFiles/pprof/profile.proto rename to App/FeatureSet/Telemetry/ProtoFiles/pprof/profile.proto diff --git a/Telemetry/Services/FluentLogsIngestService.ts b/App/FeatureSet/Telemetry/Services/FluentLogsIngestService.ts similarity index 100% rename from Telemetry/Services/FluentLogsIngestService.ts rename to App/FeatureSet/Telemetry/Services/FluentLogsIngestService.ts diff --git a/Telemetry/Services/LogDropFilterService.ts b/App/FeatureSet/Telemetry/Services/LogDropFilterService.ts similarity index 100% rename from Telemetry/Services/LogDropFilterService.ts rename to App/FeatureSet/Telemetry/Services/LogDropFilterService.ts diff --git a/Telemetry/Services/LogPipelineService.ts b/App/FeatureSet/Telemetry/Services/LogPipelineService.ts similarity index 100% rename from Telemetry/Services/LogPipelineService.ts rename to App/FeatureSet/Telemetry/Services/LogPipelineService.ts diff --git a/Telemetry/Services/LogScrubRuleService.ts b/App/FeatureSet/Telemetry/Services/LogScrubRuleService.ts similarity index 100% rename from Telemetry/Services/LogScrubRuleService.ts rename to App/FeatureSet/Telemetry/Services/LogScrubRuleService.ts diff --git a/Telemetry/Services/OtelIngestBaseService.ts b/App/FeatureSet/Telemetry/Services/OtelIngestBaseService.ts similarity index 100% rename from Telemetry/Services/OtelIngestBaseService.ts rename to App/FeatureSet/Telemetry/Services/OtelIngestBaseService.ts diff --git a/Telemetry/Services/OtelLogsIngestService.ts b/App/FeatureSet/Telemetry/Services/OtelLogsIngestService.ts similarity index 100% rename from Telemetry/Services/OtelLogsIngestService.ts rename to App/FeatureSet/Telemetry/Services/OtelLogsIngestService.ts diff --git a/Telemetry/Services/OtelMetricsIngestService.ts b/App/FeatureSet/Telemetry/Services/OtelMetricsIngestService.ts similarity index 100% rename from Telemetry/Services/OtelMetricsIngestService.ts rename to App/FeatureSet/Telemetry/Services/OtelMetricsIngestService.ts diff --git a/Telemetry/Services/OtelProfilesIngestService.ts b/App/FeatureSet/Telemetry/Services/OtelProfilesIngestService.ts similarity index 100% rename from Telemetry/Services/OtelProfilesIngestService.ts rename to App/FeatureSet/Telemetry/Services/OtelProfilesIngestService.ts diff --git a/Telemetry/Services/OtelTracesIngestService.ts b/App/FeatureSet/Telemetry/Services/OtelTracesIngestService.ts similarity index 100% rename from Telemetry/Services/OtelTracesIngestService.ts rename to App/FeatureSet/Telemetry/Services/OtelTracesIngestService.ts diff --git a/Telemetry/Services/PyroscopeIngestService.ts b/App/FeatureSet/Telemetry/Services/PyroscopeIngestService.ts similarity index 100% rename from Telemetry/Services/PyroscopeIngestService.ts rename to App/FeatureSet/Telemetry/Services/PyroscopeIngestService.ts diff --git a/Telemetry/Services/Queue/FluentLogsQueueService.ts b/App/FeatureSet/Telemetry/Services/Queue/FluentLogsQueueService.ts similarity index 100% rename from Telemetry/Services/Queue/FluentLogsQueueService.ts rename to App/FeatureSet/Telemetry/Services/Queue/FluentLogsQueueService.ts diff --git a/Telemetry/Services/Queue/LogsQueueService.ts b/App/FeatureSet/Telemetry/Services/Queue/LogsQueueService.ts similarity index 100% rename from Telemetry/Services/Queue/LogsQueueService.ts rename to App/FeatureSet/Telemetry/Services/Queue/LogsQueueService.ts diff --git a/Telemetry/Services/Queue/MetricsQueueService.ts b/App/FeatureSet/Telemetry/Services/Queue/MetricsQueueService.ts similarity index 100% rename from Telemetry/Services/Queue/MetricsQueueService.ts rename to App/FeatureSet/Telemetry/Services/Queue/MetricsQueueService.ts diff --git a/Telemetry/Services/Queue/ProfilesQueueService.ts b/App/FeatureSet/Telemetry/Services/Queue/ProfilesQueueService.ts similarity index 100% rename from Telemetry/Services/Queue/ProfilesQueueService.ts rename to App/FeatureSet/Telemetry/Services/Queue/ProfilesQueueService.ts diff --git a/Telemetry/Services/Queue/SyslogQueueService.ts b/App/FeatureSet/Telemetry/Services/Queue/SyslogQueueService.ts similarity index 100% rename from Telemetry/Services/Queue/SyslogQueueService.ts rename to App/FeatureSet/Telemetry/Services/Queue/SyslogQueueService.ts diff --git a/Telemetry/Services/Queue/TelemetryQueueService.ts b/App/FeatureSet/Telemetry/Services/Queue/TelemetryQueueService.ts similarity index 100% rename from Telemetry/Services/Queue/TelemetryQueueService.ts rename to App/FeatureSet/Telemetry/Services/Queue/TelemetryQueueService.ts diff --git a/Telemetry/Services/Queue/TracesQueueService.ts b/App/FeatureSet/Telemetry/Services/Queue/TracesQueueService.ts similarity index 100% rename from Telemetry/Services/Queue/TracesQueueService.ts rename to App/FeatureSet/Telemetry/Services/Queue/TracesQueueService.ts diff --git a/Telemetry/Services/SyslogIngestService.ts b/App/FeatureSet/Telemetry/Services/SyslogIngestService.ts similarity index 100% rename from Telemetry/Services/SyslogIngestService.ts rename to App/FeatureSet/Telemetry/Services/SyslogIngestService.ts diff --git a/Telemetry/Types/Request.ts b/App/FeatureSet/Telemetry/Types/Request.ts similarity index 100% rename from Telemetry/Types/Request.ts rename to App/FeatureSet/Telemetry/Types/Request.ts diff --git a/Telemetry/Utils/Exception.ts b/App/FeatureSet/Telemetry/Utils/Exception.ts similarity index 100% rename from Telemetry/Utils/Exception.ts rename to App/FeatureSet/Telemetry/Utils/Exception.ts diff --git a/Telemetry/Utils/LogFilterEvaluator.ts b/App/FeatureSet/Telemetry/Utils/LogFilterEvaluator.ts similarity index 100% rename from Telemetry/Utils/LogFilterEvaluator.ts rename to App/FeatureSet/Telemetry/Utils/LogFilterEvaluator.ts diff --git a/Telemetry/Utils/Monitor.ts b/App/FeatureSet/Telemetry/Utils/Monitor.ts similarity index 100% rename from Telemetry/Utils/Monitor.ts rename to App/FeatureSet/Telemetry/Utils/Monitor.ts diff --git a/Telemetry/Utils/StackTraceParser.ts b/App/FeatureSet/Telemetry/Utils/StackTraceParser.ts similarity index 100% rename from Telemetry/Utils/StackTraceParser.ts rename to App/FeatureSet/Telemetry/Utils/StackTraceParser.ts diff --git a/Telemetry/Utils/SyslogParser.ts b/App/FeatureSet/Telemetry/Utils/SyslogParser.ts similarity index 100% rename from Telemetry/Utils/SyslogParser.ts rename to App/FeatureSet/Telemetry/Utils/SyslogParser.ts diff --git a/App/Index.ts b/App/Index.ts index f0da330325..f63d7e5680 100755 --- a/App/Index.ts +++ b/App/Index.ts @@ -7,6 +7,7 @@ import IdentityRoutes from "./FeatureSet/Identity/Index"; import MCPRoutes from "./FeatureSet/MCP/Index"; import NotificationRoutes from "./FeatureSet/Notification/Index"; import WorkersRoutes from "./FeatureSet/Workers/Index"; +import TelemetryRoutes from "./FeatureSet/Telemetry/Index"; import WorkflowRoutes from "./FeatureSet/Workflow/Index"; import { PromiseVoidFunction } from "Common/Types/FunctionTypes"; import { ClickhouseAppInstance } from "Common/Server/Infrastructure/ClickhouseDatabase"; @@ -111,6 +112,7 @@ const init: PromiseVoidFunction = async (): Promise => { await DocsRoutes.init(); await APIReferenceRoutes.init(); await WorkersRoutes.init(); + await TelemetryRoutes.init(); await WorkflowRoutes.init(); // Add default routes to the app diff --git a/App/package.json b/App/package.json index a84e0a36ee..762c885ba0 100644 --- a/App/package.json +++ b/App/package.json @@ -38,12 +38,15 @@ "author": "OneUptime (https://oneuptime.com/)", "license": "Apache-2.0", "dependencies": { + "@grpc/grpc-js": "^1.12.5", + "@grpc/proto-loader": "^0.7.13", "@modelcontextprotocol/sdk": "^1.27.1", "@sendgrid/mail": "^8.1.0", "Common": "file:../Common", "ejs": "^3.1.9", "handlebars": "^4.7.8", "nodemailer": "^6.9.7", + "protobufjs": "^7.3.2", "ts-node": "^10.9.1", "twilio": "^4.20.0", "xml-crypto": "^3.2.0", diff --git a/Common/Server/EnvironmentConfig.ts b/Common/Server/EnvironmentConfig.ts index 9cbfd89283..0d107d0694 100644 --- a/Common/Server/EnvironmentConfig.ts +++ b/Common/Server/EnvironmentConfig.ts @@ -177,8 +177,8 @@ export const AppApiHostname: Hostname = Hostname.fromString( ); export const OpenTelemetryIngestHostname: Hostname = Hostname.fromString( - `${process.env["SERVER_TELEMETRY_HOSTNAME"] || "localhost"}:${ - process.env["TELEMETRY_PORT"] || 80 + `${process.env["SERVER_APP_HOSTNAME"] || "localhost"}:${ + process.env["APP_PORT"] || 80 }`, ); diff --git a/HelmChart/Public/oneuptime/templates/_helpers.tpl b/HelmChart/Public/oneuptime/templates/_helpers.tpl index 72668b6ffd..6cf34bbabe 100644 --- a/HelmChart/Public/oneuptime/templates/_helpers.tpl +++ b/HelmChart/Public/oneuptime/templates/_helpers.tpl @@ -117,13 +117,13 @@ Usage: - name: SERVER_APP_HOSTNAME value: {{ $.Release.Name }}-app.{{ $.Release.Namespace }}.svc.{{ $.Values.global.clusterDomain }} - name: TELEMETRY_HOSTNAME - value: {{ $.Release.Name }}-telemetry.{{ $.Release.Namespace }}.svc.{{ $.Values.global.clusterDomain }} + value: {{ $.Release.Name }}-app.{{ $.Release.Namespace }}.svc.{{ $.Values.global.clusterDomain }} - name: SERVER_TELEMETRY_HOSTNAME - value: {{ $.Release.Name }}-telemetry.{{ $.Release.Namespace }}.svc.{{ $.Values.global.clusterDomain }} + value: {{ $.Release.Name }}-app.{{ $.Release.Namespace }}.svc.{{ $.Values.global.clusterDomain }} - name: APP_PORT value: {{ $.Values.app.ports.http | squote }} - name: TELEMETRY_PORT - value: {{ $.Values.telemetry.ports.http | squote }} + value: {{ $.Values.app.ports.http | squote }} - name: HOME_PORT value: {{ $.Values.home.ports.http | squote }} - name: WORKER_CONCURRENCY diff --git a/HelmChart/Public/oneuptime/templates/app.yaml b/HelmChart/Public/oneuptime/templates/app.yaml index 050ad3a95f..05307dc78d 100644 --- a/HelmChart/Public/oneuptime/templates/app.yaml +++ b/HelmChart/Public/oneuptime/templates/app.yaml @@ -118,11 +118,16 @@ spec: value: {{ $.Values.app.disableTelemetryCollection | quote }} - name: ENABLE_PROFILING value: {{ $.Values.app.enableProfiling | quote }} - + - name: TELEMETRY_CONCURRENCY + value: {{ $.Values.app.telemetryConcurrency | default 100 | squote }} + {{- include "oneuptime.env.registerProbeKey" (dict "Values" $.Values "Release" $.Release) | nindent 12 }} ports: - containerPort: {{ $.Values.app.ports.http }} protocol: TCP name: http + - containerPort: {{ $.Values.app.ports.grpc | default 4317 }} + protocol: TCP + name: grpc {{- if $.Values.app.resources }} resources: {{- toYaml $.Values.app.resources | nindent 12 }} @@ -141,7 +146,7 @@ spec: {{- if and $.Values.app.enabled (not $.Values.deployment.disableDeployments) }} # OneUptime app Service -{{- $appPorts := dict "port" $.Values.app.ports.http -}} +{{- $appPorts := dict "http" $.Values.app.ports.http "grpc" ($.Values.app.ports.grpc | default 4317) -}} {{- $appServiceArgs := dict "ServiceName" "app" "Ports" $appPorts "Release" $.Release "Values" $.Values -}} {{- include "oneuptime.service" $appServiceArgs }} --- diff --git a/HelmChart/Public/oneuptime/templates/keda-scaledobjects.yaml b/HelmChart/Public/oneuptime/templates/keda-scaledobjects.yaml index 90d1c1875d..219d5e393e 100644 --- a/HelmChart/Public/oneuptime/templates/keda-scaledobjects.yaml +++ b/HelmChart/Public/oneuptime/templates/keda-scaledobjects.yaml @@ -2,13 +2,6 @@ KEDA ScaledObjects for various services */}} -{{/* Telemetry KEDA ScaledObject */}} -{{- if and .Values.keda.enabled .Values.telemetry.enabled .Values.telemetry.keda.enabled (not .Values.telemetry.disableAutoscaler) (not .Values.deployment.disableDeployments) }} -{{- $metricsConfig := dict "enabled" .Values.telemetry.keda.enabled "minReplicas" .Values.telemetry.keda.minReplicas "maxReplicas" .Values.telemetry.keda.maxReplicas "pollingInterval" .Values.telemetry.keda.pollingInterval "cooldownPeriod" .Values.telemetry.keda.cooldownPeriod "triggers" (list (dict "query" "oneuptime_telemetry_queue_size" "threshold" .Values.telemetry.keda.queueSizeThreshold "port" .Values.telemetry.ports.http)) }} -{{- $telemetryKedaArgs := dict "ServiceName" "telemetry" "Release" .Release "Values" .Values "MetricsConfig" $metricsConfig "DisableAutoscaler" .Values.telemetry.disableAutoscaler }} -{{- include "oneuptime.kedaScaledObject" $telemetryKedaArgs }} -{{- end }} - {{/* Probe KEDA ScaledObjects - one for each probe configuration */}} {{- range $key, $val := $.Values.probes }} {{- $probeEnabled := or (not (hasKey $val "enabled")) $val.enabled }} diff --git a/HelmChart/Public/oneuptime/templates/otel-collector.yaml b/HelmChart/Public/oneuptime/templates/otel-collector.yaml index 665f3084fd..a2b8d85e5f 100644 --- a/HelmChart/Public/oneuptime/templates/otel-collector.yaml +++ b/HelmChart/Public/oneuptime/templates/otel-collector.yaml @@ -1 +1 @@ -{{- /* OTel Collector has been removed. Telemetry ingestion (gRPC + HTTP) is now handled directly by the telemetry service. */ -}} +{{- /* OTel Collector has been removed. Telemetry ingestion (gRPC + HTTP) is now handled directly by the app service. */ -}} diff --git a/HelmChart/Public/oneuptime/templates/probe.yaml b/HelmChart/Public/oneuptime/templates/probe.yaml index 1ecfea3443..c772946284 100644 --- a/HelmChart/Public/oneuptime/templates/probe.yaml +++ b/HelmChart/Public/oneuptime/templates/probe.yaml @@ -86,7 +86,7 @@ spec: - name: OPENTELEMETRY_EXPORTER_OTLP_ENDPOINT value: {{ $.Values.openTelemetryExporter.endpoint }} - name: ONEUPTIME_URL - value: http://{{ $.Release.Name }}-telemetry.{{ $.Release.Namespace }}.svc.{{ $.Values.global.clusterDomain }}:{{ $.Values.telemetry.ports.http }} + value: http://{{ $.Release.Name }}-app.{{ $.Release.Namespace }}.svc.{{ $.Values.global.clusterDomain }}:{{ $.Values.app.ports.http }} - name: PROBE_NAME value: {{ $val.name }} - name: PROBE_DESCRIPTION diff --git a/HelmChart/Public/oneuptime/templates/telemetry.yaml b/HelmChart/Public/oneuptime/templates/telemetry.yaml deleted file mode 100644 index 82128f2e36..0000000000 --- a/HelmChart/Public/oneuptime/templates/telemetry.yaml +++ /dev/null @@ -1,148 +0,0 @@ -{{- if and $.Values.telemetry.enabled (not $.Values.deployment.disableDeployments) }} -# OneUptime telemetry Deployment - -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ printf "%s-%s" $.Release.Name "telemetry" }} - namespace: {{ $.Release.Namespace }} - labels: - app: {{ printf "%s-%s" $.Release.Name "telemetry" }} - app.kubernetes.io/part-of: oneuptime - app.kubernetes.io/managed-by: Helm - appname: oneuptime - {{- if $.Values.deployment.includeTimestampLabel }} - date: "{{ now | unixEpoch }}" - {{- end }} -spec: - selector: - matchLabels: - app: {{ printf "%s-%s" $.Release.Name "telemetry" }} - {{- if $.Values.telemetry.replicaCount }} - replicas: {{ $.Values.telemetry.replicaCount }} - {{- else }} - {{- if or (not $.Values.autoscaling.enabled) ($.Values.telemetry.disableAutoscaler) }} - replicas: {{ $.Values.deployment.replicaCount }} - {{- end }} - {{- end }} - strategy: {{- toYaml $.Values.deployment.updateStrategy | nindent 4 }} - template: - metadata: - labels: - app: {{ printf "%s-%s" $.Release.Name "telemetry" }} - {{- if $.Values.deployment.includeTimestampLabel }} - date: "{{ now | unixEpoch }}" - {{- end }} - appname: oneuptime - spec: - volumes: - - name: greenlockrc - emptyDir: - sizeLimit: "1Gi" - {{- if $.Values.telemetry.podSecurityContext }} - securityContext: - {{- toYaml $.Values.telemetry.podSecurityContext | nindent 8 }} - {{- else if $.Values.podSecurityContext }} - securityContext: - {{- toYaml $.Values.podSecurityContext | nindent 8 }} - {{- end }} - {{- if $.Values.imagePullSecrets }} - imagePullSecrets: - {{- toYaml $.Values.imagePullSecrets | nindent 8 }} - {{- end }} - {{- if $.Values.affinity }} - affinity: {{- $.Values.affinity | toYaml | nindent 8 }} - {{- end }} - {{- if $.Values.tolerations }} - tolerations: {{- $.Values.tolerations | toYaml | nindent 8 }} - {{- end }} - {{- if $.Values.telemetry.nodeSelector }} - nodeSelector: - {{- toYaml $.Values.telemetry.nodeSelector | nindent 8 }} - {{- else if $.Values.nodeSelector }} - nodeSelector: - {{- toYaml $.Values.nodeSelector | nindent 8 }} - {{- end }} - containers: - - image: {{ include "oneuptime.image" (dict "Values" $.Values "ServiceName" "telemetry") }} - name: {{ printf "%s-%s" $.Release.Name "telemetry" }} - {{- if $.Values.startupProbe.enabled }} - # Startup probe - startupProbe: - httpGet: - path: /status/live - port: {{ $.Values.telemetry.ports.http }} - periodSeconds: {{ $.Values.startupProbe.periodSeconds }} - failureThreshold: {{ $.Values.startupProbe.failureThreshold }} - {{- end }} - {{- if $.Values.livenessProbe.enabled }} - # Liveness probe - livenessProbe: - httpGet: - path: /status/live - port: {{ $.Values.telemetry.ports.http }} - periodSeconds: {{ $.Values.livenessProbe.periodSeconds }} - timeoutSeconds: {{ $.Values.livenessProbe.timeoutSeconds }} - initialDelaySeconds: {{ $.Values.livenessProbe.initialDelaySeconds }} - {{- end }} - {{- if $.Values.readinessProbe.enabled }} - # Readyness Probe - readinessProbe: - httpGet: - path: /status/ready - port: {{ $.Values.telemetry.ports.http }} - periodSeconds: {{ $.Values.readinessProbe.periodSeconds }} - initialDelaySeconds: {{ $.Values.readinessProbe.initialDelaySeconds }} - timeoutSeconds: {{ $.Values.readinessProbe.timeoutSeconds }} - {{- end }} - {{- if $.Values.telemetry.containerSecurityContext }} - securityContext: - {{- toYaml $.Values.telemetry.containerSecurityContext | nindent 12 }} - {{- else if $.Values.containerSecurityContext }} - securityContext: - {{- toYaml $.Values.containerSecurityContext | nindent 12 }} - {{- end }} - imagePullPolicy: {{ $.Values.image.pullPolicy }} - env: - {{- include "oneuptime.env.common" . | nindent 12 }} - {{- include "oneuptime.env.runtime" (dict "Values" $.Values "Release" $.Release) | nindent 12 }} - - name: PORT - value: {{ $.Values.telemetry.ports.http | quote }} - - name: DISABLE_TELEMETRY - value: {{ $.Values.telemetry.disableTelemetryCollection | quote }} - - name: ENABLE_PROFILING - value: {{ $.Values.telemetry.enableProfiling | quote }} - - name: TELEMETRY_CONCURRENCY - value: {{ $.Values.telemetry.concurrency | squote }} - {{- include "oneuptime.env.registerProbeKey" (dict "Values" $.Values "Release" $.Release) | nindent 12 }} - ports: - - containerPort: {{ $.Values.telemetry.ports.http }} - protocol: TCP - name: http - - containerPort: {{ $.Values.telemetry.ports.grpc }} - protocol: TCP - name: grpc - {{- if $.Values.telemetry.resources }} - resources: - {{- toYaml $.Values.telemetry.resources | nindent 12 }} - {{- end }} - restartPolicy: {{ $.Values.image.restartPolicy }} - ---- - -# OneUptime telemetry autoscaler -{{- if and (not $.Values.telemetry.disableAutoscaler) (not (and $.Values.keda.enabled $.Values.telemetry.keda.enabled)) }} -{{- $telemetryAutoScalerArgs := dict "ServiceName" "telemetry" "Release" $.Release "Values" $.Values -}} -{{- include "oneuptime.autoscaler" $telemetryAutoScalerArgs }} -{{- end }} -{{- end }} - ---- - -{{- if and $.Values.telemetry.enabled (not $.Values.deployment.disableDeployments) }} -# OneUptime telemetry Service -{{- $telemetryPorts := dict "http" $.Values.telemetry.ports.http "grpc" $.Values.telemetry.ports.grpc -}} -{{- $telemetryServiceArgs := dict "ServiceName" "telemetry" "Ports" $telemetryPorts "Release" $.Release "Values" $.Values -}} -{{- include "oneuptime.service" $telemetryServiceArgs }} ---- -{{- end }} diff --git a/HelmChart/Public/oneuptime/values.schema.json b/HelmChart/Public/oneuptime/values.schema.json index 2ba7e8ae63..1608f401da 100644 --- a/HelmChart/Public/oneuptime/values.schema.json +++ b/HelmChart/Public/oneuptime/values.schema.json @@ -1755,49 +1755,7 @@ "workerConcurrency": { "type": "integer" }, - "disableTelemetryCollection": { - "type": "boolean" - }, - "disableAutoscaler": { - "type": "boolean" - }, - "ports": { - "type": "object", - "properties": { - "http": { - "type": "integer" - } - }, - "additionalProperties": false - }, - "resources": { - "type": [ - "object", - "null" - ] - }, - "nodeSelector": { - "type": "object" - }, - "podSecurityContext": { - "type": "object" - }, - "containerSecurityContext": { - "type": "object" - }, - "enableProfiling": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "telemetry": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "replicaCount": { + "telemetryConcurrency": { "type": "integer" }, "disableTelemetryCollection": { @@ -1806,9 +1764,6 @@ "disableAutoscaler": { "type": "boolean" }, - "concurrency": { - "type": "integer" - }, "ports": { "type": "object", "properties": { @@ -1816,7 +1771,8 @@ "type": "integer" }, "grpc": { - "type": "integer" + "type": "integer", + "default": 4317 } }, "additionalProperties": false @@ -1836,30 +1792,6 @@ "containerSecurityContext": { "type": "object" }, - "keda": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "minReplicas": { - "type": "integer" - }, - "maxReplicas": { - "type": "integer" - }, - "queueSizeThreshold": { - "type": "integer" - }, - "pollingInterval": { - "type": "integer" - }, - "cooldownPeriod": { - "type": "integer" - } - }, - "additionalProperties": false - }, "enableProfiling": { "type": "boolean" } diff --git a/HelmChart/Public/oneuptime/values.yaml b/HelmChart/Public/oneuptime/values.yaml index 4be94a0343..af9a94cb04 100644 --- a/HelmChart/Public/oneuptime/values.yaml +++ b/HelmChart/Public/oneuptime/values.yaml @@ -650,42 +650,18 @@ app: enabled: true replicaCount: 1 workerConcurrency: 100 + # Max concurrent telemetry ingestion jobs processed by each pod + telemetryConcurrency: 100 disableTelemetryCollection: false enableProfiling: false disableAutoscaler: false ports: http: 3002 - resources: - nodeSelector: {} - podSecurityContext: {} - containerSecurityContext: {} - -telemetry: - enabled: true - replicaCount: 1 - disableTelemetryCollection: false - enableProfiling: false - disableAutoscaler: false - # Max concurrent telemetry jobs processed by each pod - concurrency: 100 - ports: - http: 3403 grpc: 4317 resources: nodeSelector: {} podSecurityContext: {} containerSecurityContext: {} - # KEDA autoscaling configuration based on queue metrics - keda: - enabled: false - minReplicas: 1 - maxReplicas: 100 - # Scale up when queue size exceeds this threshold - queueSizeThreshold: 100 - # Polling interval for metrics (in seconds) - pollingInterval: 30 - # Cooldown period after scaling (in seconds) - cooldownPeriod: 300 # AI Agent Configuration # Deploy this to run an AI Agent within your Kubernetes cluster diff --git a/Nginx/default.conf.template b/Nginx/default.conf.template index 03e66274ed..22b3dc1c70 100644 --- a/Nginx/default.conf.template +++ b/Nginx/default.conf.template @@ -522,7 +522,7 @@ ${PROVISION_SSL_CERTIFICATE_KEY_DIRECTIVE} location /telemetry { resolver ${NGINX_RESOLVER} valid=30s; - set $backend_telemetry http://${SERVER_TELEMETRY_HOSTNAME}:${TELEMETRY_PORT}; + set $backend_telemetry http://${SERVER_APP_HOSTNAME}:${APP_PORT}; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; @@ -533,7 +533,7 @@ ${PROVISION_SSL_CERTIFICATE_KEY_DIRECTIVE} location /incoming-request-ingest { resolver ${NGINX_RESOLVER} valid=30s; - set $backend_telemetry http://${SERVER_TELEMETRY_HOSTNAME}:${TELEMETRY_PORT}; + set $backend_telemetry http://${SERVER_APP_HOSTNAME}:${APP_PORT}; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; @@ -545,7 +545,7 @@ ${PROVISION_SSL_CERTIFICATE_KEY_DIRECTIVE} location /otlp { resolver ${NGINX_RESOLVER} valid=30s; - set $backend_telemetry http://${SERVER_TELEMETRY_HOSTNAME}:${TELEMETRY_PORT}; + set $backend_telemetry http://${SERVER_APP_HOSTNAME}:${APP_PORT}; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; @@ -562,7 +562,7 @@ ${PROVISION_SSL_CERTIFICATE_KEY_DIRECTIVE} # Pyroscope profiling ingestion endpoint location /pyroscope { resolver ${NGINX_RESOLVER} valid=30s; - set $backend_telemetry http://${SERVER_TELEMETRY_HOSTNAME}:${TELEMETRY_PORT}; + set $backend_telemetry http://${SERVER_APP_HOSTNAME}:${APP_PORT}; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; @@ -573,7 +573,7 @@ ${PROVISION_SSL_CERTIFICATE_KEY_DIRECTIVE} location ~ /opentelemetry.proto.collector* { resolver ${NGINX_RESOLVER} valid=30s; - set $backend_otel_grpc grpc://${SERVER_TELEMETRY_HOSTNAME}:4317; + set $backend_otel_grpc grpc://${SERVER_APP_HOSTNAME}:4317; grpc_pass $backend_otel_grpc; } @@ -602,7 +602,7 @@ ${PROVISION_SSL_CERTIFICATE_KEY_DIRECTIVE} location /fluentd/logs { resolver ${NGINX_RESOLVER} valid=30s; - set $backend_telemetry http://${SERVER_TELEMETRY_HOSTNAME}:${TELEMETRY_PORT}; + set $backend_telemetry http://${SERVER_APP_HOSTNAME}:${APP_PORT}; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; @@ -619,7 +619,7 @@ ${PROVISION_SSL_CERTIFICATE_KEY_DIRECTIVE} location /syslog/v1/logs { resolver ${NGINX_RESOLVER} valid=30s; - set $backend_telemetry http://${SERVER_TELEMETRY_HOSTNAME}:${TELEMETRY_PORT}; + set $backend_telemetry http://${SERVER_APP_HOSTNAME}:${APP_PORT}; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; @@ -634,7 +634,7 @@ ${PROVISION_SSL_CERTIFICATE_KEY_DIRECTIVE} location /probe-ingest { resolver ${NGINX_RESOLVER} valid=30s; - set $backend_telemetry http://${SERVER_TELEMETRY_HOSTNAME}:${TELEMETRY_PORT}; + set $backend_telemetry http://${SERVER_APP_HOSTNAME}:${APP_PORT}; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; @@ -652,7 +652,7 @@ ${PROVISION_SSL_CERTIFICATE_KEY_DIRECTIVE} # For backward compatibility with probes that are already deployed location /ingestor { resolver ${NGINX_RESOLVER} valid=30s; - set $backend_telemetry http://${SERVER_TELEMETRY_HOSTNAME}:${TELEMETRY_PORT}; + set $backend_telemetry http://${SERVER_APP_HOSTNAME}:${APP_PORT}; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; @@ -669,7 +669,7 @@ ${PROVISION_SSL_CERTIFICATE_KEY_DIRECTIVE} location /server-monitor { resolver ${NGINX_RESOLVER} valid=30s; - set $backend_telemetry http://${SERVER_TELEMETRY_HOSTNAME}:${TELEMETRY_PORT}; + set $backend_telemetry http://${SERVER_APP_HOSTNAME}:${APP_PORT}; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; @@ -914,7 +914,7 @@ ${PROVISION_SSL_CERTIFICATE_KEY_DIRECTIVE} location /heartbeat { resolver ${NGINX_RESOLVER} valid=30s; - set $backend_telemetry http://${SERVER_TELEMETRY_HOSTNAME}:${TELEMETRY_PORT}; + set $backend_telemetry http://${SERVER_APP_HOSTNAME}:${APP_PORT}; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; @@ -933,7 +933,7 @@ ${PROVISION_SSL_CERTIFICATE_KEY_DIRECTIVE} location /incoming-email { # Incoming Email Monitor webhook endpoint resolver ${NGINX_RESOLVER} valid=30s; - set $backend_telemetry http://${SERVER_TELEMETRY_HOSTNAME}:${TELEMETRY_PORT}; + set $backend_telemetry http://${SERVER_APP_HOSTNAME}:${APP_PORT}; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; diff --git a/Telemetry/.dockerignore b/Telemetry/.dockerignore deleted file mode 100644 index 3ff05dd7b8..0000000000 --- a/Telemetry/.dockerignore +++ /dev/null @@ -1,56 +0,0 @@ -.git - -node_modules -# See https://help.github.com/ignore-files/ for more about ignoring files. - -# dependencies -/node_modules -node_modules - -.idea -# testing -/coverage - -# production -/build - -# misc -.DS_Store - -env.js - -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -yarn.lock -Untitled-1 -*.local.sh -*.local.yaml -run -stop - -nohup.out* - -encrypted-credentials.tar -encrypted-credentials/ - -_README.md - -# Important Add production values to gitignore. -values-saas-production.yaml -kubernetes/values-saas-production.yaml - -/private - -/tls_cert.pem -/tls_key.pem -/keys - -temp_readme.md - -tests/coverage - -settings.json - -GoSDK/tester/ \ No newline at end of file diff --git a/Telemetry/.gitattributes b/Telemetry/.gitattributes deleted file mode 100644 index 30ddbbb6cb..0000000000 --- a/Telemetry/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -*.js text eol=lf \ No newline at end of file diff --git a/Telemetry/.gitignore b/Telemetry/.gitignore deleted file mode 100644 index fe55b57a33..0000000000 --- a/Telemetry/.gitignore +++ /dev/null @@ -1,16 +0,0 @@ -# See https://help.github.com/ignore-files/ for more about ignoring files. - -# dependencies -#/backend/node_modules -/kubernetes -/node_modules -.idea - -# misc -.DS_Store - - -npm-debug.log* -yarn-debug.log* -yarn-error.log* -yarn.lock \ No newline at end of file diff --git a/Telemetry/Dockerfile.tpl b/Telemetry/Dockerfile.tpl deleted file mode 100644 index 04e9b68bda..0000000000 --- a/Telemetry/Dockerfile.tpl +++ /dev/null @@ -1,83 +0,0 @@ -# -# OneUptime-Telemetry Dockerfile -# - -# Pull base image nodejs image. -FROM public.ecr.aws/docker/library/node:23.8 -RUN mkdir /tmp/npm && chmod 2777 /tmp/npm && chown 1000:1000 /tmp/npm && npm config set cache /tmp/npm --global - -RUN npm config set fetch-retries 5 -RUN npm config set fetch-retry-mintimeout 20000 -RUN npm config set fetch-retry-maxtimeout 60000 - - -ARG GIT_SHA -ARG APP_VERSION -ARG IS_ENTERPRISE_EDITION=false - -ENV GIT_SHA=${GIT_SHA} -ENV APP_VERSION=${APP_VERSION} -ENV IS_ENTERPRISE_EDITION=${IS_ENTERPRISE_EDITION} -ENV PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 -ENV NODE_OPTIONS="--use-openssl-ca" - -## Add Intermediate Certs -COPY ./SslCertificates /usr/local/share/ca-certificates -RUN update-ca-certificates - - -# IF APP_VERSION is not set, set it to 1.0.0 -RUN if [ -z "$APP_VERSION" ]; then export APP_VERSION=1.0.0; fi - - -RUN apt-get update - -# Install bash. -RUN apt-get install bash -y && apt-get install curl -y && apt-get install iputils-ping -y - -# Install python -RUN apt-get update && apt-get install -y .gyp python3 make g++ - -#Use bash shell by default -SHELL ["/bin/bash", "-c"] - -# Install iputils -RUN apt-get install net-tools -y - -RUN mkdir -p /usr/src - -WORKDIR /usr/src/Common -COPY ./Common/package*.json /usr/src/Common/ -# Set version in ./Common/package.json to the APP_VERSION -RUN sed -i "s/\"version\": \".*\"/\"version\": \"$APP_VERSION\"/g" /usr/src/Common/package.json -RUN npm install -COPY ./Common /usr/src/Common - - - -ENV PRODUCTION=true - -WORKDIR /usr/src/app - -# Install app dependencies -COPY ./Telemetry/package*.json /usr/src/app/ -RUN npm install - -# Expose ports. -# - 3403: OneUptime-Telemetry -EXPOSE 3403 - -{{ if eq .Env.ENVIRONMENT "development" }} -#Run the app -CMD [ "npm", "run", "dev" ] -{{ else }} -# Copy app source -COPY ./Telemetry /usr/src/app -# Bundle app source -RUN npm run compile -# Set permission to write logs and cache in case container run as non root -RUN chown -R 1000:1000 "/tmp/npm" && chmod -R 2777 "/tmp/npm" -#Run the app -CMD [ "npm", "start" ] -{{ end }} - diff --git a/Telemetry/Docs/SysLog/README.md b/Telemetry/Docs/SysLog/README.md deleted file mode 100644 index 84dc9a661e..0000000000 --- a/Telemetry/Docs/SysLog/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# Syslog Testing Instructions - -Test in terminal, send a sample RFC5424 payload: - ```bash - curl -X POST \ - -H "Content-Type: text/plain" \ - -H "x-oneuptime-token: YOUR_TEST_TOKEN" \ - -H "x-oneuptime-service-name: local-syslog" \ - --data '<134>1 2024-07-10T17:25:43.123Z host app 1234 ID47 [exampleSDID@32473 iut="3" eventSource="App"] An application event log entry' \ - https://oneuptime.com/syslog/v1/logs - ``` - -Replace `YOUR_TEST_TOKEN` and `local-syslog` with a valid telemetry key and desired service label. Please also replace oneuptime.com with your host if you're testing this locally. - -Inspect the service logs or connected queue to ensure the message is accepted and parsed. - diff --git a/Telemetry/Docs/examples/otlp-profiles-payload.json b/Telemetry/Docs/examples/otlp-profiles-payload.json deleted file mode 100644 index a64a1420ce..0000000000 --- a/Telemetry/Docs/examples/otlp-profiles-payload.json +++ /dev/null @@ -1,281 +0,0 @@ -{ - "resourceProfiles": [ - { - "resource": { - "attributes": [ - { - "key": "service.name", - "value": { - "stringValue": "my-go-service" - } - }, - { - "key": "host.name", - "value": { - "stringValue": "prod-server-01" - } - }, - { - "key": "process.runtime.name", - "value": { - "stringValue": "go" - } - }, - { - "key": "process.runtime.version", - "value": { - "stringValue": "go1.22.0" - } - }, - { - "key": "telemetry.sdk.name", - "value": { - "stringValue": "opentelemetry" - } - }, - { - "key": "telemetry.sdk.language", - "value": { - "stringValue": "go" - } - }, - { - "key": "telemetry.sdk.version", - "value": { - "stringValue": "1.28.0" - } - } - ] - }, - "scopeProfiles": [ - { - "scope": { - "name": "otel-profiling-go", - "version": "0.5.0" - }, - "profiles": [ - { - "profileId": "qg7PaWLjuqLhWlwvlHRU9A==", - "startTimeUnixNano": "1700000000000000000", - "endTimeUnixNano": "1700000030000000000", - "attributes": [ - { - "key": "profiling.data.type", - "value": { - "stringValue": "cpu" - } - } - ], - "originalPayloadFormat": "pprofext", - "profile": { - "stringTable": [ - "", - "cpu", - "nanoseconds", - "samples", - "count", - "main.handleRequest", - "/app/main.go", - "net/http.(*conn).serve", - "/usr/local/go/src/net/http/server.go", - "runtime.goexit", - "/usr/local/go/src/runtime/asm_amd64.s", - "main.processData", - "/app/processor.go", - "encoding/json.Marshal", - "/usr/local/go/src/encoding/json/encode.go", - "runtime.mallocgc", - "/usr/local/go/src/runtime/malloc.go", - "main.queryDatabase", - "/app/db.go", - "database/sql.(*DB).QueryContext", - "/usr/local/go/src/database/sql/sql.go" - ], - "sampleType": [ - { - "type": 1, - "unit": 2 - }, - { - "type": 3, - "unit": 4 - } - ], - "periodType": { - "type": 1, - "unit": 2 - }, - "period": 10000000, - "functionTable": [ - { - "name": 5, - "filename": 6 - }, - { - "name": 7, - "filename": 8 - }, - { - "name": 9, - "filename": 10 - }, - { - "name": 11, - "filename": 12 - }, - { - "name": 13, - "filename": 14 - }, - { - "name": 15, - "filename": 16 - }, - { - "name": 17, - "filename": 18 - }, - { - "name": 19, - "filename": 20 - } - ], - "locationTable": [ - { - "line": [ - { - "functionIndex": 0, - "line": 42 - } - ] - }, - { - "line": [ - { - "functionIndex": 1, - "line": 1960 - } - ] - }, - { - "line": [ - { - "functionIndex": 2, - "line": 1700 - } - ] - }, - { - "line": [ - { - "functionIndex": 3, - "line": 88 - } - ] - }, - { - "line": [ - { - "functionIndex": 4, - "line": 160 - } - ] - }, - { - "line": [ - { - "functionIndex": 5, - "line": 905 - } - ] - }, - { - "line": [ - { - "functionIndex": 6, - "line": 55 - } - ] - }, - { - "line": [ - { - "functionIndex": 7, - "line": 1612 - } - ] - } - ], - "stackTable": [ - { - "locationIndices": [0, 1, 2] - }, - { - "locationIndices": [3, 4, 0, 1, 2] - }, - { - "locationIndices": [5, 3, 0, 1, 2] - }, - { - "locationIndices": [6, 7, 0, 1, 2] - } - ], - "linkTable": [ - { - "traceId": "qg7PaWLjuqLhWlwvlHRU9A==", - "spanId": "r+N4WZXXfP4=" - } - ], - "attributeTable": [ - { - "key": "profile.frame.type", - "value": { - "stringValue": "go" - } - }, - { - "key": "thread.name", - "value": { - "stringValue": "main" - } - } - ], - "sample": [ - { - "stackIndex": 0, - "value": [50000000, 5], - "timestampsUnixNano": ["1700000005000000000"], - "linkIndex": 0, - "attributeIndices": [0, 1] - }, - { - "stackIndex": 1, - "value": [120000000, 12], - "timestampsUnixNano": ["1700000010000000000"], - "linkIndex": 0, - "attributeIndices": [0] - }, - { - "stackIndex": 2, - "value": [30000000, 3], - "timestampsUnixNano": ["1700000015000000000"], - "linkIndex": 0, - "attributeIndices": [0] - }, - { - "stackIndex": 3, - "value": [80000000, 8], - "timestampsUnixNano": ["1700000020000000000"], - "linkIndex": 0, - "attributeIndices": [0] - } - ] - } - } - ] - } - ], - "schemaUrl": "https://opentelemetry.io/schemas/1.21.0" - } - ] -} diff --git a/Telemetry/Docs/logData.example.json b/Telemetry/Docs/logData.example.json deleted file mode 100644 index fbcc846bb6..0000000000 --- a/Telemetry/Docs/logData.example.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "resourceLogs":[ - { - "resource":{ - "attributes":[ - { - "key":"service.name", - "value":{ - "stringValue":"otel-dotnet" - } - }, - { - "key":"service.instance.id", - "value":{ - "stringValue":"933c049b-1f18-4dbf-bd4f-acd9cbc3a03e" - } - }, - { - "key":"telemetry.sdk.name", - "value":{ - "stringValue":"opentelemetry" - } - }, - { - "key":"telemetry.sdk.language", - "value":{ - "stringValue":"dotnet" - } - }, - { - "key":"telemetry.sdk.version", - "value":{ - "stringValue":"1.6.0" - } - } - ] - }, - "scopeLogs":[ - { - "scope":{ - - }, - "logRecords":[ - { - "timeUnixNano":"1698069643739368000", - "severityNumber":"SEVERITY_NUMBER_INFO", - "severityText":"Information", - "body":{ - "stringValue":"Application is shutting down..." - }, - "traceId":"", - "spanId":"", - "observedTimeUnixNano":"1698069643739368000" - } - ] - } - ] - } - ] - } \ No newline at end of file diff --git a/Telemetry/Docs/metricsData.example.json b/Telemetry/Docs/metricsData.example.json deleted file mode 100644 index b2b2737236..0000000000 --- a/Telemetry/Docs/metricsData.example.json +++ /dev/null @@ -1,294 +0,0 @@ -{ - "resourceMetrics":[ - { - "resource":{ - "attributes":[ - { - "key":"host.name", - "value":{ - "stringValue":"c16e92aabd73" - } - }, - { - "key":"process.command_args", - "value":{ - "arrayValue":{ - "values":[ - { - "stringValue":"/app/main" - } - ] - } - } - }, - { - "key":"process.executable.name", - "value":{ - "stringValue":"main" - } - }, - { - "key":"process.executable.path", - "value":{ - "stringValue":"/app/main" - } - }, - { - "key":"process.owner", - "value":{ - "stringValue":"root" - } - }, - { - "key":"process.pid", - "value":{ - "intValue":"1" - } - }, - { - "key":"process.runtime.description", - "value":{ - "stringValue":"go version go1.21.2 linux/arm64" - } - }, - { - "key":"process.runtime.name", - "value":{ - "stringValue":"go" - } - }, - { - "key":"process.runtime.version", - "value":{ - "stringValue":"go1.21.2" - } - }, - { - "key":"service.name", - "value":{ - "stringValue":"demo-client" - } - }, - { - "key":"telemetry.sdk.language", - "value":{ - "stringValue":"go" - } - }, - { - "key":"telemetry.sdk.name", - "value":{ - "stringValue":"opentelemetry" - } - }, - { - "key":"telemetry.sdk.version", - "value":{ - "stringValue":"1.19.0" - } - } - ] - }, - "scopeMetrics":[ - { - "scope":{ - "name":"demo-client-meter" - }, - "metrics":[ - { - "name":"demo_client/request_latency", - "description":"The latency of requests processed", - "histogram":{ - "dataPoints":[ - { - "startTimeUnixNano":"1698055858300756753", - "timeUnixNano":"1698073168340861251", - "count":"12262", - "sum":5009057.084501003, - "bucketCounts":[ - "0", - "268", - "700", - "1805", - "852", - "770", - "645", - "1041", - "1731", - "1761", - "1451", - "1238", - "0", - "0", - "0", - "0" - ], - "explicitBounds":[ - 0, - 5, - 10, - 25, - 50, - 75, - 100, - 250, - 500, - 750, - 1000, - 2500, - 5000, - 7500, - 10000 - ], - "attributes":[ - { - "key":"client", - "value":{ - "stringValue":"cli" - } - }, - { - "key":"method", - "value":{ - "stringValue":"repl" - } - } - ], - "min":0.827, - "max":2003.162543 - } - ], - "aggregationTemporality":"AGGREGATION_TEMPORALITY_CUMULATIVE" - } - }, - { - "name":"demo_client/request_counts", - "description":"The number of requests processed", - "sum":{ - "dataPoints":[ - { - "startTimeUnixNano":"1698055858300764253", - "timeUnixNano":"1698073168340863543", - "asInt":"12262", - "attributes":[ - { - "key":"client", - "value":{ - "stringValue":"cli" - } - }, - { - "key":"method", - "value":{ - "stringValue":"repl" - } - } - ] - } - ], - "aggregationTemporality":"AGGREGATION_TEMPORALITY_CUMULATIVE", - "isMonotonic":true - } - }, - { - "name":"demo_client/line_lengths", - "description":"The lengths of the various lines in", - "histogram":{ - "dataPoints":[ - { - "startTimeUnixNano":"1698055858300770170", - "timeUnixNano":"1698073168340864918", - "count":"36845", - "sum":18342968, - "bucketCounts":[ - "27", - "174", - "185", - "586", - "928", - "967", - "904", - "5531", - "9221", - "9200", - "9122", - "0", - "0", - "0", - "0", - "0" - ], - "explicitBounds":[ - 0, - 5, - 10, - 25, - 50, - 75, - 100, - 250, - 500, - 750, - 1000, - 2500, - 5000, - 7500, - 10000 - ], - "attributes":[ - { - "key":"client", - "value":{ - "stringValue":"cli" - } - }, - { - "key":"method", - "value":{ - "stringValue":"repl" - } - } - ], - "min":0, - "max":998 - } - ], - "aggregationTemporality":"AGGREGATION_TEMPORALITY_CUMULATIVE" - } - }, - { - "name":"demo_client/line_counts", - "description":"The counts of the lines in", - "sum":{ - "dataPoints":[ - { - "startTimeUnixNano":"1698055858300772836", - "timeUnixNano":"1698073168340865418", - "asInt":"36845", - "attributes":[ - { - "key":"client", - "value":{ - "stringValue":"cli" - } - }, - { - "key":"method", - "value":{ - "stringValue":"repl" - } - } - ] - } - ], - "aggregationTemporality":"AGGREGATION_TEMPORALITY_CUMULATIVE", - "isMonotonic":true - } - } - ] - } - ], - "schemaUrl":"https://opentelemetry.io/schemas/1.21.0" - } - ] - } \ No newline at end of file diff --git a/Telemetry/Docs/opentelemetry-profiles-roadmap.md b/Telemetry/Docs/opentelemetry-profiles-roadmap.md deleted file mode 100644 index 9af802767c..0000000000 --- a/Telemetry/Docs/opentelemetry-profiles-roadmap.md +++ /dev/null @@ -1,42 +0,0 @@ -# OpenTelemetry Profiles: Remaining Roadmap - -All core phases (ingestion, storage, query API, frontend UI, alerting, docs) are implemented. This document tracks remaining future work items. - ---- - -## Performance Optimization - -- **Materialized Views**: Pre-aggregate top functions per service per hour for faster queries -- **Server-Side Sampling**: Downsampling for high-volume services to control storage costs -- **Query Caching**: Cache aggregated flamegraph results to reduce ClickHouse load - -## Symbolization Pipeline - -Symbolization is NOT yet standardized in the OTel Profiles spec. The eBPF agent handles on-target symbolization for Go, and many runtimes provide symbol info at collection time. A dedicated symbolization pipeline (symbol uploads, deferred re-symbolization, object storage) can be added once the spec stabilizes. - -## Conformance Validation - -Integrate OTel `profcheck` tool into CI once core profiling features stabilize. - ---- - -## Key Risks & Mitigations - -| Risk | Impact | Mitigation | -|------|--------|------------| -| OTLP Profiles is still Alpha — proto schema may change | Breaking changes to ingestion | Pin to specific OTLP proto version (v1.10.0+), add version detection | -| `v1development` package path will change to `v1` at GA | Proto import path migration | Abstract proto version behind internal types; plan migration script for when GA lands | -| High storage volume from continuous profiling | ClickHouse disk/cost growth | Server-side sampling, aggressive TTL defaults (15 days), ZSTD(3) compression | -| Flamegraph rendering performance with large profiles | Slow UI | Limit to top 10K stacktraces, lazy-load deep frames, pre-aggregate via materialized views | -| Symbolization is not standardized | Unsymbolized frames in flamegraphs | Store build IDs for deferred symbolization; accept eBPF agent's on-target symbolization as baseline | -| Semantic conventions are minimal (only `profile.frame.type`) | Schema may need changes as conventions mature | Keep attribute storage flexible (JSON columns); avoid hardcoding specific attribute names | - ---- - -## References - -- [OTel Profiles Alpha Blog Post](https://opentelemetry.io/blog/2026/profiles-alpha/) -- [OTLP Profiles Proto](https://github.com/open-telemetry/opentelemetry-proto/blob/main/opentelemetry/proto/profiles/v1development/profiles.proto) -- [OTel eBPF Profiling Agent](https://github.com/open-telemetry/opentelemetry-ebpf-profiler) -- [pprof Format](https://github.com/google/pprof) -- [OTel Semantic Conventions for Profiles](https://opentelemetry.io/docs/specs/semconv/general/profiles/) diff --git a/Telemetry/Docs/traceData.example.json b/Telemetry/Docs/traceData.example.json deleted file mode 100644 index 0e4ee31fde..0000000000 --- a/Telemetry/Docs/traceData.example.json +++ /dev/null @@ -1,310 +0,0 @@ -{ - "resourceSpans": [ - { - "resource": { - "attributes": [ - { - "key": "host.name", - "value": { - "stringValue": "c16e92aabd73" - } - }, - { - "key": "process.command_args", - "value": { - "arrayValue": { - "values": [ - { - "stringValue": "/app/main" - } - ] - } - } - }, - { - "key": "process.executable.name", - "value": { - "stringValue": "main" - } - }, - { - "key": "process.executable.path", - "value": { - "stringValue": "/app/main" - } - }, - { - "key": "process.owner", - "value": { - "stringValue": "root" - } - }, - { - "key": "process.pid", - "value": { - "intValue": "1" - } - }, - { - "key": "process.runtime.description", - "value": { - "stringValue": "go version go1.21.2 linux/arm64" - } - }, - { - "key": "process.runtime.name", - "value": { - "stringValue": "go" - } - }, - { - "key": "process.runtime.version", - "value": { - "stringValue": "go1.21.2" - } - }, - { - "key": "service.name", - "value": { - "stringValue": "demo-client" - } - }, - { - "key": "telemetry.sdk.language", - "value": { - "stringValue": "go" - } - }, - { - "key": "telemetry.sdk.name", - "value": { - "stringValue": "opentelemetry" - } - }, - { - "key": "telemetry.sdk.version", - "value": { - "stringValue": "1.19.0" - } - } - ] - }, - "scopeSpans": [ - { - "scope": { - "name": "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp", - "version": "0.44.0" - }, - "spans": [ - { - "traceId": "xALujWnjuqLhWlwvlHRU9A==", - "spanId": "r+N4WZXXfP4=", - "parentSpanId": "6fMLbQYm3c0=", - "name": "HTTP GET", - "kind": "SPAN_KIND_CLIENT", - "startTimeUnixNano": "1697797651330953503", - "endTimeUnixNano": "1697797651335485545", - "attributes": [ - { - "key": "http.method", - "value": { - "stringValue": "GET" - } - }, - { - "key": "http.flavor", - "value": { - "stringValue": "1.1" - } - }, - { - "key": "http.url", - "value": { - "stringValue": "http://demo-server:7080/hello" - } - }, - { - "key": "net.peer.name", - "value": { - "stringValue": "demo-server" - } - }, - { - "key": "net.peer.port", - "value": { - "intValue": "7080" - } - }, - { - "key": "http.status_code", - "value": { - "intValue": "200" - } - }, - { - "key": "http.response_content_length", - "value": { - "intValue": "11" - } - } - ], - "status": { - } - }, - { - "traceId": "+5d347OFkoNrqTJcdQ0/pQ==", - "spanId": "aYG/Gp8vKeQ=", - "parentSpanId": "Pgt2JbxFK7g=", - "name": "HTTP GET", - "kind": "SPAN_KIND_CLIENT", - "startTimeUnixNano": "1697797652336932795", - "endTimeUnixNano": "1697797653208134504", - "attributes": [ - { - "key": "http.method", - "value": { - "stringValue": "GET" - } - }, - { - "key": "http.flavor", - "value": { - "stringValue": "1.1" - } - }, - { - "key": "http.url", - "value": { - "stringValue": "http://demo-server:7080/hello" - } - }, - { - "key": "net.peer.name", - "value": { - "stringValue": "demo-server" - } - }, - { - "key": "net.peer.port", - "value": { - "intValue": "7080" - } - }, - { - "key": "http.status_code", - "value": { - "intValue": "200" - } - }, - { - "key": "http.response_content_length", - "value": { - "intValue": "11" - } - } - ], - "status": { - } - }, - { - "traceId": "W+rycekdacOYa6z/AZQAqQ==", - "spanId": "rqsqCMzBOeA=", - "parentSpanId": "XB3qqSVeF4w=", - "name": "HTTP GET", - "kind": "SPAN_KIND_CLIENT", - "startTimeUnixNano": "1697797654211901088", - "endTimeUnixNano": "1697797654913467921", - "attributes": [ - { - "key": "http.method", - "value": { - "stringValue": "GET" - } - }, - { - "key": "http.flavor", - "value": { - "stringValue": "1.1" - } - }, - { - "key": "http.url", - "value": { - "stringValue": "http://demo-server:7080/hello" - } - }, - { - "key": "net.peer.name", - "value": { - "stringValue": "demo-server" - } - }, - { - "key": "net.peer.port", - "value": { - "intValue": "7080" - } - }, - { - "key": "http.status_code", - "value": { - "intValue": "200" - } - }, - { - "key": "http.response_content_length", - "value": { - "intValue": "11" - } - } - ], - "status": { - } - } - ] - }, - { - "scope": { - "name": "demo-client-tracer" - }, - "spans": [ - { - "traceId": "xALujWnjuqLhWlwvlHRU9A==", - "spanId": "6fMLbQYm3c0=", - "parentSpanId": "", - "name": "ExecuteRequest", - "kind": "SPAN_KIND_INTERNAL", - "startTimeUnixNano": "1697797651330917795", - "endTimeUnixNano": "1697797651335519253", - "status": { - } - }, - { - "traceId": "+5d347OFkoNrqTJcdQ0/pQ==", - "spanId": "Pgt2JbxFK7g=", - "parentSpanId": "", - "name": "ExecuteRequest", - "kind": "SPAN_KIND_INTERNAL", - "startTimeUnixNano": "1697797652336904795", - "endTimeUnixNano": "1697797653208214212", - "status": { - } - }, - { - "traceId": "W+rycekdacOYa6z/AZQAqQ==", - "spanId": "XB3qqSVeF4w=", - "parentSpanId": "", - "name": "ExecuteRequest", - "kind": "SPAN_KIND_INTERNAL", - "startTimeUnixNano": "1697797654211873755", - "endTimeUnixNano": "1697797654913552214", - "status": { - } - } - ] - } - ], - "schemaUrl": "https://opentelemetry.io/schemas/1.21.0" - } - ] - } \ No newline at end of file diff --git a/Telemetry/Index.ts b/Telemetry/Index.ts deleted file mode 100644 index 43f2231440..0000000000 --- a/Telemetry/Index.ts +++ /dev/null @@ -1,133 +0,0 @@ -import OTelIngestAPI from "./API/OTelIngest"; -import MetricsAPI from "./API/Metrics"; -import SyslogAPI from "./API/Syslog"; -import FluentAPI from "./API/Fluent"; -import PyroscopeAPI from "./API/Pyroscope"; -// ProbeIngest routes -import ProbeIngestRegisterAPI from "./API/ProbeIngest/Register"; -import ProbeIngestMonitorAPI from "./API/ProbeIngest/Monitor"; -import ProbeIngestAPI from "./API/ProbeIngest/Probe"; -import IncomingEmailAPI from "./API/ProbeIngest/IncomingEmail"; -// ServerMonitorIngest routes -import ServerMonitorAPI from "./API/ServerMonitorIngest/ServerMonitor"; -// IncomingRequestIngest routes -import IncomingRequestAPI from "./API/IncomingRequestIngest/IncomingRequest"; -import { PromiseVoidFunction } from "Common/Types/FunctionTypes"; -import { ClickhouseAppInstance } from "Common/Server/Infrastructure/ClickhouseDatabase"; -import PostgresAppInstance from "Common/Server/Infrastructure/PostgresDatabase"; -import Redis from "Common/Server/Infrastructure/Redis"; -import InfrastructureStatus from "Common/Server/Infrastructure/Status"; -import Express, { ExpressApplication } from "Common/Server/Utils/Express"; -import logger from "Common/Server/Utils/Logger"; -import Realtime from "Common/Server/Utils/Realtime"; -import App from "Common/Server/Utils/StartServer"; -import Telemetry from "Common/Server/Utils/Telemetry"; -import Profiling from "Common/Server/Utils/Profiling"; -import "./Jobs/TelemetryIngest/ProcessTelemetry"; -import { TELEMETRY_CONCURRENCY } from "./Config"; -import type { StatusAPIOptions } from "Common/Server/API/StatusAPI"; -import { startGrpcServer } from "./GrpcServer"; -import "ejs"; - -const app: ExpressApplication = Express.getExpressApp(); - -const APP_NAME: string = "telemetry"; -const TELEMETRY_PREFIXES: Array = [`/${APP_NAME}`, "/"]; - -// Existing telemetry routes -app.use(TELEMETRY_PREFIXES, OTelIngestAPI); -app.use(TELEMETRY_PREFIXES, MetricsAPI); -app.use(TELEMETRY_PREFIXES, SyslogAPI); -app.use(TELEMETRY_PREFIXES, FluentAPI); -app.use(TELEMETRY_PREFIXES, PyroscopeAPI); - -/* - * ProbeIngest routes under ["/probe-ingest", "/ingestor", "/"] - * "/ingestor" is used for backward compatibility because probes are already deployed with this path in client environments. - */ -const PROBE_INGEST_PREFIXES: Array = [ - "/probe-ingest", - "/ingestor", - "/", -]; -app.use(PROBE_INGEST_PREFIXES, ProbeIngestRegisterAPI); -app.use(PROBE_INGEST_PREFIXES, ProbeIngestMonitorAPI); -app.use(PROBE_INGEST_PREFIXES, ProbeIngestAPI); -app.use(["/probe-ingest", "/"], IncomingEmailAPI); - -// ServerMonitorIngest routes under ["/server-monitor-ingest", "/"] -const SERVER_MONITOR_PREFIXES: Array = ["/server-monitor-ingest", "/"]; -app.use(SERVER_MONITOR_PREFIXES, ServerMonitorAPI); - -// IncomingRequestIngest routes under ["/incoming-request-ingest", "/"] -const INCOMING_REQUEST_PREFIXES: Array = [ - "/incoming-request-ingest", - "/", -]; -app.use(INCOMING_REQUEST_PREFIXES, IncomingRequestAPI); - -const init: PromiseVoidFunction = async (): Promise => { - try { - const statusCheck: PromiseVoidFunction = async (): Promise => { - return await InfrastructureStatus.checkStatusWithRetry({ - checkClickhouseStatus: true, - checkPostgresStatus: true, - checkRedisStatus: true, - retryCount: 3, - }); - }; - - // Initialize telemetry - Telemetry.init({ - serviceName: APP_NAME, - }); - - // Initialize profiling (opt-in via ENABLE_PROFILING env var) - Profiling.init({ - serviceName: APP_NAME, - }); - - logger.info( - `Telemetry Service - Queue concurrency: ${TELEMETRY_CONCURRENCY}`, - ); - - // init the app - const statusOptions: StatusAPIOptions = { - liveCheck: statusCheck, - readyCheck: statusCheck, - }; - - await App.init({ - appName: APP_NAME, - statusOptions: statusOptions, - }); - - // connect to the database. - await PostgresAppInstance.connect(); - - // connect redis - await Redis.connect(); - - await ClickhouseAppInstance.connect( - ClickhouseAppInstance.getDatasourceOptions(), - ); - - await Realtime.init(); - - // Start gRPC OTLP server on port 4317 - startGrpcServer(); - - // add default routes - await App.addDefaultRoutes(); - } catch (err) { - logger.error("App Init Failed:"); - logger.error(err); - throw err; - } -}; - -init().catch((err: Error) => { - logger.error(err); - logger.error("Exiting node process"); - process.exit(1); -}); diff --git a/Telemetry/Tests/Scripts/test-fluentd-ingest.sh b/Telemetry/Tests/Scripts/test-fluentd-ingest.sh deleted file mode 100755 index a5cf2c22d6..0000000000 --- a/Telemetry/Tests/Scripts/test-fluentd-ingest.sh +++ /dev/null @@ -1,191 +0,0 @@ -#!/bin/bash -# Integration test script for Fluent Bit / Fluentd log ingestion -# -# Tests the /fluentd/v1/logs endpoint with realistic payloads -# to verify that structured attributes are preserved. -# -# Usage: -# ./test-fluentd-ingest.sh [SERVICE_NAME] -# -# Example: -# ./test-fluentd-ingest.sh http://localhost:3400 your-token-here my-k8s-service - -set -euo pipefail - -URL="${1:?Usage: $0 [SERVICE_NAME]}" -TOKEN="${2:?Usage: $0 [SERVICE_NAME]}" -SERVICE_NAME="${3:-fluent-test-service}" - -ENDPOINT="${URL}/fluentd/v1/logs" - -echo "=== Fluent Bit/Fluentd Log Ingestion Integration Tests ===" -echo "Endpoint: ${ENDPOINT}" -echo "Service: ${SERVICE_NAME}" -echo "" - -# Test 1: Single structured Kubernetes log entry -echo "--- Test 1: Single Kubernetes log entry with metadata ---" -HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \ - -X POST "${ENDPOINT}" \ - -H "Content-Type: application/json" \ - -H "x-oneuptime-token: ${TOKEN}" \ - -H "x-oneuptime-service-name: ${SERVICE_NAME}" \ - -d '{ - "message": "Connection to database established successfully", - "level": "info", - "stream": "stdout", - "time": "2024-01-15T10:30:00.123456789Z", - "kubernetes": { - "namespace_name": "production", - "pod_name": "api-server-7b9f4c8d5-xk2m9", - "container_name": "api-server", - "pod_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", - "labels": { - "app": "api-server", - "version": "v2.1.0", - "team": "platform" - }, - "host": "node-pool-1-abc" - } - }') -echo "HTTP Status: ${HTTP_CODE}" -[ "${HTTP_CODE}" = "200" ] && echo "PASS" || echo "FAIL (expected 200)" -echo "" - -# Test 2: Batch of log entries (array format from Fluentd) -echo "--- Test 2: Batch of structured log entries ---" -HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \ - -X POST "${ENDPOINT}" \ - -H "Content-Type: application/json" \ - -H "x-oneuptime-token: ${TOKEN}" \ - -H "x-oneuptime-service-name: ${SERVICE_NAME}" \ - -d '[ - { - "message": "Request received: GET /api/health", - "level": "debug", - "stream": "stdout", - "kubernetes": { - "namespace_name": "production", - "pod_name": "web-abc123", - "container_name": "nginx" - } - }, - { - "message": "Upstream timeout after 30s", - "level": "error", - "stream": "stderr", - "kubernetes": { - "namespace_name": "production", - "pod_name": "web-abc123", - "container_name": "nginx" - } - }, - { - "message": "Retrying connection to upstream", - "level": "warning", - "stream": "stderr", - "kubernetes": { - "namespace_name": "production", - "pod_name": "web-abc123", - "container_name": "nginx" - } - } - ]') -echo "HTTP Status: ${HTTP_CODE}" -[ "${HTTP_CODE}" = "200" ] && echo "PASS" || echo "FAIL (expected 200)" -echo "" - -# Test 3: Fluentd json-wrapped format -echo "--- Test 3: Fluentd json-wrapped format ---" -HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \ - -X POST "${ENDPOINT}" \ - -H "Content-Type: application/json" \ - -H "x-oneuptime-token: ${TOKEN}" \ - -H "x-oneuptime-service-name: ${SERVICE_NAME}" \ - -d '{ - "json": { - "log": "2024-01-15 ERROR: Failed to connect to redis:6379", - "stream": "stderr", - "level": "error", - "kubernetes": { - "namespace_name": "default", - "pod_name": "cache-worker-xyz", - "container_name": "worker", - "labels": { - "app.kubernetes.io/name": "cache-worker", - "app.kubernetes.io/component": "background" - } - } - } - }') -echo "HTTP Status: ${HTTP_CODE}" -[ "${HTTP_CODE}" = "200" ] && echo "PASS" || echo "FAIL (expected 200)" -echo "" - -# Test 4: Log with trace context -echo "--- Test 4: Log with trace/span IDs ---" -HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \ - -X POST "${ENDPOINT}" \ - -H "Content-Type: application/json" \ - -H "x-oneuptime-token: ${TOKEN}" \ - -H "x-oneuptime-service-name: ${SERVICE_NAME}" \ - -d '{ - "message": "Processing order #12345", - "level": "info", - "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736", - "span_id": "00f067aa0ba902b7", - "kubernetes": { - "namespace_name": "production", - "pod_name": "order-service-abc" - }, - "order_id": "12345", - "customer_id": "cust-789" - }') -echo "HTTP Status: ${HTTP_CODE}" -[ "${HTTP_CODE}" = "200" ] && echo "PASS" || echo "FAIL (expected 200)" -echo "" - -# Test 5: Plain string (backward compatibility) -echo "--- Test 5: Plain string body (backward compatibility) ---" -HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \ - -X POST "${ENDPOINT}" \ - -H "Content-Type: application/json" \ - -H "x-oneuptime-token: ${TOKEN}" \ - -H "x-oneuptime-service-name: ${SERVICE_NAME}" \ - -d '"A simple plain-text log message"') -echo "HTTP Status: ${HTTP_CODE}" -[ "${HTTP_CODE}" = "200" ] && echo "PASS" || echo "FAIL (expected 200)" -echo "" - -# Test 6: Docker/container log format (log field instead of message) -echo "--- Test 6: Docker container log format (using 'log' field) ---" -HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \ - -X POST "${ENDPOINT}" \ - -H "Content-Type: application/json" \ - -H "x-oneuptime-token: ${TOKEN}" \ - -H "x-oneuptime-service-name: ${SERVICE_NAME}" \ - -d '{ - "log": "{\"ts\":\"2024-01-15T10:30:00Z\",\"msg\":\"Server started on port 8080\"}\n", - "stream": "stdout", - "time": "2024-01-15T10:30:00.000000001Z", - "kubernetes": { - "namespace_name": "staging", - "pod_name": "api-v2-deployment-85d97fb8c7-4xnpq", - "container_name": "api", - "container_image": "registry.example.com/api:v2.0.1" - } - }') -echo "HTTP Status: ${HTTP_CODE}" -[ "${HTTP_CODE}" = "200" ] && echo "PASS" || echo "FAIL (expected 200)" -echo "" - -echo "=== All integration tests completed ===" -echo "" -echo "To verify attributes were stored, query the logs in OneUptime UI" -echo "and check for attributes like:" -echo " - fluentd.kubernetes.namespace_name" -echo " - fluentd.kubernetes.pod_name" -echo " - fluentd.kubernetes.container_name" -echo " - fluentd.kubernetes.labels.*" -echo " - fluentd.stream" -echo " - fluentd.time" diff --git a/Telemetry/Tests/Services/FluentLogsIngestService.test.ts b/Telemetry/Tests/Services/FluentLogsIngestService.test.ts deleted file mode 100644 index a764d527ba..0000000000 --- a/Telemetry/Tests/Services/FluentLogsIngestService.test.ts +++ /dev/null @@ -1,554 +0,0 @@ -import FluentLogsIngestService from "../../Services/FluentLogsIngestService"; -import LogSeverity from "Common/Types/Log/LogSeverity"; -import { JSONObject } from "Common/Types/JSON"; - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -const service: any = FluentLogsIngestService as any; - -describe("FluentLogsIngestService", () => { - describe("normalizeLogEntries", () => { - test("preserves structured JSON object as-is", () => { - const payload: JSONObject = { - message: "Connection refused", - level: "error", - stream: "stderr", - kubernetes: { - namespace_name: "default", - pod_name: "my-app-xyz", - }, - }; - - const entries: Array = service["normalizeLogEntries"]( - payload, - ) as Array; - - expect(entries).toHaveLength(1); - expect(entries[0]).toEqual(payload); - }); - - test("preserves array of structured objects", () => { - const payload: Array = [ - { message: "log 1", stream: "stdout" }, - { message: "log 2", stream: "stderr" }, - ]; - - const entries: Array = service["normalizeLogEntries"]( - payload, - ) as Array; - - expect(entries).toHaveLength(2); - expect(entries[0]!["message"]).toBe("log 1"); - expect(entries[0]!["stream"]).toBe("stdout"); - expect(entries[1]!["message"]).toBe("log 2"); - expect(entries[1]!["stream"]).toBe("stderr"); - }); - - test("unwraps 'json' container field", () => { - const payload: JSONObject = { - json: { - message: "inner log", - kubernetes: { pod_name: "test-pod" }, - }, - }; - - const entries: Array = service["normalizeLogEntries"]( - payload, - ) as Array; - - expect(entries).toHaveLength(1); - expect(entries[0]!["message"]).toBe("inner log"); - expect((entries[0]!["kubernetes"] as JSONObject)["pod_name"]).toBe( - "test-pod", - ); - }); - - test("unwraps 'entries' container field", () => { - const payload: JSONObject = { - entries: [ - { message: "entry 1", host: "node-1" }, - { message: "entry 2", host: "node-2" }, - ], - }; - - const entries: Array = service["normalizeLogEntries"]( - payload, - ) as Array; - - expect(entries).toHaveLength(2); - expect(entries[0]!["host"]).toBe("node-1"); - expect(entries[1]!["host"]).toBe("node-2"); - }); - - test("wraps plain string in JSONObject with message field", () => { - const entries: Array = service["normalizeLogEntries"]( - "simple log line", - ) as Array; - - expect(entries).toHaveLength(1); - expect(entries[0]!["message"]).toBe("simple log line"); - }); - - test("splits multiline string into separate entries", () => { - const entries: Array = service["normalizeLogEntries"]( - "line one\nline two\nline three", - ) as Array; - - expect(entries).toHaveLength(3); - expect(entries[0]!["message"]).toBe("line one"); - expect(entries[1]!["message"]).toBe("line two"); - expect(entries[2]!["message"]).toBe("line three"); - }); - - test("handles null and undefined", () => { - expect(service["normalizeLogEntries"](null)).toEqual([]); - expect(service["normalizeLogEntries"](undefined)).toEqual([]); - }); - - test("handles empty string", () => { - expect(service["normalizeLogEntries"]("")).toEqual([]); - expect(service["normalizeLogEntries"](" ")).toEqual([]); - }); - }); - - describe("extractBodyFromEntry", () => { - test("extracts from 'message' field", () => { - const entry: JSONObject = { - message: "the log body", - stream: "stdout", - }; - - const body: string = service["extractBodyFromEntry"](entry) as string; - expect(body).toBe("the log body"); - }); - - test("extracts from 'log' field", () => { - const entry: JSONObject = { - log: "container output line", - stream: "stderr", - }; - - const body: string = service["extractBodyFromEntry"](entry) as string; - expect(body).toBe("container output line"); - }); - - test("extracts from 'msg' field", () => { - const entry: JSONObject = { msg: "short msg field" }; - - const body: string = service["extractBodyFromEntry"](entry) as string; - expect(body).toBe("short msg field"); - }); - - test("prefers 'message' over 'log'", () => { - const entry: JSONObject = { - message: "from message", - log: "from log", - }; - - const body: string = service["extractBodyFromEntry"](entry) as string; - expect(body).toBe("from message"); - }); - - test("stringifies entire entry when no body field found", () => { - const entry: JSONObject = { - stream: "stdout", - kubernetes: { pod_name: "test" }, - }; - - const body: string = service["extractBodyFromEntry"](entry) as string; - const parsed: JSONObject = JSON.parse(body) as JSONObject; - expect(parsed["stream"]).toBe("stdout"); - }); - - test("stringifies non-string body field values", () => { - const entry: JSONObject = { - message: { nested: "object" }, - }; - - const body: string = service["extractBodyFromEntry"](entry) as string; - expect(body).toBe('{"nested":"object"}'); - }); - }); - - describe("extractSeverityFromEntry", () => { - test("maps 'error' level", () => { - const result: { number: number; text: LogSeverity } = service[ - "extractSeverityFromEntry" - ]({ level: "error" }) as { number: number; text: LogSeverity }; - - expect(result.number).toBe(17); - expect(result.text).toBe(LogSeverity.Error); - }); - - test("maps 'info' level", () => { - const result: { number: number; text: LogSeverity } = service[ - "extractSeverityFromEntry" - ]({ level: "info" }) as { number: number; text: LogSeverity }; - - expect(result.number).toBe(9); - expect(result.text).toBe(LogSeverity.Information); - }); - - test("maps 'warn' level", () => { - const result: { number: number; text: LogSeverity } = service[ - "extractSeverityFromEntry" - ]({ level: "warn" }) as { number: number; text: LogSeverity }; - - expect(result.number).toBe(13); - expect(result.text).toBe(LogSeverity.Warning); - }); - - test("maps 'debug' level", () => { - const result: { number: number; text: LogSeverity } = service[ - "extractSeverityFromEntry" - ]({ level: "debug" }) as { number: number; text: LogSeverity }; - - expect(result.number).toBe(5); - expect(result.text).toBe(LogSeverity.Debug); - }); - - test("maps 'fatal' level", () => { - const result: { number: number; text: LogSeverity } = service[ - "extractSeverityFromEntry" - ]({ level: "fatal" }) as { number: number; text: LogSeverity }; - - expect(result.number).toBe(23); - expect(result.text).toBe(LogSeverity.Fatal); - }); - - test("reads from 'severity' field", () => { - const result: { number: number; text: LogSeverity } = service[ - "extractSeverityFromEntry" - ]({ severity: "warning" }) as { number: number; text: LogSeverity }; - - expect(result.number).toBe(13); - expect(result.text).toBe(LogSeverity.Warning); - }); - - test("is case-insensitive", () => { - const result: { number: number; text: LogSeverity } = service[ - "extractSeverityFromEntry" - ]({ level: "ERROR" }) as { number: number; text: LogSeverity }; - - expect(result.number).toBe(17); - expect(result.text).toBe(LogSeverity.Error); - }); - - test("returns Unspecified for missing severity", () => { - const result: { number: number; text: LogSeverity } = service[ - "extractSeverityFromEntry" - ]({ message: "no severity" }) as { number: number; text: LogSeverity }; - - expect(result.number).toBe(0); - expect(result.text).toBe(LogSeverity.Unspecified); - }); - - test("returns Unspecified for unknown severity value", () => { - const result: { number: number; text: LogSeverity } = service[ - "extractSeverityFromEntry" - ]({ level: "verbose" }) as { number: number; text: LogSeverity }; - - expect(result.number).toBe(0); - expect(result.text).toBe(LogSeverity.Unspecified); - }); - }); - - describe("extractStringField", () => { - test("extracts string value from first matching field", () => { - const result: string | undefined = service["extractStringField"]( - { trace_id: "abc123" }, - ["trace_id", "traceId"], - ) as string | undefined; - - expect(result).toBe("abc123"); - }); - - test("tries fields in order", () => { - const result: string | undefined = service["extractStringField"]( - { traceId: "from-camel" }, - ["trace_id", "traceId"], - ) as string | undefined; - - expect(result).toBe("from-camel"); - }); - - test("converts number to string", () => { - const result: string | undefined = service["extractStringField"]( - { priority: 42 }, - ["priority"], - ) as string | undefined; - - expect(result).toBe("42"); - }); - - test("returns undefined when no fields match", () => { - const result: string | undefined = service["extractStringField"]( - { other: "value" }, - ["trace_id", "traceId"], - ) as string | undefined; - - expect(result).toBeUndefined(); - }); - - test("skips empty strings", () => { - const result: string | undefined = service["extractStringField"]( - { trace_id: "", traceId: "fallback" }, - ["trace_id", "traceId"], - ) as string | undefined; - - expect(result).toBe("fallback"); - }); - }); - - describe("buildFluentAttributes", () => { - test("extracts top-level scalar fields with fluentd. prefix", () => { - const entry: JSONObject = { - message: "body text", - stream: "stdout", - tag: "kube.var.log", - }; - - const attrs: Record = service["buildFluentAttributes"]( - entry, - ) as Record; - - // 'message' is excluded (it's a body field) - expect(attrs["fluentd.message"]).toBeUndefined(); - // other fields are included - expect(attrs["fluentd.stream"]).toBe("stdout"); - expect(attrs["fluentd.tag"]).toBe("kube.var.log"); - }); - - test("flattens nested objects with dot notation", () => { - const entry: JSONObject = { - message: "log", - kubernetes: { - namespace_name: "default", - pod_name: "my-app-xyz", - container_name: "app", - labels: { - app: "my-app", - version: "v1", - }, - }, - }; - - const attrs: Record = service["buildFluentAttributes"]( - entry, - ) as Record; - - expect(attrs["fluentd.kubernetes.namespace_name"]).toBe("default"); - expect(attrs["fluentd.kubernetes.pod_name"]).toBe("my-app-xyz"); - expect(attrs["fluentd.kubernetes.container_name"]).toBe("app"); - expect(attrs["fluentd.kubernetes.labels.app"]).toBe("my-app"); - expect(attrs["fluentd.kubernetes.labels.version"]).toBe("v1"); - }); - - test("serializes arrays as JSON strings", () => { - const entry: JSONObject = { - message: "log", - tags: ["web", "production"], - }; - - const attrs: Record = service["buildFluentAttributes"]( - entry, - ) as Record; - - expect(attrs["fluentd.tags"]).toBe('["web","production"]'); - }); - - test("handles boolean and numeric values", () => { - const entry: JSONObject = { - message: "log", - count: 42, - success: true, - }; - - const attrs: Record = service["buildFluentAttributes"]( - entry, - ) as Record; - - expect(attrs["fluentd.count"]).toBe(42); - expect(attrs["fluentd.success"]).toBe(true); - }); - - test("excludes all body, severity, trace, and span fields", () => { - const entry: JSONObject = { - message: "body", - log: "also body", - level: "info", - severity: "info", - trace_id: "abc", - traceId: "abc", - span_id: "def", - spanId: "def", - custom_field: "should be kept", - }; - - const attrs: Record = service["buildFluentAttributes"]( - entry, - ) as Record; - - expect(attrs["fluentd.message"]).toBeUndefined(); - expect(attrs["fluentd.log"]).toBeUndefined(); - expect(attrs["fluentd.level"]).toBeUndefined(); - expect(attrs["fluentd.severity"]).toBeUndefined(); - expect(attrs["fluentd.trace_id"]).toBeUndefined(); - expect(attrs["fluentd.traceId"]).toBeUndefined(); - expect(attrs["fluentd.span_id"]).toBeUndefined(); - expect(attrs["fluentd.spanId"]).toBeUndefined(); - expect(attrs["fluentd.custom_field"]).toBe("should be kept"); - }); - - test("skips null and undefined values", () => { - const entry: JSONObject = { - message: "log", - null_field: null, - valid_field: "kept", - }; - - const attrs: Record = service["buildFluentAttributes"]( - entry, - ) as Record; - - expect(attrs["fluentd.null_field"]).toBeUndefined(); - expect(attrs["fluentd.valid_field"]).toBe("kept"); - }); - }); - - describe("full Kubernetes Fluent Bit payload", () => { - test("correctly processes a typical Kubernetes log entry", () => { - const k8sPayload: JSONObject = { - log: "2024-01-15T10:30:00.123Z ERROR Connection refused to database\n", - stream: "stderr", - time: "2024-01-15T10:30:00.123456789Z", - level: "error", - kubernetes: { - pod_name: "api-server-7b9f4c8d5-xk2m9", - namespace_name: "production", - container_name: "api-server", - pod_id: "a1b2c3d4-e5f6-7890-abcd-ef1234567890", - labels: { - app: "api-server", - "app.kubernetes.io/version": "2.1.0", - team: "platform", - }, - host: "node-pool-1-abc", - }, - }; - - // Test normalization preserves the object - const entries: Array = service["normalizeLogEntries"]( - k8sPayload, - ) as Array; - expect(entries).toHaveLength(1); - expect(entries[0]).toEqual(k8sPayload); - - // Test body extraction - const body: string = service["extractBodyFromEntry"]( - k8sPayload, - ) as string; - expect(body).toBe( - "2024-01-15T10:30:00.123Z ERROR Connection refused to database\n", - ); - - // Test severity extraction - const severity: { number: number; text: LogSeverity } = service[ - "extractSeverityFromEntry" - ](k8sPayload) as { number: number; text: LogSeverity }; - expect(severity.text).toBe(LogSeverity.Error); - expect(severity.number).toBe(17); - - // Test attributes extraction - const attrs: Record = service["buildFluentAttributes"]( - k8sPayload, - ) as Record; - - // Body and severity fields excluded - expect(attrs["fluentd.log"]).toBeUndefined(); - expect(attrs["fluentd.level"]).toBeUndefined(); - - // Other fields preserved - expect(attrs["fluentd.stream"]).toBe("stderr"); - expect(attrs["fluentd.time"]).toBe("2024-01-15T10:30:00.123456789Z"); - - // Kubernetes metadata flattened - expect(attrs["fluentd.kubernetes.pod_name"]).toBe( - "api-server-7b9f4c8d5-xk2m9", - ); - expect(attrs["fluentd.kubernetes.namespace_name"]).toBe("production"); - expect(attrs["fluentd.kubernetes.container_name"]).toBe("api-server"); - expect(attrs["fluentd.kubernetes.pod_id"]).toBe( - "a1b2c3d4-e5f6-7890-abcd-ef1234567890", - ); - expect(attrs["fluentd.kubernetes.labels.app"]).toBe("api-server"); - expect(attrs["fluentd.kubernetes.labels.app.kubernetes.io/version"]).toBe( - "2.1.0", - ); - expect(attrs["fluentd.kubernetes.labels.team"]).toBe("platform"); - expect(attrs["fluentd.kubernetes.host"]).toBe("node-pool-1-abc"); - }); - - test("handles Fluentd json-wrapped Kubernetes payload", () => { - const payload: JSONObject = { - json: { - log: "Application started successfully", - stream: "stdout", - level: "info", - kubernetes: { - namespace_name: "staging", - pod_name: "web-abc123", - }, - }, - }; - - const entries: Array = service["normalizeLogEntries"]( - payload, - ) as Array; - expect(entries).toHaveLength(1); - expect(entries[0]!["log"]).toBe("Application started successfully"); - expect((entries[0]!["kubernetes"] as JSONObject)["namespace_name"]).toBe( - "staging", - ); - }); - - test("handles batch of Fluentd log entries", () => { - const payload: Array = [ - { - message: "Request received", - level: "info", - kubernetes: { pod_name: "web-1" }, - }, - { - message: "Processing failed", - level: "error", - kubernetes: { pod_name: "web-1" }, - }, - { - message: "Retry succeeded", - level: "warn", - kubernetes: { pod_name: "web-1" }, - }, - ]; - - const entries: Array = service["normalizeLogEntries"]( - payload, - ) as Array; - - expect(entries).toHaveLength(3); - - const sev0: { text: LogSeverity } = service["extractSeverityFromEntry"]( - entries[0]!, - ) as { text: LogSeverity }; - const sev1: { text: LogSeverity } = service["extractSeverityFromEntry"]( - entries[1]!, - ) as { text: LogSeverity }; - const sev2: { text: LogSeverity } = service["extractSeverityFromEntry"]( - entries[2]!, - ) as { text: LogSeverity }; - - expect(sev0.text).toBe(LogSeverity.Information); - expect(sev1.text).toBe(LogSeverity.Error); - expect(sev2.text).toBe(LogSeverity.Warning); - }); - }); -}); diff --git a/Telemetry/Tests/Services/OtelProfilesIngestService.test.ts b/Telemetry/Tests/Services/OtelProfilesIngestService.test.ts deleted file mode 100644 index 9968ff3221..0000000000 --- a/Telemetry/Tests/Services/OtelProfilesIngestService.test.ts +++ /dev/null @@ -1,457 +0,0 @@ -import OtelProfilesIngestService from "../../Services/OtelProfilesIngestService"; -import { JSONObject, JSONArray } from "Common/Types/JSON"; - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -const service: any = OtelProfilesIngestService as any; - -describe("OtelProfilesIngestService", () => { - describe("resolveStackFrames", () => { - const baseStringTable: Array = [ - "", // 0 - empty - "main", // 1 - "app.go", // 2 - "runtime.main", // 3 - "runtime/proc.go", // 4 - "handleRequest", // 5 - "server.go", // 6 - "kernel", // 7 - "native", // 8 - "go", // 9 - ]; - - const baseFunctionTable: JSONArray = [ - { name: 1, systemName: 1, filename: 2, startLine: 10 }, // 0: main@app.go - { name: 3, systemName: 3, filename: 4, startLine: 100 }, // 1: runtime.main@runtime/proc.go - { name: 5, systemName: 5, filename: 6, startLine: 50 }, // 2: handleRequest@server.go - ]; - - const baseLocationTable: JSONArray = [ - { - mappingIndex: 0, - address: 4096, - line: [{ functionIndex: 0, line: 15, column: 0 }], - isFolded: false, - typeIndex: 0, - attributeIndices: [], - }, // 0: main@app.go:15 - { - mappingIndex: 0, - address: 8192, - line: [{ functionIndex: 1, line: 120, column: 0 }], - isFolded: false, - typeIndex: 0, - attributeIndices: [], - }, // 1: runtime.main@runtime/proc.go:120 - { - mappingIndex: 0, - address: 12288, - line: [{ functionIndex: 2, line: 55, column: 0 }], - isFolded: false, - typeIndex: 0, - attributeIndices: [], - }, // 2: handleRequest@server.go:55 - ]; - - const baseAttributeTable: JSONArray = [ - { key: "profile.frame.type", value: { stringValue: "go" } }, - ]; - - test("resolves simple stack via stack_table", () => { - const stackTable: JSONArray = [ - { locationIndices: [0, 1] }, // stack 0: main, runtime.main - ]; - - const sample: JSONObject = { stackIndex: 0 }; - - const result: { frames: Array; frameTypes: Array } = - service["resolveStackFrames"]({ - sample, - stackTable, - locationTable: baseLocationTable, - functionTable: baseFunctionTable, - stringTable: baseStringTable, - attributeTable: baseAttributeTable, - }); - - expect(result.frames).toHaveLength(2); - expect(result.frames[0]).toBe("main@app.go:15"); - expect(result.frames[1]).toBe("runtime.main@runtime/proc.go:120"); - expect(result.frameTypes[0]).toBe("go"); - expect(result.frameTypes[1]).toBe("go"); - }); - - test("resolves stack with three frames", () => { - const stackTable: JSONArray = [ - { locationIndices: [2, 0, 1] }, // handleRequest -> main -> runtime.main - ]; - - const sample: JSONObject = { stackIndex: 0 }; - - const result: { frames: Array; frameTypes: Array } = - service["resolveStackFrames"]({ - sample, - stackTable, - locationTable: baseLocationTable, - functionTable: baseFunctionTable, - stringTable: baseStringTable, - attributeTable: baseAttributeTable, - }); - - expect(result.frames).toHaveLength(3); - expect(result.frames[0]).toBe("handleRequest@server.go:55"); - expect(result.frames[1]).toBe("main@app.go:15"); - expect(result.frames[2]).toBe("runtime.main@runtime/proc.go:120"); - }); - - test("handles inline frames (multiple lines per location)", () => { - const locationTableWithInline: JSONArray = [ - { - mappingIndex: 0, - address: 4096, - line: [ - { functionIndex: 0, line: 15, column: 0 }, // main@app.go:15 - { functionIndex: 2, line: 55, column: 0 }, // handleRequest@server.go:55 (inlined) - ], - isFolded: false, - typeIndex: 0, - attributeIndices: [], - }, - ]; - - const stackTable: JSONArray = [{ locationIndices: [0] }]; - - const sample: JSONObject = { stackIndex: 0 }; - - const result: { frames: Array; frameTypes: Array } = - service["resolveStackFrames"]({ - sample, - stackTable, - locationTable: locationTableWithInline, - functionTable: baseFunctionTable, - stringTable: baseStringTable, - attributeTable: baseAttributeTable, - }); - - // Inline frames should expand into separate frames - expect(result.frames).toHaveLength(2); - expect(result.frames[0]).toBe("main@app.go:15"); - expect(result.frames[1]).toBe("handleRequest@server.go:55"); - }); - - test("handles location without line info (uses hex address)", () => { - const locationTableNoLine: JSONArray = [ - { - mappingIndex: 0, - address: 65535, - line: [], - isFolded: false, - typeIndex: 0, - attributeIndices: [], - }, - ]; - - const stackTable: JSONArray = [{ locationIndices: [0] }]; - - const sample: JSONObject = { stackIndex: 0 }; - - const result: { frames: Array; frameTypes: Array } = - service["resolveStackFrames"]({ - sample, - stackTable, - locationTable: locationTableNoLine, - functionTable: baseFunctionTable, - stringTable: baseStringTable, - attributeTable: baseAttributeTable, - }); - - expect(result.frames).toHaveLength(1); - expect(result.frames[0]).toBe("0xffff"); - }); - - test("handles empty stack", () => { - const stackTable: JSONArray = [{ locationIndices: [] }]; - - const sample: JSONObject = { stackIndex: 0 }; - - const result: { frames: Array; frameTypes: Array } = - service["resolveStackFrames"]({ - sample, - stackTable, - locationTable: baseLocationTable, - functionTable: baseFunctionTable, - stringTable: baseStringTable, - attributeTable: baseAttributeTable, - }); - - expect(result.frames).toHaveLength(0); - expect(result.frameTypes).toHaveLength(0); - }); - - test("handles out-of-bounds location index gracefully", () => { - const stackTable: JSONArray = [{ locationIndices: [999] }]; - - const sample: JSONObject = { stackIndex: 0 }; - - const result: { frames: Array; frameTypes: Array } = - service["resolveStackFrames"]({ - sample, - stackTable, - locationTable: baseLocationTable, - functionTable: baseFunctionTable, - stringTable: baseStringTable, - attributeTable: baseAttributeTable, - }); - - expect(result.frames).toHaveLength(1); - expect(result.frames[0]).toBe(""); - expect(result.frameTypes[0]).toBe("unknown"); - }); - - test("falls back to locationsStartIndex/locationsLength when no stackIndex", () => { - const sample: JSONObject = { - locationsStartIndex: 0, - locationsLength: 2, - }; - - const result: { frames: Array; frameTypes: Array } = - service["resolveStackFrames"]({ - sample, - stackTable: [], - locationTable: baseLocationTable, - functionTable: baseFunctionTable, - stringTable: baseStringTable, - attributeTable: baseAttributeTable, - }); - - expect(result.frames).toHaveLength(2); - expect(result.frames[0]).toBe("main@app.go:15"); - expect(result.frames[1]).toBe("runtime.main@runtime/proc.go:120"); - }); - - test("handles function without filename", () => { - const stringTableNoFile: Array = [ - "", // 0 - "anonymous", // 1 - ]; - - const functionTableNoFile: JSONArray = [ - { name: 1, systemName: 1, filename: 0, startLine: 0 }, // anonymous (no file) - ]; - - const locationTableNoFile: JSONArray = [ - { - mappingIndex: 0, - address: 4096, - line: [{ functionIndex: 0, line: 0, column: 0 }], - isFolded: false, - typeIndex: 0, - attributeIndices: [], - }, - ]; - - const stackTable: JSONArray = [{ locationIndices: [0] }]; - const sample: JSONObject = { stackIndex: 0 }; - - const result: { frames: Array; frameTypes: Array } = - service["resolveStackFrames"]({ - sample, - stackTable, - locationTable: locationTableNoFile, - functionTable: functionTableNoFile, - stringTable: stringTableNoFile, - attributeTable: [], - }); - - expect(result.frames).toHaveLength(1); - // Should just be function name without file or line - expect(result.frames[0]).toBe("anonymous"); - }); - }); - - describe("safeParseUnixNano", () => { - test("parses numeric value correctly", () => { - const nanos: number = 1700000000000000000; - const result: { - unixNano: number; - nano: string; - iso: string; - date: Date; - } = service["safeParseUnixNano"](nanos, "test"); - - expect(result.unixNano).toBe(nanos); - expect(result.nano).toBe(nanos.toString()); - expect(result.date).toBeInstanceOf(Date); - }); - - test("parses string value correctly", () => { - const nanos: string = "1700000000000000000"; - const result: { - unixNano: number; - nano: string; - iso: string; - date: Date; - } = service["safeParseUnixNano"](nanos, "test"); - - expect(result.unixNano).toBe(1700000000000000000); - expect(result.date).toBeInstanceOf(Date); - }); - - test("falls back to current time for undefined", () => { - const result: { - unixNano: number; - nano: string; - iso: string; - date: Date; - } = service["safeParseUnixNano"](undefined, "test"); - - expect(result.unixNano).toBeGreaterThan(0); - expect(result.date).toBeInstanceOf(Date); - }); - - test("falls back to current time for NaN string", () => { - const result: { - unixNano: number; - nano: string; - iso: string; - date: Date; - } = service["safeParseUnixNano"]("not-a-number", "test"); - - expect(result.unixNano).toBeGreaterThan(0); - expect(result.date).toBeInstanceOf(Date); - }); - - test("falls back to current time for Infinity", () => { - const result: { - unixNano: number; - nano: string; - iso: string; - date: Date; - } = service["safeParseUnixNano"](Infinity, "test"); - - expect(result.unixNano).toBeGreaterThan(0); - expect(result.date).toBeInstanceOf(Date); - }); - }); - - describe("convertBase64ToHexSafe", () => { - test("returns empty string for undefined", () => { - const result: string = service["convertBase64ToHexSafe"](undefined); - expect(result).toBe(""); - }); - - test("returns empty string for empty string", () => { - const result: string = service["convertBase64ToHexSafe"](""); - expect(result).toBe(""); - }); - - test("converts valid base64 to hex", () => { - // "AQID" is base64 for bytes [1, 2, 3] which is hex "010203" - const result: string = service["convertBase64ToHexSafe"]("AQID"); - expect(result).toBe("010203"); - }); - }); - - describe("buildProfileRow", () => { - test("builds profile row with all fields", () => { - const row: JSONObject = service["buildProfileRow"]({ - projectId: { - toString: () => { - return "proj-123"; - }, - }, - serviceId: { - toString: () => { - return "svc-456"; - }, - }, - profileId: "profile-789", - traceId: "trace-abc", - spanId: "span-def", - startTime: { - unixNano: 1700000000000000000, - nano: "1700000000000000000", - iso: "2023-11-14T22:13:20.000Z", - date: new Date("2023-11-14T22:13:20.000Z"), - }, - endTime: { - unixNano: 1700000001000000000, - nano: "1700000001000000000", - iso: "2023-11-14T22:13:21.000Z", - date: new Date("2023-11-14T22:13:21.000Z"), - }, - durationNano: 1000000000, - profileType: "cpu", - unit: "nanoseconds", - periodType: "cpu", - period: 10000000, - attributes: { "resource.service.name": "my-service" }, - attributeKeys: ["resource.service.name"], - sampleCount: 100, - originalPayloadFormat: "pprofext", - dataRetentionInDays: 15, - }); - - expect(row["projectId"]).toBe("proj-123"); - expect(row["serviceId"]).toBe("svc-456"); - expect(row["profileId"]).toBe("profile-789"); - expect(row["traceId"]).toBe("trace-abc"); - expect(row["spanId"]).toBe("span-def"); - expect(row["profileType"]).toBe("cpu"); - expect(row["unit"]).toBe("nanoseconds"); - expect(row["periodType"]).toBe("cpu"); - expect(row["sampleCount"]).toBe(100); - expect(row["originalPayloadFormat"]).toBe("pprofext"); - expect(row["_id"]).toBeDefined(); - expect(row["retentionDate"]).toBeDefined(); - }); - }); - - describe("buildSampleRow", () => { - test("builds sample row with all fields", () => { - const row: JSONObject = service["buildSampleRow"]({ - projectId: { - toString: () => { - return "proj-123"; - }, - }, - serviceId: { - toString: () => { - return "svc-456"; - }, - }, - profileId: "profile-789", - traceId: "trace-abc", - spanId: "span-def", - time: { - unixNano: 1700000000000000000, - nano: "1700000000000000000", - iso: "2023-11-14T22:13:20.000Z", - date: new Date("2023-11-14T22:13:20.000Z"), - }, - stacktrace: ["main@app.go:15", "runtime.main@runtime/proc.go:120"], - stacktraceHash: "abc123", - frameTypes: ["go", "go"], - value: 50000, - profileType: "cpu", - labels: { "thread.name": "main" }, - dataRetentionInDays: 15, - }); - - expect(row["projectId"]).toBe("proj-123"); - expect(row["serviceId"]).toBe("svc-456"); - expect(row["profileId"]).toBe("profile-789"); - expect(row["traceId"]).toBe("trace-abc"); - expect(row["stacktrace"]).toEqual([ - "main@app.go:15", - "runtime.main@runtime/proc.go:120", - ]); - expect(row["stacktraceHash"]).toBe("abc123"); - expect(row["frameTypes"]).toEqual(["go", "go"]); - expect(row["value"]).toBe("50000"); - expect(row["profileType"]).toBe("cpu"); - expect(row["labels"]).toEqual({ "thread.name": "main" }); - expect(row["_id"]).toBeDefined(); - expect(row["retentionDate"]).toBeDefined(); - }); - }); -}); diff --git a/Telemetry/Tests/Utils/Exception.test.ts b/Telemetry/Tests/Utils/Exception.test.ts deleted file mode 100644 index b094845c6d..0000000000 --- a/Telemetry/Tests/Utils/Exception.test.ts +++ /dev/null @@ -1,359 +0,0 @@ -import ExceptionUtil from "../../Utils/Exception"; -import ObjectID from "Common/Types/ObjectID"; - -describe("ExceptionUtil", () => { - describe("normalizeForFingerprint", () => { - test("normalizes Stripe subscription IDs", () => { - const message1: string = - "No such subscription: 'sub_1POgR8ANuQdJ93r7dySVHs4K'"; - const message2: string = - "No such subscription: 'sub_1PRZvTANuQdJ93r7K1nhUFZ9'"; - - const normalized1: string = - ExceptionUtil.normalizeForFingerprint(message1); - const normalized2: string = - ExceptionUtil.normalizeForFingerprint(message2); - - expect(normalized1).toBe(normalized2); - expect(normalized1).toBe("No such subscription: ''"); - }); - - test("normalizes Stripe customer IDs", () => { - const message1: string = "Customer cus_ABC123DEF456GHI not found"; - const message2: string = "Customer cus_XYZ789JKL012MNO not found"; - - const normalized1: string = - ExceptionUtil.normalizeForFingerprint(message1); - const normalized2: string = - ExceptionUtil.normalizeForFingerprint(message2); - - expect(normalized1).toBe(normalized2); - expect(normalized1).toBe("Customer not found"); - }); - - test("normalizes UUIDs", () => { - const message1: string = - "Failed to find resource 550e8400-e29b-41d4-a716-446655440000"; - const message2: string = - "Failed to find resource a1b2c3d4-e5f6-7890-abcd-ef1234567890"; - - const normalized1: string = - ExceptionUtil.normalizeForFingerprint(message1); - const normalized2: string = - ExceptionUtil.normalizeForFingerprint(message2); - - expect(normalized1).toBe(normalized2); - expect(normalized1).toBe("Failed to find resource "); - }); - - test("normalizes MongoDB ObjectIDs", () => { - const message1: string = "Document not found: 507f1f77bcf86cd799439011"; - const message2: string = "Document not found: 60a1b2c3d4e5f6a7b8c9d0e1"; - - const normalized1: string = - ExceptionUtil.normalizeForFingerprint(message1); - const normalized2: string = - ExceptionUtil.normalizeForFingerprint(message2); - - expect(normalized1).toBe(normalized2); - expect(normalized1).toBe("Document not found: "); - }); - - test("normalizes IP addresses", () => { - const message1: string = "Connection refused from 192.168.1.100"; - const message2: string = "Connection refused from 10.0.0.50"; - - const normalized1: string = - ExceptionUtil.normalizeForFingerprint(message1); - const normalized2: string = - ExceptionUtil.normalizeForFingerprint(message2); - - expect(normalized1).toBe(normalized2); - expect(normalized1).toBe("Connection refused from "); - }); - - test("normalizes email addresses", () => { - const message1: string = "Invalid email: user@example.com"; - const message2: string = "Invalid email: admin@company.org"; - - const normalized1: string = - ExceptionUtil.normalizeForFingerprint(message1); - const normalized2: string = - ExceptionUtil.normalizeForFingerprint(message2); - - expect(normalized1).toBe(normalized2); - expect(normalized1).toBe("Invalid email: "); - }); - - test("normalizes timestamps", () => { - const message1: string = "Request failed at 2024-03-15T14:30:00.000Z"; - const message2: string = "Request failed at 2024-12-01T09:15:30.500Z"; - - const normalized1: string = - ExceptionUtil.normalizeForFingerprint(message1); - const normalized2: string = - ExceptionUtil.normalizeForFingerprint(message2); - - expect(normalized1).toBe(normalized2); - expect(normalized1).toBe("Request failed at "); - }); - - test("normalizes Unix timestamps", () => { - const message1: string = "Event occurred at 1710511800000"; - const message2: string = "Event occurred at 1733059530500"; - - const normalized1: string = - ExceptionUtil.normalizeForFingerprint(message1); - const normalized2: string = - ExceptionUtil.normalizeForFingerprint(message2); - - expect(normalized1).toBe(normalized2); - expect(normalized1).toBe("Event occurred at "); - }); - - test("normalizes memory addresses", () => { - const message1: string = "Segmentation fault at 0x7fff5fbff8c0"; - const message2: string = "Segmentation fault at 0x00007ffe12345678"; - - const normalized1: string = - ExceptionUtil.normalizeForFingerprint(message1); - const normalized2: string = - ExceptionUtil.normalizeForFingerprint(message2); - - expect(normalized1).toBe(normalized2); - expect(normalized1).toBe("Segmentation fault at "); - }); - - test("normalizes session IDs", () => { - const message1: string = "Session expired: session_id=abc123def456"; - const message2: string = "Session expired: session_id=xyz789jkl012"; - - const normalized1: string = - ExceptionUtil.normalizeForFingerprint(message1); - const normalized2: string = - ExceptionUtil.normalizeForFingerprint(message2); - - expect(normalized1).toBe(normalized2); - expect(normalized1).toBe("Session expired: session_id="); - }); - - test("normalizes request IDs", () => { - const message1: string = "Request failed: request_id=req_abc123"; - const message2: string = "Request failed: request_id=req_xyz789"; - - const normalized1: string = - ExceptionUtil.normalizeForFingerprint(message1); - const normalized2: string = - ExceptionUtil.normalizeForFingerprint(message2); - - expect(normalized1).toBe(normalized2); - expect(normalized1).toBe("Request failed: request_id="); - }); - - test("normalizes large numbers", () => { - /* - * Large numbers (8+ digits) may match hex pattern since 0-9 are valid hex - * The important thing is both normalize to the same value - */ - const message1: string = "User 8234567890 not found"; - const message2: string = "User 9876543210 not found"; - - const normalized1: string = - ExceptionUtil.normalizeForFingerprint(message1); - const normalized2: string = - ExceptionUtil.normalizeForFingerprint(message2); - - // Both should normalize to the same value (ensuring same fingerprint) - expect(normalized1).toBe(normalized2); - }); - - test("normalizes 7-digit numbers as NUMBER", () => { - // 7-digit numbers don't match hex pattern (8+ chars) so fall through to NUMBER - const message1: string = "Error code 1234567"; - const message2: string = "Error code 9876543"; - - const normalized1: string = - ExceptionUtil.normalizeForFingerprint(message1); - const normalized2: string = - ExceptionUtil.normalizeForFingerprint(message2); - - expect(normalized1).toBe(normalized2); - expect(normalized1).toBe("Error code "); - }); - - test("handles empty string", () => { - const normalized: string = ExceptionUtil.normalizeForFingerprint(""); - expect(normalized).toBe(""); - }); - - test("preserves meaningful text while normalizing IDs", () => { - const message: string = - "Failed to process payment for customer cus_ABC123DEF456GHI: Card declined"; - const normalized: string = ExceptionUtil.normalizeForFingerprint(message); - - expect(normalized).toBe( - "Failed to process payment for customer : Card declined", - ); - }); - - test("normalizes multiple dynamic values in same message", () => { - const message1: string = - "User user@example.com (id=12345678) failed to access resource 550e8400-e29b-41d4-a716-446655440000"; - const message2: string = - "User admin@company.org (id=87654321) failed to access resource a1b2c3d4-e5f6-7890-abcd-ef1234567890"; - - const normalized1: string = - ExceptionUtil.normalizeForFingerprint(message1); - const normalized2: string = - ExceptionUtil.normalizeForFingerprint(message2); - - expect(normalized1).toBe(normalized2); - }); - - test("normalizes JWT tokens", () => { - const message1: string = - "Invalid token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"; - const message2: string = - "Invalid token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5ODc2NTQzMjEwIiwibmFtZSI6IkphbmUgRG9lIiwiaWF0IjoxNjE2MjM5MDIyfQ.DifferentSignatureHere123456789"; - - const normalized1: string = - ExceptionUtil.normalizeForFingerprint(message1); - const normalized2: string = - ExceptionUtil.normalizeForFingerprint(message2); - - expect(normalized1).toBe(normalized2); - expect(normalized1).toBe("Invalid token: "); - }); - - test("normalizes generic service IDs with prefix_alphanumeric pattern", () => { - const message1: string = "Failed to find resource aws_abc123def456"; - const message2: string = "Failed to find resource aws_xyz789jkl012"; - - const normalized1: string = - ExceptionUtil.normalizeForFingerprint(message1); - const normalized2: string = - ExceptionUtil.normalizeForFingerprint(message2); - - expect(normalized1).toBe(normalized2); - expect(normalized1).toBe("Failed to find resource "); - }); - }); - - describe("getFingerprint", () => { - test("generates same fingerprint for exceptions with different dynamic IDs", () => { - const projectId: ObjectID = ObjectID.generate(); - const serviceId: ObjectID = ObjectID.generate(); - - const fingerprint1: string = ExceptionUtil.getFingerprint({ - projectId, - serviceId, - message: "No such subscription: 'sub_1POgR8ANuQdJ93r7dySVHs4K'", - exceptionType: "StripeError", - stackTrace: "at processPayment (payment.js:100)", - }); - - const fingerprint2: string = ExceptionUtil.getFingerprint({ - projectId, - serviceId, - message: "No such subscription: 'sub_1PRZvTANuQdJ93r7K1nhUFZ9'", - exceptionType: "StripeError", - stackTrace: "at processPayment (payment.js:100)", - }); - - expect(fingerprint1).toBe(fingerprint2); - }); - - test("generates different fingerprints for different exception types", () => { - const projectId: ObjectID = ObjectID.generate(); - const serviceId: ObjectID = ObjectID.generate(); - - const fingerprint1: string = ExceptionUtil.getFingerprint({ - projectId, - serviceId, - message: "No such subscription: 'sub_1POgR8ANuQdJ93r7dySVHs4K'", - exceptionType: "StripeError", - stackTrace: "at processPayment (payment.js:100)", - }); - - const fingerprint2: string = ExceptionUtil.getFingerprint({ - projectId, - serviceId, - message: "No such subscription: 'sub_1PRZvTANuQdJ93r7K1nhUFZ9'", - exceptionType: "PaymentError", - stackTrace: "at processPayment (payment.js:100)", - }); - - expect(fingerprint1).not.toBe(fingerprint2); - }); - - test("generates different fingerprints for different services", () => { - const projectId: ObjectID = ObjectID.generate(); - const serviceId1: ObjectID = ObjectID.generate(); - const serviceId2: ObjectID = ObjectID.generate(); - - const fingerprint1: string = ExceptionUtil.getFingerprint({ - projectId, - serviceId: serviceId1, - message: "No such subscription: 'sub_1POgR8ANuQdJ93r7dySVHs4K'", - exceptionType: "StripeError", - }); - - const fingerprint2: string = ExceptionUtil.getFingerprint({ - projectId, - serviceId: serviceId2, - message: "No such subscription: 'sub_1PRZvTANuQdJ93r7K1nhUFZ9'", - exceptionType: "StripeError", - }); - - expect(fingerprint1).not.toBe(fingerprint2); - }); - - test("generates different fingerprints for different projects", () => { - const projectId1: ObjectID = ObjectID.generate(); - const projectId2: ObjectID = ObjectID.generate(); - const serviceId: ObjectID = ObjectID.generate(); - - const fingerprint1: string = ExceptionUtil.getFingerprint({ - projectId: projectId1, - serviceId, - message: "Error occurred", - exceptionType: "Error", - }); - - const fingerprint2: string = ExceptionUtil.getFingerprint({ - projectId: projectId2, - serviceId, - message: "Error occurred", - exceptionType: "Error", - }); - - expect(fingerprint1).not.toBe(fingerprint2); - }); - - test("generates same fingerprint for similar stack traces with different line numbers", () => { - const projectId: ObjectID = ObjectID.generate(); - const serviceId: ObjectID = ObjectID.generate(); - - // Stack traces might have memory addresses or other dynamic values - const fingerprint1: string = ExceptionUtil.getFingerprint({ - projectId, - serviceId, - message: "NullPointerException", - exceptionType: "NullPointerException", - stackTrace: - "at com.example.MyClass.method(MyClass.java:42)\nat 0x7fff5fbff8c0", - }); - - const fingerprint2: string = ExceptionUtil.getFingerprint({ - projectId, - serviceId, - message: "NullPointerException", - exceptionType: "NullPointerException", - stackTrace: - "at com.example.MyClass.method(MyClass.java:42)\nat 0x00007ffe12345678", - }); - - expect(fingerprint1).toBe(fingerprint2); - }); - }); -}); diff --git a/Telemetry/Tests/Utils/StackTraceParser.test.ts b/Telemetry/Tests/Utils/StackTraceParser.test.ts deleted file mode 100644 index 390c2cee0a..0000000000 --- a/Telemetry/Tests/Utils/StackTraceParser.test.ts +++ /dev/null @@ -1,289 +0,0 @@ -import StackTraceParser, { - ParsedStackTrace, - StackFrame, -} from "../../Utils/StackTraceParser"; - -describe("StackTraceParser", () => { - describe("parse", () => { - test("returns empty frames for empty input", () => { - const result: ParsedStackTrace = StackTraceParser.parse(""); - expect(result.frames).toHaveLength(0); - expect(result.raw).toBe(""); - }); - - test("returns empty frames for null-ish input", () => { - const result: ParsedStackTrace = StackTraceParser.parse( - undefined as unknown as string, - ); - expect(result.frames).toHaveLength(0); - }); - - test("preserves raw stack trace", () => { - const rawTrace: string = - "Error: something\n at foo (/app/bar.js:10:5)"; - const result: ParsedStackTrace = StackTraceParser.parse(rawTrace); - expect(result.raw).toBe(rawTrace); - }); - }); - - describe("JavaScript/Node.js stack traces", () => { - test("parses standard Node.js stack trace", () => { - const trace: string = `TypeError: Cannot read property 'id' of undefined - at getUser (/app/src/services/user.ts:42:15) - at processRequest (/app/src/controllers/api.ts:128:20) - at Layer.handle [as handle_request] (node_modules/express/lib/router/layer.js:95:5) - at next (node_modules/express/lib/router/route.js:144:13)`; - - const result: ParsedStackTrace = StackTraceParser.parse(trace); - - expect(result.frames.length).toBeGreaterThanOrEqual(2); - - // First frame should be getUser - const firstFrame: StackFrame | undefined = result.frames[0]; - expect(firstFrame).toBeDefined(); - expect(firstFrame!.functionName).toBe("getUser"); - expect(firstFrame!.fileName).toBe("/app/src/services/user.ts"); - expect(firstFrame!.lineNumber).toBe(42); - expect(firstFrame!.columnNumber).toBe(15); - expect(firstFrame!.inApp).toBe(true); - }); - - test("marks node_modules as library code", () => { - const trace: string = `Error: test - at handler (/app/src/handler.js:10:5) - at Layer.handle (node_modules/express/lib/router/layer.js:95:5)`; - - const result: ParsedStackTrace = StackTraceParser.parse(trace); - const expressFrame: StackFrame | undefined = result.frames.find( - (f: StackFrame) => { - return f.fileName.includes("express"); - }, - ); - expect(expressFrame).toBeDefined(); - expect(expressFrame!.inApp).toBe(false); - }); - - test("parses anonymous function frames", () => { - const trace: string = `Error: test - at /app/src/index.js:5:10`; - - const result: ParsedStackTrace = StackTraceParser.parse(trace); - expect(result.frames.length).toBeGreaterThanOrEqual(1); - expect(result.frames[0]!.functionName).toBe(""); - }); - }); - - describe("Python stack traces", () => { - test("parses standard Python traceback", () => { - const trace: string = `Traceback (most recent call last): - File "/app/main.py", line 42, in handle_request - result = process_data(data) - File "/app/utils.py", line 15, in process_data - return data["key"] -KeyError: 'key'`; - - const result: ParsedStackTrace = StackTraceParser.parse(trace); - - expect(result.frames.length).toBeGreaterThanOrEqual(2); - - const firstFrame: StackFrame | undefined = result.frames[0]; - expect(firstFrame).toBeDefined(); - expect(firstFrame!.fileName).toBe("/app/main.py"); - expect(firstFrame!.lineNumber).toBe(42); - expect(firstFrame!.functionName).toBe("handle_request"); - expect(firstFrame!.inApp).toBe(true); - }); - - test("marks site-packages as library code", () => { - const trace: string = `Traceback (most recent call last): - File "/usr/lib/python3.9/site-packages/django/core/handlers.py", line 47, in inner - response = get_response(request) - File "/app/views.py", line 10, in index - raise ValueError("test")`; - - const result: ParsedStackTrace = StackTraceParser.parse(trace); - const djangoFrame: StackFrame | undefined = result.frames.find( - (f: StackFrame) => { - return f.fileName.includes("site-packages"); - }, - ); - expect(djangoFrame).toBeDefined(); - expect(djangoFrame!.inApp).toBe(false); - - const appFrame: StackFrame | undefined = result.frames.find( - (f: StackFrame) => { - return f.fileName === "/app/views.py"; - }, - ); - expect(appFrame).toBeDefined(); - expect(appFrame!.inApp).toBe(true); - }); - }); - - describe("Java stack traces", () => { - test("parses standard Java stack trace", () => { - const trace: string = `java.lang.NullPointerException: Cannot invoke method on null - at com.myapp.service.UserService.getUser(UserService.java:42) - at com.myapp.controller.ApiController.handleRequest(ApiController.java:128) - at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:897) - at javax.servlet.http.HttpServlet.service(HttpServlet.java:750)`; - - const result: ParsedStackTrace = StackTraceParser.parse(trace); - - expect(result.frames.length).toBeGreaterThanOrEqual(2); - - const firstFrame: StackFrame | undefined = result.frames[0]; - expect(firstFrame).toBeDefined(); - expect(firstFrame!.functionName).toContain("UserService.getUser"); - expect(firstFrame!.fileName).toBe("UserService.java"); - expect(firstFrame!.lineNumber).toBe(42); - }); - - test("marks standard Java libs as library code", () => { - const trace: string = `Exception - at com.myapp.Main.run(Main.java:10) - at java.lang.Thread.run(Thread.java:748)`; - - const result: ParsedStackTrace = StackTraceParser.parse(trace); - const javaFrame: StackFrame | undefined = result.frames.find( - (f: StackFrame) => { - return f.functionName.startsWith("java."); - }, - ); - expect(javaFrame).toBeDefined(); - expect(javaFrame!.inApp).toBe(false); - }); - - test("handles Native Method entries", () => { - const trace: string = `Exception - at sun.reflect.NativeMethodAccessorImpl.invoke(Native Method)`; - - const result: ParsedStackTrace = StackTraceParser.parse(trace); - if (result.frames.length > 0) { - expect(result.frames[0]!.fileName).toBe("Native Method"); - expect(result.frames[0]!.inApp).toBe(false); - } - }); - }); - - describe("Go stack traces", () => { - test("parses standard Go stack trace", () => { - const trace: string = `goroutine 1 [running]: -main.handler(0xc0000b4000) - /app/main.go:42 +0x1a5 -net/http.(*ServeMux).ServeHTTP(0xc0000b4000, 0x7f3a9c, 0xc0000b8000) - /usr/local/go/src/net/http/server.go:2387 +0x1a5`; - - const result: ParsedStackTrace = StackTraceParser.parse(trace); - - expect(result.frames.length).toBeGreaterThanOrEqual(1); - - const appFrame: StackFrame | undefined = result.frames.find( - (f: StackFrame) => { - return f.fileName === "/app/main.go"; - }, - ); - expect(appFrame).toBeDefined(); - expect(appFrame!.lineNumber).toBe(42); - expect(appFrame!.inApp).toBe(true); - }); - }); - - describe("Ruby stack traces", () => { - test("parses standard Ruby backtrace", () => { - const trace: string = `/app/controllers/users_controller.rb:42:in 'show' -/app/middleware/auth.rb:15:in 'call' -/usr/local/lib/ruby/gems/2.7.0/gems/rack-2.2.3/lib/rack/handler.rb:12:in 'call'`; - - const result: ParsedStackTrace = StackTraceParser.parse(trace); - - expect(result.frames.length).toBeGreaterThanOrEqual(2); - - const firstFrame: StackFrame | undefined = result.frames[0]; - expect(firstFrame).toBeDefined(); - expect(firstFrame!.fileName).toBe("/app/controllers/users_controller.rb"); - expect(firstFrame!.lineNumber).toBe(42); - expect(firstFrame!.functionName).toBe("show"); - expect(firstFrame!.inApp).toBe(true); - }); - - test("marks gems as library code", () => { - const trace: string = `/usr/local/lib/ruby/gems/2.7.0/gems/rack-2.2.3/lib/rack/handler.rb:12:in 'call'`; - - const result: ParsedStackTrace = StackTraceParser.parse(trace); - if (result.frames.length > 0) { - expect(result.frames[0]!.inApp).toBe(false); - } - }); - }); - - describe("C#/.NET stack traces", () => { - test("parses .NET stack trace with file info", () => { - const trace: string = `System.NullReferenceException: Object reference not set - at MyApp.Services.UserService.GetUser(Int32 id) in /app/Services/UserService.cs:line 42 - at MyApp.Controllers.ApiController.HandleRequest() in /app/Controllers/ApiController.cs:line 128 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)`; - - const result: ParsedStackTrace = StackTraceParser.parse(trace); - - expect(result.frames.length).toBeGreaterThanOrEqual(2); - - const userServiceFrame: StackFrame | undefined = result.frames.find( - (f: StackFrame) => { - return f.fileName.includes("UserService.cs"); - }, - ); - expect(userServiceFrame).toBeDefined(); - expect(userServiceFrame!.lineNumber).toBe(42); - }); - }); - - describe("PHP stack traces", () => { - test("parses standard PHP stack trace", () => { - const trace: string = `#0 /app/src/Controller/UserController.php(42): App\\Service\\UserService->getUser() -#1 /app/vendor/symfony/http-kernel/HttpKernel.php(128): App\\Controller\\UserController->show() -#2 {main}`; - - const result: ParsedStackTrace = StackTraceParser.parse(trace); - - expect(result.frames.length).toBeGreaterThanOrEqual(2); - - const firstFrame: StackFrame | undefined = result.frames[0]; - expect(firstFrame).toBeDefined(); - expect(firstFrame!.fileName).toBe( - "/app/src/Controller/UserController.php", - ); - expect(firstFrame!.lineNumber).toBe(42); - expect(firstFrame!.inApp).toBe(true); - }); - - test("marks vendor as library code", () => { - const trace: string = `#0 /app/vendor/symfony/http-kernel/HttpKernel.php(128): App\\Controller\\UserController->show()`; - - const result: ParsedStackTrace = StackTraceParser.parse(trace); - if (result.frames.length > 0) { - expect(result.frames[0]!.inApp).toBe(false); - } - }); - }); - - describe("inApp detection", () => { - test("node_modules is not app code", () => { - const trace: string = `Error: test - at handler (node_modules/express/lib/router.js:10:5)`; - const result: ParsedStackTrace = StackTraceParser.parse(trace); - if (result.frames.length > 0) { - expect(result.frames[0]!.inApp).toBe(false); - } - }); - - test("application source is app code", () => { - const trace: string = `Error: test - at handler (/app/src/handler.ts:10:5)`; - const result: ParsedStackTrace = StackTraceParser.parse(trace); - if (result.frames.length > 0) { - expect(result.frames[0]!.inApp).toBe(true); - } - }); - }); -}); diff --git a/Telemetry/Tests/Utils/SyslogParser.test.ts b/Telemetry/Tests/Utils/SyslogParser.test.ts deleted file mode 100644 index 8e7ebd28aa..0000000000 --- a/Telemetry/Tests/Utils/SyslogParser.test.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { - ParsedSyslogMessage, - parseSyslogMessage, -} from "../../Utils/SyslogParser"; - -describe("SyslogParser", () => { - test("parses RFC5424 message with structured data", () => { - const message: string = - "<34>1 2025-03-02T14:48:05.003Z mymachine app-name 1234 ID47 " + - '[exampleSDID@32473 iut="3" eventSource="Application" eventID="1011"][meta key="value"] ' + - "BOMAn application event log entry"; - - const parsed: ParsedSyslogMessage | null = parseSyslogMessage(message); - - expect(parsed).not.toBeNull(); - expect(parsed?.priority).toBe(34); - expect(parsed?.severity).toBe(2); - expect(parsed?.facility).toBe(4); - expect(parsed?.version).toBe(1); - expect(parsed?.hostname).toBe("mymachine"); - expect(parsed?.appName).toBe("app-name"); - expect(parsed?.procId).toBe("1234"); - expect(parsed?.msgId).toBe("ID47"); - expect(parsed?.timestamp?.toISOString()).toBe("2025-03-02T14:48:05.003Z"); - expect(parsed?.structuredData?.["exampleSDID_32473"]?.["iut"]).toBe("3"); - expect(parsed?.structuredData?.["meta"]?.["key"]).toBe("value"); - expect(parsed?.message).toBe("An application event log entry"); - }); - - test("parses RFC3164 message", () => { - const message: string = - "<13>Feb 5 17:32:18 mymachine su[12345]: 'su root' failed for lonvick on /dev/pts/8"; - - const parsed: ParsedSyslogMessage | null = parseSyslogMessage(message); - - expect(parsed).not.toBeNull(); - expect(parsed?.priority).toBe(13); - expect(parsed?.severity).toBe(5); - expect(parsed?.facility).toBe(1); - expect(parsed?.hostname).toBe("mymachine"); - expect(parsed?.appName).toBe("su"); - expect(parsed?.procId).toBe("12345"); - expect(parsed?.message).toBe("'su root' failed for lonvick on /dev/pts/8"); - expect(parsed?.timestamp).toBeInstanceOf(Date); - }); - - test("handles message without priority", () => { - const message: string = "Simple message without metadata"; - const parsed: ParsedSyslogMessage | null = parseSyslogMessage(message); - - expect(parsed).not.toBeNull(); - expect(parsed?.priority).toBeUndefined(); - expect(parsed?.severity).toBeUndefined(); - expect(parsed?.facility).toBeUndefined(); - expect(parsed?.message).toBe("Simple message without metadata"); - }); -}); diff --git a/Telemetry/jest.config.json b/Telemetry/jest.config.json deleted file mode 100644 index 4ea0f190e9..0000000000 --- a/Telemetry/jest.config.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - - "preset": "ts-jest", -"testPathIgnorePatterns": [ - "node_modules", - "dist" - ], - "verbose": true, - "globals": { - "ts-jest": { - "tsconfig": "tsconfig.json", - "babelConfig": false - } - }, - "moduleFileExtensions": ["ts", "js", "json"], - "transform": { - ".(ts|tsx)": "ts-jest" - }, - "testEnvironment": "node", - "collectCoverage": false, - "coverageReporters": ["text", "lcov"], - "testRegex": "./Tests/(.*).test.ts", - "collectCoverageFrom": ["./**/*.(tsx||ts)"], - "coverageThreshold": { - "global": { - "lines": 0, - "functions": 0, - "branches": 0, - "statements": 0 - } - } -} diff --git a/Telemetry/nodemon.json b/Telemetry/nodemon.json deleted file mode 100644 index 07abceddc5..0000000000 --- a/Telemetry/nodemon.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "watch": [ - "./", - "../Common/Server", - "../Common/Types", - "../Common/Utils", - "../Common/Models" - ], - "ext": "ts,tsx", - "ignore": ["./node_modules/**", "./public/**", "./bin/**", "./build/**"], - "watchOptions": { "useFsEvents": false, "interval": 500 }, - "env": { "TS_NODE_TRANSPILE_ONLY": "1", "TS_NODE_FILES": "false" }, - "exec": "node --use-openssl-ca -r ts-node/register/transpile-only Index.ts" -} diff --git a/Telemetry/package-lock.json b/Telemetry/package-lock.json deleted file mode 100644 index bef61702a8..0000000000 --- a/Telemetry/package-lock.json +++ /dev/null @@ -1,4792 +0,0 @@ -{ - "name": "@oneuptime/telemetry", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "@oneuptime/telemetry", - "version": "1.0.0", - "license": "Apache-2.0", - "dependencies": { - "@grpc/grpc-js": "^1.12.5", - "@grpc/proto-loader": "^0.7.13", - "Common": "file:../Common", - "ejs": "^3.1.10", - "protobufjs": "^7.3.2", - "ts-node": "^10.9.1" - }, - "devDependencies": { - "@types/jest": "^27.5.0", - "@types/node": "^17.0.31", - "jest": "^28.1.0", - "nodemon": "^2.0.20", - "ts-jest": "^28.0.2" - } - }, - "../Common": { - "name": "@oneuptime/common", - "version": "1.0.0", - "license": "Apache-2.0", - "dependencies": { - "@asteasolutions/zod-to-openapi": "^7.3.2", - "@bull-board/express": "^5.21.4", - "@clickhouse/client": "^1.10.1", - "@elastic/elasticsearch": "^8.12.1", - "@hcaptcha/react-hcaptcha": "^1.14.0", - "@monaco-editor/react": "^4.4.6", - "@opentelemetry/api": "^1.9.0", - "@opentelemetry/api-logs": "^0.206.0", - "@opentelemetry/context-zone": "^1.25.1", - "@opentelemetry/exporter-logs-otlp-http": "^0.207.0", - "@opentelemetry/exporter-metrics-otlp-proto": "^0.207.0", - "@opentelemetry/exporter-trace-otlp-http": "^0.207.0", - "@opentelemetry/exporter-trace-otlp-proto": "^0.207.0", - "@opentelemetry/id-generator-aws-xray": "^1.2.2", - "@opentelemetry/instrumentation": "^0.207.0", - "@opentelemetry/instrumentation-fetch": "^0.207.0", - "@opentelemetry/instrumentation-xml-http-request": "^0.207.0", - "@opentelemetry/resources": "^1.25.1", - "@opentelemetry/sdk-logs": "^0.207.0", - "@opentelemetry/sdk-metrics": "^1.25.1", - "@opentelemetry/sdk-node": "^0.207.0", - "@opentelemetry/sdk-trace-web": "^1.25.1", - "@opentelemetry/semantic-conventions": "^1.37.0", - "@pyroscope/nodejs": "^0.4.11", - "@remixicon/react": "^4.2.0", - "@simplewebauthn/server": "^13.2.2", - "@tippyjs/react": "^4.2.6", - "@types/archiver": "^6.0.3", - "@types/crypto-js": "^4.2.2", - "@types/dompurify": "^3.0.5", - "@types/multer": "^2.0.0", - "@types/qrcode": "^1.5.5", - "@types/react-highlight": "^0.12.8", - "@types/react-syntax-highlighter": "^15.5.13", - "@types/uuid": "^8.3.4", - "@types/web-push": "^3.6.4", - "acme-client": "^5.3.0", - "airtable": "^0.12.2", - "archiver": "^7.0.1", - "axios": "^1.12.0", - "botbuilder": "^4.23.3", - "bullmq": "^5.61.0", - "cookie-parser": "^1.4.7", - "cors": "^2.8.5", - "cron-parser": "^4.8.1", - "crypto-js": "^4.2.0", - "dompurify": "^3.3.2", - "dotenv": "^16.4.4", - "ejs": "^3.1.10", - "elkjs": "^0.10.0", - "esbuild": "^0.25.5", - "expo-server-sdk": "^3.15.0", - "express": "^4.21.1", - "formik": "^2.4.6", - "history": "^5.3.0", - "ioredis": "^5.3.2", - "isolated-vm": "^6.0.2", - "json2csv": "^5.0.7", - "json5": "^2.2.3", - "jsonwebtoken": "^9.0.0", - "jwt-decode": "^4.0.0", - "marked": "^12.0.2", - "mermaid": "^11.12.2", - "moment": "^2.30.1", - "moment-timezone": "^0.5.45", - "multer": "^2.1.1", - "node-cron": "^3.0.3", - "nodemailer": "^7.0.7", - "otpauth": "^9.3.1", - "pg": "^8.16.3", - "playwright": "^1.56.0", - "posthog-js": "^1.275.3", - "prop-types": "^15.8.1", - "qrcode": "^1.5.3", - "react": "^18.3.1", - "react-beautiful-dnd": "^13.1.1", - "react-big-calendar": "^1.19.4", - "react-color": "^2.19.3", - "react-dom": "^18.3.1", - "react-dropzone": "^14.2.2", - "react-error-boundary": "^4.0.13", - "react-highlight": "^0.15.0", - "react-markdown": "^9.0.0", - "react-router-dom": "^6.30.1", - "react-select": "^5.4.0", - "react-spinners": "^0.14.1", - "react-syntax-highlighter": "^16.0.0", - "react-toggle": "^4.1.3", - "reactflow": "^11.11.4", - "recharts": "^2.12.7", - "redis-semaphore": "^5.5.1", - "reflect-metadata": "^0.2.2", - "remark-gfm": "^4.0.0", - "slackify-markdown": "^4.4.0", - "slugify": "^1.6.5", - "socket.io": "^4.7.4", - "socket.io-client": "^4.7.5", - "stripe": "^10.17.0", - "tailwind-merge": "^2.6.0", - "tippy.js": "^6.3.7", - "twilio": "^4.22.0", - "typeorm": "^0.3.26", - "typeorm-extension": "^2.2.13", - "universal-cookie": "^7.2.1", - "use-async-effect": "^2.2.6", - "uuid": "^8.3.2", - "web-push": "^3.6.7", - "zod": "^3.25.76" - }, - "devDependencies": { - "@faker-js/faker": "^8.0.2", - "@testing-library/jest-dom": "^5.16.5", - "@testing-library/react": "^13.3.0", - "@testing-library/user-event": "^14.4.3", - "@types/cookie-parser": "^1.4.4", - "@types/cors": "^2.8.12", - "@types/ejs": "^3.1.1", - "@types/express": "^4.17.13", - "@types/jest": "^28.1.4", - "@types/json2csv": "^5.0.3", - "@types/jsonwebtoken": "^8.5.9", - "@types/node": "^17.0.45", - "@types/node-cron": "^3.0.7", - "@types/nodemailer": "^6.4.7", - "@types/react": "^18.2.38", - "@types/react-beautiful-dnd": "^13.1.2", - "@types/react-big-calendar": "^1.8.5", - "@types/react-color": "^3.0.6", - "@types/react-test-renderer": "^18.0.0", - "@types/react-toggle": "^4.0.3", - "jest": "^28.1.1", - "jest-environment-jsdom": "^29.7.0", - "jest-mock-extended": "^3.0.5", - "react-test-renderer": "^18.2.0", - "sass": "^1.89.2", - "ts-jest": "^28.0.5" - } - }, - "../CommonServer": { - "name": "@oneuptime/common-server", - "version": "1.0.0", - "extraneous": true, - "license": "Apache-2.0", - "dependencies": { - "@clickhouse/client": "^0.2.10", - "@elastic/elasticsearch": "^8.12.1", - "@opentelemetry/api": "^1.7.0", - "@opentelemetry/api-logs": "^0.49.1", - "@opentelemetry/auto-instrumentations-node": "^0.43.0", - "@opentelemetry/exporter-logs-otlp-http": "^0.49.1", - "@opentelemetry/exporter-metrics-otlp-proto": "^0.49.1", - "@opentelemetry/exporter-trace-otlp-proto": "^0.49.1", - "@opentelemetry/id-generator-aws-xray": "^1.2.1", - "@opentelemetry/sdk-logs": "^0.49.1", - "@opentelemetry/sdk-metrics": "^1.21.0", - "@opentelemetry/sdk-node": "^0.48.0", - "@opentelemetry/sdk-trace-node": "^1.21.0", - "@types/crypto-js": "^4.2.2", - "acme-client": "^5.3.0", - "airtable": "^0.12.2", - "bullmq": "^5.3.3", - "Common": "file:../Common", - "CommonProject": "file:../CommonProject", - "cookie-parser": "^1.4.6", - "cors": "^2.8.5", - "cron-parser": "^4.8.1", - "crypto-js": "^4.2.0", - "dotenv": "^16.4.4", - "ejs": "^3.1.10", - "express": "^4.19.2", - "ioredis": "^5.3.2", - "json2csv": "^5.0.7", - "jsonwebtoken": "^9.0.0", - "marked": "^12.0.2", - "Model": "file:../Model", - "node-cron": "^3.0.3", - "nodemailer": "^6.9.10", - "pg": "^8.7.3", - "redis-semaphore": "^5.5.1", - "socket.io": "^4.7.4", - "stripe": "^10.17.0", - "twilio": "^4.22.0", - "typeorm": "^0.3.20", - "typeorm-extension": "^2.2.13" - }, - "devDependencies": { - "@faker-js/faker": "^6.3.1", - "@types/cookie-parser": "^1.4.4", - "@types/cors": "^2.8.12", - "@types/ejs": "^3.1.1", - "@types/express": "^4.17.13", - "@types/jest": "^27.4.1", - "@types/json2csv": "^5.0.3", - "@types/jsonwebtoken": "^8.5.9", - "@types/node": "^17.0.22", - "@types/node-cron": "^3.0.7", - "@types/nodemailer": "^6.4.7", - "jest": "^27.5.1", - "jest-mock-extended": "^3.0.5", - "ts-jest": "^27.1.4" - } - }, - "../Model": { - "name": "@oneuptime/model", - "version": "1.0.0", - "extraneous": true, - "license": "Apache-2.0", - "dependencies": { - "Common": "file:../Common", - "typeorm": "^0.3.20" - }, - "devDependencies": { - "@types/jest": "^27.4.1", - "@types/node": "^17.0.22", - "jest": "^27.5.1", - "ts-jest": "^27.1.4" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", - "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.6.tgz", - "integrity": "sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.6", - "@babel/parser": "^7.23.6", - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.6", - "@babel/types": "^7.23.6", - "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/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 - }, - "node_modules/@babel/generator": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", - "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.23.6", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", - "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.23.5", - "@babel/helper-validator-option": "^7.23.5", - "browserslist": "^4.22.2", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", - "dev": true, - "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", - "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.15" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", - "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.20" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", - "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", - "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", - "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", - "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.28.5" - }, - "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, - "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, - "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, - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "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, - "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, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.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, - "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, - "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, - "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, - "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, - "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, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.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, - "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.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", - "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.6.tgz", - "integrity": "sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.6", - "@babel/types": "^7.23.6", - "debug": "^4.3.1", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", - "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" - }, - "engines": { - "node": ">=6.9.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 - }, - "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==", - "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==", - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "node_modules/@grpc/grpc-js": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.14.3.tgz", - "integrity": "sha512-Iq8QQQ/7X3Sac15oB6p0FmUg/klxQvXLeileoqrTRGJYLV+/9tubbr9ipz0GKHjmXVsgFPo/+W+2cA8eNcR+XA==", - "license": "Apache-2.0", - "dependencies": { - "@grpc/proto-loader": "^0.8.0", - "@js-sdsl/ordered-map": "^4.4.2" - }, - "engines": { - "node": ">=12.10.0" - } - }, - "node_modules/@grpc/grpc-js/node_modules/@grpc/proto-loader": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.8.0.tgz", - "integrity": "sha512-rc1hOQtjIWGxcxpb9aHAfLpIctjEnsDehj0DAiVfBlmT84uvR0uUtN2hEi/ecvWVjXUGf5qPF4qEgiLOx1YIMQ==", - "license": "Apache-2.0", - "dependencies": { - "lodash.camelcase": "^4.3.0", - "long": "^5.0.0", - "protobufjs": "^7.5.3", - "yargs": "^17.7.2" - }, - "bin": { - "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@grpc/proto-loader": { - "version": "0.7.15", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.15.tgz", - "integrity": "sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==", - "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/@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, - "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/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, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.3.tgz", - "integrity": "sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^28.1.3", - "jest-util": "^28.1.3", - "slash": "^3.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/@jest/core": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-28.1.3.tgz", - "integrity": "sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA==", - "dev": true, - "dependencies": { - "@jest/console": "^28.1.3", - "@jest/reporters": "^28.1.3", - "@jest/test-result": "^28.1.3", - "@jest/transform": "^28.1.3", - "@jest/types": "^28.1.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": "^28.1.3", - "jest-config": "^28.1.3", - "jest-haste-map": "^28.1.3", - "jest-message-util": "^28.1.3", - "jest-regex-util": "^28.0.2", - "jest-resolve": "^28.1.3", - "jest-resolve-dependencies": "^28.1.3", - "jest-runner": "^28.1.3", - "jest-runtime": "^28.1.3", - "jest-snapshot": "^28.1.3", - "jest-util": "^28.1.3", - "jest-validate": "^28.1.3", - "jest-watcher": "^28.1.3", - "micromatch": "^4.0.4", - "pretty-format": "^28.1.3", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/core/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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/core/node_modules/pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", - "dev": true, - "dependencies": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/@jest/core/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "node_modules/@jest/environment": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", - "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", - "dev": true, - "dependencies": { - "@jest/fake-timers": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "jest-mock": "^28.1.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/@jest/expect": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-28.1.3.tgz", - "integrity": "sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw==", - "dev": true, - "dependencies": { - "expect": "^28.1.3", - "jest-snapshot": "^28.1.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/@jest/expect-utils": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-28.1.3.tgz", - "integrity": "sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==", - "dev": true, - "dependencies": { - "jest-get-type": "^28.0.2" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/@jest/fake-timers": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", - "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@sinonjs/fake-timers": "^9.1.2", - "@types/node": "*", - "jest-message-util": "^28.1.3", - "jest-mock": "^28.1.3", - "jest-util": "^28.1.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/@jest/globals": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-28.1.3.tgz", - "integrity": "sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA==", - "dev": true, - "dependencies": { - "@jest/environment": "^28.1.3", - "@jest/expect": "^28.1.3", - "@jest/types": "^28.1.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/@jest/reporters": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-28.1.3.tgz", - "integrity": "sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg==", - "dev": true, - "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^28.1.3", - "@jest/test-result": "^28.1.3", - "@jest/transform": "^28.1.3", - "@jest/types": "^28.1.3", - "@jridgewell/trace-mapping": "^0.3.13", - "@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": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-message-util": "^28.1.3", - "jest-util": "^28.1.3", - "jest-worker": "^28.1.3", - "slash": "^3.0.0", - "string-length": "^4.0.1", - "strip-ansi": "^6.0.0", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^9.0.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/schemas": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", - "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==", - "dev": true, - "dependencies": { - "@sinclair/typebox": "^0.24.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/@jest/source-map": { - "version": "28.1.2", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-28.1.2.tgz", - "integrity": "sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.13", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/@jest/test-result": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.3.tgz", - "integrity": "sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==", - "dev": true, - "dependencies": { - "@jest/console": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/@jest/test-sequencer": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-28.1.3.tgz", - "integrity": "sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw==", - "dev": true, - "dependencies": { - "@jest/test-result": "^28.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^28.1.3", - "slash": "^3.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/@jest/transform": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-28.1.3.tgz", - "integrity": "sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA==", - "dev": true, - "dependencies": { - "@babel/core": "^7.11.6", - "@jest/types": "^28.1.3", - "@jridgewell/trace-mapping": "^0.3.13", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^28.1.3", - "jest-regex-util": "^28.0.2", - "jest-util": "^28.1.3", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^28.1.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": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.20", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", - "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", - "dev": true, - "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/@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==" - }, - "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==" - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" - }, - "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==", - "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==" - }, - "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==" - }, - "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==" - }, - "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==" - }, - "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==" - }, - "node_modules/@sinclair/typebox": { - "version": "0.24.51", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", - "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==", - "dev": true - }, - "node_modules/@sinonjs/commons": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", - "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^1.7.0" - } - }, - "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" - }, - "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==" - }, - "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==" - }, - "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==" - }, - "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, - "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.7", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.7.tgz", - "integrity": "sha512-6Sfsq+EaaLrw4RmdFWE9Onp63TOUue71AWb4Gpa6JxzgTYtimbM086WnYTy2U67AofR++QKCo08ZP6pwx8YFHQ==", - "dev": true, - "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, - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.20.4", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.4.tgz", - "integrity": "sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.20.7" - } - }, - "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, - "dependencies": { - "@types/node": "*" - } - }, - "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 - }, - "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, - "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, - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/jest": { - "version": "27.5.2", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz", - "integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==", - "dev": true, - "dependencies": { - "jest-matcher-utils": "^27.0.0", - "pretty-format": "^27.0.0" - } - }, - "node_modules/@types/node": { - "version": "17.0.45", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", - "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" - }, - "node_modules/@types/prettier": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", - "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", - "dev": true - }, - "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 - }, - "node_modules/@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", - "dev": true, - "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 - }, - "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==", - "dev": true - }, - "node_modules/acorn": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", - "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.1.tgz", - "integrity": "sha512-TgUZgYvqZprrl7YldZNoa9OciCAyZR+Ejm9eXzKCmjsF5IKp/wgQ7Z/ZpjpGTIUPwrHQIcYeI8qDh4PsEwxMbw==", - "engines": { - "node": ">=0.4.0" - } - }, - "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, - "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==", - "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==", - "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, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" - }, - "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, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "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/babel-jest": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.3.tgz", - "integrity": "sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q==", - "dev": true, - "dependencies": { - "@jest/transform": "^28.1.3", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^28.1.3", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.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, - "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-jest-hoist": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz", - "integrity": "sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q==", - "dev": true, - "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": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dev": true, - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@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-top-level-await": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babel-preset-jest": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz", - "integrity": "sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A==", - "dev": true, - "dependencies": { - "babel-plugin-jest-hoist": "^28.1.3", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.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==", - "dev": true - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "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.22.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", - "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", - "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" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001565", - "electron-to-chromium": "^1.4.601", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" - }, - "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, - "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, - "dependencies": { - "node-int64": "^0.4.0" - } - }, - "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 - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001568", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001568.tgz", - "integrity": "sha512-vSUkH84HontZJ88MiNrOau1EBrCqEQYgkC5gIySiDlpsm8sGVrhU7Kx4V6h0tnqaHzIHZv08HlJIwPbL4XL9+A==", - "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" - } - ] - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/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, - "engines": { - "node": ">=10" - } - }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "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" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "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" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/cjs-module-lexer": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", - "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", - "dev": true - }, - "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==", - "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, - "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 - }, - "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==", - "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==" - }, - "node_modules/Common": { - "resolved": "../Common", - "link": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "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==" - }, - "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/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", - "dev": true - }, - "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, - "engines": { - "node": ">=0.10.0" - } - }, - "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, - "engines": { - "node": ">=8" - } - }, - "node_modules/diff": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz", - "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/diff-sequences": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", - "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", - "dev": true, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/ejs": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", - "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", - "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.4.610", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.610.tgz", - "integrity": "sha512-mqi2oL1mfeHYtOdCxbPQYV/PL7YrQlxbvFEZ0Ee8GbDdShimqt2/S6z2RWqysuvlwdOrQdqvE0KZrBTipAeJzg==", - "dev": true - }, - "node_modules/emittery": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", - "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==", - "dev": true, - "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==" - }, - "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==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "engines": { - "node": ">=6" - } - }, - "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, - "engines": { - "node": ">=8" - } - }, - "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==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "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/expect": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/expect/-/expect-28.1.3.tgz", - "integrity": "sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==", - "dev": true, - "dependencies": { - "@jest/expect-utils": "^28.1.3", - "jest-get-type": "^28.0.2", - "jest-matcher-utils": "^28.1.3", - "jest-message-util": "^28.1.3", - "jest-util": "^28.1.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/expect/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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/expect/node_modules/diff-sequences": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz", - "integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==", - "dev": true, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/expect/node_modules/jest-diff": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz", - "integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^28.1.1", - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/expect/node_modules/jest-matcher-utils": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz", - "integrity": "sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^28.1.3", - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/expect/node_modules/pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", - "dev": true, - "dependencies": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/expect/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/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, - "dependencies": { - "bser": "2.1.1" - } - }, - "node_modules/filelist": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.5.tgz", - "integrity": "sha512-ct/ckWBV/9Dg3MlvCXsLcSUyoWwv9mCKqlhLNB2DAuXR/NZolSXlQqP5dyy6guWlPXBhodZyZ5lGPQcbQDxrEQ==", - "license": "Apache-2.0", - "dependencies": { - "minimatch": "^10.2.1" - }, - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/filelist/node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "license": "MIT", - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/filelist/node_modules/brace-expansion": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", - "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/filelist/node_modules/minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", - "license": "BlueOak-1.0.0", - "dependencies": { - "brace-expansion": "^5.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "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/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, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.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==", - "dev": true - }, - "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, - "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==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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, - "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==", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "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, - "engines": { - "node": ">=8.0.0" - } - }, - "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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "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, - "engines": { - "node": ">=4" - } - }, - "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==", - "dev": true - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "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 - }, - "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, - "engines": { - "node": ">=10.17.0" - } - }, - "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 - }, - "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "dev": true, - "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==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "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, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "dev": true, - "dependencies": { - "hasown": "^2.0.0" - }, - "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, - "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==", - "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, - "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, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "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==", - "dev": true - }, - "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, - "engines": { - "node": ">=8" - } - }, - "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, - "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/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, - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "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, - "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.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", - "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", - "dev": true, - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jake": { - "version": "10.9.4", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz", - "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==", - "license": "Apache-2.0", - "dependencies": { - "async": "^3.2.6", - "filelist": "^1.0.4", - "picocolors": "^1.1.1" - }, - "bin": { - "jake": "bin/cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest/-/jest-28.1.3.tgz", - "integrity": "sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA==", - "dev": true, - "dependencies": { - "@jest/core": "^28.1.3", - "@jest/types": "^28.1.3", - "import-local": "^3.0.2", - "jest-cli": "^28.1.3" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.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": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-28.1.3.tgz", - "integrity": "sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA==", - "dev": true, - "dependencies": { - "execa": "^5.0.0", - "p-limit": "^3.1.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-circus": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-28.1.3.tgz", - "integrity": "sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow==", - "dev": true, - "dependencies": { - "@jest/environment": "^28.1.3", - "@jest/expect": "^28.1.3", - "@jest/test-result": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^28.1.3", - "jest-matcher-utils": "^28.1.3", - "jest-message-util": "^28.1.3", - "jest-runtime": "^28.1.3", - "jest-snapshot": "^28.1.3", - "jest-util": "^28.1.3", - "p-limit": "^3.1.0", - "pretty-format": "^28.1.3", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-circus/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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-circus/node_modules/diff-sequences": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz", - "integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==", - "dev": true, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-circus/node_modules/jest-diff": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz", - "integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^28.1.1", - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-circus/node_modules/jest-matcher-utils": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz", - "integrity": "sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^28.1.3", - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-circus/node_modules/pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", - "dev": true, - "dependencies": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-circus/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "node_modules/jest-cli": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-28.1.3.tgz", - "integrity": "sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ==", - "dev": true, - "dependencies": { - "@jest/core": "^28.1.3", - "@jest/test-result": "^28.1.3", - "@jest/types": "^28.1.3", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "import-local": "^3.0.2", - "jest-config": "^28.1.3", - "jest-util": "^28.1.3", - "jest-validate": "^28.1.3", - "prompts": "^2.0.1", - "yargs": "^17.3.1" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-config": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-28.1.3.tgz", - "integrity": "sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ==", - "dev": true, - "dependencies": { - "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^28.1.3", - "@jest/types": "^28.1.3", - "babel-jest": "^28.1.3", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-circus": "^28.1.3", - "jest-environment-node": "^28.1.3", - "jest-get-type": "^28.0.2", - "jest-regex-util": "^28.0.2", - "jest-resolve": "^28.1.3", - "jest-runner": "^28.1.3", - "jest-util": "^28.1.3", - "jest-validate": "^28.1.3", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^28.1.3", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - }, - "peerDependencies": { - "@types/node": "*", - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "ts-node": { - "optional": true - } - } - }, - "node_modules/jest-config/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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-config/node_modules/pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", - "dev": true, - "dependencies": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-config/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "node_modules/jest-diff": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", - "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-diff/node_modules/jest-get-type": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", - "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", - "dev": true, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-docblock": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-28.1.1.tgz", - "integrity": "sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA==", - "dev": true, - "dependencies": { - "detect-newline": "^3.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-each": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-28.1.3.tgz", - "integrity": "sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "chalk": "^4.0.0", - "jest-get-type": "^28.0.2", - "jest-util": "^28.1.3", - "pretty-format": "^28.1.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-each/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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-each/node_modules/pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", - "dev": true, - "dependencies": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-each/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "node_modules/jest-environment-node": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-28.1.3.tgz", - "integrity": "sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A==", - "dev": true, - "dependencies": { - "@jest/environment": "^28.1.3", - "@jest/fake-timers": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "jest-mock": "^28.1.3", - "jest-util": "^28.1.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-get-type": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", - "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", - "dev": true, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-haste-map": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-28.1.3.tgz", - "integrity": "sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.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": "^28.0.2", - "jest-util": "^28.1.3", - "jest-worker": "^28.1.3", - "micromatch": "^4.0.4", - "walker": "^1.0.8" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" - } - }, - "node_modules/jest-leak-detector": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-28.1.3.tgz", - "integrity": "sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA==", - "dev": true, - "dependencies": { - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-leak-detector/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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-leak-detector/node_modules/pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", - "dev": true, - "dependencies": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-leak-detector/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "node_modules/jest-matcher-utils": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", - "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-matcher-utils/node_modules/jest-get-type": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", - "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", - "dev": true, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-message-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", - "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^28.1.3", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-message-util/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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-message-util/node_modules/pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", - "dev": true, - "dependencies": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-message-util/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "node_modules/jest-mock": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", - "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.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, - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } - } - }, - "node_modules/jest-regex-util": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", - "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==", - "dev": true, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-resolve": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-28.1.3.tgz", - "integrity": "sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^28.1.3", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^28.1.3", - "jest-validate": "^28.1.3", - "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-resolve-dependencies": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.3.tgz", - "integrity": "sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA==", - "dev": true, - "dependencies": { - "jest-regex-util": "^28.0.2", - "jest-snapshot": "^28.1.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-runner": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-28.1.3.tgz", - "integrity": "sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA==", - "dev": true, - "dependencies": { - "@jest/console": "^28.1.3", - "@jest/environment": "^28.1.3", - "@jest/test-result": "^28.1.3", - "@jest/transform": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.10.2", - "graceful-fs": "^4.2.9", - "jest-docblock": "^28.1.1", - "jest-environment-node": "^28.1.3", - "jest-haste-map": "^28.1.3", - "jest-leak-detector": "^28.1.3", - "jest-message-util": "^28.1.3", - "jest-resolve": "^28.1.3", - "jest-runtime": "^28.1.3", - "jest-util": "^28.1.3", - "jest-watcher": "^28.1.3", - "jest-worker": "^28.1.3", - "p-limit": "^3.1.0", - "source-map-support": "0.5.13" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-runtime": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-28.1.3.tgz", - "integrity": "sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw==", - "dev": true, - "dependencies": { - "@jest/environment": "^28.1.3", - "@jest/fake-timers": "^28.1.3", - "@jest/globals": "^28.1.3", - "@jest/source-map": "^28.1.2", - "@jest/test-result": "^28.1.3", - "@jest/transform": "^28.1.3", - "@jest/types": "^28.1.3", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "execa": "^5.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^28.1.3", - "jest-message-util": "^28.1.3", - "jest-mock": "^28.1.3", - "jest-regex-util": "^28.0.2", - "jest-resolve": "^28.1.3", - "jest-snapshot": "^28.1.3", - "jest-util": "^28.1.3", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-snapshot": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-28.1.3.tgz", - "integrity": "sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg==", - "dev": true, - "dependencies": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^28.1.3", - "@jest/transform": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/babel__traverse": "^7.0.6", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^28.1.3", - "graceful-fs": "^4.2.9", - "jest-diff": "^28.1.3", - "jest-get-type": "^28.0.2", - "jest-haste-map": "^28.1.3", - "jest-matcher-utils": "^28.1.3", - "jest-message-util": "^28.1.3", - "jest-util": "^28.1.3", - "natural-compare": "^1.4.0", - "pretty-format": "^28.1.3", - "semver": "^7.3.5" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-snapshot/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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-snapshot/node_modules/diff-sequences": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz", - "integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==", - "dev": true, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-snapshot/node_modules/jest-diff": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz", - "integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^28.1.1", - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-snapshot/node_modules/jest-matcher-utils": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz", - "integrity": "sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^28.1.3", - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-snapshot/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==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-snapshot/node_modules/pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", - "dev": true, - "dependencies": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-snapshot/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-snapshot/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-validate": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-28.1.3.tgz", - "integrity": "sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^28.0.2", - "leven": "^3.1.0", - "pretty-format": "^28.1.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-validate/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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-validate/node_modules/pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", - "dev": true, - "dependencies": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-validate/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "node_modules/jest-watcher": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.3.tgz", - "integrity": "sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==", - "dev": true, - "dependencies": { - "@jest/test-result": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.10.2", - "jest-util": "^28.1.3", - "string-length": "^4.0.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-worker": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", - "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==", - "dev": true, - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.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, - "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==", - "dev": true, - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", - "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "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==", - "dev": true - }, - "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, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "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, - "engines": { - "node": ">=6" - } - }, - "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, - "engines": { - "node": ">=6" - } - }, - "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==", - "dev": true - }, - "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, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "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 - }, - "node_modules/long": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" - }, - "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, - "dependencies": { - "yallist": "^3.0.2" - } - }, - "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, - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-dir/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==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-dir/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "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==" - }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, - "dependencies": { - "tmpl": "1.0.5" - } - }, - "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 - }, - "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/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/minimatch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/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 - }, - "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true - }, - "node_modules/nodemon": { - "version": "2.0.22", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz", - "integrity": "sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==", - "dev": true, - "dependencies": { - "chokidar": "^3.5.2", - "debug": "^3.2.7", - "ignore-by-default": "^1.0.1", - "minimatch": "^3.1.2", - "pstree.remy": "^1.1.8", - "semver": "^5.7.1", - "simple-update-notifier": "^1.0.7", - "supports-color": "^5.5.0", - "touch": "^3.1.0", - "undefsafe": "^2.0.5" - }, - "bin": { - "nodemon": "bin/nodemon.js" - }, - "engines": { - "node": ">=8.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nodemon" - } - }, - "node_modules/nodemon/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "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, - "engines": { - "node": ">=4" - } - }, - "node_modules/nodemon/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, - "bin": { - "semver": "bin/semver" - } - }, - "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, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", - "dev": true, - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "*" - } - }, - "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, - "engines": { - "node": ">=0.10.0" - } - }, - "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, - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=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==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "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, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-locate/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, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "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, - "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==", - "dev": true, - "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/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/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 - }, - "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": "2.3.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", - "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "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, - "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, - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "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, - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/protobufjs": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz", - "integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==", - "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/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 - }, - "node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "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, - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve.exports": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.1.tgz", - "integrity": "sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "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, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/simple-update-notifier": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz", - "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==", - "dev": true, - "dependencies": { - "semver": "~7.0.0" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/simple-update-notifier/node_modules/semver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "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==", - "dev": true, - "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, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "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 - }, - "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, - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "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, - "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==", - "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==", - "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, - "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, - "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, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", - "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.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, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dev": true, - "dependencies": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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, - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "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 - }, - "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/touch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", - "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", - "dev": true, - "dependencies": { - "nopt": "~1.0.10" - }, - "bin": { - "nodetouch": "bin/nodetouch.js" - } - }, - "node_modules/ts-jest": { - "version": "28.0.8", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-28.0.8.tgz", - "integrity": "sha512-5FaG0lXmRPzApix8oFG8RKjAz4ehtm8yMKOTy5HX3fY6W8kmvOrmcY0hKDElW52FJov+clhUbrKAqofnj4mXTg==", - "dev": true, - "dependencies": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^28.0.0", - "json5": "^2.2.1", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "7.x", - "yargs-parser": "^21.0.1" - }, - "bin": { - "ts-jest": "cli.js" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - }, - "peerDependencies": { - "@babel/core": ">=7.0.0-beta.0 <8", - "@jest/types": "^28.0.0", - "babel-jest": "^28.0.0", - "jest": "^28.0.0", - "typescript": ">=4.3" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "@jest/types": { - "optional": true - }, - "babel-jest": { - "optional": true - }, - "esbuild": { - "optional": true - } - } - }, - "node_modules/ts-jest/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==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/ts-jest/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/ts-jest/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": 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==", - "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/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, - "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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undefsafe": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", - "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", - "dev": true - }, - "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", - "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" - } - ], - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "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==" - }, - "node_modules/v8-to-istanbul": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", - "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", - "dev": true, - "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/v8-to-istanbul/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 - }, - "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, - "dependencies": { - "makeerror": "1.0.12" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/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==", - "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==", - "dev": true - }, - "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, - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "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 - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "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==", - "engines": { - "node": ">=12" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/Telemetry/package.json b/Telemetry/package.json deleted file mode 100644 index 336c9dad2a..0000000000 --- a/Telemetry/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "@oneuptime/telemetry", - "version": "1.0.0", - "description": "", - "repository": { - "type": "git", - "url": "https://github.com/OneUptime/oneuptime" - }, - "main": "index.js", - "scripts": { - "start": "export NODE_OPTIONS='--max-old-space-size=8096 --use-openssl-ca' && node --require ts-node/register Index.ts", - "compile": "tsc", - "clear-modules": "rm -rf node_modules && rm package-lock.json && npm install", - "dev": "NODE_OPTIONS='--use-openssl-ca' npx nodemon", - "audit": "npm audit --audit-level=low", - "dep-check": "npm install -g depcheck && depcheck ./ --skip-missing=true", - "test": "jest --passWithNoTests" - }, - "author": "OneUptime (https://oneuptime.com/)", - "license": "Apache-2.0", - "dependencies": { - "@grpc/grpc-js": "^1.12.5", - "@grpc/proto-loader": "^0.7.13", - "Common": "file:../Common", - "ejs": "^3.1.10", - "protobufjs": "^7.3.2", - "ts-node": "^10.9.1" - }, - "devDependencies": { - "@types/jest": "^27.5.0", - "@types/node": "^17.0.31", - "jest": "^28.1.0", - "nodemon": "^2.0.20", - "ts-jest": "^28.0.2" - } -} diff --git a/Telemetry/tsconfig.json b/Telemetry/tsconfig.json deleted file mode 100644 index 8d973aca93..0000000000 --- a/Telemetry/tsconfig.json +++ /dev/null @@ -1,115 +0,0 @@ -{ - "ts-node": { - // these options are overrides used only by ts-node - // same as the --compilerOptions flag and the TS_NODE_COMPILER_OPTIONS environment variable - "compilerOptions": { - "module": "commonjs", - "resolveJsonModule": true, - } - }, - "compilerOptions": { - /* Visit https://aka.ms/tsconfig.json to read more about this file */ - - /* Projects */ - // "incremental": true, /* Enable incremental compilation */ - // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ - // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ - // "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": "es2017" /* 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": "react" /* 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. */ - - /* 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": {}, /* 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": [ - "./node_modules/@types" - ] /* Specify multiple folders that act like `./node_modules/@types`. */, - "types": [ - "node", - "jest" - ] /* Specify type package names to be included without being referenced in a source file. */, - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - // "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": "build/dist" /* 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 /* Type catch clause variables as 'unknown' instead of 'any'. */, - "alwaysStrict": true /* Ensure 'use strict' is always emitted. */, - "noUnusedLocals": true /* Enable error reporting when a 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 /* Include 'undefined' in index signature results */, - "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. */ - "resolveJsonModule": true - } -} diff --git a/config.example.env b/config.example.env index e4f78013f0..d3010769c5 100644 --- a/config.example.env +++ b/config.example.env @@ -99,14 +99,14 @@ REDIS_TLS_CA= REDIS_TLS_SENTINEL_MODE=false # Hostnames. Usually does not need to change. -TELEMETRY_HOSTNAME=telemetry:3403 +TELEMETRY_HOSTNAME=app:3002 SERVER_APP_HOSTNAME=app -SERVER_TELEMETRY_HOSTNAME=telemetry +SERVER_TELEMETRY_HOSTNAME=app #Ports. Usually they don't need to change. APP_PORT=3002 -TELEMETRY_PORT=3403 +TELEMETRY_PORT=3002 TEST_SERVER_PORT=3800 HOME_PORT=1444 # Plans @@ -290,7 +290,6 @@ AI_AGENT_PORT=3876 # By default telemetry is disabled for all services in docker compose. If you want to enable telemetry for a service, then set the env var to false. DISABLE_TELEMETRY_FOR_APP=true -DISABLE_TELEMETRY_FOR_TELEMETRY=true DISABLE_TELEMETRY_FOR_TEST_SERVER=true DISABLE_TELEMETRY_FOR_PROBE=true DISABLE_TELEMETRY_FOR_INGRESS=true @@ -298,7 +297,6 @@ DISABLE_TELEMETRY_FOR_AI_AGENT=true # By default profiling is disabled for all services. Set to true to enable CPU profiling for a service. ENABLE_PROFILING_FOR_APP=false -ENABLE_PROFILING_FOR_TELEMETRY=false ENABLE_PROFILING_FOR_TEST_SERVER=false ENABLE_PROFILING_FOR_PROBE=false ENABLE_PROFILING_FOR_AI_AGENT=false diff --git a/docker-compose.base.yml b/docker-compose.base.yml index 0ac693ae06..7e00c4c4d0 100644 --- a/docker-compose.base.yml +++ b/docker-compose.base.yml @@ -30,12 +30,12 @@ x-common-variables: &common-variables ALLOWED_ACTIVE_MONITOR_COUNT_IN_FREE_PLAN: ${ALLOWED_ACTIVE_MONITOR_COUNT_IN_FREE_PLAN} SERVER_APP_HOSTNAME: app - SERVER_TELEMETRY_HOSTNAME: telemetry + SERVER_TELEMETRY_HOSTNAME: app SERVER_HOME_HOSTNAME: home #Ports. Usually they don't need to change. APP_PORT: ${APP_PORT} HOME_PORT: ${HOME_PORT} - TELEMETRY_PORT: ${TELEMETRY_PORT} + TELEMETRY_PORT: ${APP_PORT} OPENTELEMETRY_EXPORTER_OTLP_ENDPOINT: ${OPENTELEMETRY_EXPORTER_OTLP_ENDPOINT} OPENTELEMETRY_EXPORTER_OTLP_HEADERS: ${OPENTELEMETRY_EXPORTER_OTLP_HEADERS} @@ -232,7 +232,7 @@ services: networks: - oneuptime restart: always - environment: + environment: <<: *common-runtime-variables PORT: ${APP_PORT} SMS_DEFAULT_COST_IN_CENTS: ${SMS_DEFAULT_COST_IN_CENTS} @@ -243,6 +243,9 @@ services: DISABLE_TELEMETRY: ${DISABLE_TELEMETRY_FOR_APP} ENABLE_PROFILING: ${ENABLE_PROFILING_FOR_APP} WORKER_CONCURRENCY: ${WORKER_CONCURRENCY} + # Telemetry ingestion settings (merged from telemetry service) + TELEMETRY_CONCURRENCY: ${TELEMETRY_CONCURRENCY} + REGISTER_PROBE_KEY: ${REGISTER_PROBE_KEY} logging: driver: "local" options: @@ -343,23 +346,6 @@ services: options: max-size: "1000m" - telemetry: - networks: - - oneuptime - restart: always - environment: - <<: *common-runtime-variables - PORT: ${TELEMETRY_PORT} - DISABLE_TELEMETRY: ${DISABLE_TELEMETRY_FOR_TELEMETRY} - ENABLE_PROFILING: ${ENABLE_PROFILING_FOR_TELEMETRY} - # Max concurrent telemetry jobs the worker will process - TELEMETRY_CONCURRENCY: ${TELEMETRY_CONCURRENCY} - REGISTER_PROBE_KEY: ${REGISTER_PROBE_KEY} - logging: - driver: "local" - options: - max-size: "1000m" - e2e: restart: "no" network_mode: host # This is needed to access the host network, diff --git a/docker-compose.billing.yml b/docker-compose.billing.yml index 1bfe5021c4..88b4d58d6f 100644 --- a/docker-compose.billing.yml +++ b/docker-compose.billing.yml @@ -53,14 +53,6 @@ services: depends_on: <<: *common-depends-on - telemetry: - image: oneuptime/telemetry:${APP_TAG} - extends: - file: ./docker-compose.base.yml - service: telemetry - depends_on: - <<: *common-depends-on - ingress: image: oneuptime/nginx:${APP_TAG} extends: diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 788d5bd6e9..7207977bf7 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -173,26 +173,6 @@ services: context: . dockerfile: ./AIAgent/Dockerfile - telemetry: - volumes: - - ./Telemetry:/usr/src/app:cached - # Use node modules of the container and not host system. - # https://stackoverflow.com/questions/29181032/add-a-volume-to-docker-but-exclude-a-sub-folder - - /usr/src/app/node_modules/ - - ./Common:/usr/src/Common:cached - - /usr/src/Common/node_modules/ - ports: - - '9938:9229' # Debugging port. - extends: - file: ./docker-compose.base.yml - service: telemetry - depends_on: - <<: *common-depends-on - build: - network: host - context: . - dockerfile: ./Telemetry/Dockerfile - # Fluentd. Required only for development. In production its the responsibility of the customer to run fluentd and pipe logs to OneUptime. # We run this container just for development, to see if logs are piped. diff --git a/docker-compose.yml b/docker-compose.yml index 7762185845..7060b94e3b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -45,14 +45,6 @@ services: depends_on: <<: *common-depends-on - telemetry: - image: oneuptime/telemetry:${APP_TAG} - extends: - file: ./docker-compose.base.yml - service: telemetry - depends_on: - <<: *common-depends-on - ingress: image: oneuptime/nginx:${APP_TAG} extends: