From b82c9f3fe155efbc2ad8995b2493a8fe7a792559 Mon Sep 17 00:00:00 2001 From: Anmol1696 Date: Sat, 8 Nov 2025 09:31:53 +0400 Subject: [PATCH 01/11] convert to pnpm module for kubernetesjs, move docs, remove k8s --- .../.github => .github}/workflows/build.yml | 0 .../workflows/test-client.yml | 0 .../workflows/test-e2e-client.yml | 0 .../workflows/test-e2e-dashboard.yml | 0 .../workflows/test-unit-dashboard.yml | 0 .../.github => .github}/workflows/tests.yml | 0 PUBLISH.md | 41 + .../kubernetesjs_design_doc.md | 111 +- interweb/k8s/Makefile | 27 - interweb/k8s/README.md | 53 - interweb/k8s/cnpg-cluster.yaml | 131 - interweb/k8s/minio-tenant.yaml | 61 - lerna.json | 21 +- package.json | 18 +- packages/cli/package.json | 2 +- packages/react/package.json | 2 +- pnpm-lock.yaml | 7310 +++++++++++++++++ pnpm-workspace.yaml | 3 + yarn.lock | 6833 --------------- 19 files changed, 7419 insertions(+), 7194 deletions(-) rename {interweb/.github => .github}/workflows/build.yml (100%) rename {interweb/.github => .github}/workflows/test-client.yml (100%) rename {interweb/.github => .github}/workflows/test-e2e-client.yml (100%) rename {interweb/.github => .github}/workflows/test-e2e-dashboard.yml (100%) rename {interweb/.github => .github}/workflows/test-unit-dashboard.yml (100%) rename {interweb/.github => .github}/workflows/tests.yml (100%) create mode 100644 PUBLISH.md rename interweb/docs/interweb_design_doc.md => docs/kubernetesjs_design_doc.md (67%) delete mode 100644 interweb/k8s/Makefile delete mode 100644 interweb/k8s/README.md delete mode 100644 interweb/k8s/cnpg-cluster.yaml delete mode 100644 interweb/k8s/minio-tenant.yaml create mode 100644 pnpm-lock.yaml create mode 100644 pnpm-workspace.yaml delete mode 100644 yarn.lock diff --git a/interweb/.github/workflows/build.yml b/.github/workflows/build.yml similarity index 100% rename from interweb/.github/workflows/build.yml rename to .github/workflows/build.yml diff --git a/interweb/.github/workflows/test-client.yml b/.github/workflows/test-client.yml similarity index 100% rename from interweb/.github/workflows/test-client.yml rename to .github/workflows/test-client.yml diff --git a/interweb/.github/workflows/test-e2e-client.yml b/.github/workflows/test-e2e-client.yml similarity index 100% rename from interweb/.github/workflows/test-e2e-client.yml rename to .github/workflows/test-e2e-client.yml diff --git a/interweb/.github/workflows/test-e2e-dashboard.yml b/.github/workflows/test-e2e-dashboard.yml similarity index 100% rename from interweb/.github/workflows/test-e2e-dashboard.yml rename to .github/workflows/test-e2e-dashboard.yml diff --git a/interweb/.github/workflows/test-unit-dashboard.yml b/.github/workflows/test-unit-dashboard.yml similarity index 100% rename from interweb/.github/workflows/test-unit-dashboard.yml rename to .github/workflows/test-unit-dashboard.yml diff --git a/interweb/.github/workflows/tests.yml b/.github/workflows/tests.yml similarity index 100% rename from interweb/.github/workflows/tests.yml rename to .github/workflows/tests.yml diff --git a/PUBLISH.md b/PUBLISH.md new file mode 100644 index 0000000..c35c341 --- /dev/null +++ b/PUBLISH.md @@ -0,0 +1,41 @@ +# Publishing Guide + +## Quick Publishing Workflow + +### 1. Prepare +```bash +pnpm install +pnpm -r build +pnpm -r test +``` + +### 2. Version +```bash +# Independent versioning (recommended) +pnpm lerna version + +# Or fixed versioning +pnpm lerna version --conventional-commits +``` + +### 3. Publish + +use `from-package` option + +```bash +pnpm lerna publish from-package +``` + +## Dry Run Commands +```bash +# Test versioning (no git operations) +pnpm lerna version --no-git-tag-version --no-push + +# Test publishing +pnpm lerna publish from-package --dry-run +``` + +## One-liner for Full Workflow +```bash +pnpm install && pnpm -r build && pnpm -r test && lerna version && lerna publish from-package +``` \ No newline at end of file diff --git a/interweb/docs/interweb_design_doc.md b/docs/kubernetesjs_design_doc.md similarity index 67% rename from interweb/docs/interweb_design_doc.md rename to docs/kubernetesjs_design_doc.md index 563f327..2dde98c 100644 --- a/interweb/docs/interweb_design_doc.md +++ b/docs/kubernetesjs_design_doc.md @@ -1,12 +1,12 @@ -# Interweb: Design Document +# KubernetesJS: Design Document ## Overview -Interweb is a JavaScript-native Kubernetes developer toolkit that simplifies cluster setup, operator management, and application deployment. It replaces bash-script-based workflows with a modern CLI and programmatic API. +KubernetesJS is a JavaScript‑native Kubernetes toolkit that combines a fully‑typed client, CLIs, and opinionated ops tooling for cluster setup, operator management, and application deployment. It replaces brittle bash workflows with modern CLIs and a programmatic API. ## Core Principles -- **JavaScript-Native**: Use kubernetesjs directly instead of wrapping kubectl/helm +- **JavaScript‑Native**: Use `kubernetesjs` directly instead of wrapping kubectl/helm - **Configuration-Driven**: Simple YAML/JSON configs for setup and deployment - **Developer-Focused**: Optimized for development workflows - **Minimal Input**: Sensible defaults with override capabilities @@ -16,30 +16,37 @@ Interweb is a JavaScript-native Kubernetes developer toolkit that simplifies clu ### Project Structure ``` -interweb/ +kubernetesjs/ ├── packages/ -│ ├── cli/ # Main CLI package -│ ├── client/ # Kubernetes client wrapper -│ ├── interwebjs/ # Core library (from starshipjs) -│ ├── operators/ # Operator management -│ ├── config/ # Configuration management -│ └── templates/ # Deployment templates +│ ├── cli/ # Low‑level CLI for typed K8s ops +│ ├── ops-cli/ # Ops CLI (formerly interweb CLI) +│ ├── client/ # Higher‑level client wrapper +│ ├── ops/ # Ops library (formerly interwebjs) +│ ├── manifests/ # Curated operator manifests/bundles +│ └── kubernetesjs/ # Core fully‑typed K8s client (SDK) ├── docs/ ├── examples/ -└── templates/ # Project scaffolding +└── templates/ # Project scaffolding ``` ### Core Components -#### 1. CLI Package (`@interweb/cli`) +#### 1. CLI Package (`@kubernetesjs/cli`) - **Commands:** - - `interweb setup` - Initialize cluster with operators - - `interweb deploy` - Deploy applications - - `interweb status` - Cluster and app status - - `interweb destroy` - Cleanup resources - - `interweb scaffold` - Generate project templates + - Resource‑centric helpers around the typed client (e.g., inspect, diff, apply) + - Codegen utilities and developer ergonomics + - Focused on low‑level Kubernetes actions and DX -#### 2. Client Package (`@interweb/client`) +#### 2. Ops CLI (`@kubernetesjs/ops-cli`) +- **Purpose:** Higher‑level operational workflows (migrated from Interweb CLI) +- **Commands:** + - `kjs setup` – Initialize cluster with operators + - `kjs deploy` – Deploy applications + - `kjs status` – Cluster and app status + - `kjs destroy` – Cleanup resources + - `kjs scaffold` – Generate project templates + +#### 3. Client Package (`@kubernetesjs/client`) - **Purpose:** Enhanced kubernetesjs wrapper - **Features:** - Connection management @@ -48,16 +55,16 @@ interweb/ - Custom resource definitions - Helm-like templating -#### 3. InterwebJS Package (`@interweb/interwebjs`) -- **Purpose:** Core library (evolved from starshipjs) +#### 4. Ops Package (`@kubernetesjs/ops`) +- **Purpose:** Core ops library (migrated from InterwebJS) - **Features:** - Resource management - Deployment orchestration - Configuration validation - Template rendering -#### 4. Operators Package (`@interweb/operators`) -- **Purpose:** Operator lifecycle management +#### 5. Manifests Package (`@kubernetesjs/manifests`) +- **Purpose:** Curated operator and platform manifests - **Features:** - CloudNativePG management - Knative Serving setup @@ -65,19 +72,15 @@ interweb/ - Ingress controller setup - Monitoring stack deployment -#### 5. Config Package (`@interweb/config`) -- **Purpose:** Configuration management -- **Features:** - - Schema validation - - Environment interpolation - - Multi-environment support - - Secret management +#### 6. KubernetesJS SDK (`kubernetesjs`) +- **Purpose:** Fully‑typed core client and SDK +- **Features:** Typed API surface, discovery, watch, codegen ## Configuration Files -### 1. Cluster Setup Config (`interweb.setup.yaml`) +### 1. Cluster Setup Config (`kjs.setup.yaml`) ```yaml -apiVersion: interweb.dev/v1 +apiVersion: kjs.dev/v1 kind: ClusterSetup metadata: name: dev-cluster @@ -109,9 +112,9 @@ spec: domain: "127.0.0.1.nip.io" # Default for development ``` -### 2. Application Deploy Config (`interweb.deploy.yaml`) +### 2. Application Deploy Config (`kjs.deploy.yaml`) ```yaml -apiVersion: interweb.dev/v1 +apiVersion: kjs.dev/v1 kind: Application metadata: name: postgres-api-app @@ -265,14 +268,14 @@ spec: ## Migration Path from Current Scripts -### Current → Interweb Mapping +### Current → KubernetesJS (ops-cli) Mapping -| Current Script | Interweb Command | Configuration | +| Current Script | kjs Command | Configuration | |---|---|---| -| `00-setup-cluster.sh` | `interweb setup --infrastructure` | `interweb.setup.yaml` (infrastructure section) | -| `01-install-operators.sh` | `interweb setup --operators` | `interweb.setup.yaml` (operators section) | -| `02-deploy-postgres.sh` | `interweb deploy --database` | `interweb.deploy.yaml` (database section) | -| `03-deploy-knative-app.sh` | `interweb deploy --services` | `interweb.deploy.yaml` (services section) | +| `00-setup-cluster.sh` | `kjs setup --infrastructure` | `kjs.setup.yaml` (infrastructure section) | +| `01-install-operators.sh` | `kjs setup --operators` | `kjs.setup.yaml` (operators section) | +| `02-deploy-postgres.sh` | `kjs deploy --database` | `kjs.deploy.yaml` (database section) | +| `03-deploy-knative-app.sh` | `kjs deploy --services` | `kjs.deploy.yaml` (services section) | ### Migration Benefits 1. **Declarative**: Configuration over imperative scripts @@ -284,26 +287,14 @@ spec: ## Example Usage ```bash -# Initialize a new project -interweb init my-app - -# Setup cluster with operators -interweb setup - -# Deploy application -interweb deploy - -# Check status -interweb status - -# Scale service -interweb scale backend-api --min 2 --max 20 - -# View logs -interweb logs backend-api --follow - -# Destroy everything -interweb destroy --confirm +# Low-level typed client CLI +k8s get pods -n default + +# Ops CLI (higher-level workflows) +kjs setup +kjs deploy +kjs status +kjs destroy --confirm ``` ## Next Steps @@ -316,4 +307,4 @@ interweb destroy --confirm 6. **Testing**: Setup CI/CD and testing framework 7. **Documentation**: Usage guides and API documentation -This design provides a solid foundation for building Interweb as a modern, JavaScript-native alternative to your current bash scripts while maintaining the same functionality and improving developer experience. \ No newline at end of file +This design aligns the KubernetesJS monorepo around a clear split between the core typed client (SDK + `@kubernetesjs/cli`) and opinionated operational tooling (`@kubernetesjs/ops-cli`, `@kubernetesjs/ops`, and `@kubernetesjs/manifests`) for a better developer experience. diff --git a/interweb/k8s/Makefile b/interweb/k8s/Makefile deleted file mode 100644 index ea010fe..0000000 --- a/interweb/k8s/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -KUBECTL ?= kubectl -K8S_DIR ?= $(CURDIR) -CLIENT_DIR ?= $(abspath $(K8S_DIR)/../packages/client) - -.PHONY: setup install teardown uninstall check-crds - -setup: - pnpm --prefix $(CLIENT_DIR) run operators:setup - -teardown: - pnpm --prefix $(CLIENT_DIR) run operators:teardown - -install: - $(KUBECTL) apply -f $(K8S_DIR)/cnpg-cluster.yaml - $(KUBECTL) apply -f $(K8S_DIR)/minio-tenant.yaml - -uninstall: - $(KUBECTL) delete -f $(K8S_DIR)/minio-tenant.yaml --ignore-not-found - $(KUBECTL) delete -f $(K8S_DIR)/cnpg-cluster.yaml --ignore-not-found - pnpm --prefix $(CLIENT_DIR) run operators:teardown - -check-crds: - @echo "CloudNativePG CRDs" && \ - $(KUBECTL) get crd | grep postgresql.cnpg.io || echo "\t(none found)"; \ - echo ""; \ - echo "MinIO CRDs" && \ - $(KUBECTL) get crd tenants.minio.min.io 2>/dev/null || echo "\ttenants.minio.min.io not found" diff --git a/interweb/k8s/README.md b/interweb/k8s/README.md deleted file mode 100644 index fe53366..0000000 --- a/interweb/k8s/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# Interweb Data Plane Setup - -This folder now provides a Makefile-driven workflow for installing the Interweb data-plane operators and applying the core Kubernetes resources (CloudNativePG cluster + MinIO tenant) without relying on a Helm release. - -## Getting Started - -1. **Install the operators** (CloudNativePG & MinIO). This runs the client package script which installs supported operators via manifests and the MinIO operator via Helm: - -```shell -make -C k8s setup -``` - -2. **Apply the CNPG cluster and MinIO tenant manifests** from the `k8s/` folder: - -```shell -make -C k8s install -``` - -3. **Tear everything down** (tenant, cluster, operators) when finished: - -```shell -make -C k8s uninstall -``` - -## Makefile Shortcuts - -```shell -# Install operators (idempotent) -make -C k8s setup - -# Apply CNPG cluster + PgBouncer + MinIO tenant manifests -make -C k8s install - -# Remove manifests and uninstall operators -make -C k8s uninstall -``` - -## Manifests in `k8s/` - -- `cnpg-cluster.yaml` – creates the `postgres-db` namespace, credentials, a CloudNativePG `Cluster`, and a single-instance PgBouncer `Pooler` sized for local development. -- `minio-tenant.yaml` – creates the `minio` namespace, credentials secret, and a single-pool MinIO `Tenant` with 2 Gi of storage. - -These manifests assume the corresponding operators (CloudNativePG and MinIO) are already installed. Adjust storage classes, resource requests, and credentials before using outside of local clusters. - -## Notes - -- `make setup` delegates to `packages/client/scripts/setup-operators.ts`, which ensures the CloudNativePG operator is applied via manifests and installs the MinIO operator via Helm. -- Secrets included in the manifests (`postgres*` and `interweb-minio-creds`) contain development defaults—replace them or source from a secret manager for production environments. -- The legacy Helm chart files remain for reference but are no longer used in this workflow. - -## Credits - -🛠 Built by [Interweb](https://interweb.co) — if you like our tools, please checkout and contribute [https://interweb.co](https://interweb.co) diff --git a/interweb/k8s/cnpg-cluster.yaml b/interweb/k8s/cnpg-cluster.yaml deleted file mode 100644 index 458d4d0..0000000 --- a/interweb/k8s/cnpg-cluster.yaml +++ /dev/null @@ -1,131 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: postgres-db - labels: - app.interweb.dev/managed: "true" ---- -apiVersion: v1 -kind: Secret -metadata: - name: postgres-superuser - namespace: postgres-db - labels: - app.interweb.dev/managed: "true" - app.kubernetes.io/name: postgres-superuser - app.kubernetes.io/component: database -stringData: - username: postgres - password: postgres123! ---- -apiVersion: v1 -kind: Secret -metadata: - name: postgres-app-user - namespace: postgres-db - labels: - app.interweb.dev/managed: "true" - app.kubernetes.io/name: postgres-app-user - app.kubernetes.io/component: database -stringData: - username: appuser - password: appuser123! ---- -apiVersion: postgresql.cnpg.io/v1 -kind: Cluster -metadata: - name: postgres-cluster - namespace: postgres-db - labels: - app.interweb.dev/managed: "true" - app.kubernetes.io/name: postgres-cluster - app.kubernetes.io/component: database -spec: - instances: 1 - imageName: ghcr.io/cloudnative-pg/postgresql:16.4 - enablePDB: false - superuserSecret: - name: postgres-superuser - storage: - size: 2Gi - resources: - requests: - cpu: 50m - memory: 256Mi - limits: - cpu: 200m - memory: 512Mi - bootstrap: - initdb: - database: postgres - owner: postgres - encoding: UTF8 - localeCollate: en_US.UTF-8 - localeCType: en_US.UTF-8 - postInitSQL: - - "CREATE USER appuser WITH PASSWORD 'appuser123!' CREATEDB;" - - "GRANT CREATE ON DATABASE postgres TO appuser;" - - "CREATE SCHEMA IF NOT EXISTS public;" - - "GRANT ALL PRIVILEGES ON SCHEMA public TO appuser;" - monitoring: - enablePodMonitor: false - affinity: - enablePodAntiAffinity: true - topologyKey: kubernetes.io/hostname - podAntiAffinityType: preferred ---- -apiVersion: postgresql.cnpg.io/v1 -kind: Pooler -metadata: - name: postgres-pooler - namespace: postgres-db - labels: - app.interweb.dev/managed: "true" - app.kubernetes.io/name: postgres-pooler - app.kubernetes.io/component: connection-pooler -spec: - cluster: - name: postgres-cluster - instances: 1 - type: rw - pgbouncer: - poolMode: transaction - parameters: - default_pool_size: "10" - max_client_conn: "100" - max_db_connections: "10" - max_user_connections: "10" - server_reset_query: DISCARD ALL - log_connections: "1" - log_disconnections: "1" - log_pooler_errors: "1" - server_idle_timeout: "30" - client_idle_timeout: "60" - server_login_retry: "5" - query_timeout: "30" - ignore_startup_parameters: extra_float_digits - application_name_add_host: "1" - template: - metadata: - labels: - app.kubernetes.io/name: postgres-pooler - app.kubernetes.io/component: connection-pooler - spec: - containers: - - name: pgbouncer - resources: - requests: - cpu: 20m - memory: 32Mi - limits: - cpu: 100m - memory: 128Mi - affinity: - podAntiAffinity: - preferredDuringSchedulingIgnoredDuringExecution: - - weight: 100 - podAffinityTerm: - labelSelector: - matchLabels: - cnpg.io/poolerName: postgres-pooler - topologyKey: kubernetes.io/hostname diff --git a/interweb/k8s/minio-tenant.yaml b/interweb/k8s/minio-tenant.yaml deleted file mode 100644 index 96b3c79..0000000 --- a/interweb/k8s/minio-tenant.yaml +++ /dev/null @@ -1,61 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: minio - labels: - app.interweb.dev/managed: "true" ---- -apiVersion: v1 -kind: Secret -metadata: - name: interweb-minio-creds - namespace: minio - labels: - app.interweb.dev/managed: "true" - app.kubernetes.io/name: interweb-minio-creds - app.kubernetes.io/component: object-storage-credentials -stringData: - accesskey: minioadmin - secretkey: minioadmin ---- -apiVersion: minio.min.io/v2 -kind: Tenant -metadata: - name: interweb-tenant - namespace: minio - labels: - app.interweb.dev/managed: "true" - app.kubernetes.io/name: interweb-tenant - app.kubernetes.io/component: object-storage -spec: - credsSecret: - name: interweb-minio-creds - image: quay.io/minio/minio:RELEASE.2024-08-17T00-00-00Z - imagePullPolicy: IfNotPresent - exposeServices: - minio: true - console: true - requestAutoCert: false - pools: - - name: pool-0 - servers: 1 - volumesPerServer: 1 - volumeClaimTemplate: - metadata: - name: data - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 2Gi - resources: - requests: - cpu: 100m - memory: 128Mi - limits: - cpu: 300m - memory: 256Mi - buckets: - - name: interweb-app - region: us-east-1 diff --git a/lerna.json b/lerna.json index 51e0479..5ec017c 100644 --- a/lerna.json +++ b/lerna.json @@ -1,24 +1,11 @@ { - "lerna": "6", - "conventionalCommits": true, - "npmClient": "yarn", - "npmClientArgs": [ - "--no-lockfile" - ], - "packages": [ - "packages/*" - ], + "$schema": "node_modules/lerna/schemas/lerna-schema.json", "version": "independent", - "registry": "https://registry.npmjs.org", + "npmClient": "pnpm", "command": { - "create": { - "homepage": "https://github.com/hyperweb-io/kubernetesjs", - "license": "SEE LICENSE IN LICENSE", - "access": "restricted" - }, "publish": { - "allowBranch": "main", + "conventionalCommits": true, "message": "chore(release): publish" } } -} \ No newline at end of file +} diff --git a/package.json b/package.json index bc0d98c..a823060 100644 --- a/package.json +++ b/package.json @@ -11,16 +11,15 @@ "publishConfig": { "access": "restricted" }, + "packageManager": "pnpm@10.20.0", "workspaces": [ "packages/*" ], "scripts": { - "clean": "lerna run clean", - "build": "lerna run build --stream", - "build:dev": "lerna run build:dev --stream; yarn symlink", - "lint": "lerna run lint --parallel", - "symlink": "symlink-workspace --logLevel error", - "postinstall": "yarn symlink" + "clean": "pnpm -r clean", + "build": "pnpm -r build", + "build:dev": "pnpm -r build:dev", + "lint": "pnpm -r lint" }, "devDependencies": { "@types/jest": "^29.5.11", @@ -28,18 +27,17 @@ "@typescript-eslint/eslint-plugin": "^7.10.0", "@typescript-eslint/parser": "^7.10.0", "copyfiles": "^2.4.1", + "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-simple-import-sort": "^12.1.0", "eslint-plugin-unused-imports": "^4.0.0", - "eslint": "^8.56.0", "jest": "^29.6.2", - "lerna": "^6", + "lerna": "^8.2.3", "prettier": "^3.0.2", "rimraf": "4.4.1", "strip-ansi": "^6", - "symlink-workspace": "^1.9.0", "ts-jest": "^29.1.1", "ts-node": "^10.9.2", "typescript": "^5.1.6" } -} \ No newline at end of file +} diff --git a/packages/cli/package.json b/packages/cli/package.json index b6319f9..39cf21f 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -56,7 +56,7 @@ "deepmerge": "^4.3.1", "inquirerer": "^2.0.8", "js-yaml": "^4.1.0", - "kubernetesjs": "^0.7.3", + "kubernetesjs": "workspace:^", "minimist": "^1.2.8" } } diff --git a/packages/react/package.json b/packages/react/package.json index 5a7de8d..83f00e8 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -51,7 +51,7 @@ }, "dependencies": { "@tanstack/react-query": "5.79.2", - "kubernetesjs": "^0.7.3", + "kubernetesjs": "workspace:^", "react": "^18.2.0" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..8911bbf --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,7310 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@types/jest': + specifier: ^29.5.11 + version: 29.5.14 + '@types/node': + specifier: ^20.12.7 + version: 20.19.24 + '@typescript-eslint/eslint-plugin': + specifier: ^7.10.0 + version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/parser': + specifier: ^7.10.0 + version: 7.18.0(eslint@8.57.1)(typescript@5.9.3) + copyfiles: + specifier: ^2.4.1 + version: 2.4.1 + eslint: + specifier: ^8.56.0 + version: 8.57.1 + eslint-config-prettier: + specifier: ^9.1.0 + version: 9.1.2(eslint@8.57.1) + eslint-plugin-simple-import-sort: + specifier: ^12.1.0 + version: 12.1.1(eslint@8.57.1) + eslint-plugin-unused-imports: + specifier: ^4.0.0 + version: 4.3.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1) + jest: + specifier: ^29.6.2 + version: 29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3)) + lerna: + specifier: ^8.2.3 + version: 8.2.4(@types/node@20.19.24)(encoding@0.1.13) + prettier: + specifier: ^3.0.2 + version: 3.6.2 + rimraf: + specifier: 4.4.1 + version: 4.4.1 + strip-ansi: + specifier: ^6 + version: 6.0.1 + ts-jest: + specifier: ^29.1.1 + version: 29.4.5(@babel/core@7.28.5)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.5))(jest-util@29.7.0)(jest@29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3)))(typescript@5.9.3) + ts-node: + specifier: ^10.9.2 + version: 10.9.2(@types/node@20.19.24)(typescript@5.9.3) + typescript: + specifier: ^5.1.6 + version: 5.9.3 + + packages/cli: + dependencies: + chalk: + specifier: ^4.1.0 + version: 4.1.2 + deepmerge: + specifier: ^4.3.1 + version: 4.3.1 + inquirerer: + specifier: ^2.0.8 + version: 2.0.8 + js-yaml: + specifier: ^4.1.0 + version: 4.1.0 + kubernetesjs: + specifier: workspace:^ + version: link:../kubernetesjs/dist + minimist: + specifier: ^1.2.8 + version: 1.2.8 + devDependencies: + '@types/js-yaml': + specifier: ^4.0.9 + version: 4.0.9 + publishDirectory: dist + + packages/kubernetesjs: + devDependencies: + schema-sdk: + specifier: ^0.12.0 + version: 0.12.0(encoding@0.1.13) + publishDirectory: dist + + packages/react: + dependencies: + '@tanstack/react-query': + specifier: 5.79.2 + version: 5.79.2(react@18.3.1) + kubernetesjs: + specifier: workspace:^ + version: link:../kubernetesjs/dist + react: + specifier: ^18.2.0 + version: 18.3.1 + devDependencies: + '@types/react': + specifier: ^18.2.77 + version: 18.3.26 + schema-sdk: + specifier: ^0.12.0 + version: 0.12.0(encoding@0.1.13) + publishDirectory: dist + +packages: + + '@babel/code-frame@7.27.1': + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.28.5': + resolution: {integrity: sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.28.5': + resolution: {integrity: sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.28.5': + resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.27.2': + resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.27.1': + resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.3': + resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-plugin-utils@7.27.1': + resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.28.4': + resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.28.5': + resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-syntax-async-generators@7.8.4': + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-bigint@7.8.3': + resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-properties@7.12.13': + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-static-block@7.14.5': + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-attributes@7.27.1': + resolution: {integrity: sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-meta@7.10.4': + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-json-strings@7.8.3': + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-jsx@7.27.1': + resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4': + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3': + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-numeric-separator@7.10.4': + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-object-rest-spread@7.8.3': + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3': + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-chaining@7.8.3': + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-private-property-in-object@7.14.5': + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-top-level-await@7.14.5': + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.27.1': + resolution: {integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/template@7.27.2': + resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.28.5': + resolution: {integrity: sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.28.5': + resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} + engines: {node: '>=6.9.0'} + + '@bcoe/v8-coverage@0.2.3': + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + + '@emnapi/core@1.7.0': + resolution: {integrity: sha512-pJdKGq/1iquWYtv1RRSljZklxHCOCAJFJrImO5ZLKPJVJlVUcs8yFwNQlqS0Lo8xT1VAXXTCZocF9n26FWEKsw==} + + '@emnapi/runtime@1.7.0': + resolution: {integrity: sha512-oAYoQnCYaQZKVS53Fq23ceWMRxq5EhQsE0x0RdQ55jT7wagMu5k+fS39v1fiSLrtrLQlXwVINenqhLMtTrV/1Q==} + + '@emnapi/wasi-threads@1.1.0': + resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} + + '@eslint-community/eslint-utils@4.9.0': + resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/eslintrc@2.1.4': + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@eslint/js@8.57.1': + resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@humanwhocodes/config-array@0.13.0': + resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} + engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/object-schema@2.0.3': + resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + deprecated: Use @eslint/object-schema instead + + '@hutson/parse-repository-url@3.0.2': + resolution: {integrity: sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==} + engines: {node: '>=6.9.0'} + + '@inquirer/external-editor@1.0.2': + resolution: {integrity: sha512-yy9cOoBnx58TlsPrIxauKIFQTiyH+0MK4e97y4sV9ERbI+zDxw7i2hxHLCIEGIE/8PPvDxGhgzIOTSOWcs6/MQ==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@interweb-utils/casing@0.2.0': + resolution: {integrity: sha512-ORQySrHzMYmtVRkYvtE1HGa8QnoqYPhu5UWQyv9302D/ZZe0Ae6cpk4NH1xEXgHeFq/CraiOcnLhmc3h7wdNHg==} + + '@interweb/fetch-api-client@0.6.1': + resolution: {integrity: sha512-+QfJrK8c+uGhnIkGaoLeyuL7NuLbNgH8AeZwVkGqtOr9/hkrYMJQN+Jnw06TJeeuM12R8QZgM/0M8bpdG8KnlQ==} + + '@interweb/http-errors@0.1.1': + resolution: {integrity: sha512-JEwL0a8ixMT1WQwx4YNEHLiFrB/7QKxMU2j/HxycdS1BIfZxWVLggdmONHENdmsVPOuaxUJduGmhzFVidOL0IA==} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@isaacs/string-locale-compare@1.1.0': + resolution: {integrity: sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ==} + + '@istanbuljs/load-nyc-config@1.1.0': + resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} + engines: {node: '>=8'} + + '@istanbuljs/schema@0.1.3': + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + + '@jest/console@29.7.0': + resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/core@29.7.0': + resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + '@jest/environment@29.7.0': + resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/expect-utils@29.7.0': + resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/expect@29.7.0': + resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/fake-timers@29.7.0': + resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/globals@29.7.0': + resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/reporters@29.7.0': + resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/source-map@29.6.3': + resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/test-result@29.7.0': + resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/test-sequencer@29.7.0': + resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/transform@29.7.0': + resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/types@29.6.3': + resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + + '@lerna/create@8.2.4': + resolution: {integrity: sha512-A8AlzetnS2WIuhijdAzKUyFpR5YbLLfV3luQ4lzBgIBgRfuoBDZeF+RSZPhra+7A6/zTUlrbhKZIOi/MNhqgvQ==} + engines: {node: '>=18.0.0'} + + '@napi-rs/wasm-runtime@0.2.4': + resolution: {integrity: sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@npmcli/agent@2.2.2': + resolution: {integrity: sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@npmcli/arborist@7.5.4': + resolution: {integrity: sha512-nWtIc6QwwoUORCRNzKx4ypHqCk3drI+5aeYdMTQQiRCcn4lOOgfQh7WyZobGYTxXPSq1VwV53lkpN/BRlRk08g==} + engines: {node: ^16.14.0 || >=18.0.0} + hasBin: true + + '@npmcli/fs@3.1.1': + resolution: {integrity: sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@npmcli/git@5.0.8': + resolution: {integrity: sha512-liASfw5cqhjNW9UFd+ruwwdEf/lbOAQjLL2XY2dFW/bkJheXDYZgOyul/4gVvEV4BWkTXjYGmDqMw9uegdbJNQ==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@npmcli/installed-package-contents@2.1.0': + resolution: {integrity: sha512-c8UuGLeZpm69BryRykLuKRyKFZYJsZSCT4aVY5ds4omyZqJ172ApzgfKJ5eV/r3HgLdUYgFVe54KSFVjKoe27w==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + + '@npmcli/map-workspaces@3.0.6': + resolution: {integrity: sha512-tkYs0OYnzQm6iIRdfy+LcLBjcKuQCeE5YLb8KnrIlutJfheNaPvPpgoFEyEFgbjzl5PLZ3IA/BWAwRU0eHuQDA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@npmcli/metavuln-calculator@7.1.1': + resolution: {integrity: sha512-Nkxf96V0lAx3HCpVda7Vw4P23RILgdi/5K1fmj2tZkWIYLpXAN8k2UVVOsW16TsS5F8Ws2I7Cm+PU1/rsVF47g==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@npmcli/name-from-folder@2.0.0': + resolution: {integrity: sha512-pwK+BfEBZJbKdNYpHHRTNBwBoqrN/iIMO0AiGvYsp3Hoaq0WbgGSWQR6SCldZovoDpY3yje5lkFUe6gsDgJ2vg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@npmcli/node-gyp@3.0.0': + resolution: {integrity: sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@npmcli/package-json@5.2.0': + resolution: {integrity: sha512-qe/kiqqkW0AGtvBjL8TJKZk/eBBSpnJkUWvHdQ9jM2lKHXRYYJuyNpJPlJw3c8QjC2ow6NZYiLExhUaeJelbxQ==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@npmcli/promise-spawn@7.0.2': + resolution: {integrity: sha512-xhfYPXoV5Dy4UkY0D+v2KkwvnDfiA/8Mt3sWCGI/hM03NsYIH8ZaG6QzS9x7pje5vHZBZJ2v6VRFVTWACnqcmQ==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@npmcli/query@3.1.0': + resolution: {integrity: sha512-C/iR0tk7KSKGldibYIB9x8GtO/0Bd0I2mhOaDb8ucQL/bQVTmGoeREaFj64Z5+iCBRf3dQfed0CjJL7I8iTkiQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@npmcli/redact@2.0.1': + resolution: {integrity: sha512-YgsR5jCQZhVmTJvjduTOIHph0L73pK8xwMVaDY0PatySqVM9AZj93jpoXYSJqfHFxFkN9dmqTw6OiqExsS3LPw==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@npmcli/run-script@8.1.0': + resolution: {integrity: sha512-y7efHHwghQfk28G2z3tlZ67pLG0XdfYbcVG26r7YIXALRsrVQcTq4/tdenSmdOrEsNahIYA/eh8aEVROWGFUDg==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@nx/devkit@20.8.2': + resolution: {integrity: sha512-rr9p2/tZDQivIpuBUpZaFBK6bZ+b5SAjZk75V4tbCUqGW3+5OPuVvBPm+X+7PYwUF6rwSpewxkjWNeGskfCe+Q==} + peerDependencies: + nx: '>= 19 <= 21' + + '@nx/nx-darwin-arm64@20.8.2': + resolution: {integrity: sha512-t+bmCn6sRPNGU6hnSyWNvbQYA/KgsxGZKYlaCLRwkNhI2akModcBUqtktJzCKd1XHDqs6EkEFBWjFr8/kBEkSg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@nx/nx-darwin-x64@20.8.2': + resolution: {integrity: sha512-pt/wmDLM31Es8/EzazlyT5U+ou2l60rfMNFGCLqleHEQ0JUTc0KWnOciBLbHIQFiPsCQZJFEKyfV5V/ncePmmw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@nx/nx-freebsd-x64@20.8.2': + resolution: {integrity: sha512-joZxFbgJfkHkB9uMIJr73Gpnm9pnpvr0XKGbWC409/d2x7q1qK77tKdyhGm+A3+kaZFwstNVPmCUtUwJYyU6LA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] + + '@nx/nx-linux-arm-gnueabihf@20.8.2': + resolution: {integrity: sha512-98O/qsxn4vIMPY/FyzvmVrl7C5yFhCUVk0/4PF+PA2SvtQ051L1eMRY6bq/lb69qfN6szJPZ41PG5mPx0NeLZw==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + + '@nx/nx-linux-arm64-gnu@20.8.2': + resolution: {integrity: sha512-h6a+HxwfSpxsi4KpxGgPh9GDBmD2E+XqGCdfYpobabxqEBvlnIlJyuDhlRR06cTWpuNXHpRdrVogmV6m/YbtDg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@nx/nx-linux-arm64-musl@20.8.2': + resolution: {integrity: sha512-4Ev+jM0VAxDHV/dFgMXjQTCXS4I8W4oMe7FSkXpG8RUn6JK659DC8ExIDPoGIh+Cyqq6r6mw1CSia+ciQWICWQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@nx/nx-linux-x64-gnu@20.8.2': + resolution: {integrity: sha512-nR0ev+wxu+nQYRd7bhqggOxK7UfkV6h+Ko1mumUFyrM5GvPpz/ELhjJFSnMcOkOMcvH0b6G5uTBJvN1XWCkbmg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@nx/nx-linux-x64-musl@20.8.2': + resolution: {integrity: sha512-ost41l5yc2aq2Gc9bMMpaPi/jkXqbXEMEPHrxWKuKmaek3K2zbVDQzvBBNcQKxf/mlCsrqN4QO0mKYSRRqag5A==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@nx/nx-win32-arm64-msvc@20.8.2': + resolution: {integrity: sha512-0SEOqT/daBG5WtM9vOGilrYaAuf1tiALdrFavY62+/arXYxXemUKmRI5qoKDTnvoLMBGkJs6kxhMO5b7aUXIvQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@nx/nx-win32-x64-msvc@20.8.2': + resolution: {integrity: sha512-iIsY+tVqes/NOqTbJmggL9Juie/iaDYlWgXA9IUv88FE9thqWKhVj4/tCcPjsOwzD+1SVna3YISEEFsx5UV4ew==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@octokit/auth-token@4.0.0': + resolution: {integrity: sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==} + engines: {node: '>= 18'} + + '@octokit/core@5.2.2': + resolution: {integrity: sha512-/g2d4sW9nUDJOMz3mabVQvOGhVa4e/BN/Um7yca9Bb2XTzPPnfTWHWQg+IsEYO7M3Vx+EXvaM/I2pJWIMun1bg==} + engines: {node: '>= 18'} + + '@octokit/endpoint@9.0.6': + resolution: {integrity: sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==} + engines: {node: '>= 18'} + + '@octokit/graphql@7.1.1': + resolution: {integrity: sha512-3mkDltSfcDUoa176nlGoA32RGjeWjl3K7F/BwHwRMJUW/IteSa4bnSV8p2ThNkcIcZU2umkZWxwETSSCJf2Q7g==} + engines: {node: '>= 18'} + + '@octokit/openapi-types@24.2.0': + resolution: {integrity: sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==} + + '@octokit/plugin-enterprise-rest@6.0.1': + resolution: {integrity: sha512-93uGjlhUD+iNg1iWhUENAtJata6w5nE+V4urXOAlIXdco6xNZtUSfYY8dzp3Udy74aqO/B5UZL80x/YMa5PKRw==} + + '@octokit/plugin-paginate-rest@11.4.4-cjs.2': + resolution: {integrity: sha512-2dK6z8fhs8lla5PaOTgqfCGBxgAv/le+EhPs27KklPhm1bKObpu6lXzwfUEQ16ajXzqNrKMujsFyo9K2eaoISw==} + engines: {node: '>= 18'} + peerDependencies: + '@octokit/core': '5' + + '@octokit/plugin-request-log@4.0.1': + resolution: {integrity: sha512-GihNqNpGHorUrO7Qa9JbAl0dbLnqJVrV8OXe2Zm5/Y4wFkZQDfTreBzVmiRfJVfE4mClXdihHnbpyyO9FSX4HA==} + engines: {node: '>= 18'} + peerDependencies: + '@octokit/core': '5' + + '@octokit/plugin-rest-endpoint-methods@13.3.2-cjs.1': + resolution: {integrity: sha512-VUjIjOOvF2oELQmiFpWA1aOPdawpyaCUqcEBc/UOUnj3Xp6DJGrJ1+bjUIIDzdHjnFNO6q57ODMfdEZnoBkCwQ==} + engines: {node: '>= 18'} + peerDependencies: + '@octokit/core': ^5 + + '@octokit/request-error@5.1.1': + resolution: {integrity: sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==} + engines: {node: '>= 18'} + + '@octokit/request@8.4.1': + resolution: {integrity: sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==} + engines: {node: '>= 18'} + + '@octokit/rest@20.1.2': + resolution: {integrity: sha512-GmYiltypkHHtihFwPRxlaorG5R9VAHuk/vbszVoRTGXnAsY60wYLkh/E2XiFmdZmqrisw+9FaazS1i5SbdWYgA==} + engines: {node: '>= 18'} + + '@octokit/types@13.10.0': + resolution: {integrity: sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@sigstore/bundle@2.3.2': + resolution: {integrity: sha512-wueKWDk70QixNLB363yHc2D2ItTgYiMTdPwK8D9dKQMR3ZQ0c35IxP5xnwQ8cNLoCgCRcHf14kE+CLIvNX1zmA==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@sigstore/core@1.1.0': + resolution: {integrity: sha512-JzBqdVIyqm2FRQCulY6nbQzMpJJpSiJ8XXWMhtOX9eKgaXXpfNOF53lzQEjIydlStnd/eFtuC1dW4VYdD93oRg==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@sigstore/protobuf-specs@0.3.3': + resolution: {integrity: sha512-RpacQhBlwpBWd7KEJsRKcBQalbV28fvkxwTOJIqhIuDysMMaJW47V4OqW30iJB9uRpqOSxxEAQFdr8tTattReQ==} + engines: {node: ^18.17.0 || >=20.5.0} + + '@sigstore/sign@2.3.2': + resolution: {integrity: sha512-5Vz5dPVuunIIvC5vBb0APwo7qKA4G9yM48kPWJT+OEERs40md5GoUR1yedwpekWZ4m0Hhw44m6zU+ObsON+iDA==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@sigstore/tuf@2.3.4': + resolution: {integrity: sha512-44vtsveTPUpqhm9NCrbU8CWLe3Vck2HO1PNLw7RIajbB7xhtn5RBPm1VNSCMwqGYHhDsBJG8gDF0q4lgydsJvw==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@sigstore/verify@1.2.1': + resolution: {integrity: sha512-8iKx79/F73DKbGfRf7+t4dqrc0bRr0thdPrxAtCKWRm/F0tG71i6O1rvlnScncJLLBZHn3h8M3c1BSUAb9yu8g==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@sinclair/typebox@0.27.8': + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + + '@sinonjs/commons@3.0.1': + resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} + + '@sinonjs/fake-timers@10.3.0': + resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + + '@tanstack/query-core@5.79.2': + resolution: {integrity: sha512-kr+KQrBuqd6495eP9S41BoftFI1H50XA9O+6FmbnTx/Te6bjiq1mj8rt9rJjW3YZSO2aaUNUres0TWesJW1j1g==} + + '@tanstack/react-query@5.79.2': + resolution: {integrity: sha512-kadeprsH6bWuhHCpqukXHRykJkxcLBxAaF0cQ05yawPmLZ/KiCpR1DyQenonF7A/70rnRUxhJD0RJejqk9wImQ==} + peerDependencies: + react: ^18 || ^19 + + '@tsconfig/node10@1.0.11': + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + + '@tufjs/canonical-json@2.0.0': + resolution: {integrity: sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@tufjs/models@2.0.1': + resolution: {integrity: sha512-92F7/SFyufn4DXsha9+QfKnN03JGqtMFMXgSHbZOo8JG59WkTni7UzAouNQDf7AuP9OAMxVOPQcqG3sB7w+kkg==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@tybys/wasm-util@0.9.0': + resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.28.0': + resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + + '@types/graceful-fs@4.1.9': + resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} + + '@types/istanbul-lib-coverage@2.0.6': + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + + '@types/istanbul-lib-report@3.0.3': + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + + '@types/istanbul-reports@3.0.4': + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + + '@types/jest@29.5.14': + resolution: {integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==} + + '@types/js-yaml@4.0.9': + resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} + + '@types/minimatch@3.0.5': + resolution: {integrity: sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==} + + '@types/minimist@1.2.5': + resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} + + '@types/node@20.19.24': + resolution: {integrity: sha512-FE5u0ezmi6y9OZEzlJfg37mqqf6ZDSF2V/NLjUyGrR9uTZ7Sb9F7bLNZ03S4XVUNRWGA7Ck4c1kK+YnuWjl+DA==} + + '@types/normalize-package-data@2.4.4': + resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + + '@types/prop-types@15.7.15': + resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} + + '@types/react@18.3.26': + resolution: {integrity: sha512-RFA/bURkcKzx/X9oumPG9Vp3D3JUgus/d0b67KB0t5S/raciymilkOa66olh78MUI92QLbEJevO7rvqU/kjwKA==} + + '@types/stack-utils@2.0.3': + resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + + '@types/yargs-parser@21.0.3': + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + + '@types/yargs@17.0.34': + resolution: {integrity: sha512-KExbHVa92aJpw9WDQvzBaGVE2/Pz+pLZQloT2hjL8IqsZnV62rlPOYvNnLmf/L2dyllfVUOVBj64M0z/46eR2A==} + + '@typescript-eslint/eslint-plugin@7.18.0': + resolution: {integrity: sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + '@typescript-eslint/parser': ^7.0.0 + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/parser@7.18.0': + resolution: {integrity: sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/scope-manager@7.18.0': + resolution: {integrity: sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==} + engines: {node: ^18.18.0 || >=20.0.0} + + '@typescript-eslint/type-utils@7.18.0': + resolution: {integrity: sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/types@7.18.0': + resolution: {integrity: sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==} + engines: {node: ^18.18.0 || >=20.0.0} + + '@typescript-eslint/typescript-estree@7.18.0': + resolution: {integrity: sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/utils@7.18.0': + resolution: {integrity: sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + + '@typescript-eslint/visitor-keys@7.18.0': + resolution: {integrity: sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==} + engines: {node: ^18.18.0 || >=20.0.0} + + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + + '@yarnpkg/lockfile@1.1.0': + resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==} + + '@yarnpkg/parsers@3.0.2': + resolution: {integrity: sha512-/HcYgtUSiJiot/XWGLOlGxPYUG65+/31V8oqk17vZLW1xlCoR4PampyePljOxY2n8/3jz9+tIFzICsyGujJZoA==} + engines: {node: '>=18.12.0'} + + '@zkochan/js-yaml@0.0.7': + resolution: {integrity: sha512-nrUSn7hzt7J6JWgWGz78ZYI8wj+gdIJdk0Ynjpp8l+trkn58Uqsf6RYrYkEK+3X18EX+TNdtJI0WxAtc+L84SQ==} + hasBin: true + + JSONStream@1.3.5: + resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} + hasBin: true + + abbrev@2.0.0: + resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn-walk@8.3.4: + resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} + engines: {node: '>=0.4.0'} + + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + engines: {node: '>=0.4.0'} + hasBin: true + + add-stream@1.0.0: + resolution: {integrity: sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==} + + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + engines: {node: '>= 14'} + + aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + aproba@2.0.0: + resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} + + arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + array-differ@3.0.0: + resolution: {integrity: sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==} + engines: {node: '>=8'} + + array-ify@1.0.0: + resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + arrify@1.0.1: + resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} + engines: {node: '>=0.10.0'} + + arrify@2.0.1: + resolution: {integrity: sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==} + engines: {node: '>=8'} + + async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + axios@1.13.2: + resolution: {integrity: sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==} + + babel-jest@29.7.0: + resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.8.0 + + babel-plugin-istanbul@6.1.1: + resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} + engines: {node: '>=8'} + + babel-plugin-jest-hoist@29.6.3: + resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + babel-preset-current-node-syntax@1.2.0: + resolution: {integrity: sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==} + peerDependencies: + '@babel/core': ^7.0.0 || ^8.0.0-0 + + babel-preset-jest@29.6.3: + resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.0.0 + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + baseline-browser-mapping@2.8.25: + resolution: {integrity: sha512-2NovHVesVF5TXefsGX1yzx1xgr7+m9JQenvz6FQY3qd+YXkKkYiv+vTCc7OriP9mcDZpTC5mAOYN4ocd29+erA==} + hasBin: true + + before-after-hook@2.2.3: + resolution: {integrity: sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==} + + bin-links@4.0.4: + resolution: {integrity: sha512-cMtq4W5ZsEwcutJrVId+a/tjt8GSbS+h0oNkdl6+6rBuEv8Ot33Bevj5KPm40t309zuhVic8NjpuL42QCiJWWA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + + brace-expansion@2.0.2: + resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.27.0: + resolution: {integrity: sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + bs-logger@0.2.6: + resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} + engines: {node: '>= 6'} + + bser@2.1.1: + resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + + byte-size@8.1.1: + resolution: {integrity: sha512-tUkzZWK0M/qdoLEqikxBWe4kumyuwjl3HO6zHTr4yEI23EojPtLYXdG1+AQY7MN0cGyNDvEaJ8wiYQm6P2bPxg==} + engines: {node: '>=12.17'} + + cacache@18.0.4: + resolution: {integrity: sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==} + engines: {node: ^16.14.0 || >=18.0.0} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camelcase-keys@6.2.2: + resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==} + engines: {node: '>=8'} + + camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + + caniuse-lite@1.0.30001754: + resolution: {integrity: sha512-x6OeBXueoAceOmotzx3PO4Zpt4rzpeIFsSr6AAePTZxSkXiYDUmpypEl7e2+8NCd9bD7bXjqyef8CJYPC1jfxg==} + + chalk@4.1.0: + resolution: {integrity: sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==} + engines: {node: '>=10'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + + chardet@2.1.1: + resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} + + chownr@2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} + + ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + + ci-info@4.3.1: + resolution: {integrity: sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==} + engines: {node: '>=8'} + + cjs-module-lexer@1.4.3: + resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} + + clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + + cli-cursor@3.1.0: + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} + engines: {node: '>=8'} + + cli-spinners@2.6.1: + resolution: {integrity: sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==} + engines: {node: '>=6'} + + cli-spinners@2.9.2: + resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} + engines: {node: '>=6'} + + cli-width@3.0.0: + resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} + engines: {node: '>= 10'} + + cliui@7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + clone-deep@4.0.1: + resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} + engines: {node: '>=6'} + + clone@1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} + + cmd-shim@6.0.3: + resolution: {integrity: sha512-FMabTRlc5t5zjdenF6mS0MBeFZm0XqHqeOkcskKFb/LYCcRQ5fVgLOHVc4Lq9CqABd9zhjwPjMBCJvMCziSVtA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + co@4.6.0: + resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + + collect-v8-coverage@1.0.3: + resolution: {integrity: sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + color-support@1.1.3: + resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} + hasBin: true + + columnify@1.6.0: + resolution: {integrity: sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q==} + engines: {node: '>=8.0.0'} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + common-ancestor-path@1.0.1: + resolution: {integrity: sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==} + + compare-func@2.0.0: + resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + concat-stream@2.0.0: + resolution: {integrity: sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==} + engines: {'0': node >= 6.0} + + console-control-strings@1.1.0: + resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} + + conventional-changelog-angular@7.0.0: + resolution: {integrity: sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==} + engines: {node: '>=16'} + + conventional-changelog-core@5.0.1: + resolution: {integrity: sha512-Rvi5pH+LvgsqGwZPZ3Cq/tz4ty7mjijhr3qR4m9IBXNbxGGYgTVVO+duXzz9aArmHxFtwZ+LRkrNIMDQzgoY4A==} + engines: {node: '>=14'} + + conventional-changelog-preset-loader@3.0.0: + resolution: {integrity: sha512-qy9XbdSLmVnwnvzEisjxdDiLA4OmV3o8db+Zdg4WiFw14fP3B6XNz98X0swPPpkTd/pc1K7+adKgEDM1JCUMiA==} + engines: {node: '>=14'} + + conventional-changelog-writer@6.0.1: + resolution: {integrity: sha512-359t9aHorPw+U+nHzUXHS5ZnPBOizRxfQsWT5ZDHBfvfxQOAik+yfuhKXG66CN5LEWPpMNnIMHUTCKeYNprvHQ==} + engines: {node: '>=14'} + hasBin: true + + conventional-commits-filter@3.0.0: + resolution: {integrity: sha512-1ymej8b5LouPx9Ox0Dw/qAO2dVdfpRFq28e5Y0jJEU8ZrLdy0vOSkkIInwmxErFGhg6SALro60ZrwYFVTUDo4Q==} + engines: {node: '>=14'} + + conventional-commits-parser@4.0.0: + resolution: {integrity: sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==} + engines: {node: '>=14'} + hasBin: true + + conventional-recommended-bump@7.0.1: + resolution: {integrity: sha512-Ft79FF4SlOFvX4PkwFDRnaNiIVX7YbmqGU0RwccUaiGvgp3S0a8ipR2/Qxk31vclDNM+GSdJOVs2KrsUCjblVA==} + engines: {node: '>=14'} + hasBin: true + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + copyfiles@2.4.1: + resolution: {integrity: sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg==} + hasBin: true + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + cosmiconfig@9.0.0: + resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + + create-jest@29.7.0: + resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + + create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + dargs@7.0.0: + resolution: {integrity: sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==} + engines: {node: '>=8'} + + dateformat@3.0.3: + resolution: {integrity: sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decamelize-keys@1.1.1: + resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} + engines: {node: '>=0.10.0'} + + decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + + dedent@1.5.3: + resolution: {integrity: sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + + dedent@1.7.0: + resolution: {integrity: sha512-HGFtf8yhuhGhqO07SV79tRp+br4MnbdjeVxotpn1QBl30pcLLCQjX5b2295ll0fv8RKDKsmWYrl05usHM9CewQ==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + defaults@1.0.4: + resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + + define-lazy-prop@2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + deprecation@2.3.1: + resolution: {integrity: sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==} + + detect-indent@5.0.0: + resolution: {integrity: sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g==} + engines: {node: '>=4'} + + detect-newline@3.1.0: + resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} + engines: {node: '>=8'} + + diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + + dot-prop@5.3.0: + resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} + engines: {node: '>=8'} + + dotenv-expand@11.0.7: + resolution: {integrity: sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==} + engines: {node: '>=12'} + + dotenv@16.4.7: + resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} + engines: {node: '>=12'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + ejs@3.1.10: + resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} + engines: {node: '>=0.10.0'} + hasBin: true + + electron-to-chromium@1.5.249: + resolution: {integrity: sha512-5vcfL3BBe++qZ5kuFhD/p8WOM1N9m3nwvJPULJx+4xf2usSlZFJ0qoNYO2fOX4hi3ocuDcmDobtA+5SFr4OmBg==} + + emittery@0.13.1: + resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} + engines: {node: '>=12'} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + encoding@0.1.13: + resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} + + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + + enquirer@2.3.6: + resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} + engines: {node: '>=8.6'} + + env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + + envinfo@7.13.0: + resolution: {integrity: sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==} + engines: {node: '>=4'} + hasBin: true + + err-code@2.0.3: + resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} + + error-ex@1.3.4: + resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-config-prettier@9.1.2: + resolution: {integrity: sha512-iI1f+D2ViGn+uvv5HuHVUamg8ll4tN+JRHGc6IJi4TP9Kl976C57fzPXgseXNs8v0iA8aSJpHsTWjDb9QJamGQ==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + + eslint-plugin-simple-import-sort@12.1.1: + resolution: {integrity: sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA==} + peerDependencies: + eslint: '>=5.0.0' + + eslint-plugin-unused-imports@4.3.0: + resolution: {integrity: sha512-ZFBmXMGBYfHttdRtOG9nFFpmUvMtbHSjsKrS20vdWdbfiVYsO3yA2SGYy9i9XmZJDfMGBflZGBCm70SEnFQtOA==} + peerDependencies: + '@typescript-eslint/eslint-plugin': ^8.0.0-0 || ^7.0.0 || ^6.0.0 || ^5.0.0 + eslint: ^9.0.0 || ^8.0.0 + peerDependenciesMeta: + '@typescript-eslint/eslint-plugin': + optional: true + + eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint@8.57.1: + resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. + hasBin: true + + espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + + execa@5.0.0: + resolution: {integrity: sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==} + engines: {node: '>=10'} + + execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + + exit@0.1.2: + resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} + engines: {node: '>= 0.8.0'} + + expect@29.7.0: + resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + exponential-backoff@3.1.3: + resolution: {integrity: sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-json-patch@3.1.1: + resolution: {integrity: sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + + fb-watchman@2.0.2: + resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + figures@3.2.0: + resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} + engines: {node: '>=8'} + + file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + + filelist@1.0.4: + resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@2.1.0: + resolution: {integrity: sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==} + engines: {node: '>=4'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} + engines: {node: ^10.12.0 || >=12.0.0} + + flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + hasBin: true + + flatted@3.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + + follow-redirects@1.15.11: + resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + + form-data@4.0.4: + resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} + engines: {node: '>= 6'} + + front-matter@4.0.2: + resolution: {integrity: sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==} + + fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + + fs-extra@11.3.2: + resolution: {integrity: sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==} + engines: {node: '>=14.14'} + + fs-minipass@2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + + fs-minipass@3.0.3: + resolution: {integrity: sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-package-type@0.1.0: + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} + engines: {node: '>=8.0.0'} + + get-pkg-repo@4.2.1: + resolution: {integrity: sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==} + engines: {node: '>=6.9.0'} + hasBin: true + + get-port@5.1.1: + resolution: {integrity: sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==} + engines: {node: '>=8'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-stream@6.0.0: + resolution: {integrity: sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==} + engines: {node: '>=10'} + + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + + git-raw-commits@3.0.0: + resolution: {integrity: sha512-b5OHmZ3vAgGrDn/X0kS+9qCfNKWe4K/jFnhwzVWWg0/k5eLa3060tZShrRg8Dja5kPc+YjS0Gc6y7cRr44Lpjw==} + engines: {node: '>=14'} + hasBin: true + + git-remote-origin-url@2.0.0: + resolution: {integrity: sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw==} + engines: {node: '>=4'} + + git-semver-tags@5.0.1: + resolution: {integrity: sha512-hIvOeZwRbQ+7YEUmCkHqo8FOLQZCEn18yevLHADlFPZY02KJGsu5FZt9YW/lybfK2uhWFI7Qg/07LekJiTv7iA==} + engines: {node: '>=14'} + hasBin: true + + git-up@7.0.0: + resolution: {integrity: sha512-ONdIrbBCFusq1Oy0sC71F5azx8bVkvtZtMJAsv+a6lz5YAmbNnLD6HAB4gptHZVLPR8S2/kVN6Gab7lryq5+lQ==} + + git-url-parse@14.0.0: + resolution: {integrity: sha512-NnLweV+2A4nCvn4U/m2AoYu0pPKlsmhK9cknG7IMwsjFY1S2jxM+mAhsDxyxfCIGfGaD+dozsyX4b6vkYc83yQ==} + + gitconfiglocal@1.0.0: + resolution: {integrity: sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + glob@9.3.5: + resolution: {integrity: sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==} + engines: {node: '>=16 || 14 >=14.17'} + + globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} + engines: {node: '>=8'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + handlebars@4.7.8: + resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} + engines: {node: '>=0.4.7'} + hasBin: true + + hard-rejection@2.1.0: + resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==} + engines: {node: '>=6'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + has-unicode@2.0.1: + resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + hosted-git-info@2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + + hosted-git-info@4.1.0: + resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} + engines: {node: '>=10'} + + hosted-git-info@7.0.2: + resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} + engines: {node: ^16.14.0 || >=18.0.0} + + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + + http-cache-semantics@4.2.0: + resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} + + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + + human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + iconv-lite@0.7.0: + resolution: {integrity: sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==} + engines: {node: '>=0.10.0'} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + ignore-walk@6.0.5: + resolution: {integrity: sha512-VuuG0wCnjhnylG1ABXT3dAuIpTNDs/G8jlpmwXY03fXoXy/8ZK8/T+hMzt8L4WnrLCJgdybqgPagnF/f97cg3A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + import-local@3.1.0: + resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==} + engines: {node: '>=8'} + hasBin: true + + import-local@3.2.0: + resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==} + engines: {node: '>=8'} + hasBin: true + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + ini@4.1.3: + resolution: {integrity: sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + init-package-json@6.0.3: + resolution: {integrity: sha512-Zfeb5ol+H+eqJWHTaGca9BovufyGeIfr4zaaBorPmJBMrJ+KBnN+kQx2ZtXdsotUTgldHmHQV44xvUWOUA7E2w==} + engines: {node: ^16.14.0 || >=18.0.0} + + inquirer@8.2.7: + resolution: {integrity: sha512-UjOaSel/iddGZJ5xP/Eixh6dY1XghiBw4XK13rCCIJcJfyhhoul/7KhLLUGtebEj6GDYM6Vnx/mVsjx2L/mFIA==} + engines: {node: '>=12.0.0'} + + inquirerer@2.0.8: + resolution: {integrity: sha512-/LfmACfRG/pCg0C/Ll1matjeFWUQoyiHNJTgZqxpqw20mDg/9bdzcRQ/6PFRANKaC+BUf9J/bXvsQ6FEXJV3Xw==} + + ip-address@10.0.1: + resolution: {integrity: sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==} + engines: {node: '>= 12'} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-ci@3.0.1: + resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} + hasBin: true + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-generator-fn@2.1.0: + resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} + engines: {node: '>=6'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-interactive@1.0.0: + resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} + engines: {node: '>=8'} + + is-lambda@1.0.1: + resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-obj@2.0.0: + resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} + engines: {node: '>=8'} + + is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + + is-plain-obj@1.1.0: + resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} + engines: {node: '>=0.10.0'} + + is-plain-object@2.0.4: + resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} + engines: {node: '>=0.10.0'} + + is-ssh@1.4.1: + resolution: {integrity: sha512-JNeu1wQsHjyHgn9NcWTaXq6zWSR6hqE0++zhfZlkFBbScNkyvxCdeV8sRkSBaeLKxmbpR21brail63ACNxJ0Tg==} + + is-stream@2.0.0: + resolution: {integrity: sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==} + engines: {node: '>=8'} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + is-text-path@1.0.1: + resolution: {integrity: sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==} + engines: {node: '>=0.10.0'} + + is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + + is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + + isarray@0.0.1: + resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isexe@3.1.1: + resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} + engines: {node: '>=16'} + + isobject@3.0.1: + resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} + engines: {node: '>=0.10.0'} + + isomorphic-fetch@3.0.0: + resolution: {integrity: sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==} + + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-instrument@5.2.1: + resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} + engines: {node: '>=8'} + + istanbul-lib-instrument@6.0.3: + resolution: {integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==} + engines: {node: '>=10'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-lib-source-maps@4.0.1: + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} + + istanbul-reports@3.2.0: + resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} + engines: {node: '>=8'} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + jake@10.9.4: + resolution: {integrity: sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==} + engines: {node: '>=10'} + hasBin: true + + jest-changed-files@29.7.0: + resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-circus@29.7.0: + resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-cli@29.7.0: + resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + jest-config@29.7.0: + resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + + jest-diff@29.7.0: + resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-docblock@29.7.0: + resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-each@29.7.0: + resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-environment-node@29.7.0: + resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-get-type@29.6.3: + resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-haste-map@29.7.0: + resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-leak-detector@29.7.0: + resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-matcher-utils@29.7.0: + resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-message-util@29.7.0: + resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-mock@29.7.0: + resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-pnp-resolver@1.2.3: + resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} + engines: {node: '>=6'} + peerDependencies: + jest-resolve: '*' + peerDependenciesMeta: + jest-resolve: + optional: true + + jest-regex-util@29.6.3: + resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-resolve-dependencies@29.7.0: + resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-resolve@29.7.0: + resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-runner@29.7.0: + resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-runtime@29.7.0: + resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-snapshot@29.7.0: + resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-util@29.7.0: + resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-validate@29.7.0: + resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-watcher@29.7.0: + resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-worker@29.7.0: + resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest@29.7.0: + resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-parse-better-errors@1.0.2: + resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json-parse-even-better-errors@3.0.2: + resolution: {integrity: sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json-stringify-nice@1.1.4: + resolution: {integrity: sha512-5Z5RFW63yxReJ7vANgW6eZFGWaQvnPE3WNmZoOJrSkGju2etKA2L5rrOa1sm877TVTFt57A80BH1bArcmlLfPw==} + + json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonc-parser@3.2.0: + resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} + + jsonfile@6.2.0: + resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} + + jsonparse@1.3.1: + resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} + engines: {'0': node >= 0.2.0} + + just-diff-apply@5.5.0: + resolution: {integrity: sha512-OYTthRfSh55WOItVqwpefPtNt2VdKsq5AnAK6apdtR6yCH8pr0CmSr710J0Mf+WdQy7K/OzMy7K2MgAfdQURDw==} + + just-diff@6.0.2: + resolution: {integrity: sha512-S59eriX5u3/QhMNq3v/gm8Kd0w8OS6Tz2FS1NG4blv+z0MuQcBRJyFWjdovM0Rad4/P4aUPFtnkNjMjyMlMSYA==} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + lerna@8.2.4: + resolution: {integrity: sha512-0gaVWDIVT7fLfprfwpYcQajb7dBJv3EGavjG7zvJ+TmGx3/wovl5GklnSwM2/WeE0Z2wrIz7ndWhBcDUHVjOcQ==} + engines: {node: '>=18.0.0'} + hasBin: true + + leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + libnpmaccess@8.0.6: + resolution: {integrity: sha512-uM8DHDEfYG6G5gVivVl+yQd4pH3uRclHC59lzIbSvy7b5FEwR+mU49Zq1jEyRtRFv7+M99mUW9S0wL/4laT4lw==} + engines: {node: ^16.14.0 || >=18.0.0} + + libnpmpublish@9.0.9: + resolution: {integrity: sha512-26zzwoBNAvX9AWOPiqqF6FG4HrSCPsHFkQm7nT+xU1ggAujL/eae81RnCv4CJ2In9q9fh10B88sYSzKCUh/Ghg==} + engines: {node: ^16.14.0 || >=18.0.0} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + lines-and-columns@2.0.3: + resolution: {integrity: sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + load-json-file@4.0.0: + resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} + engines: {node: '>=4'} + + load-json-file@6.2.0: + resolution: {integrity: sha512-gUD/epcRms75Cw8RT1pUdHugZYM5ce64ucs2GEISABwkRsOQr0q2wm/MV2TKThycIe5e0ytRweW2RZxclogCdQ==} + engines: {node: '>=8'} + + locate-path@2.0.0: + resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==} + engines: {node: '>=4'} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.ismatch@4.4.0: + resolution: {integrity: sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==} + + lodash.memoize@4.1.2: + resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + + make-dir@2.1.0: + resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} + engines: {node: '>=6'} + + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + make-fetch-happen@13.0.1: + resolution: {integrity: sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==} + engines: {node: ^16.14.0 || >=18.0.0} + + makeerror@1.0.12: + resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + + map-obj@1.0.1: + resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} + engines: {node: '>=0.10.0'} + + map-obj@4.3.0: + resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==} + engines: {node: '>=8'} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + meow@8.1.2: + resolution: {integrity: sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==} + engines: {node: '>=10'} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + + minimatch@3.0.5: + resolution: {integrity: sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + + minimatch@8.0.4: + resolution: {integrity: sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==} + engines: {node: '>=16 || 14 >=14.17'} + + minimatch@9.0.3: + resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} + engines: {node: '>=16 || 14 >=14.17'} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist-options@4.1.0: + resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} + engines: {node: '>= 6'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass-collect@2.0.1: + resolution: {integrity: sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==} + engines: {node: '>=16 || 14 >=14.17'} + + minipass-fetch@3.0.5: + resolution: {integrity: sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + minipass-flush@1.0.5: + resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} + engines: {node: '>= 8'} + + minipass-pipeline@1.2.4: + resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==} + engines: {node: '>=8'} + + minipass-sized@1.0.3: + resolution: {integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==} + engines: {node: '>=8'} + + minipass@3.3.6: + resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} + engines: {node: '>=8'} + + minipass@4.2.8: + resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==} + engines: {node: '>=8'} + + minipass@5.0.0: + resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} + engines: {node: '>=8'} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + minizlib@2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + + modify-values@1.0.1: + resolution: {integrity: sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==} + engines: {node: '>=0.10.0'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + multimatch@5.0.0: + resolution: {integrity: sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==} + engines: {node: '>=10'} + + mute-stream@0.0.8: + resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} + + mute-stream@1.0.0: + resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + negotiator@0.6.4: + resolution: {integrity: sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==} + engines: {node: '>= 0.6'} + + neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + + node-fetch@2.6.7: + resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-gyp@10.3.1: + resolution: {integrity: sha512-Pp3nFHBThHzVtNY7U6JfPjvT/DTE8+o/4xKsLQtBoU+j2HLsGlhcfzflAoUreaJbNmYnX+LlLi0qjV8kpyO6xQ==} + engines: {node: ^16.14.0 || >=18.0.0} + hasBin: true + + node-int64@0.4.0: + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + + node-machine-id@1.1.12: + resolution: {integrity: sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==} + + node-releases@2.0.27: + resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + + noms@0.0.0: + resolution: {integrity: sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow==} + + nopt@7.2.1: + resolution: {integrity: sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + + normalize-package-data@2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + + normalize-package-data@3.0.3: + resolution: {integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==} + engines: {node: '>=10'} + + normalize-package-data@6.0.2: + resolution: {integrity: sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==} + engines: {node: ^16.14.0 || >=18.0.0} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + npm-bundled@3.0.1: + resolution: {integrity: sha512-+AvaheE/ww1JEwRHOrn4WHNzOxGtVp+adrg2AeZS/7KuxGUYFuBta98wYpfHBbJp6Tg6j1NKSEVHNcfZzJHQwQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-install-checks@6.3.0: + resolution: {integrity: sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-normalize-package-bin@3.0.1: + resolution: {integrity: sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-package-arg@11.0.2: + resolution: {integrity: sha512-IGN0IAwmhDJwy13Wc8k+4PEbTPhpJnMtfR53ZbOyjkvmEcLS4nCwp6mvMWjS5sUjeiW3mpx6cHmuhKEu9XmcQw==} + engines: {node: ^16.14.0 || >=18.0.0} + + npm-packlist@8.0.2: + resolution: {integrity: sha512-shYrPFIS/JLP4oQmAwDyk5HcyysKW8/JLTEA32S0Z5TzvpaeeX2yMFfoK1fjEBnCBvVyIB/Jj/GBFdm0wsgzbA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-pick-manifest@9.1.0: + resolution: {integrity: sha512-nkc+3pIIhqHVQr085X9d2JzPzLyjzQS96zbruppqC9aZRm/x8xx6xhI98gHtsfELP2bE+loHq8ZaHFHhe+NauA==} + engines: {node: ^16.14.0 || >=18.0.0} + + npm-registry-fetch@17.1.0: + resolution: {integrity: sha512-5+bKQRH0J1xG1uZ1zMNvxW0VEyoNWgJpY9UDuluPFLKDfJ9u2JmmjmTJV1srBGQOROfdBMiVvnH2Zvpbm+xkVA==} + engines: {node: ^16.14.0 || >=18.0.0} + + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + + nx@20.8.2: + resolution: {integrity: sha512-mDKpbH3vEpUFDx0rrLh+tTqLq1PYU8KiD/R7OVZGd1FxQxghx2HOl32MiqNsfPcw6AvKlXhslbwIESV+N55FLQ==} + hasBin: true + peerDependencies: + '@swc-node/register': ^1.8.0 + '@swc/core': ^1.3.85 + peerDependenciesMeta: + '@swc-node/register': + optional: true + '@swc/core': + optional: true + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + open@8.4.2: + resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} + engines: {node: '>=12'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + ora@5.3.0: + resolution: {integrity: sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g==} + engines: {node: '>=10'} + + ora@5.4.1: + resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} + engines: {node: '>=10'} + + p-finally@1.0.0: + resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} + engines: {node: '>=4'} + + p-limit@1.3.0: + resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==} + engines: {node: '>=4'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@2.0.0: + resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==} + engines: {node: '>=4'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + p-map-series@2.1.0: + resolution: {integrity: sha512-RpYIIK1zXSNEOdwxcfe7FdvGcs7+y5n8rifMhMNWvaxRNMPINJHF5GDeuVxWqnfrcHPSCnp7Oo5yNXHId9Av2Q==} + engines: {node: '>=8'} + + p-map@4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + + p-pipe@3.1.0: + resolution: {integrity: sha512-08pj8ATpzMR0Y80x50yJHn37NF6vjrqHutASaX5LiH5npS9XPvrUmscd9MF5R4fuYRHOxQR1FfMIlF7AzwoPqw==} + engines: {node: '>=8'} + + p-queue@6.6.2: + resolution: {integrity: sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==} + engines: {node: '>=8'} + + p-reduce@2.1.0: + resolution: {integrity: sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw==} + engines: {node: '>=8'} + + p-timeout@3.2.0: + resolution: {integrity: sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==} + engines: {node: '>=8'} + + p-try@1.0.0: + resolution: {integrity: sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==} + engines: {node: '>=4'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + p-waterfall@2.1.1: + resolution: {integrity: sha512-RRTnDb2TBG/epPRI2yYXsimO0v3BXC8Yd3ogr1545IaqKK17VGhbWVeGGN+XfCm/08OK8635nH31c8bATkHuSw==} + engines: {node: '>=8'} + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + pacote@18.0.6: + resolution: {integrity: sha512-+eK3G27SMwsB8kLIuj4h1FUhHtwiEUo21Tw8wNjmvdlpOEr613edv+8FUsTj/4F/VN5ywGE19X18N7CC2EJk6A==} + engines: {node: ^16.14.0 || >=18.0.0} + hasBin: true + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-conflict-json@3.0.1: + resolution: {integrity: sha512-01TvEktc68vwbJOtWZluyWeVGWjP+bZwXtPDMQVbBKzbJ/vZBif0L69KH1+cHv1SZ6e0FKLvjyHe8mqsIqYOmw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + parse-json@4.0.0: + resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} + engines: {node: '>=4'} + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + + parse-path@7.1.0: + resolution: {integrity: sha512-EuCycjZtfPcjWk7KTksnJ5xPMvWGA/6i4zrLYhRG0hGvC3GPU/jGUj3Cy+ZR0v30duV3e23R95T1lE2+lsndSw==} + + parse-url@8.1.0: + resolution: {integrity: sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w==} + + path-exists@3.0.0: + resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} + engines: {node: '>=4'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + path-type@3.0.0: + resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} + engines: {node: '>=4'} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + + pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + + pify@3.0.0: + resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} + engines: {node: '>=4'} + + pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + + pify@5.0.0: + resolution: {integrity: sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==} + engines: {node: '>=10'} + + pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} + engines: {node: '>= 6'} + + pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier@3.6.2: + resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} + engines: {node: '>=14'} + hasBin: true + + pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + proc-log@4.2.0: + resolution: {integrity: sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + proggy@2.0.0: + resolution: {integrity: sha512-69agxLtnI8xBs9gUGqEnK26UfiexpHy+KUpBQWabiytQjnn5wFY8rklAi7GRfABIuPNnQ/ik48+LGLkYYJcy4A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + promise-all-reject-late@1.0.1: + resolution: {integrity: sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==} + + promise-call-limit@3.0.2: + resolution: {integrity: sha512-mRPQO2T1QQVw11E7+UdCJu7S61eJVWknzml9sC1heAdj1jxl0fWMBypIt9ZOcLFf8FkG995ZD7RnVk7HH72fZw==} + + promise-inflight@1.0.1: + resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==} + peerDependencies: + bluebird: '*' + peerDependenciesMeta: + bluebird: + optional: true + + promise-retry@2.0.1: + resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} + engines: {node: '>=10'} + + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + + promzard@1.0.2: + resolution: {integrity: sha512-2FPputGL+mP3jJ3UZg/Dl9YOkovB7DX0oOr+ck5QbZ5MtORtds8k/BZdn+02peDLI8/YWbmzx34k5fA+fHvCVQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + protocols@2.0.2: + resolution: {integrity: sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ==} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + pure-rand@6.1.0: + resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + quick-lru@4.0.1: + resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} + engines: {node: '>=8'} + + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + + react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + engines: {node: '>=0.10.0'} + + read-cmd-shim@4.0.0: + resolution: {integrity: sha512-yILWifhaSEEytfXI76kB9xEEiG1AiozaCJZ83A87ytjRiN+jVibXjedjCRNjoZviinhG+4UkalO3mWTd8u5O0Q==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + read-package-json-fast@3.0.2: + resolution: {integrity: sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + read-pkg-up@3.0.0: + resolution: {integrity: sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==} + engines: {node: '>=4'} + + read-pkg-up@7.0.1: + resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} + engines: {node: '>=8'} + + read-pkg@3.0.0: + resolution: {integrity: sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==} + engines: {node: '>=4'} + + read-pkg@5.2.0: + resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} + engines: {node: '>=8'} + + read@3.0.1: + resolution: {integrity: sha512-SLBrDU/Srs/9EoWhU5GdbAoxG1GzpQHo/6qiGItaoLJ1thmYpcNIM1qISEUvyHBzfGlWIyd6p2DNi1oV1VmAuw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + readable-stream@1.0.34: + resolution: {integrity: sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + redent@3.0.0: + resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} + engines: {node: '>=8'} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + resolve-cwd@3.0.0: + resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} + engines: {node: '>=8'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + resolve.exports@2.0.3: + resolution: {integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==} + engines: {node: '>=10'} + + resolve@1.22.11: + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} + engines: {node: '>= 0.4'} + hasBin: true + + restore-cursor@3.1.0: + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} + engines: {node: '>=8'} + + retry@0.12.0: + resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} + engines: {node: '>= 4'} + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + rimraf@4.4.1: + resolution: {integrity: sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==} + engines: {node: '>=14'} + hasBin: true + + run-async@2.4.1: + resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} + engines: {node: '>=0.12.0'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + rxjs@7.8.2: + resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + schema-sdk@0.12.0: + resolution: {integrity: sha512-Za2kaXpanSioGqkK4cRe/epndQkJc6a037EcJ6ZrvhoFs6N9IW9IRT/IVEv7J0bpyR4WGloB2yk4w+/eSUkMdg==} + + schema-typescript@0.12.1: + resolution: {integrity: sha512-dgfQrLjqsXEAC7vZ3fJDBsIPpUDJ2SrzuQFvXslrEjVjOSQyVykBua2tNmM4uFn4uIL7K3Ux64pXbaUnngkhhw==} + + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.3: + resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} + engines: {node: '>=10'} + hasBin: true + + set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + + shallow-clone@3.0.1: + resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} + engines: {node: '>=8'} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + sigstore@2.3.1: + resolution: {integrity: sha512-8G+/XDU8wNsJOQS5ysDVO0Etg9/2uA5gR9l4ZwijjlwxBcrU6RPfwi2+jJmbP+Ap1Hlp/nVAaEO4Fj22/SL2gQ==} + engines: {node: ^16.14.0 || >=18.0.0} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + smart-buffer@4.2.0: + resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} + engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + + socks-proxy-agent@8.0.5: + resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==} + engines: {node: '>= 14'} + + socks@2.8.7: + resolution: {integrity: sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==} + engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} + + sort-keys@2.0.0: + resolution: {integrity: sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg==} + engines: {node: '>=4'} + + source-map-support@0.5.13: + resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + + spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + + spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + + spdx-license-ids@3.0.22: + resolution: {integrity: sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==} + + split2@3.2.2: + resolution: {integrity: sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==} + + split@1.0.1: + resolution: {integrity: sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + ssri@10.0.6: + resolution: {integrity: sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + stack-utils@2.0.6: + resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} + engines: {node: '>=10'} + + string-length@4.0.2: + resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} + engines: {node: '>=10'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string_decoder@0.10.31: + resolution: {integrity: sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.2: + resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} + engines: {node: '>=12'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-bom@4.0.0: + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} + engines: {node: '>=8'} + + strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + + strip-indent@3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + + tar@6.2.1: + resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} + engines: {node: '>=10'} + + temp-dir@1.0.0: + resolution: {integrity: sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ==} + engines: {node: '>=4'} + + test-exclude@6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + + text-extensions@1.9.0: + resolution: {integrity: sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==} + engines: {node: '>=0.10'} + + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + + through2@2.0.5: + resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} + + through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + + tinyglobby@0.2.12: + resolution: {integrity: sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==} + engines: {node: '>=12.0.0'} + + tmp@0.2.5: + resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} + engines: {node: '>=14.14'} + + tmpl@1.0.5: + resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + treeverse@3.0.0: + resolution: {integrity: sha512-gcANaAnd2QDZFmHFEOF4k7uc1J/6a6z3DJMd/QwEyxLoKGiptJRwid582r7QIsFlFMIZ3SnxfS52S4hm2DHkuQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + trim-newlines@3.0.1: + resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} + engines: {node: '>=8'} + + ts-api-utils@1.4.3: + resolution: {integrity: sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==} + engines: {node: '>=16'} + peerDependencies: + typescript: '>=4.2.0' + + ts-jest@29.4.5: + resolution: {integrity: sha512-HO3GyiWn2qvTQA4kTgjDcXiMwYQt68a1Y8+JuLRVpdIzm+UOLSHgl/XqR4c6nzJkq5rOkjc02O2I7P7l/Yof0Q==} + engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@babel/core': '>=7.0.0-beta.0 <8' + '@jest/transform': ^29.0.0 || ^30.0.0 + '@jest/types': ^29.0.0 || ^30.0.0 + babel-jest: ^29.0.0 || ^30.0.0 + esbuild: '*' + jest: ^29.0.0 || ^30.0.0 + jest-util: ^29.0.0 || ^30.0.0 + typescript: '>=4.3 <6' + peerDependenciesMeta: + '@babel/core': + optional: true + '@jest/transform': + optional: true + '@jest/types': + optional: true + babel-jest: + optional: true + esbuild: + optional: true + jest-util: + optional: true + + ts-node@10.9.2: + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} + hasBin: true + 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 + + tsconfig-paths@4.2.0: + resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} + engines: {node: '>=6'} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tuf-js@2.2.1: + resolution: {integrity: sha512-GwIJau9XaA8nLVbUXsN3IlFi7WmQ48gBUrl3FTkkL/XLu/POhBzfmX9hd33FNMX1qAsfl6ozO1iMmW9NC8YniA==} + engines: {node: ^16.14.0 || >=18.0.0} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + + type-fest@0.18.1: + resolution: {integrity: sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==} + engines: {node: '>=10'} + + type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + + type-fest@0.4.1: + resolution: {integrity: sha512-IwzA/LSfD2vC1/YDYMv/zHP4rDF1usCwllsDpbolT3D4fUepIO7f9K70jjmUewU/LmGUKJcwcVtDCpnKk4BPMw==} + engines: {node: '>=6'} + + type-fest@0.6.0: + resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} + engines: {node: '>=8'} + + type-fest@0.8.1: + resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} + engines: {node: '>=8'} + + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} + + typedarray@0.0.6: + resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + uglify-js@3.19.3: + resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} + engines: {node: '>=0.8.0'} + hasBin: true + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + unique-filename@3.0.0: + resolution: {integrity: sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + unique-slug@4.0.0: + resolution: {integrity: sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + universal-user-agent@6.0.1: + resolution: {integrity: sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + untildify@4.0.0: + resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} + engines: {node: '>=8'} + + upath@2.0.1: + resolution: {integrity: sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==} + engines: {node: '>=4'} + + update-browserslist-db@1.1.4: + resolution: {integrity: sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + uuid@10.0.0: + resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} + hasBin: true + + v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + + v8-to-istanbul@9.3.0: + resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} + engines: {node: '>=10.12.0'} + + validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + + validate-npm-package-name@5.0.1: + resolution: {integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + walk-up-path@3.0.1: + resolution: {integrity: sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==} + + walker@1.0.8: + resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + + wcwidth@1.0.1: + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + whatwg-fetch@3.6.20: + resolution: {integrity: sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + which@4.0.0: + resolution: {integrity: sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==} + engines: {node: ^16.13.0 || >=18.0.0} + hasBin: true + + wide-align@1.1.5: + resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wordwrap@1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + write-file-atomic@2.4.3: + resolution: {integrity: sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==} + + write-file-atomic@4.0.2: + resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + write-file-atomic@5.0.1: + resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + write-json-file@3.2.0: + resolution: {integrity: sha512-3xZqT7Byc2uORAatYiP3DHUUAVEkNOswEWNs9H5KXiicRTvzYzYqKjYc4G7p+8pltvAw641lVByKVtMpf+4sYQ==} + engines: {node: '>=6'} + + write-pkg@4.0.0: + resolution: {integrity: sha512-v2UQ+50TNf2rNHJ8NyWttfm/EJUBWMJcx6ZTYZr6Qp52uuegWw/lBkCtCbnYZEmPRNL61m+u67dAmGxo+HTULA==} + engines: {node: '>=8'} + + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + yaml@2.8.1: + resolution: {integrity: sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==} + engines: {node: '>= 14.6'} + hasBin: true + + yargs-parser@20.2.9: + resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} + engines: {node: '>=10'} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@16.2.0: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + engines: {node: '>=10'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + +snapshots: + + '@babel/code-frame@7.27.1': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.28.5': {} + + '@babel/core@7.28.5': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.5 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) + '@babel/helpers': 7.28.4 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.28.5': + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-compilation-targets@7.27.2': + dependencies: + '@babel/compat-data': 7.28.5 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.27.0 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-module-imports@7.27.1': + dependencies: + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-plugin-utils@7.27.1': {} + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.28.4': + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.28.5 + + '@babel/parser@7.28.5': + dependencies: + '@babel/types': 7.28.5 + + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/template@7.27.2': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + + '@babel/traverse@7.28.5': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.5 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.2 + '@babel/types': 7.28.5 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.28.5': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@bcoe/v8-coverage@0.2.3': {} + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + + '@emnapi/core@1.7.0': + dependencies: + '@emnapi/wasi-threads': 1.1.0 + tslib: 2.8.1 + + '@emnapi/runtime@1.7.0': + dependencies: + tslib: 2.8.1 + + '@emnapi/wasi-threads@1.1.0': + dependencies: + tslib: 2.8.1 + + '@eslint-community/eslint-utils@4.9.0(eslint@8.57.1)': + dependencies: + eslint: 8.57.1 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/eslintrc@2.1.4': + dependencies: + ajv: 6.12.6 + debug: 4.4.3 + espree: 9.6.1 + globals: 13.24.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@8.57.1': {} + + '@humanwhocodes/config-array@0.13.0': + dependencies: + '@humanwhocodes/object-schema': 2.0.3 + debug: 4.4.3 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/object-schema@2.0.3': {} + + '@hutson/parse-repository-url@3.0.2': {} + + '@inquirer/external-editor@1.0.2(@types/node@20.19.24)': + dependencies: + chardet: 2.1.1 + iconv-lite: 0.7.0 + optionalDependencies: + '@types/node': 20.19.24 + + '@interweb-utils/casing@0.2.0': {} + + '@interweb/fetch-api-client@0.6.1(encoding@0.1.13)': + dependencies: + '@interweb/http-errors': 0.1.1 + isomorphic-fetch: 3.0.0(encoding@0.1.13) + transitivePeerDependencies: + - encoding + + '@interweb/http-errors@0.1.1': {} + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.2 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@isaacs/string-locale-compare@1.1.0': {} + + '@istanbuljs/load-nyc-config@1.1.0': + dependencies: + camelcase: 5.3.1 + find-up: 4.1.0 + get-package-type: 0.1.0 + js-yaml: 3.14.1 + resolve-from: 5.0.0 + + '@istanbuljs/schema@0.1.3': {} + + '@jest/console@29.7.0': + dependencies: + '@jest/types': 29.6.3 + '@types/node': 20.19.24 + chalk: 4.1.2 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + + '@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3))': + dependencies: + '@jest/console': 29.7.0 + '@jest/reporters': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.19.24 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.9.0 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-changed-files: 29.7.0 + jest-config: 29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3)) + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-resolve-dependencies: 29.7.0 + jest-runner: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + jest-watcher: 29.7.0 + micromatch: 4.0.8 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + - ts-node + + '@jest/environment@29.7.0': + dependencies: + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.19.24 + jest-mock: 29.7.0 + + '@jest/expect-utils@29.7.0': + dependencies: + jest-get-type: 29.6.3 + + '@jest/expect@29.7.0': + dependencies: + expect: 29.7.0 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + + '@jest/fake-timers@29.7.0': + dependencies: + '@jest/types': 29.6.3 + '@sinonjs/fake-timers': 10.3.0 + '@types/node': 20.19.24 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-util: 29.7.0 + + '@jest/globals@29.7.0': + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/types': 29.6.3 + jest-mock: 29.7.0 + transitivePeerDependencies: + - supports-color + + '@jest/reporters@29.7.0': + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.31 + '@types/node': 20.19.24 + chalk: 4.1.2 + collect-v8-coverage: 1.0.3 + exit: 0.1.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-instrument: 6.0.3 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.2.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + jest-worker: 29.7.0 + slash: 3.0.0 + string-length: 4.0.2 + strip-ansi: 6.0.1 + v8-to-istanbul: 9.3.0 + transitivePeerDependencies: + - supports-color + + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.8 + + '@jest/source-map@29.6.3': + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + callsites: 3.1.0 + graceful-fs: 4.2.11 + + '@jest/test-result@29.7.0': + dependencies: + '@jest/console': 29.7.0 + '@jest/types': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + collect-v8-coverage: 1.0.3 + + '@jest/test-sequencer@29.7.0': + dependencies: + '@jest/test-result': 29.7.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + slash: 3.0.0 + + '@jest/transform@29.7.0': + dependencies: + '@babel/core': 7.28.5 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.31 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 + convert-source-map: 2.0.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + micromatch: 4.0.8 + pirates: 4.0.7 + slash: 3.0.0 + write-file-atomic: 4.0.2 + transitivePeerDependencies: + - supports-color + + '@jest/types@29.6.3': + dependencies: + '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 20.19.24 + '@types/yargs': 17.0.34 + chalk: 4.1.2 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@lerna/create@8.2.4(@types/node@20.19.24)(encoding@0.1.13)(typescript@5.9.3)': + dependencies: + '@npmcli/arborist': 7.5.4 + '@npmcli/package-json': 5.2.0 + '@npmcli/run-script': 8.1.0 + '@nx/devkit': 20.8.2(nx@20.8.2) + '@octokit/plugin-enterprise-rest': 6.0.1 + '@octokit/rest': 20.1.2 + aproba: 2.0.0 + byte-size: 8.1.1 + chalk: 4.1.0 + clone-deep: 4.0.1 + cmd-shim: 6.0.3 + color-support: 1.1.3 + columnify: 1.6.0 + console-control-strings: 1.1.0 + conventional-changelog-core: 5.0.1 + conventional-recommended-bump: 7.0.1 + cosmiconfig: 9.0.0(typescript@5.9.3) + dedent: 1.5.3 + execa: 5.0.0 + fs-extra: 11.3.2 + get-stream: 6.0.0 + git-url-parse: 14.0.0 + glob-parent: 6.0.2 + graceful-fs: 4.2.11 + has-unicode: 2.0.1 + ini: 1.3.8 + init-package-json: 6.0.3 + inquirer: 8.2.7(@types/node@20.19.24) + is-ci: 3.0.1 + is-stream: 2.0.0 + js-yaml: 4.1.0 + libnpmpublish: 9.0.9 + load-json-file: 6.2.0 + make-dir: 4.0.0 + minimatch: 3.0.5 + multimatch: 5.0.0 + node-fetch: 2.6.7(encoding@0.1.13) + npm-package-arg: 11.0.2 + npm-packlist: 8.0.2 + npm-registry-fetch: 17.1.0 + nx: 20.8.2 + p-map: 4.0.0 + p-map-series: 2.1.0 + p-queue: 6.6.2 + p-reduce: 2.1.0 + pacote: 18.0.6 + pify: 5.0.0 + read-cmd-shim: 4.0.0 + resolve-from: 5.0.0 + rimraf: 4.4.1 + semver: 7.7.3 + set-blocking: 2.0.0 + signal-exit: 3.0.7 + slash: 3.0.0 + ssri: 10.0.6 + string-width: 4.2.3 + tar: 6.2.1 + temp-dir: 1.0.0 + through: 2.3.8 + tinyglobby: 0.2.12 + upath: 2.0.1 + uuid: 10.0.0 + validate-npm-package-license: 3.0.4 + validate-npm-package-name: 5.0.1 + wide-align: 1.1.5 + write-file-atomic: 5.0.1 + write-pkg: 4.0.0 + yargs: 17.7.2 + yargs-parser: 21.1.1 + transitivePeerDependencies: + - '@swc-node/register' + - '@swc/core' + - '@types/node' + - babel-plugin-macros + - bluebird + - debug + - encoding + - supports-color + - typescript + + '@napi-rs/wasm-runtime@0.2.4': + dependencies: + '@emnapi/core': 1.7.0 + '@emnapi/runtime': 1.7.0 + '@tybys/wasm-util': 0.9.0 + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.19.1 + + '@npmcli/agent@2.2.2': + dependencies: + agent-base: 7.1.4 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + lru-cache: 10.4.3 + socks-proxy-agent: 8.0.5 + transitivePeerDependencies: + - supports-color + + '@npmcli/arborist@7.5.4': + dependencies: + '@isaacs/string-locale-compare': 1.1.0 + '@npmcli/fs': 3.1.1 + '@npmcli/installed-package-contents': 2.1.0 + '@npmcli/map-workspaces': 3.0.6 + '@npmcli/metavuln-calculator': 7.1.1 + '@npmcli/name-from-folder': 2.0.0 + '@npmcli/node-gyp': 3.0.0 + '@npmcli/package-json': 5.2.0 + '@npmcli/query': 3.1.0 + '@npmcli/redact': 2.0.1 + '@npmcli/run-script': 8.1.0 + bin-links: 4.0.4 + cacache: 18.0.4 + common-ancestor-path: 1.0.1 + hosted-git-info: 7.0.2 + json-parse-even-better-errors: 3.0.2 + json-stringify-nice: 1.1.4 + lru-cache: 10.4.3 + minimatch: 9.0.5 + nopt: 7.2.1 + npm-install-checks: 6.3.0 + npm-package-arg: 11.0.2 + npm-pick-manifest: 9.1.0 + npm-registry-fetch: 17.1.0 + pacote: 18.0.6 + parse-conflict-json: 3.0.1 + proc-log: 4.2.0 + proggy: 2.0.0 + promise-all-reject-late: 1.0.1 + promise-call-limit: 3.0.2 + read-package-json-fast: 3.0.2 + semver: 7.7.3 + ssri: 10.0.6 + treeverse: 3.0.0 + walk-up-path: 3.0.1 + transitivePeerDependencies: + - bluebird + - supports-color + + '@npmcli/fs@3.1.1': + dependencies: + semver: 7.7.3 + + '@npmcli/git@5.0.8': + dependencies: + '@npmcli/promise-spawn': 7.0.2 + ini: 4.1.3 + lru-cache: 10.4.3 + npm-pick-manifest: 9.1.0 + proc-log: 4.2.0 + promise-inflight: 1.0.1 + promise-retry: 2.0.1 + semver: 7.7.3 + which: 4.0.0 + transitivePeerDependencies: + - bluebird + + '@npmcli/installed-package-contents@2.1.0': + dependencies: + npm-bundled: 3.0.1 + npm-normalize-package-bin: 3.0.1 + + '@npmcli/map-workspaces@3.0.6': + dependencies: + '@npmcli/name-from-folder': 2.0.0 + glob: 10.4.5 + minimatch: 9.0.5 + read-package-json-fast: 3.0.2 + + '@npmcli/metavuln-calculator@7.1.1': + dependencies: + cacache: 18.0.4 + json-parse-even-better-errors: 3.0.2 + pacote: 18.0.6 + proc-log: 4.2.0 + semver: 7.7.3 + transitivePeerDependencies: + - bluebird + - supports-color + + '@npmcli/name-from-folder@2.0.0': {} + + '@npmcli/node-gyp@3.0.0': {} + + '@npmcli/package-json@5.2.0': + dependencies: + '@npmcli/git': 5.0.8 + glob: 10.4.5 + hosted-git-info: 7.0.2 + json-parse-even-better-errors: 3.0.2 + normalize-package-data: 6.0.2 + proc-log: 4.2.0 + semver: 7.7.3 + transitivePeerDependencies: + - bluebird + + '@npmcli/promise-spawn@7.0.2': + dependencies: + which: 4.0.0 + + '@npmcli/query@3.1.0': + dependencies: + postcss-selector-parser: 6.1.2 + + '@npmcli/redact@2.0.1': {} + + '@npmcli/run-script@8.1.0': + dependencies: + '@npmcli/node-gyp': 3.0.0 + '@npmcli/package-json': 5.2.0 + '@npmcli/promise-spawn': 7.0.2 + node-gyp: 10.3.1 + proc-log: 4.2.0 + which: 4.0.0 + transitivePeerDependencies: + - bluebird + - supports-color + + '@nx/devkit@20.8.2(nx@20.8.2)': + dependencies: + ejs: 3.1.10 + enquirer: 2.3.6 + ignore: 5.3.2 + minimatch: 9.0.3 + nx: 20.8.2 + semver: 7.7.3 + tmp: 0.2.5 + tslib: 2.8.1 + yargs-parser: 21.1.1 + + '@nx/nx-darwin-arm64@20.8.2': + optional: true + + '@nx/nx-darwin-x64@20.8.2': + optional: true + + '@nx/nx-freebsd-x64@20.8.2': + optional: true + + '@nx/nx-linux-arm-gnueabihf@20.8.2': + optional: true + + '@nx/nx-linux-arm64-gnu@20.8.2': + optional: true + + '@nx/nx-linux-arm64-musl@20.8.2': + optional: true + + '@nx/nx-linux-x64-gnu@20.8.2': + optional: true + + '@nx/nx-linux-x64-musl@20.8.2': + optional: true + + '@nx/nx-win32-arm64-msvc@20.8.2': + optional: true + + '@nx/nx-win32-x64-msvc@20.8.2': + optional: true + + '@octokit/auth-token@4.0.0': {} + + '@octokit/core@5.2.2': + dependencies: + '@octokit/auth-token': 4.0.0 + '@octokit/graphql': 7.1.1 + '@octokit/request': 8.4.1 + '@octokit/request-error': 5.1.1 + '@octokit/types': 13.10.0 + before-after-hook: 2.2.3 + universal-user-agent: 6.0.1 + + '@octokit/endpoint@9.0.6': + dependencies: + '@octokit/types': 13.10.0 + universal-user-agent: 6.0.1 + + '@octokit/graphql@7.1.1': + dependencies: + '@octokit/request': 8.4.1 + '@octokit/types': 13.10.0 + universal-user-agent: 6.0.1 + + '@octokit/openapi-types@24.2.0': {} + + '@octokit/plugin-enterprise-rest@6.0.1': {} + + '@octokit/plugin-paginate-rest@11.4.4-cjs.2(@octokit/core@5.2.2)': + dependencies: + '@octokit/core': 5.2.2 + '@octokit/types': 13.10.0 + + '@octokit/plugin-request-log@4.0.1(@octokit/core@5.2.2)': + dependencies: + '@octokit/core': 5.2.2 + + '@octokit/plugin-rest-endpoint-methods@13.3.2-cjs.1(@octokit/core@5.2.2)': + dependencies: + '@octokit/core': 5.2.2 + '@octokit/types': 13.10.0 + + '@octokit/request-error@5.1.1': + dependencies: + '@octokit/types': 13.10.0 + deprecation: 2.3.1 + once: 1.4.0 + + '@octokit/request@8.4.1': + dependencies: + '@octokit/endpoint': 9.0.6 + '@octokit/request-error': 5.1.1 + '@octokit/types': 13.10.0 + universal-user-agent: 6.0.1 + + '@octokit/rest@20.1.2': + dependencies: + '@octokit/core': 5.2.2 + '@octokit/plugin-paginate-rest': 11.4.4-cjs.2(@octokit/core@5.2.2) + '@octokit/plugin-request-log': 4.0.1(@octokit/core@5.2.2) + '@octokit/plugin-rest-endpoint-methods': 13.3.2-cjs.1(@octokit/core@5.2.2) + + '@octokit/types@13.10.0': + dependencies: + '@octokit/openapi-types': 24.2.0 + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@sigstore/bundle@2.3.2': + dependencies: + '@sigstore/protobuf-specs': 0.3.3 + + '@sigstore/core@1.1.0': {} + + '@sigstore/protobuf-specs@0.3.3': {} + + '@sigstore/sign@2.3.2': + dependencies: + '@sigstore/bundle': 2.3.2 + '@sigstore/core': 1.1.0 + '@sigstore/protobuf-specs': 0.3.3 + make-fetch-happen: 13.0.1 + proc-log: 4.2.0 + promise-retry: 2.0.1 + transitivePeerDependencies: + - supports-color + + '@sigstore/tuf@2.3.4': + dependencies: + '@sigstore/protobuf-specs': 0.3.3 + tuf-js: 2.2.1 + transitivePeerDependencies: + - supports-color + + '@sigstore/verify@1.2.1': + dependencies: + '@sigstore/bundle': 2.3.2 + '@sigstore/core': 1.1.0 + '@sigstore/protobuf-specs': 0.3.3 + + '@sinclair/typebox@0.27.8': {} + + '@sinonjs/commons@3.0.1': + dependencies: + type-detect: 4.0.8 + + '@sinonjs/fake-timers@10.3.0': + dependencies: + '@sinonjs/commons': 3.0.1 + + '@tanstack/query-core@5.79.2': {} + + '@tanstack/react-query@5.79.2(react@18.3.1)': + dependencies: + '@tanstack/query-core': 5.79.2 + react: 18.3.1 + + '@tsconfig/node10@1.0.11': {} + + '@tsconfig/node12@1.0.11': {} + + '@tsconfig/node14@1.0.3': {} + + '@tsconfig/node16@1.0.4': {} + + '@tufjs/canonical-json@2.0.0': {} + + '@tufjs/models@2.0.1': + dependencies: + '@tufjs/canonical-json': 2.0.0 + minimatch: 9.0.5 + + '@tybys/wasm-util@0.9.0': + dependencies: + tslib: 2.8.1 + + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + '@types/babel__generator': 7.27.0 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.28.0 + + '@types/babel__generator@7.27.0': + dependencies: + '@babel/types': 7.28.5 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + + '@types/babel__traverse@7.28.0': + dependencies: + '@babel/types': 7.28.5 + + '@types/graceful-fs@4.1.9': + dependencies: + '@types/node': 20.19.24 + + '@types/istanbul-lib-coverage@2.0.6': {} + + '@types/istanbul-lib-report@3.0.3': + dependencies: + '@types/istanbul-lib-coverage': 2.0.6 + + '@types/istanbul-reports@3.0.4': + dependencies: + '@types/istanbul-lib-report': 3.0.3 + + '@types/jest@29.5.14': + dependencies: + expect: 29.7.0 + pretty-format: 29.7.0 + + '@types/js-yaml@4.0.9': {} + + '@types/minimatch@3.0.5': {} + + '@types/minimist@1.2.5': {} + + '@types/node@20.19.24': + dependencies: + undici-types: 6.21.0 + + '@types/normalize-package-data@2.4.4': {} + + '@types/prop-types@15.7.15': {} + + '@types/react@18.3.26': + dependencies: + '@types/prop-types': 15.7.15 + csstype: 3.1.3 + + '@types/stack-utils@2.0.3': {} + + '@types/yargs-parser@21.0.3': {} + + '@types/yargs@17.0.34': + dependencies: + '@types/yargs-parser': 21.0.3 + + '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/scope-manager': 7.18.0 + '@typescript-eslint/type-utils': 7.18.0(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 7.18.0 + eslint: 8.57.1 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare: 1.4.0 + ts-api-utils: 1.4.3(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/scope-manager': 7.18.0 + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 7.18.0 + debug: 4.4.3 + eslint: 8.57.1 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@7.18.0': + dependencies: + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/visitor-keys': 7.18.0 + + '@typescript-eslint/type-utils@7.18.0(eslint@8.57.1)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.9.3) + '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.9.3) + debug: 4.4.3 + eslint: 8.57.1 + ts-api-utils: 1.4.3(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@7.18.0': {} + + '@typescript-eslint/typescript-estree@7.18.0(typescript@5.9.3)': + dependencies: + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/visitor-keys': 7.18.0 + debug: 4.4.3 + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.7.3 + ts-api-utils: 1.4.3(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@7.18.0(eslint@8.57.1)(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.0(eslint@8.57.1) + '@typescript-eslint/scope-manager': 7.18.0 + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.9.3) + eslint: 8.57.1 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/visitor-keys@7.18.0': + dependencies: + '@typescript-eslint/types': 7.18.0 + eslint-visitor-keys: 3.4.3 + + '@ungap/structured-clone@1.3.0': {} + + '@yarnpkg/lockfile@1.1.0': {} + + '@yarnpkg/parsers@3.0.2': + dependencies: + js-yaml: 3.14.1 + tslib: 2.8.1 + + '@zkochan/js-yaml@0.0.7': + dependencies: + argparse: 2.0.1 + + JSONStream@1.3.5: + dependencies: + jsonparse: 1.3.1 + through: 2.3.8 + + abbrev@2.0.0: {} + + acorn-jsx@5.3.2(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + + acorn-walk@8.3.4: + dependencies: + acorn: 8.15.0 + + acorn@8.15.0: {} + + add-stream@1.0.0: {} + + agent-base@7.1.4: {} + + aggregate-error@3.1.0: + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-colors@4.1.3: {} + + ansi-escapes@4.3.2: + dependencies: + type-fest: 0.21.3 + + ansi-regex@5.0.1: {} + + ansi-regex@6.2.2: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@5.2.0: {} + + ansi-styles@6.2.3: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + aproba@2.0.0: {} + + arg@4.1.3: {} + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + + array-differ@3.0.0: {} + + array-ify@1.0.0: {} + + array-union@2.1.0: {} + + arrify@1.0.1: {} + + arrify@2.0.1: {} + + async@3.2.6: {} + + asynckit@0.4.0: {} + + axios@1.13.2: + dependencies: + follow-redirects: 1.15.11 + form-data: 4.0.4 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + babel-jest@29.7.0(@babel/core@7.28.5): + dependencies: + '@babel/core': 7.28.5 + '@jest/transform': 29.7.0 + '@types/babel__core': 7.20.5 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 29.6.3(@babel/core@7.28.5) + chalk: 4.1.2 + graceful-fs: 4.2.11 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-istanbul@6.1.1: + dependencies: + '@babel/helper-plugin-utils': 7.27.1 + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-instrument: 5.2.1 + test-exclude: 6.0.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-jest-hoist@29.6.3: + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.28.5 + '@types/babel__core': 7.20.5 + '@types/babel__traverse': 7.28.0 + + babel-preset-current-node-syntax@1.2.0(@babel/core@7.28.5): + dependencies: + '@babel/core': 7.28.5 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.28.5) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.28.5) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.28.5) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.28.5) + '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.28.5) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.28.5) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.28.5) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.28.5) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.28.5) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.28.5) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.28.5) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.28.5) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.28.5) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.28.5) + + babel-preset-jest@29.6.3(@babel/core@7.28.5): + dependencies: + '@babel/core': 7.28.5 + babel-plugin-jest-hoist: 29.6.3 + babel-preset-current-node-syntax: 1.2.0(@babel/core@7.28.5) + + balanced-match@1.0.2: {} + + base64-js@1.5.1: {} + + baseline-browser-mapping@2.8.25: {} + + before-after-hook@2.2.3: {} + + bin-links@4.0.4: + dependencies: + cmd-shim: 6.0.3 + npm-normalize-package-bin: 3.0.1 + read-cmd-shim: 4.0.0 + write-file-atomic: 5.0.1 + + bl@4.1.0: + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + + brace-expansion@1.1.12: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.2: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.27.0: + dependencies: + baseline-browser-mapping: 2.8.25 + caniuse-lite: 1.0.30001754 + electron-to-chromium: 1.5.249 + node-releases: 2.0.27 + update-browserslist-db: 1.1.4(browserslist@4.27.0) + + bs-logger@0.2.6: + dependencies: + fast-json-stable-stringify: 2.1.0 + + bser@2.1.1: + dependencies: + node-int64: 0.4.0 + + buffer-from@1.1.2: {} + + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + byte-size@8.1.1: {} + + cacache@18.0.4: + dependencies: + '@npmcli/fs': 3.1.1 + fs-minipass: 3.0.3 + glob: 10.4.5 + lru-cache: 10.4.3 + minipass: 7.1.2 + minipass-collect: 2.0.1 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + p-map: 4.0.0 + ssri: 10.0.6 + tar: 6.2.1 + unique-filename: 3.0.0 + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + callsites@3.1.0: {} + + camelcase-keys@6.2.2: + dependencies: + camelcase: 5.3.1 + map-obj: 4.3.0 + quick-lru: 4.0.1 + + camelcase@5.3.1: {} + + camelcase@6.3.0: {} + + caniuse-lite@1.0.30001754: {} + + chalk@4.1.0: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + char-regex@1.0.2: {} + + chardet@2.1.1: {} + + chownr@2.0.0: {} + + ci-info@3.9.0: {} + + ci-info@4.3.1: {} + + cjs-module-lexer@1.4.3: {} + + clean-stack@2.2.0: {} + + cli-cursor@3.1.0: + dependencies: + restore-cursor: 3.1.0 + + cli-spinners@2.6.1: {} + + cli-spinners@2.9.2: {} + + cli-width@3.0.0: {} + + cliui@7.0.4: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + clone-deep@4.0.1: + dependencies: + is-plain-object: 2.0.4 + kind-of: 6.0.3 + shallow-clone: 3.0.1 + + clone@1.0.4: {} + + cmd-shim@6.0.3: {} + + co@4.6.0: {} + + collect-v8-coverage@1.0.3: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + color-support@1.1.3: {} + + columnify@1.6.0: + dependencies: + strip-ansi: 6.0.1 + wcwidth: 1.0.1 + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + common-ancestor-path@1.0.1: {} + + compare-func@2.0.0: + dependencies: + array-ify: 1.0.0 + dot-prop: 5.3.0 + + concat-map@0.0.1: {} + + concat-stream@2.0.0: + dependencies: + buffer-from: 1.1.2 + inherits: 2.0.4 + readable-stream: 3.6.2 + typedarray: 0.0.6 + + console-control-strings@1.1.0: {} + + conventional-changelog-angular@7.0.0: + dependencies: + compare-func: 2.0.0 + + conventional-changelog-core@5.0.1: + dependencies: + add-stream: 1.0.0 + conventional-changelog-writer: 6.0.1 + conventional-commits-parser: 4.0.0 + dateformat: 3.0.3 + get-pkg-repo: 4.2.1 + git-raw-commits: 3.0.0 + git-remote-origin-url: 2.0.0 + git-semver-tags: 5.0.1 + normalize-package-data: 3.0.3 + read-pkg: 3.0.0 + read-pkg-up: 3.0.0 + + conventional-changelog-preset-loader@3.0.0: {} + + conventional-changelog-writer@6.0.1: + dependencies: + conventional-commits-filter: 3.0.0 + dateformat: 3.0.3 + handlebars: 4.7.8 + json-stringify-safe: 5.0.1 + meow: 8.1.2 + semver: 7.7.3 + split: 1.0.1 + + conventional-commits-filter@3.0.0: + dependencies: + lodash.ismatch: 4.4.0 + modify-values: 1.0.1 + + conventional-commits-parser@4.0.0: + dependencies: + JSONStream: 1.3.5 + is-text-path: 1.0.1 + meow: 8.1.2 + split2: 3.2.2 + + conventional-recommended-bump@7.0.1: + dependencies: + concat-stream: 2.0.0 + conventional-changelog-preset-loader: 3.0.0 + conventional-commits-filter: 3.0.0 + conventional-commits-parser: 4.0.0 + git-raw-commits: 3.0.0 + git-semver-tags: 5.0.1 + meow: 8.1.2 + + convert-source-map@2.0.0: {} + + copyfiles@2.4.1: + dependencies: + glob: 7.2.3 + minimatch: 3.1.2 + mkdirp: 1.0.4 + noms: 0.0.0 + through2: 2.0.5 + untildify: 4.0.0 + yargs: 16.2.0 + + core-util-is@1.0.3: {} + + cosmiconfig@9.0.0(typescript@5.9.3): + dependencies: + env-paths: 2.2.1 + import-fresh: 3.3.1 + js-yaml: 4.1.0 + parse-json: 5.2.0 + optionalDependencies: + typescript: 5.9.3 + + create-jest@29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3)): + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-config: 29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3)) + jest-util: 29.7.0 + prompts: 2.4.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + create-require@1.1.1: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + cssesc@3.0.0: {} + + csstype@3.1.3: {} + + dargs@7.0.0: {} + + dateformat@3.0.3: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decamelize-keys@1.1.1: + dependencies: + decamelize: 1.2.0 + map-obj: 1.0.1 + + decamelize@1.2.0: {} + + dedent@1.5.3: {} + + dedent@1.7.0: {} + + deep-is@0.1.4: {} + + deepmerge@4.3.1: {} + + defaults@1.0.4: + dependencies: + clone: 1.0.4 + + define-lazy-prop@2.0.0: {} + + delayed-stream@1.0.0: {} + + deprecation@2.3.1: {} + + detect-indent@5.0.0: {} + + detect-newline@3.1.0: {} + + diff-sequences@29.6.3: {} + + diff@4.0.2: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + doctrine@3.0.0: + dependencies: + esutils: 2.0.3 + + dot-prop@5.3.0: + dependencies: + is-obj: 2.0.0 + + dotenv-expand@11.0.7: + dependencies: + dotenv: 16.4.7 + + dotenv@16.4.7: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + eastasianwidth@0.2.0: {} + + ejs@3.1.10: + dependencies: + jake: 10.9.4 + + electron-to-chromium@1.5.249: {} + + emittery@0.13.1: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + encoding@0.1.13: + dependencies: + iconv-lite: 0.6.3 + optional: true + + end-of-stream@1.4.5: + dependencies: + once: 1.4.0 + + enquirer@2.3.6: + dependencies: + ansi-colors: 4.1.3 + + env-paths@2.2.1: {} + + envinfo@7.13.0: {} + + err-code@2.0.3: {} + + error-ex@1.3.4: + dependencies: + is-arrayish: 0.2.1 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + escalade@3.2.0: {} + + escape-string-regexp@1.0.5: {} + + escape-string-regexp@2.0.0: {} + + escape-string-regexp@4.0.0: {} + + eslint-config-prettier@9.1.2(eslint@8.57.1): + dependencies: + eslint: 8.57.1 + + eslint-plugin-simple-import-sort@12.1.1(eslint@8.57.1): + dependencies: + eslint: 8.57.1 + + eslint-plugin-unused-imports@4.3.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1): + dependencies: + eslint: 8.57.1 + optionalDependencies: + '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3) + + eslint-scope@7.2.2: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint@8.57.1: + dependencies: + '@eslint-community/eslint-utils': 4.9.0(eslint@8.57.1) + '@eslint-community/regexpp': 4.12.2 + '@eslint/eslintrc': 2.1.4 + '@eslint/js': 8.57.1 + '@humanwhocodes/config-array': 0.13.0 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + '@ungap/structured-clone': 1.3.0 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.24.0 + graphemer: 1.4.0 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + + espree@9.6.1: + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + eslint-visitor-keys: 3.4.3 + + esprima@4.0.1: {} + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + esutils@2.0.3: {} + + eventemitter3@4.0.7: {} + + execa@5.0.0: + dependencies: + cross-spawn: 7.0.6 + 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.7 + strip-final-newline: 2.0.0 + + execa@5.1.1: + dependencies: + cross-spawn: 7.0.6 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + + exit@0.1.2: {} + + expect@29.7.0: + dependencies: + '@jest/expect-utils': 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + + exponential-backoff@3.1.3: {} + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-patch@3.1.1: {} + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fastq@1.19.1: + dependencies: + reusify: 1.1.0 + + fb-watchman@2.0.2: + dependencies: + bser: 2.1.1 + + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + + figures@3.2.0: + dependencies: + escape-string-regexp: 1.0.5 + + file-entry-cache@6.0.1: + dependencies: + flat-cache: 3.2.0 + + filelist@1.0.4: + dependencies: + minimatch: 5.1.6 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@2.1.0: + dependencies: + locate-path: 2.0.0 + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@3.2.0: + dependencies: + flatted: 3.3.3 + keyv: 4.5.4 + rimraf: 3.0.2 + + flat@5.0.2: {} + + flatted@3.3.3: {} + + follow-redirects@1.15.11: {} + + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + form-data@4.0.4: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.2 + mime-types: 2.1.35 + + front-matter@4.0.2: + dependencies: + js-yaml: 3.14.1 + + fs-constants@1.0.0: {} + + fs-extra@11.3.2: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.0 + universalify: 2.0.1 + + fs-minipass@2.1.0: + dependencies: + minipass: 3.3.6 + + fs-minipass@3.0.3: + dependencies: + minipass: 7.1.2 + + fs.realpath@1.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + gensync@1.0.0-beta.2: {} + + get-caller-file@2.0.5: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-package-type@0.1.0: {} + + get-pkg-repo@4.2.1: + dependencies: + '@hutson/parse-repository-url': 3.0.2 + hosted-git-info: 4.1.0 + through2: 2.0.5 + yargs: 16.2.0 + + get-port@5.1.1: {} + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-stream@6.0.0: {} + + get-stream@6.0.1: {} + + git-raw-commits@3.0.0: + dependencies: + dargs: 7.0.0 + meow: 8.1.2 + split2: 3.2.2 + + git-remote-origin-url@2.0.0: + dependencies: + gitconfiglocal: 1.0.0 + pify: 2.3.0 + + git-semver-tags@5.0.1: + dependencies: + meow: 8.1.2 + semver: 7.7.3 + + git-up@7.0.0: + dependencies: + is-ssh: 1.4.1 + parse-url: 8.1.0 + + git-url-parse@14.0.0: + dependencies: + git-up: 7.0.0 + + gitconfiglocal@1.0.0: + dependencies: + ini: 1.3.8 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob@10.4.5: + dependencies: + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + glob@9.3.5: + dependencies: + fs.realpath: 1.0.0 + minimatch: 8.0.4 + minipass: 4.2.8 + path-scurry: 1.11.1 + + globals@13.24.0: + dependencies: + type-fest: 0.20.2 + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + gopd@1.2.0: {} + + graceful-fs@4.2.11: {} + + graphemer@1.4.0: {} + + handlebars@4.7.8: + dependencies: + minimist: 1.2.8 + neo-async: 2.6.2 + source-map: 0.6.1 + wordwrap: 1.0.0 + optionalDependencies: + uglify-js: 3.19.3 + + hard-rejection@2.1.0: {} + + has-flag@4.0.0: {} + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + has-unicode@2.0.1: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + hosted-git-info@2.8.9: {} + + hosted-git-info@4.1.0: + dependencies: + lru-cache: 6.0.0 + + hosted-git-info@7.0.2: + dependencies: + lru-cache: 10.4.3 + + html-escaper@2.0.2: {} + + http-cache-semantics@4.2.0: {} + + http-proxy-agent@7.0.2: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + human-signals@2.1.0: {} + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + optional: true + + iconv-lite@0.7.0: + dependencies: + safer-buffer: 2.1.2 + + ieee754@1.2.1: {} + + ignore-walk@6.0.5: + dependencies: + minimatch: 9.0.5 + + ignore@5.3.2: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + import-local@3.1.0: + dependencies: + pkg-dir: 4.2.0 + resolve-cwd: 3.0.0 + + import-local@3.2.0: + dependencies: + pkg-dir: 4.2.0 + resolve-cwd: 3.0.0 + + imurmurhash@0.1.4: {} + + indent-string@4.0.0: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + ini@1.3.8: {} + + ini@4.1.3: {} + + init-package-json@6.0.3: + dependencies: + '@npmcli/package-json': 5.2.0 + npm-package-arg: 11.0.2 + promzard: 1.0.2 + read: 3.0.1 + semver: 7.7.3 + validate-npm-package-license: 3.0.4 + validate-npm-package-name: 5.0.1 + transitivePeerDependencies: + - bluebird + + inquirer@8.2.7(@types/node@20.19.24): + dependencies: + '@inquirer/external-editor': 1.0.2(@types/node@20.19.24) + ansi-escapes: 4.3.2 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-width: 3.0.0 + figures: 3.2.0 + lodash: 4.17.21 + mute-stream: 0.0.8 + ora: 5.4.1 + run-async: 2.4.1 + rxjs: 7.8.2 + string-width: 4.2.3 + strip-ansi: 6.0.1 + through: 2.3.8 + wrap-ansi: 6.2.0 + transitivePeerDependencies: + - '@types/node' + + inquirerer@2.0.8: + dependencies: + chalk: 4.1.2 + deepmerge: 4.3.1 + js-yaml: 4.1.0 + minimist: 1.2.8 + + ip-address@10.0.1: {} + + is-arrayish@0.2.1: {} + + is-ci@3.0.1: + dependencies: + ci-info: 3.9.0 + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-docker@2.2.1: {} + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-generator-fn@2.1.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-interactive@1.0.0: {} + + is-lambda@1.0.1: {} + + is-number@7.0.0: {} + + is-obj@2.0.0: {} + + is-path-inside@3.0.3: {} + + is-plain-obj@1.1.0: {} + + is-plain-object@2.0.4: + dependencies: + isobject: 3.0.1 + + is-ssh@1.4.1: + dependencies: + protocols: 2.0.2 + + is-stream@2.0.0: {} + + is-stream@2.0.1: {} + + is-text-path@1.0.1: + dependencies: + text-extensions: 1.9.0 + + is-unicode-supported@0.1.0: {} + + is-wsl@2.2.0: + dependencies: + is-docker: 2.2.1 + + isarray@0.0.1: {} + + isarray@1.0.0: {} + + isexe@2.0.0: {} + + isexe@3.1.1: {} + + isobject@3.0.1: {} + + isomorphic-fetch@3.0.0(encoding@0.1.13): + dependencies: + node-fetch: 2.7.0(encoding@0.1.13) + whatwg-fetch: 3.6.20 + transitivePeerDependencies: + - encoding + + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-instrument@5.2.1: + dependencies: + '@babel/core': 7.28.5 + '@babel/parser': 7.28.5 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + istanbul-lib-instrument@6.0.3: + dependencies: + '@babel/core': 7.28.5 + '@babel/parser': 7.28.5 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 7.7.3 + transitivePeerDependencies: + - supports-color + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-lib-source-maps@4.0.1: + dependencies: + debug: 4.4.3 + istanbul-lib-coverage: 3.2.2 + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + + istanbul-reports@3.2.0: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jake@10.9.4: + dependencies: + async: 3.2.6 + filelist: 1.0.4 + picocolors: 1.1.1 + + jest-changed-files@29.7.0: + dependencies: + execa: 5.1.1 + jest-util: 29.7.0 + p-limit: 3.1.0 + + jest-circus@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.19.24 + chalk: 4.1.2 + co: 4.6.0 + dedent: 1.7.0 + is-generator-fn: 2.1.0 + jest-each: 29.7.0 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + p-limit: 3.1.0 + pretty-format: 29.7.0 + pure-rand: 6.1.0 + slash: 3.0.0 + stack-utils: 2.0.6 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + jest-cli@29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3)): + dependencies: + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3)) + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + chalk: 4.1.2 + create-jest: 29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3)) + exit: 0.1.2 + import-local: 3.2.0 + jest-config: 29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3)) + jest-util: 29.7.0 + jest-validate: 29.7.0 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + jest-config@29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3)): + dependencies: + '@babel/core': 7.28.5 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.28.5) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0 + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.8 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 20.19.24 + ts-node: 10.9.2(@types/node@20.19.24)(typescript@5.9.3) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + jest-diff@29.7.0: + dependencies: + chalk: 4.1.0 + diff-sequences: 29.6.3 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-docblock@29.7.0: + dependencies: + detect-newline: 3.1.0 + + jest-each@29.7.0: + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + jest-get-type: 29.6.3 + jest-util: 29.7.0 + pretty-format: 29.7.0 + + jest-environment-node@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.19.24 + jest-mock: 29.7.0 + jest-util: 29.7.0 + + jest-get-type@29.6.3: {} + + jest-haste-map@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/graceful-fs': 4.1.9 + '@types/node': 20.19.24 + anymatch: 3.1.3 + fb-watchman: 2.0.2 + graceful-fs: 4.2.11 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + jest-worker: 29.7.0 + micromatch: 4.0.8 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.3 + + jest-leak-detector@29.7.0: + dependencies: + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-matcher-utils@29.7.0: + dependencies: + chalk: 4.1.2 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-message-util@29.7.0: + dependencies: + '@babel/code-frame': 7.27.1 + '@jest/types': 29.6.3 + '@types/stack-utils': 2.0.3 + chalk: 4.1.2 + graceful-fs: 4.2.11 + micromatch: 4.0.8 + pretty-format: 29.7.0 + slash: 3.0.0 + stack-utils: 2.0.6 + + jest-mock@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/node': 20.19.24 + jest-util: 29.7.0 + + jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): + optionalDependencies: + jest-resolve: 29.7.0 + + jest-regex-util@29.6.3: {} + + jest-resolve-dependencies@29.7.0: + dependencies: + jest-regex-util: 29.6.3 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + + jest-resolve@29.7.0: + dependencies: + chalk: 4.1.2 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0) + jest-util: 29.7.0 + jest-validate: 29.7.0 + resolve: 1.22.11 + resolve.exports: 2.0.3 + slash: 3.0.0 + + jest-runner@29.7.0: + dependencies: + '@jest/console': 29.7.0 + '@jest/environment': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.19.24 + chalk: 4.1.2 + emittery: 0.13.1 + graceful-fs: 4.2.11 + jest-docblock: 29.7.0 + jest-environment-node: 29.7.0 + jest-haste-map: 29.7.0 + jest-leak-detector: 29.7.0 + jest-message-util: 29.7.0 + jest-resolve: 29.7.0 + jest-runtime: 29.7.0 + jest-util: 29.7.0 + jest-watcher: 29.7.0 + jest-worker: 29.7.0 + p-limit: 3.1.0 + source-map-support: 0.5.13 + transitivePeerDependencies: + - supports-color + + jest-runtime@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/globals': 29.7.0 + '@jest/source-map': 29.6.3 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.19.24 + chalk: 4.1.2 + cjs-module-lexer: 1.4.3 + collect-v8-coverage: 1.0.3 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + strip-bom: 4.0.0 + transitivePeerDependencies: + - supports-color + + jest-snapshot@29.7.0: + dependencies: + '@babel/core': 7.28.5 + '@babel/generator': 7.28.5 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.5) + '@babel/types': 7.28.5 + '@jest/expect-utils': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + babel-preset-current-node-syntax: 1.2.0(@babel/core@7.28.5) + chalk: 4.1.2 + expect: 29.7.0 + graceful-fs: 4.2.11 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + natural-compare: 1.4.0 + pretty-format: 29.7.0 + semver: 7.7.3 + transitivePeerDependencies: + - supports-color + + jest-util@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/node': 20.19.24 + chalk: 4.1.2 + ci-info: 3.9.0 + graceful-fs: 4.2.11 + picomatch: 2.3.1 + + jest-validate@29.7.0: + dependencies: + '@jest/types': 29.6.3 + camelcase: 6.3.0 + chalk: 4.1.2 + jest-get-type: 29.6.3 + leven: 3.1.0 + pretty-format: 29.7.0 + + jest-watcher@29.7.0: + dependencies: + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.19.24 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + emittery: 0.13.1 + jest-util: 29.7.0 + string-length: 4.0.2 + + jest-worker@29.7.0: + dependencies: + '@types/node': 20.19.24 + jest-util: 29.7.0 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + jest@29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3)): + dependencies: + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3)) + '@jest/types': 29.6.3 + import-local: 3.2.0 + jest-cli: 29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3)) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + js-tokens@4.0.0: {} + + js-yaml@3.14.1: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + jsesc@3.1.0: {} + + json-buffer@3.0.1: {} + + json-parse-better-errors@1.0.2: {} + + json-parse-even-better-errors@2.3.1: {} + + json-parse-even-better-errors@3.0.2: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json-stringify-nice@1.1.4: {} + + json-stringify-safe@5.0.1: {} + + json5@2.2.3: {} + + jsonc-parser@3.2.0: {} + + jsonfile@6.2.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + jsonparse@1.3.1: {} + + just-diff-apply@5.5.0: {} + + just-diff@6.0.2: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + kind-of@6.0.3: {} + + kleur@3.0.3: {} + + lerna@8.2.4(@types/node@20.19.24)(encoding@0.1.13): + dependencies: + '@lerna/create': 8.2.4(@types/node@20.19.24)(encoding@0.1.13)(typescript@5.9.3) + '@npmcli/arborist': 7.5.4 + '@npmcli/package-json': 5.2.0 + '@npmcli/run-script': 8.1.0 + '@nx/devkit': 20.8.2(nx@20.8.2) + '@octokit/plugin-enterprise-rest': 6.0.1 + '@octokit/rest': 20.1.2 + aproba: 2.0.0 + byte-size: 8.1.1 + chalk: 4.1.0 + clone-deep: 4.0.1 + cmd-shim: 6.0.3 + color-support: 1.1.3 + columnify: 1.6.0 + console-control-strings: 1.1.0 + conventional-changelog-angular: 7.0.0 + conventional-changelog-core: 5.0.1 + conventional-recommended-bump: 7.0.1 + cosmiconfig: 9.0.0(typescript@5.9.3) + dedent: 1.5.3 + envinfo: 7.13.0 + execa: 5.0.0 + fs-extra: 11.3.2 + get-port: 5.1.1 + get-stream: 6.0.0 + git-url-parse: 14.0.0 + glob-parent: 6.0.2 + graceful-fs: 4.2.11 + has-unicode: 2.0.1 + import-local: 3.1.0 + ini: 1.3.8 + init-package-json: 6.0.3 + inquirer: 8.2.7(@types/node@20.19.24) + is-ci: 3.0.1 + is-stream: 2.0.0 + jest-diff: 29.7.0 + js-yaml: 4.1.0 + libnpmaccess: 8.0.6 + libnpmpublish: 9.0.9 + load-json-file: 6.2.0 + make-dir: 4.0.0 + minimatch: 3.0.5 + multimatch: 5.0.0 + node-fetch: 2.6.7(encoding@0.1.13) + npm-package-arg: 11.0.2 + npm-packlist: 8.0.2 + npm-registry-fetch: 17.1.0 + nx: 20.8.2 + p-map: 4.0.0 + p-map-series: 2.1.0 + p-pipe: 3.1.0 + p-queue: 6.6.2 + p-reduce: 2.1.0 + p-waterfall: 2.1.1 + pacote: 18.0.6 + pify: 5.0.0 + read-cmd-shim: 4.0.0 + resolve-from: 5.0.0 + rimraf: 4.4.1 + semver: 7.7.3 + set-blocking: 2.0.0 + signal-exit: 3.0.7 + slash: 3.0.0 + ssri: 10.0.6 + string-width: 4.2.3 + tar: 6.2.1 + temp-dir: 1.0.0 + through: 2.3.8 + tinyglobby: 0.2.12 + typescript: 5.9.3 + upath: 2.0.1 + uuid: 10.0.0 + validate-npm-package-license: 3.0.4 + validate-npm-package-name: 5.0.1 + wide-align: 1.1.5 + write-file-atomic: 5.0.1 + write-pkg: 4.0.0 + yargs: 17.7.2 + yargs-parser: 21.1.1 + transitivePeerDependencies: + - '@swc-node/register' + - '@swc/core' + - '@types/node' + - babel-plugin-macros + - bluebird + - debug + - encoding + - supports-color + + leven@3.1.0: {} + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + libnpmaccess@8.0.6: + dependencies: + npm-package-arg: 11.0.2 + npm-registry-fetch: 17.1.0 + transitivePeerDependencies: + - supports-color + + libnpmpublish@9.0.9: + dependencies: + ci-info: 4.3.1 + normalize-package-data: 6.0.2 + npm-package-arg: 11.0.2 + npm-registry-fetch: 17.1.0 + proc-log: 4.2.0 + semver: 7.7.3 + sigstore: 2.3.1 + ssri: 10.0.6 + transitivePeerDependencies: + - supports-color + + lines-and-columns@1.2.4: {} + + lines-and-columns@2.0.3: {} + + load-json-file@4.0.0: + dependencies: + graceful-fs: 4.2.11 + parse-json: 4.0.0 + pify: 3.0.0 + strip-bom: 3.0.0 + + load-json-file@6.2.0: + dependencies: + graceful-fs: 4.2.11 + parse-json: 5.2.0 + strip-bom: 4.0.0 + type-fest: 0.6.0 + + locate-path@2.0.0: + dependencies: + p-locate: 2.0.0 + path-exists: 3.0.0 + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.ismatch@4.4.0: {} + + lodash.memoize@4.1.2: {} + + lodash.merge@4.6.2: {} + + lodash@4.17.21: {} + + log-symbols@4.1.0: + dependencies: + chalk: 4.1.0 + is-unicode-supported: 0.1.0 + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + lru-cache@10.4.3: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + lru-cache@6.0.0: + dependencies: + yallist: 4.0.0 + + make-dir@2.1.0: + dependencies: + pify: 4.0.1 + semver: 5.7.2 + + make-dir@4.0.0: + dependencies: + semver: 7.7.3 + + make-error@1.3.6: {} + + make-fetch-happen@13.0.1: + dependencies: + '@npmcli/agent': 2.2.2 + cacache: 18.0.4 + http-cache-semantics: 4.2.0 + is-lambda: 1.0.1 + minipass: 7.1.2 + minipass-fetch: 3.0.5 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + negotiator: 0.6.4 + proc-log: 4.2.0 + promise-retry: 2.0.1 + ssri: 10.0.6 + transitivePeerDependencies: + - supports-color + + makeerror@1.0.12: + dependencies: + tmpl: 1.0.5 + + map-obj@1.0.1: {} + + map-obj@4.3.0: {} + + math-intrinsics@1.1.0: {} + + meow@8.1.2: + dependencies: + '@types/minimist': 1.2.5 + camelcase-keys: 6.2.2 + decamelize-keys: 1.1.1 + hard-rejection: 2.1.0 + minimist-options: 4.1.0 + normalize-package-data: 3.0.3 + read-pkg-up: 7.0.1 + redent: 3.0.0 + trim-newlines: 3.0.1 + type-fest: 0.18.1 + yargs-parser: 20.2.9 + + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mimic-fn@2.1.0: {} + + min-indent@1.0.1: {} + + minimatch@3.0.5: + dependencies: + brace-expansion: 1.1.12 + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.12 + + minimatch@5.1.6: + dependencies: + brace-expansion: 2.0.2 + + minimatch@8.0.4: + dependencies: + brace-expansion: 2.0.2 + + minimatch@9.0.3: + dependencies: + brace-expansion: 2.0.2 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.2 + + minimist-options@4.1.0: + dependencies: + arrify: 1.0.1 + is-plain-obj: 1.1.0 + kind-of: 6.0.3 + + minimist@1.2.8: {} + + minipass-collect@2.0.1: + dependencies: + minipass: 7.1.2 + + minipass-fetch@3.0.5: + dependencies: + minipass: 7.1.2 + minipass-sized: 1.0.3 + minizlib: 2.1.2 + optionalDependencies: + encoding: 0.1.13 + + minipass-flush@1.0.5: + dependencies: + minipass: 3.3.6 + + minipass-pipeline@1.2.4: + dependencies: + minipass: 3.3.6 + + minipass-sized@1.0.3: + dependencies: + minipass: 3.3.6 + + minipass@3.3.6: + dependencies: + yallist: 4.0.0 + + minipass@4.2.8: {} + + minipass@5.0.0: {} + + minipass@7.1.2: {} + + minizlib@2.1.2: + dependencies: + minipass: 3.3.6 + yallist: 4.0.0 + + mkdirp@1.0.4: {} + + modify-values@1.0.1: {} + + ms@2.1.3: {} + + multimatch@5.0.0: + dependencies: + '@types/minimatch': 3.0.5 + array-differ: 3.0.0 + array-union: 2.1.0 + arrify: 2.0.1 + minimatch: 3.0.5 + + mute-stream@0.0.8: {} + + mute-stream@1.0.0: {} + + natural-compare@1.4.0: {} + + negotiator@0.6.4: {} + + neo-async@2.6.2: {} + + node-fetch@2.6.7(encoding@0.1.13): + dependencies: + whatwg-url: 5.0.0 + optionalDependencies: + encoding: 0.1.13 + + node-fetch@2.7.0(encoding@0.1.13): + dependencies: + whatwg-url: 5.0.0 + optionalDependencies: + encoding: 0.1.13 + + node-gyp@10.3.1: + dependencies: + env-paths: 2.2.1 + exponential-backoff: 3.1.3 + glob: 10.4.5 + graceful-fs: 4.2.11 + make-fetch-happen: 13.0.1 + nopt: 7.2.1 + proc-log: 4.2.0 + semver: 7.7.3 + tar: 6.2.1 + which: 4.0.0 + transitivePeerDependencies: + - supports-color + + node-int64@0.4.0: {} + + node-machine-id@1.1.12: {} + + node-releases@2.0.27: {} + + noms@0.0.0: + dependencies: + inherits: 2.0.4 + readable-stream: 1.0.34 + + nopt@7.2.1: + dependencies: + abbrev: 2.0.0 + + normalize-package-data@2.5.0: + dependencies: + hosted-git-info: 2.8.9 + resolve: 1.22.11 + semver: 5.7.2 + validate-npm-package-license: 3.0.4 + + normalize-package-data@3.0.3: + dependencies: + hosted-git-info: 4.1.0 + is-core-module: 2.16.1 + semver: 7.7.3 + validate-npm-package-license: 3.0.4 + + normalize-package-data@6.0.2: + dependencies: + hosted-git-info: 7.0.2 + semver: 7.7.3 + validate-npm-package-license: 3.0.4 + + normalize-path@3.0.0: {} + + npm-bundled@3.0.1: + dependencies: + npm-normalize-package-bin: 3.0.1 + + npm-install-checks@6.3.0: + dependencies: + semver: 7.7.3 + + npm-normalize-package-bin@3.0.1: {} + + npm-package-arg@11.0.2: + dependencies: + hosted-git-info: 7.0.2 + proc-log: 4.2.0 + semver: 7.7.3 + validate-npm-package-name: 5.0.1 + + npm-packlist@8.0.2: + dependencies: + ignore-walk: 6.0.5 + + npm-pick-manifest@9.1.0: + dependencies: + npm-install-checks: 6.3.0 + npm-normalize-package-bin: 3.0.1 + npm-package-arg: 11.0.2 + semver: 7.7.3 + + npm-registry-fetch@17.1.0: + dependencies: + '@npmcli/redact': 2.0.1 + jsonparse: 1.3.1 + make-fetch-happen: 13.0.1 + minipass: 7.1.2 + minipass-fetch: 3.0.5 + minizlib: 2.1.2 + npm-package-arg: 11.0.2 + proc-log: 4.2.0 + transitivePeerDependencies: + - supports-color + + npm-run-path@4.0.1: + dependencies: + path-key: 3.1.1 + + nx@20.8.2: + dependencies: + '@napi-rs/wasm-runtime': 0.2.4 + '@yarnpkg/lockfile': 1.1.0 + '@yarnpkg/parsers': 3.0.2 + '@zkochan/js-yaml': 0.0.7 + axios: 1.13.2 + chalk: 4.1.0 + cli-cursor: 3.1.0 + cli-spinners: 2.6.1 + cliui: 8.0.1 + dotenv: 16.4.7 + dotenv-expand: 11.0.7 + enquirer: 2.3.6 + figures: 3.2.0 + flat: 5.0.2 + front-matter: 4.0.2 + ignore: 5.3.2 + jest-diff: 29.7.0 + jsonc-parser: 3.2.0 + lines-and-columns: 2.0.3 + minimatch: 9.0.3 + node-machine-id: 1.1.12 + npm-run-path: 4.0.1 + open: 8.4.2 + ora: 5.3.0 + resolve.exports: 2.0.3 + semver: 7.7.3 + string-width: 4.2.3 + tar-stream: 2.2.0 + tmp: 0.2.5 + tsconfig-paths: 4.2.0 + tslib: 2.8.1 + yaml: 2.8.1 + yargs: 17.7.2 + yargs-parser: 21.1.1 + optionalDependencies: + '@nx/nx-darwin-arm64': 20.8.2 + '@nx/nx-darwin-x64': 20.8.2 + '@nx/nx-freebsd-x64': 20.8.2 + '@nx/nx-linux-arm-gnueabihf': 20.8.2 + '@nx/nx-linux-arm64-gnu': 20.8.2 + '@nx/nx-linux-arm64-musl': 20.8.2 + '@nx/nx-linux-x64-gnu': 20.8.2 + '@nx/nx-linux-x64-musl': 20.8.2 + '@nx/nx-win32-arm64-msvc': 20.8.2 + '@nx/nx-win32-x64-msvc': 20.8.2 + transitivePeerDependencies: + - debug + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + open@8.4.2: + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + ora@5.3.0: + dependencies: + bl: 4.1.0 + chalk: 4.1.0 + cli-cursor: 3.1.0 + cli-spinners: 2.6.1 + is-interactive: 1.0.0 + log-symbols: 4.1.0 + strip-ansi: 6.0.1 + wcwidth: 1.0.1 + + ora@5.4.1: + dependencies: + bl: 4.1.0 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-spinners: 2.9.2 + is-interactive: 1.0.0 + is-unicode-supported: 0.1.0 + log-symbols: 4.1.0 + strip-ansi: 6.0.1 + wcwidth: 1.0.1 + + p-finally@1.0.0: {} + + p-limit@1.3.0: + dependencies: + p-try: 1.0.0 + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@2.0.0: + dependencies: + p-limit: 1.3.0 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + p-map-series@2.1.0: {} + + p-map@4.0.0: + dependencies: + aggregate-error: 3.1.0 + + p-pipe@3.1.0: {} + + p-queue@6.6.2: + dependencies: + eventemitter3: 4.0.7 + p-timeout: 3.2.0 + + p-reduce@2.1.0: {} + + p-timeout@3.2.0: + dependencies: + p-finally: 1.0.0 + + p-try@1.0.0: {} + + p-try@2.2.0: {} + + p-waterfall@2.1.1: + dependencies: + p-reduce: 2.1.0 + + package-json-from-dist@1.0.1: {} + + pacote@18.0.6: + dependencies: + '@npmcli/git': 5.0.8 + '@npmcli/installed-package-contents': 2.1.0 + '@npmcli/package-json': 5.2.0 + '@npmcli/promise-spawn': 7.0.2 + '@npmcli/run-script': 8.1.0 + cacache: 18.0.4 + fs-minipass: 3.0.3 + minipass: 7.1.2 + npm-package-arg: 11.0.2 + npm-packlist: 8.0.2 + npm-pick-manifest: 9.1.0 + npm-registry-fetch: 17.1.0 + proc-log: 4.2.0 + promise-retry: 2.0.1 + sigstore: 2.3.1 + ssri: 10.0.6 + tar: 6.2.1 + transitivePeerDependencies: + - bluebird + - supports-color + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse-conflict-json@3.0.1: + dependencies: + json-parse-even-better-errors: 3.0.2 + just-diff: 6.0.2 + just-diff-apply: 5.5.0 + + parse-json@4.0.0: + dependencies: + error-ex: 1.3.4 + json-parse-better-errors: 1.0.2 + + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.27.1 + error-ex: 1.3.4 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + + parse-path@7.1.0: + dependencies: + protocols: 2.0.2 + + parse-url@8.1.0: + dependencies: + parse-path: 7.1.0 + + path-exists@3.0.0: {} + + path-exists@4.0.0: {} + + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + + path-type@3.0.0: + dependencies: + pify: 3.0.0 + + path-type@4.0.0: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.3: {} + + pify@2.3.0: {} + + pify@3.0.0: {} + + pify@4.0.1: {} + + pify@5.0.0: {} + + pirates@4.0.7: {} + + pkg-dir@4.2.0: + dependencies: + find-up: 4.1.0 + + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + prelude-ls@1.2.1: {} + + prettier@3.6.2: {} + + pretty-format@29.7.0: + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.3.1 + + proc-log@4.2.0: {} + + process-nextick-args@2.0.1: {} + + proggy@2.0.0: {} + + promise-all-reject-late@1.0.1: {} + + promise-call-limit@3.0.2: {} + + promise-inflight@1.0.1: {} + + promise-retry@2.0.1: + dependencies: + err-code: 2.0.3 + retry: 0.12.0 + + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + + promzard@1.0.2: + dependencies: + read: 3.0.1 + + protocols@2.0.2: {} + + proxy-from-env@1.1.0: {} + + punycode@2.3.1: {} + + pure-rand@6.1.0: {} + + queue-microtask@1.2.3: {} + + quick-lru@4.0.1: {} + + react-is@18.3.1: {} + + react@18.3.1: + dependencies: + loose-envify: 1.4.0 + + read-cmd-shim@4.0.0: {} + + read-package-json-fast@3.0.2: + dependencies: + json-parse-even-better-errors: 3.0.2 + npm-normalize-package-bin: 3.0.1 + + read-pkg-up@3.0.0: + dependencies: + find-up: 2.1.0 + read-pkg: 3.0.0 + + read-pkg-up@7.0.1: + dependencies: + find-up: 4.1.0 + read-pkg: 5.2.0 + type-fest: 0.8.1 + + read-pkg@3.0.0: + dependencies: + load-json-file: 4.0.0 + normalize-package-data: 2.5.0 + path-type: 3.0.0 + + read-pkg@5.2.0: + dependencies: + '@types/normalize-package-data': 2.4.4 + normalize-package-data: 2.5.0 + parse-json: 5.2.0 + type-fest: 0.6.0 + + read@3.0.1: + dependencies: + mute-stream: 1.0.0 + + readable-stream@1.0.34: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 0.0.1 + string_decoder: 0.10.31 + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + redent@3.0.0: + dependencies: + indent-string: 4.0.0 + strip-indent: 3.0.0 + + require-directory@2.1.1: {} + + resolve-cwd@3.0.0: + dependencies: + resolve-from: 5.0.0 + + resolve-from@4.0.0: {} + + resolve-from@5.0.0: {} + + resolve.exports@2.0.3: {} + + resolve@1.22.11: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + restore-cursor@3.1.0: + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + + retry@0.12.0: {} + + reusify@1.1.0: {} + + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + + rimraf@4.4.1: + dependencies: + glob: 9.3.5 + + run-async@2.4.1: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + rxjs@7.8.2: + dependencies: + tslib: 2.8.1 + + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + + safer-buffer@2.1.2: {} + + schema-sdk@0.12.0(encoding@0.1.13): + dependencies: + '@babel/generator': 7.28.5 + '@babel/types': 7.28.5 + '@interweb-utils/casing': 0.2.0 + '@interweb/fetch-api-client': 0.6.1(encoding@0.1.13) + deepmerge: 4.3.1 + fast-json-patch: 3.1.1 + schema-typescript: 0.12.1 + transitivePeerDependencies: + - encoding + + schema-typescript@0.12.1: + dependencies: + '@babel/generator': 7.28.5 + '@babel/types': 7.28.5 + '@interweb-utils/casing': 0.2.0 + deepmerge: 4.3.1 + minimatch: 9.0.5 + + semver@5.7.2: {} + + semver@6.3.1: {} + + semver@7.7.3: {} + + set-blocking@2.0.0: {} + + shallow-clone@3.0.1: + dependencies: + kind-of: 6.0.3 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + signal-exit@3.0.7: {} + + signal-exit@4.1.0: {} + + sigstore@2.3.1: + dependencies: + '@sigstore/bundle': 2.3.2 + '@sigstore/core': 1.1.0 + '@sigstore/protobuf-specs': 0.3.3 + '@sigstore/sign': 2.3.2 + '@sigstore/tuf': 2.3.4 + '@sigstore/verify': 1.2.1 + transitivePeerDependencies: + - supports-color + + sisteransi@1.0.5: {} + + slash@3.0.0: {} + + smart-buffer@4.2.0: {} + + socks-proxy-agent@8.0.5: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + socks: 2.8.7 + transitivePeerDependencies: + - supports-color + + socks@2.8.7: + dependencies: + ip-address: 10.0.1 + smart-buffer: 4.2.0 + + sort-keys@2.0.0: + dependencies: + is-plain-obj: 1.1.0 + + source-map-support@0.5.13: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + + spdx-correct@3.2.0: + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.22 + + spdx-exceptions@2.5.0: {} + + spdx-expression-parse@3.0.1: + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.22 + + spdx-license-ids@3.0.22: {} + + split2@3.2.2: + dependencies: + readable-stream: 3.6.2 + + split@1.0.1: + dependencies: + through: 2.3.8 + + sprintf-js@1.0.3: {} + + ssri@10.0.6: + dependencies: + minipass: 7.1.2 + + stack-utils@2.0.6: + dependencies: + escape-string-regexp: 2.0.0 + + string-length@4.0.2: + dependencies: + char-regex: 1.0.2 + strip-ansi: 6.0.1 + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.2 + + string_decoder@0.10.31: {} + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.2: + dependencies: + ansi-regex: 6.2.2 + + strip-bom@3.0.0: {} + + strip-bom@4.0.0: {} + + strip-final-newline@2.0.0: {} + + strip-indent@3.0.0: + dependencies: + min-indent: 1.0.1 + + strip-json-comments@3.1.1: {} + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + tar-stream@2.2.0: + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.5 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + + tar@6.2.1: + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 5.0.0 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + + temp-dir@1.0.0: {} + + test-exclude@6.0.0: + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 7.2.3 + minimatch: 3.1.2 + + text-extensions@1.9.0: {} + + text-table@0.2.0: {} + + through2@2.0.5: + dependencies: + readable-stream: 2.3.8 + xtend: 4.0.2 + + through@2.3.8: {} + + tinyglobby@0.2.12: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + + tmp@0.2.5: {} + + tmpl@1.0.5: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + tr46@0.0.3: {} + + treeverse@3.0.0: {} + + trim-newlines@3.0.1: {} + + ts-api-utils@1.4.3(typescript@5.9.3): + dependencies: + typescript: 5.9.3 + + ts-jest@29.4.5(@babel/core@7.28.5)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.5))(jest-util@29.7.0)(jest@29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3)))(typescript@5.9.3): + dependencies: + bs-logger: 0.2.6 + fast-json-stable-stringify: 2.1.0 + handlebars: 4.7.8 + jest: 29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3)) + json5: 2.2.3 + lodash.memoize: 4.1.2 + make-error: 1.3.6 + semver: 7.7.3 + type-fest: 4.41.0 + typescript: 5.9.3 + yargs-parser: 21.1.1 + optionalDependencies: + '@babel/core': 7.28.5 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.28.5) + jest-util: 29.7.0 + + ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 20.19.24 + acorn: 8.15.0 + acorn-walk: 8.3.4 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.9.3 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + + tsconfig-paths@4.2.0: + dependencies: + json5: 2.2.3 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tslib@2.8.1: {} + + tuf-js@2.2.1: + dependencies: + '@tufjs/models': 2.0.1 + debug: 4.4.3 + make-fetch-happen: 13.0.1 + transitivePeerDependencies: + - supports-color + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type-detect@4.0.8: {} + + type-fest@0.18.1: {} + + type-fest@0.20.2: {} + + type-fest@0.21.3: {} + + type-fest@0.4.1: {} + + type-fest@0.6.0: {} + + type-fest@0.8.1: {} + + type-fest@4.41.0: {} + + typedarray@0.0.6: {} + + typescript@5.9.3: {} + + uglify-js@3.19.3: + optional: true + + undici-types@6.21.0: {} + + unique-filename@3.0.0: + dependencies: + unique-slug: 4.0.0 + + unique-slug@4.0.0: + dependencies: + imurmurhash: 0.1.4 + + universal-user-agent@6.0.1: {} + + universalify@2.0.1: {} + + untildify@4.0.0: {} + + upath@2.0.1: {} + + update-browserslist-db@1.1.4(browserslist@4.27.0): + dependencies: + browserslist: 4.27.0 + escalade: 3.2.0 + picocolors: 1.1.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + util-deprecate@1.0.2: {} + + uuid@10.0.0: {} + + v8-compile-cache-lib@3.0.1: {} + + v8-to-istanbul@9.3.0: + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + '@types/istanbul-lib-coverage': 2.0.6 + convert-source-map: 2.0.0 + + validate-npm-package-license@3.0.4: + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + + validate-npm-package-name@5.0.1: {} + + walk-up-path@3.0.1: {} + + walker@1.0.8: + dependencies: + makeerror: 1.0.12 + + wcwidth@1.0.1: + dependencies: + defaults: 1.0.4 + + webidl-conversions@3.0.1: {} + + whatwg-fetch@3.6.20: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + which@4.0.0: + dependencies: + isexe: 3.1.1 + + wide-align@1.1.5: + dependencies: + string-width: 4.2.3 + + word-wrap@1.2.5: {} + + wordwrap@1.0.0: {} + + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.3 + string-width: 5.1.2 + strip-ansi: 7.1.2 + + wrappy@1.0.2: {} + + write-file-atomic@2.4.3: + dependencies: + graceful-fs: 4.2.11 + imurmurhash: 0.1.4 + signal-exit: 3.0.7 + + write-file-atomic@4.0.2: + dependencies: + imurmurhash: 0.1.4 + signal-exit: 3.0.7 + + write-file-atomic@5.0.1: + dependencies: + imurmurhash: 0.1.4 + signal-exit: 4.1.0 + + write-json-file@3.2.0: + dependencies: + detect-indent: 5.0.0 + graceful-fs: 4.2.11 + make-dir: 2.1.0 + pify: 4.0.1 + sort-keys: 2.0.0 + write-file-atomic: 2.4.3 + + write-pkg@4.0.0: + dependencies: + sort-keys: 2.0.0 + type-fest: 0.4.1 + write-json-file: 3.2.0 + + xtend@4.0.2: {} + + y18n@5.0.8: {} + + yallist@3.1.1: {} + + yallist@4.0.0: {} + + yaml@2.8.1: {} + + yargs-parser@20.2.9: {} + + yargs-parser@21.1.1: {} + + yargs@16.2.0: + dependencies: + cliui: 7.0.4 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 20.2.9 + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yn@3.1.1: {} + + yocto-queue@0.1.0: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..66330e2 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,3 @@ +packages: + - 'packages/*' + diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index d1be38b..0000000 --- a/yarn.lock +++ /dev/null @@ -1,6833 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@ampproject/remapping@^2.2.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4" - integrity sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw== - dependencies: - "@jridgewell/gen-mapping" "^0.3.5" - "@jridgewell/trace-mapping" "^0.3.24" - -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.27.1.tgz#200f715e66d52a23b221a9435534a91cc13ad5be" - integrity sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg== - dependencies: - "@babel/helper-validator-identifier" "^7.27.1" - js-tokens "^4.0.0" - picocolors "^1.1.1" - -"@babel/compat-data@^7.27.2": - version "7.27.3" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.27.3.tgz#cc49c2ac222d69b889bf34c795f537c0c6311111" - integrity sha512-V42wFfx1ymFte+ecf6iXghnnP8kWTO+ZLXIyZq+1LAXHHvTZdVxicn4yiVYdYMGaCO3tmqub11AorKkv+iodqw== - -"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.23.9": - version "7.27.4" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.27.4.tgz#cc1fc55d0ce140a1828d1dd2a2eba285adbfb3ce" - integrity sha512-bXYxrXFubeYdvB0NhD/NBB3Qi6aZeV20GOWVI47t2dkecCEoneR4NPVcb7abpXDEvejgrUfFtG6vG/zxAKmg+g== - dependencies: - "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.27.1" - "@babel/generator" "^7.27.3" - "@babel/helper-compilation-targets" "^7.27.2" - "@babel/helper-module-transforms" "^7.27.3" - "@babel/helpers" "^7.27.4" - "@babel/parser" "^7.27.4" - "@babel/template" "^7.27.2" - "@babel/traverse" "^7.27.4" - "@babel/types" "^7.27.3" - convert-source-map "^2.0.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.3" - semver "^6.3.1" - -"@babel/generator@^7.24.4", "@babel/generator@^7.27.3", "@babel/generator@^7.7.2": - version "7.27.3" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.27.3.tgz#ef1c0f7cfe3b5fc8cbb9f6cc69f93441a68edefc" - integrity sha512-xnlJYj5zepml8NXtjkG0WquFUv8RskFqyFcVgTBp5k+NaA/8uw/K+OSVf8AMGw5e9HKP2ETd5xpK5MLZQD6b4Q== - dependencies: - "@babel/parser" "^7.27.3" - "@babel/types" "^7.27.3" - "@jridgewell/gen-mapping" "^0.3.5" - "@jridgewell/trace-mapping" "^0.3.25" - jsesc "^3.0.2" - -"@babel/helper-compilation-targets@^7.27.2": - version "7.27.2" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz#46a0f6efab808d51d29ce96858dd10ce8732733d" - integrity sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ== - dependencies: - "@babel/compat-data" "^7.27.2" - "@babel/helper-validator-option" "^7.27.1" - browserslist "^4.24.0" - lru-cache "^5.1.1" - semver "^6.3.1" - -"@babel/helper-module-imports@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz#7ef769a323e2655e126673bb6d2d6913bbead204" - integrity sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w== - dependencies: - "@babel/traverse" "^7.27.1" - "@babel/types" "^7.27.1" - -"@babel/helper-module-transforms@^7.27.3": - version "7.27.3" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz#db0bbcfba5802f9ef7870705a7ef8788508ede02" - integrity sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg== - dependencies: - "@babel/helper-module-imports" "^7.27.1" - "@babel/helper-validator-identifier" "^7.27.1" - "@babel/traverse" "^7.27.3" - -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.27.1", "@babel/helper-plugin-utils@^7.8.0": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz#ddb2f876534ff8013e6c2b299bf4d39b3c51d44c" - integrity sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw== - -"@babel/helper-string-parser@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz#54da796097ab19ce67ed9f88b47bb2ec49367687" - integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA== - -"@babel/helper-validator-identifier@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz#a7054dcc145a967dd4dc8fee845a57c1316c9df8" - integrity sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow== - -"@babel/helper-validator-option@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz#fa52f5b1e7db1ab049445b421c4471303897702f" - integrity sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg== - -"@babel/helpers@^7.27.4": - version "7.27.4" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.27.4.tgz#c79050c6a0e41e095bfc96d469c85431e9ed7fe7" - integrity sha512-Y+bO6U+I7ZKaM5G5rDUZiYfUvQPUibYmAFe7EnKdnKBbVXDZxvp+MWOH5gYciY0EPk4EScsuFMQBbEfpdRKSCQ== - dependencies: - "@babel/template" "^7.27.2" - "@babel/types" "^7.27.3" - -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.27.2", "@babel/parser@^7.27.3", "@babel/parser@^7.27.4": - version "7.27.4" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.27.4.tgz#f92e89e4f51847be05427285836fc88341c956df" - integrity sha512-BRmLHGwpUqLFR2jzx9orBuX/ABDkj2jLKOXrHDTN2aOKL+jFDDKaRNo9nyYsIl9h/UE/7lMKdDjKQQyxKKDZ7g== - dependencies: - "@babel/types" "^7.27.3" - -"@babel/plugin-syntax-async-generators@^7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" - integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-bigint@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" - integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-class-properties@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" - integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== - dependencies: - "@babel/helper-plugin-utils" "^7.12.13" - -"@babel/plugin-syntax-class-static-block@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" - integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-syntax-import-attributes@^7.24.7": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz#34c017d54496f9b11b61474e7ea3dfd5563ffe07" - integrity sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-syntax-import-meta@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" - integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-json-strings@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" - integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-jsx@^7.7.2": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz#2f9beb5eff30fa507c5532d107daac7b888fa34c" - integrity sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" - integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" - integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-numeric-separator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" - integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-object-rest-spread@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" - integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-catch-binding@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" - integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-chaining@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" - integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-private-property-in-object@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" - integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-syntax-top-level-await@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" - integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-syntax-typescript@^7.7.2": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz#5147d29066a793450f220c63fa3a9431b7e6dd18" - integrity sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/template@^7.27.2", "@babel/template@^7.3.3": - version "7.27.2" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.27.2.tgz#fa78ceed3c4e7b63ebf6cb39e5852fca45f6809d" - integrity sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw== - dependencies: - "@babel/code-frame" "^7.27.1" - "@babel/parser" "^7.27.2" - "@babel/types" "^7.27.1" - -"@babel/traverse@^7.27.1", "@babel/traverse@^7.27.3", "@babel/traverse@^7.27.4": - version "7.27.4" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.27.4.tgz#b0045ac7023c8472c3d35effd7cc9ebd638da6ea" - integrity sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA== - dependencies: - "@babel/code-frame" "^7.27.1" - "@babel/generator" "^7.27.3" - "@babel/parser" "^7.27.4" - "@babel/template" "^7.27.2" - "@babel/types" "^7.27.3" - debug "^4.3.1" - globals "^11.1.0" - -"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.24.0", "@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.3.3": - version "7.27.3" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.27.3.tgz#c0257bedf33aad6aad1f406d35c44758321eb3ec" - integrity sha512-Y1GkI4ktrtvmawoSq+4FCVHNryea6uR+qUQy0AGxLSsjCX0nVmkYQMBLHDkXZuo5hGx7eYdnIaslsdBFm7zbUw== - dependencies: - "@babel/helper-string-parser" "^7.27.1" - "@babel/helper-validator-identifier" "^7.27.1" - -"@bcoe/v8-coverage@^0.2.3": - version "0.2.3" - resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" - integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== - -"@cspotcode/source-map-support@^0.8.0": - version "0.8.1" - resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" - integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== - dependencies: - "@jridgewell/trace-mapping" "0.3.9" - -"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": - version "4.7.0" - resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz#607084630c6c033992a082de6e6fbc1a8b52175a" - integrity sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw== - dependencies: - eslint-visitor-keys "^3.4.3" - -"@eslint-community/regexpp@^4.10.0", "@eslint-community/regexpp@^4.6.1": - version "4.12.1" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.1.tgz#cfc6cffe39df390a3841cde2abccf92eaa7ae0e0" - integrity sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ== - -"@eslint/eslintrc@^2.1.4": - version "2.1.4" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz#388a269f0f25c1b6adc317b5a2c55714894c70ad" - integrity sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ== - dependencies: - ajv "^6.12.4" - debug "^4.3.2" - espree "^9.6.0" - globals "^13.19.0" - ignore "^5.2.0" - import-fresh "^3.2.1" - js-yaml "^4.1.0" - minimatch "^3.1.2" - strip-json-comments "^3.1.1" - -"@eslint/js@8.57.1": - version "8.57.1" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.1.tgz#de633db3ec2ef6a3c89e2f19038063e8a122e2c2" - integrity sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q== - -"@gar/promisify@^1.1.3": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" - integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== - -"@humanwhocodes/config-array@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.13.0.tgz#fb907624df3256d04b9aa2df50d7aa97ec648748" - integrity sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw== - dependencies: - "@humanwhocodes/object-schema" "^2.0.3" - debug "^4.3.1" - minimatch "^3.0.5" - -"@humanwhocodes/module-importer@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" - integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== - -"@humanwhocodes/object-schema@^2.0.3": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3" - integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA== - -"@hutson/parse-repository-url@^3.0.0": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz#98c23c950a3d9b6c8f0daed06da6c3af06981340" - integrity sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q== - -"@interweb-utils/casing@^0.2.0": - version "0.2.0" - resolved "https://registry.yarnpkg.com/@interweb-utils/casing/-/casing-0.2.0.tgz#dbe9aa742cadf60805511093c9afa66290a50e28" - integrity sha512-ORQySrHzMYmtVRkYvtE1HGa8QnoqYPhu5UWQyv9302D/ZZe0Ae6cpk4NH1xEXgHeFq/CraiOcnLhmc3h7wdNHg== - -"@interweb/fetch-api-client@^0.6.1": - version "0.6.1" - resolved "https://registry.yarnpkg.com/@interweb/fetch-api-client/-/fetch-api-client-0.6.1.tgz#8f50e7651aeca0513daae649be4cdd6d4f440ebd" - integrity sha512-+QfJrK8c+uGhnIkGaoLeyuL7NuLbNgH8AeZwVkGqtOr9/hkrYMJQN+Jnw06TJeeuM12R8QZgM/0M8bpdG8KnlQ== - dependencies: - "@interweb/http-errors" "^0.1.1" - isomorphic-fetch "^3.0.0" - -"@interweb/http-errors@^0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@interweb/http-errors/-/http-errors-0.1.1.tgz#f38c5337bec03fb20397a8e8d8cb5c76c2eaa973" - integrity sha512-JEwL0a8ixMT1WQwx4YNEHLiFrB/7QKxMU2j/HxycdS1BIfZxWVLggdmONHENdmsVPOuaxUJduGmhzFVidOL0IA== - -"@isaacs/cliui@^8.0.2": - version "8.0.2" - resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" - integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== - dependencies: - string-width "^5.1.2" - string-width-cjs "npm:string-width@^4.2.0" - strip-ansi "^7.0.1" - strip-ansi-cjs "npm:strip-ansi@^6.0.1" - wrap-ansi "^8.1.0" - wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" - -"@isaacs/string-locale-compare@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@isaacs/string-locale-compare/-/string-locale-compare-1.1.0.tgz#291c227e93fd407a96ecd59879a35809120e432b" - integrity sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ== - -"@istanbuljs/load-nyc-config@^1.0.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" - integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== - 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" - -"@istanbuljs/schema@^0.1.2", "@istanbuljs/schema@^0.1.3": - version "0.1.3" - resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" - integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== - -"@jest/console@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.7.0.tgz#cd4822dbdb84529265c5a2bdb529a3c9cc950ffc" - integrity sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg== - dependencies: - "@jest/types" "^29.6.3" - "@types/node" "*" - chalk "^4.0.0" - jest-message-util "^29.7.0" - jest-util "^29.7.0" - slash "^3.0.0" - -"@jest/core@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.7.0.tgz#b6cccc239f30ff36609658c5a5e2291757ce448f" - integrity sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg== - dependencies: - "@jest/console" "^29.7.0" - "@jest/reporters" "^29.7.0" - "@jest/test-result" "^29.7.0" - "@jest/transform" "^29.7.0" - "@jest/types" "^29.6.3" - "@types/node" "*" - ansi-escapes "^4.2.1" - chalk "^4.0.0" - ci-info "^3.2.0" - exit "^0.1.2" - graceful-fs "^4.2.9" - jest-changed-files "^29.7.0" - jest-config "^29.7.0" - jest-haste-map "^29.7.0" - jest-message-util "^29.7.0" - jest-regex-util "^29.6.3" - jest-resolve "^29.7.0" - jest-resolve-dependencies "^29.7.0" - jest-runner "^29.7.0" - jest-runtime "^29.7.0" - jest-snapshot "^29.7.0" - jest-util "^29.7.0" - jest-validate "^29.7.0" - jest-watcher "^29.7.0" - micromatch "^4.0.4" - pretty-format "^29.7.0" - slash "^3.0.0" - strip-ansi "^6.0.0" - -"@jest/environment@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.7.0.tgz#24d61f54ff1f786f3cd4073b4b94416383baf2a7" - integrity sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw== - dependencies: - "@jest/fake-timers" "^29.7.0" - "@jest/types" "^29.6.3" - "@types/node" "*" - jest-mock "^29.7.0" - -"@jest/expect-utils@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.7.0.tgz#023efe5d26a8a70f21677d0a1afc0f0a44e3a1c6" - integrity sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA== - dependencies: - jest-get-type "^29.6.3" - -"@jest/expect@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.7.0.tgz#76a3edb0cb753b70dfbfe23283510d3d45432bf2" - integrity sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ== - dependencies: - expect "^29.7.0" - jest-snapshot "^29.7.0" - -"@jest/fake-timers@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.7.0.tgz#fd91bf1fffb16d7d0d24a426ab1a47a49881a565" - integrity sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ== - dependencies: - "@jest/types" "^29.6.3" - "@sinonjs/fake-timers" "^10.0.2" - "@types/node" "*" - jest-message-util "^29.7.0" - jest-mock "^29.7.0" - jest-util "^29.7.0" - -"@jest/globals@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.7.0.tgz#8d9290f9ec47ff772607fa864ca1d5a2efae1d4d" - integrity sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ== - dependencies: - "@jest/environment" "^29.7.0" - "@jest/expect" "^29.7.0" - "@jest/types" "^29.6.3" - jest-mock "^29.7.0" - -"@jest/reporters@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.7.0.tgz#04b262ecb3b8faa83b0b3d321623972393e8f4c7" - integrity sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg== - dependencies: - "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^29.7.0" - "@jest/test-result" "^29.7.0" - "@jest/transform" "^29.7.0" - "@jest/types" "^29.6.3" - "@jridgewell/trace-mapping" "^0.3.18" - "@types/node" "*" - chalk "^4.0.0" - collect-v8-coverage "^1.0.0" - exit "^0.1.2" - glob "^7.1.3" - graceful-fs "^4.2.9" - istanbul-lib-coverage "^3.0.0" - istanbul-lib-instrument "^6.0.0" - istanbul-lib-report "^3.0.0" - istanbul-lib-source-maps "^4.0.0" - istanbul-reports "^3.1.3" - jest-message-util "^29.7.0" - jest-util "^29.7.0" - jest-worker "^29.7.0" - slash "^3.0.0" - string-length "^4.0.1" - strip-ansi "^6.0.0" - v8-to-istanbul "^9.0.1" - -"@jest/schemas@^29.4.3", "@jest/schemas@^29.6.3": - version "29.6.3" - resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" - integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== - dependencies: - "@sinclair/typebox" "^0.27.8" - -"@jest/source-map@^29.6.3": - version "29.6.3" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.6.3.tgz#d90ba772095cf37a34a5eb9413f1b562a08554c4" - integrity sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw== - dependencies: - "@jridgewell/trace-mapping" "^0.3.18" - callsites "^3.0.0" - graceful-fs "^4.2.9" - -"@jest/test-result@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.7.0.tgz#8db9a80aa1a097bb2262572686734baed9b1657c" - integrity sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA== - dependencies: - "@jest/console" "^29.7.0" - "@jest/types" "^29.6.3" - "@types/istanbul-lib-coverage" "^2.0.0" - collect-v8-coverage "^1.0.0" - -"@jest/test-sequencer@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz#6cef977ce1d39834a3aea887a1726628a6f072ce" - integrity sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw== - dependencies: - "@jest/test-result" "^29.7.0" - graceful-fs "^4.2.9" - jest-haste-map "^29.7.0" - slash "^3.0.0" - -"@jest/transform@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.7.0.tgz#df2dd9c346c7d7768b8a06639994640c642e284c" - integrity sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw== - dependencies: - "@babel/core" "^7.11.6" - "@jest/types" "^29.6.3" - "@jridgewell/trace-mapping" "^0.3.18" - babel-plugin-istanbul "^6.1.1" - chalk "^4.0.0" - convert-source-map "^2.0.0" - fast-json-stable-stringify "^2.1.0" - graceful-fs "^4.2.9" - jest-haste-map "^29.7.0" - jest-regex-util "^29.6.3" - jest-util "^29.7.0" - micromatch "^4.0.4" - pirates "^4.0.4" - slash "^3.0.0" - write-file-atomic "^4.0.2" - -"@jest/types@^29.6.3": - version "29.6.3" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59" - integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== - dependencies: - "@jest/schemas" "^29.6.3" - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^3.0.0" - "@types/node" "*" - "@types/yargs" "^17.0.8" - chalk "^4.0.0" - -"@jridgewell/gen-mapping@^0.3.5": - version "0.3.8" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz#4f0e06362e01362f823d348f1872b08f666d8142" - integrity sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA== - dependencies: - "@jridgewell/set-array" "^1.2.1" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping" "^0.3.24" - -"@jridgewell/resolve-uri@^3.0.3", "@jridgewell/resolve-uri@^3.1.0": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" - integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== - -"@jridgewell/set-array@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280" - integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== - -"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" - integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== - -"@jridgewell/trace-mapping@0.3.9": - version "0.3.9" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" - integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== - dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" - -"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": - version "0.3.25" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" - integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== - dependencies: - "@jridgewell/resolve-uri" "^3.1.0" - "@jridgewell/sourcemap-codec" "^1.4.14" - -"@lerna/child-process@6.6.2": - version "6.6.2" - resolved "https://registry.yarnpkg.com/@lerna/child-process/-/child-process-6.6.2.tgz#5d803c8dee81a4e013dc428292e77b365cba876c" - integrity sha512-QyKIWEnKQFnYu2ey+SAAm1A5xjzJLJJj3bhIZd3QKyXKKjaJ0hlxam/OsWSltxTNbcyH1jRJjC6Cxv31usv0Ag== - dependencies: - chalk "^4.1.0" - execa "^5.0.0" - strong-log-transformer "^2.1.0" - -"@lerna/create@6.6.2": - version "6.6.2" - resolved "https://registry.yarnpkg.com/@lerna/create/-/create-6.6.2.tgz#39a36d80cddb355340c297ed785aa76f4498177f" - integrity sha512-xQ+1Y7D+9etvUlE+unhG/TwmM6XBzGIdFBaNoW8D8kyOa9M2Jf3vdEtAxVa7mhRz66CENfhL/+I/QkVaa7pwbQ== - dependencies: - "@lerna/child-process" "6.6.2" - dedent "^0.7.0" - fs-extra "^9.1.0" - init-package-json "^3.0.2" - npm-package-arg "8.1.1" - p-reduce "^2.1.0" - pacote "15.1.1" - pify "^5.0.0" - semver "^7.3.4" - slash "^3.0.0" - validate-npm-package-license "^3.0.4" - validate-npm-package-name "^4.0.0" - yargs-parser "20.2.4" - -"@lerna/legacy-package-management@6.6.2": - version "6.6.2" - resolved "https://registry.yarnpkg.com/@lerna/legacy-package-management/-/legacy-package-management-6.6.2.tgz#411c395e72e563ab98f255df77e4068627a85bb0" - integrity sha512-0hZxUPKnHwehUO2xC4ldtdX9bW0W1UosxebDIQlZL2STnZnA2IFmIk2lJVUyFW+cmTPQzV93jfS0i69T9Z+teg== - dependencies: - "@npmcli/arborist" "6.2.3" - "@npmcli/run-script" "4.1.7" - "@nrwl/devkit" ">=15.5.2 < 16" - "@octokit/rest" "19.0.3" - byte-size "7.0.0" - chalk "4.1.0" - clone-deep "4.0.1" - cmd-shim "5.0.0" - columnify "1.6.0" - config-chain "1.1.12" - conventional-changelog-core "4.2.4" - conventional-recommended-bump "6.1.0" - cosmiconfig "7.0.0" - dedent "0.7.0" - dot-prop "6.0.1" - execa "5.0.0" - file-url "3.0.0" - find-up "5.0.0" - fs-extra "9.1.0" - get-port "5.1.1" - get-stream "6.0.0" - git-url-parse "13.1.0" - glob-parent "5.1.2" - globby "11.1.0" - graceful-fs "4.2.10" - has-unicode "2.0.1" - inquirer "8.2.4" - is-ci "2.0.0" - is-stream "2.0.0" - libnpmpublish "7.1.4" - load-json-file "6.2.0" - make-dir "3.1.0" - minimatch "3.0.5" - multimatch "5.0.0" - node-fetch "2.6.7" - npm-package-arg "8.1.1" - npm-packlist "5.1.1" - npm-registry-fetch "14.0.3" - npmlog "6.0.2" - p-map "4.0.0" - p-map-series "2.1.0" - p-queue "6.6.2" - p-waterfall "2.1.1" - pacote "15.1.1" - pify "5.0.0" - pretty-format "29.4.3" - read-cmd-shim "3.0.0" - read-package-json "5.0.1" - resolve-from "5.0.0" - semver "7.3.8" - signal-exit "3.0.7" - slash "3.0.0" - ssri "9.0.1" - strong-log-transformer "2.1.0" - tar "6.1.11" - temp-dir "1.0.0" - tempy "1.0.0" - upath "2.0.1" - uuid "8.3.2" - write-file-atomic "4.0.1" - write-pkg "4.0.0" - yargs "16.2.0" - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": - version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@npmcli/arborist@6.2.3": - version "6.2.3" - resolved "https://registry.yarnpkg.com/@npmcli/arborist/-/arborist-6.2.3.tgz#31f8aed2588341864d3811151d929c01308f8e71" - integrity sha512-lpGOC2ilSJXcc2zfW9QtukcCTcMbl3fVI0z4wvFB2AFIl0C+Q6Wv7ccrpdrQa8rvJ1ZVuc6qkX7HVTyKlzGqKA== - dependencies: - "@isaacs/string-locale-compare" "^1.1.0" - "@npmcli/fs" "^3.1.0" - "@npmcli/installed-package-contents" "^2.0.0" - "@npmcli/map-workspaces" "^3.0.2" - "@npmcli/metavuln-calculator" "^5.0.0" - "@npmcli/name-from-folder" "^2.0.0" - "@npmcli/node-gyp" "^3.0.0" - "@npmcli/package-json" "^3.0.0" - "@npmcli/query" "^3.0.0" - "@npmcli/run-script" "^6.0.0" - bin-links "^4.0.1" - cacache "^17.0.4" - common-ancestor-path "^1.0.1" - hosted-git-info "^6.1.1" - json-parse-even-better-errors "^3.0.0" - json-stringify-nice "^1.1.4" - minimatch "^6.1.6" - nopt "^7.0.0" - npm-install-checks "^6.0.0" - npm-package-arg "^10.1.0" - npm-pick-manifest "^8.0.1" - npm-registry-fetch "^14.0.3" - npmlog "^7.0.1" - pacote "^15.0.8" - parse-conflict-json "^3.0.0" - proc-log "^3.0.0" - promise-all-reject-late "^1.0.0" - promise-call-limit "^1.0.1" - read-package-json-fast "^3.0.2" - semver "^7.3.7" - ssri "^10.0.1" - treeverse "^3.0.0" - walk-up-path "^1.0.0" - -"@npmcli/fs@^2.1.0": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-2.1.2.tgz#a9e2541a4a2fec2e69c29b35e6060973da79b865" - integrity sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ== - dependencies: - "@gar/promisify" "^1.1.3" - semver "^7.3.5" - -"@npmcli/fs@^3.1.0": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-3.1.1.tgz#59cdaa5adca95d135fc00f2bb53f5771575ce726" - integrity sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg== - dependencies: - semver "^7.3.5" - -"@npmcli/git@^4.0.0", "@npmcli/git@^4.1.0": - version "4.1.0" - resolved "https://registry.yarnpkg.com/@npmcli/git/-/git-4.1.0.tgz#ab0ad3fd82bc4d8c1351b6c62f0fa56e8fe6afa6" - integrity sha512-9hwoB3gStVfa0N31ymBmrX+GuDGdVA/QWShZVqE0HK2Af+7QGGrCTbZia/SW0ImUTjTne7SP91qxDmtXvDHRPQ== - dependencies: - "@npmcli/promise-spawn" "^6.0.0" - lru-cache "^7.4.4" - npm-pick-manifest "^8.0.0" - proc-log "^3.0.0" - promise-inflight "^1.0.1" - promise-retry "^2.0.1" - semver "^7.3.5" - which "^3.0.0" - -"@npmcli/installed-package-contents@^2.0.0", "@npmcli/installed-package-contents@^2.0.1": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@npmcli/installed-package-contents/-/installed-package-contents-2.1.0.tgz#63048e5f6e40947a3a88dcbcb4fd9b76fdd37c17" - integrity sha512-c8UuGLeZpm69BryRykLuKRyKFZYJsZSCT4aVY5ds4omyZqJ172ApzgfKJ5eV/r3HgLdUYgFVe54KSFVjKoe27w== - dependencies: - npm-bundled "^3.0.0" - npm-normalize-package-bin "^3.0.0" - -"@npmcli/map-workspaces@^3.0.2": - version "3.0.6" - resolved "https://registry.yarnpkg.com/@npmcli/map-workspaces/-/map-workspaces-3.0.6.tgz#27dc06c20c35ef01e45a08909cab9cb3da08cea6" - integrity sha512-tkYs0OYnzQm6iIRdfy+LcLBjcKuQCeE5YLb8KnrIlutJfheNaPvPpgoFEyEFgbjzl5PLZ3IA/BWAwRU0eHuQDA== - dependencies: - "@npmcli/name-from-folder" "^2.0.0" - glob "^10.2.2" - minimatch "^9.0.0" - read-package-json-fast "^3.0.0" - -"@npmcli/metavuln-calculator@^5.0.0": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@npmcli/metavuln-calculator/-/metavuln-calculator-5.0.1.tgz#426b3e524c2008bcc82dbc2ef390aefedd643d76" - integrity sha512-qb8Q9wIIlEPj3WeA1Lba91R4ZboPL0uspzV0F9uwP+9AYMVB2zOoa7Pbk12g6D2NHAinSbHh6QYmGuRyHZ874Q== - dependencies: - cacache "^17.0.0" - json-parse-even-better-errors "^3.0.0" - pacote "^15.0.0" - semver "^7.3.5" - -"@npmcli/move-file@^2.0.0": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-2.0.1.tgz#26f6bdc379d87f75e55739bab89db525b06100e4" - integrity sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ== - dependencies: - mkdirp "^1.0.4" - rimraf "^3.0.2" - -"@npmcli/name-from-folder@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@npmcli/name-from-folder/-/name-from-folder-2.0.0.tgz#c44d3a7c6d5c184bb6036f4d5995eee298945815" - integrity sha512-pwK+BfEBZJbKdNYpHHRTNBwBoqrN/iIMO0AiGvYsp3Hoaq0WbgGSWQR6SCldZovoDpY3yje5lkFUe6gsDgJ2vg== - -"@npmcli/node-gyp@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@npmcli/node-gyp/-/node-gyp-2.0.0.tgz#8c20e53e34e9078d18815c1d2dda6f2420d75e35" - integrity sha512-doNI35wIe3bBaEgrlPfdJPaCpUR89pJWep4Hq3aRdh6gKazIVWfs0jHttvSSoq47ZXgC7h73kDsUl8AoIQUB+A== - -"@npmcli/node-gyp@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz#101b2d0490ef1aa20ed460e4c0813f0db560545a" - integrity sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA== - -"@npmcli/package-json@^3.0.0": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@npmcli/package-json/-/package-json-3.1.1.tgz#5628332aac90fa1b4d6f98e03988c5958b35e0c5" - integrity sha512-+UW0UWOYFKCkvszLoTwrYGrjNrT8tI5Ckeb/h+Z1y1fsNJEctl7HmerA5j2FgmoqFaLI2gsA1X9KgMFqx/bRmA== - dependencies: - "@npmcli/git" "^4.1.0" - glob "^10.2.2" - json-parse-even-better-errors "^3.0.0" - normalize-package-data "^5.0.0" - npm-normalize-package-bin "^3.0.1" - proc-log "^3.0.0" - -"@npmcli/promise-spawn@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@npmcli/promise-spawn/-/promise-spawn-3.0.0.tgz#53283b5f18f855c6925f23c24e67c911501ef573" - integrity sha512-s9SgS+p3a9Eohe68cSI3fi+hpcZUmXq5P7w0kMlAsWVtR7XbK3ptkZqKT2cK1zLDObJ3sR+8P59sJE0w/KTL1g== - dependencies: - infer-owner "^1.0.4" - -"@npmcli/promise-spawn@^6.0.0", "@npmcli/promise-spawn@^6.0.1": - version "6.0.2" - resolved "https://registry.yarnpkg.com/@npmcli/promise-spawn/-/promise-spawn-6.0.2.tgz#c8bc4fa2bd0f01cb979d8798ba038f314cfa70f2" - integrity sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg== - dependencies: - which "^3.0.0" - -"@npmcli/query@^3.0.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@npmcli/query/-/query-3.1.0.tgz#bc202c59e122a06cf8acab91c795edda2cdad42c" - integrity sha512-C/iR0tk7KSKGldibYIB9x8GtO/0Bd0I2mhOaDb8ucQL/bQVTmGoeREaFj64Z5+iCBRf3dQfed0CjJL7I8iTkiQ== - dependencies: - postcss-selector-parser "^6.0.10" - -"@npmcli/run-script@4.1.7": - version "4.1.7" - resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-4.1.7.tgz#b1a2f57568eb738e45e9ea3123fb054b400a86f7" - integrity sha512-WXr/MyM4tpKA4BotB81NccGAv8B48lNH0gRoILucbcAhTQXLCoi6HflMV3KdXubIqvP9SuLsFn68Z7r4jl+ppw== - dependencies: - "@npmcli/node-gyp" "^2.0.0" - "@npmcli/promise-spawn" "^3.0.0" - node-gyp "^9.0.0" - read-package-json-fast "^2.0.3" - which "^2.0.2" - -"@npmcli/run-script@^6.0.0": - version "6.0.2" - resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-6.0.2.tgz#a25452d45ee7f7fb8c16dfaf9624423c0c0eb885" - integrity sha512-NCcr1uQo1k5U+SYlnIrbAh3cxy+OQT1VtqiAbxdymSlptbzBb62AjH2xXgjNCoP073hoa1CfCAcwoZ8k96C4nA== - dependencies: - "@npmcli/node-gyp" "^3.0.0" - "@npmcli/promise-spawn" "^6.0.0" - node-gyp "^9.0.0" - read-package-json-fast "^3.0.0" - which "^3.0.0" - -"@nrwl/cli@15.9.7": - version "15.9.7" - resolved "https://registry.yarnpkg.com/@nrwl/cli/-/cli-15.9.7.tgz#1db113f5cb1cfe63213097be1ece041eef33da1f" - integrity sha512-1jtHBDuJzA57My5nLzYiM372mJW0NY6rFKxlWt5a0RLsAZdPTHsd8lE3Gs9XinGC1jhXbruWmhhnKyYtZvX/zA== - dependencies: - nx "15.9.7" - -"@nrwl/devkit@>=15.5.2 < 16": - version "15.9.7" - resolved "https://registry.yarnpkg.com/@nrwl/devkit/-/devkit-15.9.7.tgz#14d19ec82ff4209c12147a97f1cdea05d8f6c087" - integrity sha512-Sb7Am2TMT8AVq8e+vxOlk3AtOA2M0qCmhBzoM1OJbdHaPKc0g0UgSnWRml1kPGg5qfPk72tWclLoZJ5/ut0vTg== - dependencies: - ejs "^3.1.7" - ignore "^5.0.4" - semver "7.5.4" - tmp "~0.2.1" - tslib "^2.3.0" - -"@nrwl/nx-darwin-arm64@15.9.7": - version "15.9.7" - resolved "https://registry.yarnpkg.com/@nrwl/nx-darwin-arm64/-/nx-darwin-arm64-15.9.7.tgz#a2cb7390c782b8acf3bb8806a3002620226a933d" - integrity sha512-aBUgnhlkrgC0vu0fK6eb9Vob7eFnkuknrK+YzTjmLrrZwj7FGNAeyGXSlyo1dVokIzjVKjJg2saZZ0WQbfuCJw== - -"@nrwl/nx-darwin-x64@15.9.7": - version "15.9.7" - resolved "https://registry.yarnpkg.com/@nrwl/nx-darwin-x64/-/nx-darwin-x64-15.9.7.tgz#af0437e726aeb97eb660646bfd9a7da5ba7a0a6f" - integrity sha512-L+elVa34jhGf1cmn38Z0sotQatmLovxoASCIw5r1CBZZeJ5Tg7Y9nOwjRiDixZxNN56hPKXm6xl9EKlVHVeKlg== - -"@nrwl/nx-linux-arm-gnueabihf@15.9.7": - version "15.9.7" - resolved "https://registry.yarnpkg.com/@nrwl/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-15.9.7.tgz#e29f4d31afa903bfb4d0fd7421e19be1086eae87" - integrity sha512-pqmfqqEUGFu6PmmHKyXyUw1Al0Ki8PSaR0+ndgCAb1qrekVDGDfznJfaqxN0JSLeolPD6+PFtLyXNr9ZyPFlFg== - -"@nrwl/nx-linux-arm64-gnu@15.9.7": - version "15.9.7" - resolved "https://registry.yarnpkg.com/@nrwl/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-15.9.7.tgz#eb2880a24d3268dd93583d21a6a0b9ff96bb23b4" - integrity sha512-NYOa/eRrqmM+In5g3M0rrPVIS9Z+q6fvwXJYf/KrjOHqqan/KL+2TOfroA30UhcBrwghZvib7O++7gZ2hzwOnA== - -"@nrwl/nx-linux-arm64-musl@15.9.7": - version "15.9.7" - resolved "https://registry.yarnpkg.com/@nrwl/nx-linux-arm64-musl/-/nx-linux-arm64-musl-15.9.7.tgz#5d04913c4672a96cefa78491824620d8a8bcfd7f" - integrity sha512-zyStqjEcmbvLbejdTOrLUSEdhnxNtdQXlmOuymznCzYUEGRv+4f7OAepD3yRoR0a/57SSORZmmGQB7XHZoYZJA== - -"@nrwl/nx-linux-x64-gnu@15.9.7": - version "15.9.7" - resolved "https://registry.yarnpkg.com/@nrwl/nx-linux-x64-gnu/-/nx-linux-x64-gnu-15.9.7.tgz#cf7f61fd87f35a793e6824952a6eb12242fe43fd" - integrity sha512-saNK5i2A8pKO3Il+Ejk/KStTApUpWgCxjeUz9G+T8A+QHeDloZYH2c7pU/P3jA9QoNeKwjVO9wYQllPL9loeVg== - -"@nrwl/nx-linux-x64-musl@15.9.7": - version "15.9.7" - resolved "https://registry.yarnpkg.com/@nrwl/nx-linux-x64-musl/-/nx-linux-x64-musl-15.9.7.tgz#2bec23c3696780540eb47fa1358dda780c84697f" - integrity sha512-extIUThYN94m4Vj4iZggt6hhMZWQSukBCo8pp91JHnDcryBg7SnYmnikwtY1ZAFyyRiNFBLCKNIDFGkKkSrZ9Q== - -"@nrwl/nx-win32-arm64-msvc@15.9.7": - version "15.9.7" - resolved "https://registry.yarnpkg.com/@nrwl/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-15.9.7.tgz#21b56ef3ab4190370effea71bd83fdc3e47ec69c" - integrity sha512-GSQ54hJ5AAnKZb4KP4cmBnJ1oC4ILxnrG1mekxeM65c1RtWg9NpBwZ8E0gU3xNrTv8ZNsBeKi/9UhXBxhsIh8A== - -"@nrwl/nx-win32-x64-msvc@15.9.7": - version "15.9.7" - resolved "https://registry.yarnpkg.com/@nrwl/nx-win32-x64-msvc/-/nx-win32-x64-msvc-15.9.7.tgz#1677ab1dcce921706b5677dc2844e3e0027f8bd5" - integrity sha512-x6URof79RPd8AlapVbPefUD3ynJZpmah3tYaYZ9xZRMXojVtEHV8Qh5vysKXQ1rNYJiiB8Ah6evSKWLbAH60tw== - -"@nrwl/tao@15.9.7": - version "15.9.7" - resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-15.9.7.tgz#c0e78c99caa6742762f7558f20d8524bc9015e97" - integrity sha512-OBnHNvQf3vBH0qh9YnvBQQWyyFZ+PWguF6dJ8+1vyQYlrLVk/XZ8nJ4ukWFb+QfPv/O8VBmqaofaOI9aFC4yTw== - dependencies: - nx "15.9.7" - -"@octokit/auth-token@^3.0.0": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-3.0.4.tgz#70e941ba742bdd2b49bdb7393e821dea8520a3db" - integrity sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ== - -"@octokit/core@^4.0.0": - version "4.2.4" - resolved "https://registry.yarnpkg.com/@octokit/core/-/core-4.2.4.tgz#d8769ec2b43ff37cc3ea89ec4681a20ba58ef907" - integrity sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ== - dependencies: - "@octokit/auth-token" "^3.0.0" - "@octokit/graphql" "^5.0.0" - "@octokit/request" "^6.0.0" - "@octokit/request-error" "^3.0.0" - "@octokit/types" "^9.0.0" - before-after-hook "^2.2.0" - universal-user-agent "^6.0.0" - -"@octokit/endpoint@^7.0.0": - version "7.0.6" - resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-7.0.6.tgz#791f65d3937555141fb6c08f91d618a7d645f1e2" - integrity sha512-5L4fseVRUsDFGR00tMWD/Trdeeihn999rTMGRMC1G/Ldi1uWlWJzI98H4Iak5DB/RVvQuyMYKqSK/R6mbSOQyg== - dependencies: - "@octokit/types" "^9.0.0" - is-plain-object "^5.0.0" - universal-user-agent "^6.0.0" - -"@octokit/graphql@^5.0.0": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-5.0.6.tgz#9eac411ac4353ccc5d3fca7d76736e6888c5d248" - integrity sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw== - dependencies: - "@octokit/request" "^6.0.0" - "@octokit/types" "^9.0.0" - universal-user-agent "^6.0.0" - -"@octokit/openapi-types@^12.11.0": - version "12.11.0" - resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-12.11.0.tgz#da5638d64f2b919bca89ce6602d059f1b52d3ef0" - integrity sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ== - -"@octokit/openapi-types@^14.0.0": - version "14.0.0" - resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-14.0.0.tgz#949c5019028c93f189abbc2fb42f333290f7134a" - integrity sha512-HNWisMYlR8VCnNurDU6os2ikx0s0VyEjDYHNS/h4cgb8DeOxQ0n72HyinUtdDVxJhFy3FWLGl0DJhfEWk3P5Iw== - -"@octokit/openapi-types@^18.0.0": - version "18.1.1" - resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-18.1.1.tgz#09bdfdabfd8e16d16324326da5148010d765f009" - integrity sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw== - -"@octokit/plugin-enterprise-rest@6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-6.0.1.tgz#e07896739618dab8da7d4077c658003775f95437" - integrity sha512-93uGjlhUD+iNg1iWhUENAtJata6w5nE+V4urXOAlIXdco6xNZtUSfYY8dzp3Udy74aqO/B5UZL80x/YMa5PKRw== - -"@octokit/plugin-paginate-rest@^3.0.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-3.1.0.tgz#86f8be759ce2d6d7c879a31490fd2f7410b731f0" - integrity sha512-+cfc40pMzWcLkoDcLb1KXqjX0jTGYXjKuQdFQDc6UAknISJHnZTiBqld6HDwRJvD4DsouDKrWXNbNV0lE/3AXA== - dependencies: - "@octokit/types" "^6.41.0" - -"@octokit/plugin-request-log@^1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz#5e50ed7083a613816b1e4a28aeec5fb7f1462e85" - integrity sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA== - -"@octokit/plugin-rest-endpoint-methods@^6.0.0": - version "6.8.1" - resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-6.8.1.tgz#97391fda88949eb15f68dc291957ccbe1d3e8ad1" - integrity sha512-QrlaTm8Lyc/TbU7BL/8bO49vp+RZ6W3McxxmmQTgYxf2sWkO8ZKuj4dLhPNJD6VCUW1hetCmeIM0m6FTVpDiEg== - dependencies: - "@octokit/types" "^8.1.1" - deprecation "^2.3.1" - -"@octokit/request-error@^3.0.0": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-3.0.3.tgz#ef3dd08b8e964e53e55d471acfe00baa892b9c69" - integrity sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ== - dependencies: - "@octokit/types" "^9.0.0" - deprecation "^2.0.0" - once "^1.4.0" - -"@octokit/request@^6.0.0": - version "6.2.8" - resolved "https://registry.yarnpkg.com/@octokit/request/-/request-6.2.8.tgz#aaf480b32ab2b210e9dadd8271d187c93171d8eb" - integrity sha512-ow4+pkVQ+6XVVsekSYBzJC0VTVvh/FCTUUgTsboGq+DTeWdyIFV8WSCdo0RIxk6wSkBTHqIK1mYuY7nOBXOchw== - dependencies: - "@octokit/endpoint" "^7.0.0" - "@octokit/request-error" "^3.0.0" - "@octokit/types" "^9.0.0" - is-plain-object "^5.0.0" - node-fetch "^2.6.7" - universal-user-agent "^6.0.0" - -"@octokit/rest@19.0.3": - version "19.0.3" - resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-19.0.3.tgz#b9a4e8dc8d53e030d611c053153ee6045f080f02" - integrity sha512-5arkTsnnRT7/sbI4fqgSJ35KiFaN7zQm0uQiQtivNQLI8RQx8EHwJCajcTUwmaCMNDg7tdCvqAnc7uvHHPxrtQ== - dependencies: - "@octokit/core" "^4.0.0" - "@octokit/plugin-paginate-rest" "^3.0.0" - "@octokit/plugin-request-log" "^1.0.4" - "@octokit/plugin-rest-endpoint-methods" "^6.0.0" - -"@octokit/types@^6.41.0": - version "6.41.0" - resolved "https://registry.yarnpkg.com/@octokit/types/-/types-6.41.0.tgz#e58ef78d78596d2fb7df9c6259802464b5f84a04" - integrity sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg== - dependencies: - "@octokit/openapi-types" "^12.11.0" - -"@octokit/types@^8.1.1": - version "8.2.1" - resolved "https://registry.yarnpkg.com/@octokit/types/-/types-8.2.1.tgz#a6de091ae68b5541f8d4fcf9a12e32836d4648aa" - integrity sha512-8oWMUji8be66q2B9PmEIUyQm00VPDPun07umUWSaCwxmeaquFBro4Hcc3ruVoDo3zkQyZBlRvhIMEYS3pBhanw== - dependencies: - "@octokit/openapi-types" "^14.0.0" - -"@octokit/types@^9.0.0": - version "9.3.2" - resolved "https://registry.yarnpkg.com/@octokit/types/-/types-9.3.2.tgz#3f5f89903b69f6a2d196d78ec35f888c0013cac5" - integrity sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA== - dependencies: - "@octokit/openapi-types" "^18.0.0" - -"@parcel/watcher@2.0.4": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@parcel/watcher/-/watcher-2.0.4.tgz#f300fef4cc38008ff4b8c29d92588eced3ce014b" - integrity sha512-cTDi+FUDBIUOBKEtj+nhiJ71AZVlkAsQFuGQTun5tV9mwQBQgZvhCzG+URPQc8myeN32yRVZEfVAPCs1RW+Jvg== - dependencies: - node-addon-api "^3.2.1" - node-gyp-build "^4.3.0" - -"@pkgjs/parseargs@^0.11.0": - version "0.11.0" - resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" - integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== - -"@sigstore/bundle@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@sigstore/bundle/-/bundle-1.1.0.tgz#17f8d813b09348b16eeed66a8cf1c3d6bd3d04f1" - integrity sha512-PFutXEy0SmQxYI4texPw3dd2KewuNqv7OuK1ZFtY2fM754yhvG2KdgwIhRnoEE2uHdtdGNQ8s0lb94dW9sELog== - dependencies: - "@sigstore/protobuf-specs" "^0.2.0" - -"@sigstore/protobuf-specs@^0.2.0": - version "0.2.1" - resolved "https://registry.yarnpkg.com/@sigstore/protobuf-specs/-/protobuf-specs-0.2.1.tgz#be9ef4f3c38052c43bd399d3f792c97ff9e2277b" - integrity sha512-XTWVxnWJu+c1oCshMLwnKvz8ZQJJDVOlciMfgpJBQbThVjKTCG8dwyhgLngBD2KN0ap9F/gOV8rFDEx8uh7R2A== - -"@sigstore/sign@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@sigstore/sign/-/sign-1.0.0.tgz#6b08ebc2f6c92aa5acb07a49784cb6738796f7b4" - integrity sha512-INxFVNQteLtcfGmcoldzV6Je0sbbfh9I16DM4yJPw3j5+TFP8X6uIiA18mvpEa9yyeycAKgPmOA3X9hVdVTPUA== - dependencies: - "@sigstore/bundle" "^1.1.0" - "@sigstore/protobuf-specs" "^0.2.0" - make-fetch-happen "^11.0.1" - -"@sigstore/tuf@^1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@sigstore/tuf/-/tuf-1.0.3.tgz#2a65986772ede996485728f027b0514c0b70b160" - integrity sha512-2bRovzs0nJZFlCN3rXirE4gwxCn97JNjMmwpecqlbgV9WcxX7WRuIrgzx/X7Ib7MYRbyUTpBYE0s2x6AmZXnlg== - dependencies: - "@sigstore/protobuf-specs" "^0.2.0" - tuf-js "^1.1.7" - -"@sinclair/typebox@^0.27.8": - version "0.27.8" - resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" - integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== - -"@sinonjs/commons@^3.0.0": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-3.0.1.tgz#1029357e44ca901a615585f6d27738dbc89084cd" - integrity sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ== - dependencies: - type-detect "4.0.8" - -"@sinonjs/fake-timers@^10.0.2": - version "10.3.0" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz#55fdff1ecab9f354019129daf4df0dd4d923ea66" - integrity sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA== - dependencies: - "@sinonjs/commons" "^3.0.0" - -"@tanstack/query-core@5.79.2": - version "5.79.2" - resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.79.2.tgz#92b048bd6794b0dec7b14253b08b85f368afe00f" - integrity sha512-kr+KQrBuqd6495eP9S41BoftFI1H50XA9O+6FmbnTx/Te6bjiq1mj8rt9rJjW3YZSO2aaUNUres0TWesJW1j1g== - -"@tanstack/react-query@5.79.2": - version "5.79.2" - resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-5.79.2.tgz#1cc4dea3b6199cbfae91c3ce1d4d6092b530dafe" - integrity sha512-kadeprsH6bWuhHCpqukXHRykJkxcLBxAaF0cQ05yawPmLZ/KiCpR1DyQenonF7A/70rnRUxhJD0RJejqk9wImQ== - dependencies: - "@tanstack/query-core" "5.79.2" - -"@tootallnate/once@2": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" - integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== - -"@tsconfig/node10@^1.0.7": - version "1.0.11" - resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.11.tgz#6ee46400685f130e278128c7b38b7e031ff5b2f2" - integrity sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw== - -"@tsconfig/node12@^1.0.7": - version "1.0.11" - resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" - integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== - -"@tsconfig/node14@^1.0.0": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" - integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== - -"@tsconfig/node16@^1.0.2": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" - integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== - -"@tufjs/canonical-json@1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@tufjs/canonical-json/-/canonical-json-1.0.0.tgz#eade9fd1f537993bc1f0949f3aea276ecc4fab31" - integrity sha512-QTnf++uxunWvG2z3UFNzAoQPHxnSXOwtaI3iJ+AohhV+5vONuArPjJE7aPXPVXfXJsqrVbZBu9b81AJoSd09IQ== - -"@tufjs/models@1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@tufjs/models/-/models-1.0.4.tgz#5a689630f6b9dbda338d4b208019336562f176ef" - integrity sha512-qaGV9ltJP0EO25YfFUPhxRVK0evXFIAGicsVXuRim4Ed9cjPxYhNnNJ49SFmbeLgtxpslIkX317IgpfcHPVj/A== - dependencies: - "@tufjs/canonical-json" "1.0.0" - minimatch "^9.0.0" - -"@types/babel__core@^7.1.14": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017" - integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== - dependencies: - "@babel/parser" "^7.20.7" - "@babel/types" "^7.20.7" - "@types/babel__generator" "*" - "@types/babel__template" "*" - "@types/babel__traverse" "*" - -"@types/babel__generator@*": - version "7.27.0" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.27.0.tgz#b5819294c51179957afaec341442f9341e4108a9" - integrity sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg== - dependencies: - "@babel/types" "^7.0.0" - -"@types/babel__template@*": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.4.tgz#5672513701c1b2199bc6dad636a9d7491586766f" - integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A== - dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" - -"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.7.tgz#968cdc2366ec3da159f61166428ee40f370e56c2" - integrity sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng== - dependencies: - "@babel/types" "^7.20.7" - -"@types/graceful-fs@^4.1.3": - version "4.1.9" - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.9.tgz#2a06bc0f68a20ab37b3e36aa238be6abdf49e8b4" - integrity sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ== - dependencies: - "@types/node" "*" - -"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": - version "2.0.6" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz#7739c232a1fee9b4d3ce8985f314c0c6d33549d7" - integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w== - -"@types/istanbul-lib-report@*": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz#53047614ae72e19fc0401d872de3ae2b4ce350bf" - integrity sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA== - dependencies: - "@types/istanbul-lib-coverage" "*" - -"@types/istanbul-reports@^3.0.0": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz#0f03e3d2f670fbdac586e34b433783070cc16f54" - integrity sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ== - dependencies: - "@types/istanbul-lib-report" "*" - -"@types/jest@^29.5.11": - version "29.5.14" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.14.tgz#2b910912fa1d6856cadcd0c1f95af7df1d6049e5" - integrity sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ== - dependencies: - expect "^29.0.0" - pretty-format "^29.0.0" - -"@types/js-yaml@^4.0.9": - version "4.0.9" - resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-4.0.9.tgz#cd82382c4f902fed9691a2ed79ec68c5898af4c2" - integrity sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg== - -"@types/minimatch@^3.0.3": - version "3.0.5" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" - integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== - -"@types/minimist@^1.2.0": - version "1.2.5" - resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.5.tgz#ec10755e871497bcd83efe927e43ec46e8c0747e" - integrity sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag== - -"@types/node@*": - version "22.15.29" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.15.29.tgz#c75999124a8224a3f79dd8b6ccfb37d74098f678" - integrity sha512-LNdjOkUDlU1RZb8e1kOIUpN1qQUlzGkEtbVNo53vbrwDg5om6oduhm4SiUaPW5ASTXhAiP0jInWG8Qx9fVlOeQ== - dependencies: - undici-types "~6.21.0" - -"@types/node@^20.12.7": - version "20.17.57" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.17.57.tgz#f807455e3303ba8ba08fcb1db90619356abfaa99" - integrity sha512-f3T4y6VU4fVQDKVqJV4Uppy8c1p/sVvS3peyqxyWnzkqXFJLRU7Y1Bl7rMS1Qe9z0v4M6McY0Fp9yBsgHJUsWQ== - dependencies: - undici-types "~6.19.2" - -"@types/normalize-package-data@^2.4.0": - version "2.4.4" - resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz#56e2cc26c397c038fab0e3a917a12d5c5909e901" - integrity sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA== - -"@types/parse-json@^4.0.0": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.2.tgz#5950e50960793055845e956c427fc2b0d70c5239" - integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw== - -"@types/prop-types@*": - version "15.7.14" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.14.tgz#1433419d73b2a7ebfc6918dcefd2ec0d5cd698f2" - integrity sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ== - -"@types/react@^18.2.77": - version "18.3.23" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.23.tgz#86ae6f6b95a48c418fecdaccc8069e0fbb63696a" - integrity sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w== - dependencies: - "@types/prop-types" "*" - csstype "^3.0.2" - -"@types/stack-utils@^2.0.0": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8" - integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== - -"@types/yargs-parser@*": - version "21.0.3" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15" - integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ== - -"@types/yargs@^17.0.8": - version "17.0.33" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.33.tgz#8c32303da83eec050a84b3c7ae7b9f922d13e32d" - integrity sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA== - dependencies: - "@types/yargs-parser" "*" - -"@typescript-eslint/eslint-plugin@^7.10.0": - version "7.18.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz#b16d3cf3ee76bf572fdf511e79c248bdec619ea3" - integrity sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw== - dependencies: - "@eslint-community/regexpp" "^4.10.0" - "@typescript-eslint/scope-manager" "7.18.0" - "@typescript-eslint/type-utils" "7.18.0" - "@typescript-eslint/utils" "7.18.0" - "@typescript-eslint/visitor-keys" "7.18.0" - graphemer "^1.4.0" - ignore "^5.3.1" - natural-compare "^1.4.0" - ts-api-utils "^1.3.0" - -"@typescript-eslint/parser@^7.10.0": - version "7.18.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-7.18.0.tgz#83928d0f1b7f4afa974098c64b5ce6f9051f96a0" - integrity sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg== - dependencies: - "@typescript-eslint/scope-manager" "7.18.0" - "@typescript-eslint/types" "7.18.0" - "@typescript-eslint/typescript-estree" "7.18.0" - "@typescript-eslint/visitor-keys" "7.18.0" - debug "^4.3.4" - -"@typescript-eslint/scope-manager@7.18.0": - version "7.18.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz#c928e7a9fc2c0b3ed92ab3112c614d6bd9951c83" - integrity sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA== - dependencies: - "@typescript-eslint/types" "7.18.0" - "@typescript-eslint/visitor-keys" "7.18.0" - -"@typescript-eslint/type-utils@7.18.0": - version "7.18.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz#2165ffaee00b1fbbdd2d40aa85232dab6998f53b" - integrity sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA== - dependencies: - "@typescript-eslint/typescript-estree" "7.18.0" - "@typescript-eslint/utils" "7.18.0" - debug "^4.3.4" - ts-api-utils "^1.3.0" - -"@typescript-eslint/types@7.18.0": - version "7.18.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.18.0.tgz#b90a57ccdea71797ffffa0321e744f379ec838c9" - integrity sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ== - -"@typescript-eslint/typescript-estree@7.18.0": - version "7.18.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz#b5868d486c51ce8f312309ba79bdb9f331b37931" - integrity sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA== - dependencies: - "@typescript-eslint/types" "7.18.0" - "@typescript-eslint/visitor-keys" "7.18.0" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - minimatch "^9.0.4" - semver "^7.6.0" - ts-api-utils "^1.3.0" - -"@typescript-eslint/utils@7.18.0": - version "7.18.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.18.0.tgz#bca01cde77f95fc6a8d5b0dbcbfb3d6ca4be451f" - integrity sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw== - dependencies: - "@eslint-community/eslint-utils" "^4.4.0" - "@typescript-eslint/scope-manager" "7.18.0" - "@typescript-eslint/types" "7.18.0" - "@typescript-eslint/typescript-estree" "7.18.0" - -"@typescript-eslint/visitor-keys@7.18.0": - version "7.18.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz#0564629b6124d67607378d0f0332a0495b25e7d7" - integrity sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg== - dependencies: - "@typescript-eslint/types" "7.18.0" - eslint-visitor-keys "^3.4.3" - -"@ungap/structured-clone@^1.2.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.3.0.tgz#d06bbb384ebcf6c505fde1c3d0ed4ddffe0aaff8" - integrity sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g== - -"@yarnpkg/lockfile@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" - integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== - -"@yarnpkg/parsers@3.0.0-rc.46": - version "3.0.0-rc.46" - resolved "https://registry.yarnpkg.com/@yarnpkg/parsers/-/parsers-3.0.0-rc.46.tgz#03f8363111efc0ea670e53b0282cd3ef62de4e01" - integrity sha512-aiATs7pSutzda/rq8fnuPwTglyVwjM22bNnK2ZgjrpAjQHSSl3lztd2f9evst1W/qnC58DRz7T7QndUDumAR4Q== - dependencies: - js-yaml "^3.10.0" - tslib "^2.4.0" - -"@zkochan/js-yaml@0.0.6": - version "0.0.6" - resolved "https://registry.yarnpkg.com/@zkochan/js-yaml/-/js-yaml-0.0.6.tgz#975f0b306e705e28b8068a07737fa46d3fc04826" - integrity sha512-nzvgl3VfhcELQ8LyVrYOru+UtAy1nrygk2+AGbTm8a5YcO6o8lSjAT+pfg3vJWxIoZKOUhrK6UU7xW/+00kQrg== - dependencies: - argparse "^2.0.1" - -JSONStream@^1.0.4: - version "1.3.5" - resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" - integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== - dependencies: - jsonparse "^1.2.0" - through ">=2.2.7 <3" - -abbrev@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - -abbrev@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-2.0.0.tgz#cf59829b8b4f03f89dda2771cb7f3653828c89bf" - integrity sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ== - -acorn-jsx@^5.3.2: - version "5.3.2" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" - integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== - -acorn-walk@^8.1.1: - version "8.3.4" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.4.tgz#794dd169c3977edf4ba4ea47583587c5866236b7" - integrity sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g== - dependencies: - acorn "^8.11.0" - -acorn@^8.11.0, acorn@^8.4.1, acorn@^8.9.0: - version "8.14.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.1.tgz#721d5dc10f7d5b5609a891773d47731796935dfb" - integrity sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg== - -add-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa" - integrity sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ== - -agent-base@6, agent-base@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - -agentkeepalive@^4.2.1: - version "4.6.0" - resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.6.0.tgz#35f73e94b3f40bf65f105219c623ad19c136ea6a" - integrity sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ== - dependencies: - humanize-ms "^1.2.1" - -aggregate-error@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" - integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== - dependencies: - clean-stack "^2.0.0" - indent-string "^4.0.0" - -ajv@^6.12.4: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ansi-colors@^4.1.1: - version "4.1.3" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" - integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== - -ansi-escapes@^4.2.1: - version "4.3.2" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" - integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== - dependencies: - type-fest "^0.21.3" - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-regex@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.1.0.tgz#95ec409c69619d6cb1b8b34f14b660ef28ebd654" - integrity sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA== - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -ansi-styles@^5.0.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" - integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== - -ansi-styles@^6.1.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" - integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== - -anymatch@^3.0.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" - integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -"aproba@^1.0.3 || ^2.0.0", aproba@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" - integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== - -are-we-there-yet@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz#679df222b278c64f2cdba1175cdc00b0d96164bd" - integrity sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg== - dependencies: - delegates "^1.0.0" - readable-stream "^3.6.0" - -are-we-there-yet@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-4.0.2.tgz#aed25dd0eae514660d49ac2b2366b175c614785a" - integrity sha512-ncSWAawFhKMJDTdoAeOV+jyW1VCMj5QIAwULIBV0SSR7B/RLPPEQiknKcg/RIIZlUQrxELpsxMiTUoAQ4sIUyg== - -arg@^4.1.0: - version "4.1.3" - resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" - integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -array-differ@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-3.0.0.tgz#3cbb3d0f316810eafcc47624734237d6aee4ae6b" - integrity sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg== - -array-ify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" - integrity sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng== - -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - -arrify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" - integrity sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA== - -arrify@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa" - integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug== - -async@^3.2.3: - version "3.2.6" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.6.tgz#1b0728e14929d51b85b449b7f06e27c1145e38ce" - integrity sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA== - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== - -at-least-node@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" - integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== - -axios@^1.0.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.9.0.tgz#25534e3b72b54540077d33046f77e3b8d7081901" - integrity sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg== - dependencies: - follow-redirects "^1.15.6" - form-data "^4.0.0" - proxy-from-env "^1.1.0" - -babel-jest@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5" - integrity sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg== - dependencies: - "@jest/transform" "^29.7.0" - "@types/babel__core" "^7.1.14" - babel-plugin-istanbul "^6.1.1" - babel-preset-jest "^29.6.3" - chalk "^4.0.0" - graceful-fs "^4.2.9" - slash "^3.0.0" - -babel-plugin-istanbul@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" - integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== - 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" - -babel-plugin-jest-hoist@^29.6.3: - version "29.6.3" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz#aadbe943464182a8922c3c927c3067ff40d24626" - integrity sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg== - dependencies: - "@babel/template" "^7.3.3" - "@babel/types" "^7.3.3" - "@types/babel__core" "^7.1.14" - "@types/babel__traverse" "^7.0.6" - -babel-preset-current-node-syntax@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz#9a929eafece419612ef4ae4f60b1862ebad8ef30" - integrity sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw== - dependencies: - "@babel/plugin-syntax-async-generators" "^7.8.4" - "@babel/plugin-syntax-bigint" "^7.8.3" - "@babel/plugin-syntax-class-properties" "^7.12.13" - "@babel/plugin-syntax-class-static-block" "^7.14.5" - "@babel/plugin-syntax-import-attributes" "^7.24.7" - "@babel/plugin-syntax-import-meta" "^7.10.4" - "@babel/plugin-syntax-json-strings" "^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" - "@babel/plugin-syntax-top-level-await" "^7.14.5" - -babel-preset-jest@^29.6.3: - version "29.6.3" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz#fa05fa510e7d493896d7b0dd2033601c840f171c" - integrity sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA== - dependencies: - babel-plugin-jest-hoist "^29.6.3" - babel-preset-current-node-syntax "^1.0.0" - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -before-after-hook@^2.2.0: - version "2.2.3" - resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.3.tgz#c51e809c81a4e354084422b9b26bad88249c517c" - integrity sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ== - -bin-links@^4.0.1: - version "4.0.4" - resolved "https://registry.yarnpkg.com/bin-links/-/bin-links-4.0.4.tgz#c3565832b8e287c85f109a02a17027d152a58a63" - integrity sha512-cMtq4W5ZsEwcutJrVId+a/tjt8GSbS+h0oNkdl6+6rBuEv8Ot33Bevj5KPm40t309zuhVic8NjpuL42QCiJWWA== - dependencies: - cmd-shim "^6.0.0" - npm-normalize-package-bin "^3.0.0" - read-cmd-shim "^4.0.0" - write-file-atomic "^5.0.0" - -bl@^4.0.3, bl@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" - integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== - dependencies: - buffer "^5.5.0" - inherits "^2.0.4" - readable-stream "^3.4.0" - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -brace-expansion@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" - integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== - dependencies: - balanced-match "^1.0.0" - -braces@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" - integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== - dependencies: - fill-range "^7.1.1" - -browserslist@^4.24.0: - version "4.25.0" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.25.0.tgz#986aa9c6d87916885da2b50d8eb577ac8d133b2c" - integrity sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA== - dependencies: - caniuse-lite "^1.0.30001718" - electron-to-chromium "^1.5.160" - node-releases "^2.0.19" - update-browserslist-db "^1.1.3" - -bs-logger@^0.2.6: - version "0.2.6" - resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" - integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== - dependencies: - fast-json-stable-stringify "2.x" - -bser@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" - integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== - dependencies: - node-int64 "^0.4.0" - -buffer-from@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - -buffer@^5.5.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" - integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.1.13" - -builtins@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" - integrity sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ== - -builtins@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/builtins/-/builtins-5.1.0.tgz#6d85eeb360c4ebc166c3fdef922a15aa7316a5e8" - integrity sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg== - dependencies: - semver "^7.0.0" - -byte-size@7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-7.0.0.tgz#36528cd1ca87d39bd9abd51f5715dc93b6ceb032" - integrity sha512-NNiBxKgxybMBtWdmvx7ZITJi4ZG+CYUgwOSZTfqB1qogkRHrhbQE/R2r5Fh94X+InN5MCYz6SvB/ejHMj/HbsQ== - -cacache@^16.1.0: - version "16.1.3" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-16.1.3.tgz#a02b9f34ecfaf9a78c9f4bc16fceb94d5d67a38e" - integrity sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ== - dependencies: - "@npmcli/fs" "^2.1.0" - "@npmcli/move-file" "^2.0.0" - chownr "^2.0.0" - fs-minipass "^2.1.0" - glob "^8.0.1" - infer-owner "^1.0.4" - lru-cache "^7.7.1" - minipass "^3.1.6" - minipass-collect "^1.0.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - mkdirp "^1.0.4" - p-map "^4.0.0" - promise-inflight "^1.0.1" - rimraf "^3.0.2" - ssri "^9.0.0" - tar "^6.1.11" - unique-filename "^2.0.0" - -cacache@^17.0.0, cacache@^17.0.4: - version "17.1.4" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-17.1.4.tgz#b3ff381580b47e85c6e64f801101508e26604b35" - integrity sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A== - dependencies: - "@npmcli/fs" "^3.1.0" - fs-minipass "^3.0.0" - glob "^10.2.2" - lru-cache "^7.7.1" - minipass "^7.0.3" - minipass-collect "^1.0.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - p-map "^4.0.0" - ssri "^10.0.0" - tar "^6.1.11" - unique-filename "^3.0.0" - -call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6" - integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ== - dependencies: - es-errors "^1.3.0" - function-bind "^1.1.2" - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -camelcase-keys@^6.2.2: - version "6.2.2" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-6.2.2.tgz#5e755d6ba51aa223ec7d3d52f25778210f9dc3c0" - integrity sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg== - dependencies: - camelcase "^5.3.1" - map-obj "^4.0.0" - quick-lru "^4.0.1" - -camelcase@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -camelcase@^6.2.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" - integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== - -caniuse-lite@^1.0.30001718: - version "1.0.30001720" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001720.tgz#c138cb6026d362be9d8d7b0e4bcd0183a850edfd" - integrity sha512-Ec/2yV2nNPwb4DnTANEV99ZWwm3ZWfdlfkQbWSDDt+PsXEVYwlhPH8tdMaPunYTKKmz7AnHi2oNEi1GcmKCD8g== - -chalk@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" - integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chalk@4.1.2, chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.1: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -char-regex@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" - integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== - -chardet@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" - integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== - -chownr@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" - integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== - -ci-info@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" - integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== - -ci-info@^3.2.0, ci-info@^3.6.1: - version "3.9.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" - integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== - -cjs-module-lexer@^1.0.0: - version "1.4.3" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz#0f79731eb8cfe1ec72acd4066efac9d61991b00d" - integrity sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q== - -clean-stack@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" - integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== - -cli-cursor@3.1.0, cli-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" - integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== - dependencies: - restore-cursor "^3.1.0" - -cli-spinners@2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.1.tgz#adc954ebe281c37a6319bfa401e6dd2488ffb70d" - integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g== - -cli-spinners@^2.5.0: - version "2.9.2" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.2.tgz#1773a8f4b9c4d6ac31563df53b3fc1d79462fe41" - integrity sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg== - -cli-width@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" - integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== - -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - -cliui@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" - 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" - -clone-deep@4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" - integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== - dependencies: - is-plain-object "^2.0.4" - kind-of "^6.0.2" - shallow-clone "^3.0.0" - -clone@^1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" - integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== - -cmd-shim@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-5.0.0.tgz#8d0aaa1a6b0708630694c4dbde070ed94c707724" - integrity sha512-qkCtZ59BidfEwHltnJwkyVZn+XQojdAySM1D1gSeh11Z4pW1Kpolkyo53L5noc0nrxmIvyFwTmJRo4xs7FFLPw== - dependencies: - mkdirp-infer-owner "^2.0.0" - -cmd-shim@^6.0.0: - version "6.0.3" - resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-6.0.3.tgz#c491e9656594ba17ac83c4bd931590a9d6e26033" - integrity sha512-FMabTRlc5t5zjdenF6mS0MBeFZm0XqHqeOkcskKFb/LYCcRQ5fVgLOHVc4Lq9CqABd9zhjwPjMBCJvMCziSVtA== - -co@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== - -collect-v8-coverage@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9" - integrity sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q== - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -color-support@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" - integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== - -columnify@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.6.0.tgz#6989531713c9008bb29735e61e37acf5bd553cf3" - integrity sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q== - dependencies: - strip-ansi "^6.0.1" - wcwidth "^1.0.0" - -combined-stream@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -common-ancestor-path@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz#4f7d2d1394d91b7abdf51871c62f71eadb0182a7" - integrity sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w== - -compare-func@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/compare-func/-/compare-func-2.0.0.tgz#fb65e75edbddfd2e568554e8b5b05fff7a51fcb3" - integrity sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA== - dependencies: - array-ify "^1.0.0" - dot-prop "^5.1.0" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - -concat-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-2.0.0.tgz#414cf5af790a48c60ab9be4527d56d5e41133cb1" - integrity sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A== - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^3.0.2" - typedarray "^0.0.6" - -config-chain@1.1.12: - version "1.1.12" - resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa" - integrity sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA== - dependencies: - ini "^1.3.4" - proto-list "~1.2.1" - -console-control-strings@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== - -conventional-changelog-angular@5.0.12: - version "5.0.12" - resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-5.0.12.tgz#c979b8b921cbfe26402eb3da5bbfda02d865a2b9" - integrity sha512-5GLsbnkR/7A89RyHLvvoExbiGbd9xKdKqDTrArnPbOqBqG/2wIosu0fHwpeIRI8Tl94MhVNBXcLJZl92ZQ5USw== - dependencies: - compare-func "^2.0.0" - q "^1.5.1" - -conventional-changelog-core@4.2.4: - version "4.2.4" - resolved "https://registry.yarnpkg.com/conventional-changelog-core/-/conventional-changelog-core-4.2.4.tgz#e50d047e8ebacf63fac3dc67bf918177001e1e9f" - integrity sha512-gDVS+zVJHE2v4SLc6B0sLsPiloR0ygU7HaDW14aNJE1v4SlqJPILPl/aJC7YdtRE4CybBf8gDwObBvKha8Xlyg== - dependencies: - add-stream "^1.0.0" - conventional-changelog-writer "^5.0.0" - conventional-commits-parser "^3.2.0" - dateformat "^3.0.0" - get-pkg-repo "^4.0.0" - git-raw-commits "^2.0.8" - git-remote-origin-url "^2.0.0" - git-semver-tags "^4.1.1" - lodash "^4.17.15" - normalize-package-data "^3.0.0" - q "^1.5.1" - read-pkg "^3.0.0" - read-pkg-up "^3.0.0" - through2 "^4.0.0" - -conventional-changelog-preset-loader@^2.3.4: - version "2.3.4" - resolved "https://registry.yarnpkg.com/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz#14a855abbffd59027fd602581f1f34d9862ea44c" - integrity sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g== - -conventional-changelog-writer@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-5.0.1.tgz#e0757072f045fe03d91da6343c843029e702f359" - integrity sha512-5WsuKUfxW7suLblAbFnxAcrvf6r+0b7GvNaWUwUIk0bXMnENP/PEieGKVUQrjPqwPT4o3EPAASBXiY6iHooLOQ== - dependencies: - conventional-commits-filter "^2.0.7" - dateformat "^3.0.0" - handlebars "^4.7.7" - json-stringify-safe "^5.0.1" - lodash "^4.17.15" - meow "^8.0.0" - semver "^6.0.0" - split "^1.0.0" - through2 "^4.0.0" - -conventional-commits-filter@^2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz#f8d9b4f182fce00c9af7139da49365b136c8a0b3" - integrity sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA== - dependencies: - lodash.ismatch "^4.4.0" - modify-values "^1.0.0" - -conventional-commits-parser@^3.2.0: - version "3.2.4" - resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz#a7d3b77758a202a9b2293d2112a8d8052c740972" - integrity sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q== - dependencies: - JSONStream "^1.0.4" - is-text-path "^1.0.1" - lodash "^4.17.15" - meow "^8.0.0" - split2 "^3.0.0" - through2 "^4.0.0" - -conventional-recommended-bump@6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/conventional-recommended-bump/-/conventional-recommended-bump-6.1.0.tgz#cfa623285d1de554012f2ffde70d9c8a22231f55" - integrity sha512-uiApbSiNGM/kkdL9GTOLAqC4hbptObFo4wW2QRyHsKciGAfQuLU1ShZ1BIVI/+K2BE/W1AWYQMCXAsv4dyKPaw== - dependencies: - concat-stream "^2.0.0" - conventional-changelog-preset-loader "^2.3.4" - conventional-commits-filter "^2.0.7" - conventional-commits-parser "^3.2.0" - git-raw-commits "^2.0.8" - git-semver-tags "^4.1.1" - meow "^8.0.0" - q "^1.5.1" - -convert-source-map@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" - integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== - -copyfiles@^2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/copyfiles/-/copyfiles-2.4.1.tgz#d2dcff60aaad1015f09d0b66e7f0f1c5cd3c5da5" - integrity sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg== - dependencies: - glob "^7.0.5" - minimatch "^3.0.3" - mkdirp "^1.0.4" - noms "0.0.0" - through2 "^2.0.1" - untildify "^4.0.0" - yargs "^16.1.0" - -core-util-is@~1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" - integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== - -cosmiconfig@7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.0.tgz#ef9b44d773959cae63ddecd122de23853b60f8d3" - integrity sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA== - dependencies: - "@types/parse-json" "^4.0.0" - import-fresh "^3.2.1" - parse-json "^5.0.0" - path-type "^4.0.0" - yaml "^1.10.0" - -create-jest@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/create-jest/-/create-jest-29.7.0.tgz#a355c5b3cb1e1af02ba177fe7afd7feee49a5320" - integrity sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q== - dependencies: - "@jest/types" "^29.6.3" - chalk "^4.0.0" - exit "^0.1.2" - graceful-fs "^4.2.9" - jest-config "^29.7.0" - jest-util "^29.7.0" - prompts "^2.0.1" - -create-require@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" - integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== - -cross-spawn@^7.0.2, cross-spawn@^7.0.3, cross-spawn@^7.0.6: - version "7.0.6" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" - integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -crypto-random-string@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" - integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== - -cssesc@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" - integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== - -csstype@^3.0.2: - version "3.1.3" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" - integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== - -dargs@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/dargs/-/dargs-7.0.0.tgz#04015c41de0bcb69ec84050f3d9be0caf8d6d5cc" - integrity sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg== - -dateformat@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" - integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== - -debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4: - version "4.4.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.1.tgz#e5a8bc6cbc4c6cd3e64308b0693a3d4fa550189b" - integrity sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ== - dependencies: - ms "^2.1.3" - -decamelize-keys@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.1.tgz#04a2d523b2f18d80d0158a43b895d56dff8d19d8" - integrity sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg== - dependencies: - decamelize "^1.1.0" - map-obj "^1.0.0" - -decamelize@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== - -dedent@0.7.0, dedent@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" - integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== - -dedent@^1.0.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.6.0.tgz#79d52d6389b1ffa67d2bcef59ba51847a9d503b2" - integrity sha512-F1Z+5UCFpmQUzJa11agbyPVMbpgT/qA3/SKyJ1jyBgm7dUcUEa8v9JwDkerSQXfakBwFljIxhOJqGkjUwZ9FSA== - -deep-is@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" - integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== - -deepmerge@^4.2.2, deepmerge@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" - integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== - -defaults@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.4.tgz#b0b02062c1e2aa62ff5d9528f0f98baa90978d7a" - integrity sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A== - dependencies: - clone "^1.0.2" - -define-lazy-prop@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" - integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== - -del@^6.0.0: - version "6.1.1" - resolved "https://registry.yarnpkg.com/del/-/del-6.1.1.tgz#3b70314f1ec0aa325c6b14eb36b95786671edb7a" - integrity sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg== - dependencies: - globby "^11.0.1" - graceful-fs "^4.2.4" - is-glob "^4.0.1" - is-path-cwd "^2.2.0" - is-path-inside "^3.0.2" - p-map "^4.0.0" - rimraf "^3.0.2" - slash "^3.0.0" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== - -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== - -deprecation@^2.0.0, deprecation@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" - integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ== - -detect-indent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" - integrity sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g== - -detect-newline@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" - integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== - -diff-sequences@^29.6.3: - version "29.6.3" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" - integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== - -diff@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -dot-prop@6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-6.0.1.tgz#fc26b3cf142b9e59b74dbd39ed66ce620c681083" - integrity sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA== - dependencies: - is-obj "^2.0.0" - -dot-prop@^5.1.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" - integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q== - dependencies: - is-obj "^2.0.0" - -dotenv@~10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" - integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== - -dunder-proto@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a" - integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A== - dependencies: - call-bind-apply-helpers "^1.0.1" - es-errors "^1.3.0" - gopd "^1.2.0" - -duplexer@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" - integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== - -eastasianwidth@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" - integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== - -ejs@^3.1.10, ejs@^3.1.7: - version "3.1.10" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.10.tgz#69ab8358b14e896f80cc39e62087b88500c3ac3b" - integrity sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA== - dependencies: - jake "^10.8.5" - -electron-to-chromium@^1.5.160: - version "1.5.162" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.162.tgz#5305c15292a960f36e86f8b330da958f8ae1690d" - integrity sha512-hQA+Zb5QQwoSaXJWEAGEw1zhk//O7qDzib05Z4qTqZfNju/FAkrm5ZInp0JbTp4Z18A6bilopdZWEYrFSsfllA== - -emittery@^0.13.1: - version "0.13.1" - resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" - integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -emoji-regex@^9.2.2: - version "9.2.2" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - -encoding@^0.1.13: - version "0.1.13" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" - integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== - dependencies: - iconv-lite "^0.6.2" - -end-of-stream@^1.4.1: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - -enquirer@~2.3.6: - version "2.3.6" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" - integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== - dependencies: - ansi-colors "^4.1.1" - -env-paths@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" - integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== - -envinfo@^7.7.4: - version "7.14.0" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.14.0.tgz#26dac5db54418f2a4c1159153a0b2ae980838aae" - integrity sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg== - -err-code@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" - integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== - -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -es-define-property@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa" - integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g== - -es-errors@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" - integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== - -es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz#1c4f2c4837327597ce69d2ca190a7fdd172338c1" - integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA== - dependencies: - es-errors "^1.3.0" - -es-set-tostringtag@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz#f31dbbe0c183b00a6d26eb6325c810c0fd18bd4d" - integrity sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA== - dependencies: - es-errors "^1.3.0" - get-intrinsic "^1.2.6" - has-tostringtag "^1.0.2" - hasown "^2.0.2" - -escalade@^3.1.1, escalade@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" - integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== - -escape-string-regexp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" - integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== - -escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -eslint-config-prettier@^9.1.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz#31af3d94578645966c082fcb71a5846d3c94867f" - integrity sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw== - -eslint-plugin-simple-import-sort@^12.1.0: - version "12.1.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-12.1.1.tgz#e64bfdaf91c5b98a298619aa634a9f7aa43b709e" - integrity sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA== - -eslint-plugin-unused-imports@^4.0.0: - version "4.1.4" - resolved "https://registry.yarnpkg.com/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-4.1.4.tgz#62ddc7446ccbf9aa7b6f1f0b00a980423cda2738" - integrity sha512-YptD6IzQjDardkl0POxnnRBhU1OEePMV0nd6siHaRBbd+lyh6NAhFEobiznKU7kTsSsDeSD62Pe7kAM1b7dAZQ== - -eslint-scope@^7.2.2: - version "7.2.2" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" - integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== - dependencies: - esrecurse "^4.3.0" - estraverse "^5.2.0" - -eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: - version "3.4.3" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" - integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== - -eslint@^8.56.0: - version "8.57.1" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.1.tgz#7df109654aba7e3bbe5c8eae533c5e461d3c6ca9" - integrity sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.6.1" - "@eslint/eslintrc" "^2.1.4" - "@eslint/js" "8.57.1" - "@humanwhocodes/config-array" "^0.13.0" - "@humanwhocodes/module-importer" "^1.0.1" - "@nodelib/fs.walk" "^1.2.8" - "@ungap/structured-clone" "^1.2.0" - ajv "^6.12.4" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.3.2" - doctrine "^3.0.0" - escape-string-regexp "^4.0.0" - eslint-scope "^7.2.2" - eslint-visitor-keys "^3.4.3" - espree "^9.6.1" - esquery "^1.4.2" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" - find-up "^5.0.0" - glob-parent "^6.0.2" - globals "^13.19.0" - graphemer "^1.4.0" - ignore "^5.2.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - is-path-inside "^3.0.3" - js-yaml "^4.1.0" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash.merge "^4.6.2" - minimatch "^3.1.2" - natural-compare "^1.4.0" - optionator "^0.9.3" - strip-ansi "^6.0.1" - text-table "^0.2.0" - -espree@^9.6.0, espree@^9.6.1: - version "9.6.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" - integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== - dependencies: - acorn "^8.9.0" - acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.4.1" - -esprima@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -esquery@^1.4.2: - version "1.6.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.6.0.tgz#91419234f804d852a82dceec3e16cdc22cf9dae7" - integrity sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg== - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^5.1.0, estraverse@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -eventemitter3@^4.0.4: - version "4.0.7" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" - integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== - -execa@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.0.0.tgz#4029b0007998a841fbd1032e5f4de86a3c1e3376" - integrity sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ== - 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" - -execa@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" - integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== - 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" - -exit@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" - integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== - -expect@^29.0.0, expect@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/expect/-/expect-29.7.0.tgz#578874590dcb3214514084c08115d8aee61e11bc" - integrity sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw== - dependencies: - "@jest/expect-utils" "^29.7.0" - jest-get-type "^29.6.3" - jest-matcher-utils "^29.7.0" - jest-message-util "^29.7.0" - jest-util "^29.7.0" - -exponential-backoff@^3.1.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.2.tgz#a8f26adb96bf78e8cd8ad1037928d5e5c0679d91" - integrity sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA== - -external-editor@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" - integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== - dependencies: - chardet "^0.7.0" - iconv-lite "^0.4.24" - tmp "^0.0.33" - -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-glob@3.2.7: - version "3.2.7" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1" - integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fast-glob@^3.2.9: - version "3.3.3" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.3.tgz#d06d585ce8dba90a16b0505c543c3ccfb3aeb818" - integrity sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.8" - -fast-json-patch@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/fast-json-patch/-/fast-json-patch-3.1.1.tgz#85064ea1b1ebf97a3f7ad01e23f9337e72c66947" - integrity sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ== - -fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== - -fastq@^1.6.0: - version "1.19.1" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.19.1.tgz#d50eaba803c8846a883c16492821ebcd2cda55f5" - integrity sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ== - dependencies: - reusify "^1.0.4" - -fb-watchman@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" - integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== - dependencies: - bser "2.1.1" - -figures@3.2.0, figures@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" - integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== - dependencies: - escape-string-regexp "^1.0.5" - -file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" - integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== - dependencies: - flat-cache "^3.0.4" - -file-url@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/file-url/-/file-url-3.0.0.tgz#247a586a746ce9f7a8ed05560290968afc262a77" - integrity sha512-g872QGsHexznxkIAdK8UiZRe7SkE6kvylShU4Nsj8NvfvZag7S0QuQ4IgvPDkk75HxgjIVDwycFTDAgIiO4nDA== - -filelist@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" - integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== - dependencies: - minimatch "^5.0.1" - -fill-range@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" - integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== - dependencies: - to-regex-range "^5.0.1" - -find-up@5.0.0, find-up@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -find-up@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ== - dependencies: - locate-path "^2.0.0" - -find-up@^4.0.0, find-up@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -flat-cache@^3.0.4: - version "3.2.0" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee" - integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw== - dependencies: - flatted "^3.2.9" - keyv "^4.5.3" - rimraf "^3.0.2" - -flat@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" - integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== - -flatted@^3.2.9: - version "3.3.3" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.3.tgz#67c8fad95454a7c7abebf74bb78ee74a44023358" - integrity sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg== - -follow-redirects@^1.15.6: - version "1.15.9" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.9.tgz#a604fa10e443bf98ca94228d9eebcc2e8a2c8ee1" - integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ== - -foreground-child@^3.1.0: - version "3.3.1" - resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.1.tgz#32e8e9ed1b68a3497befb9ac2b6adf92a638576f" - integrity sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw== - dependencies: - cross-spawn "^7.0.6" - signal-exit "^4.0.1" - -form-data@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.2.tgz#35cabbdd30c3ce73deb2c42d3c8d3ed9ca51794c" - integrity sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - es-set-tostringtag "^2.1.0" - mime-types "^2.1.12" - -fs-constants@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" - integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== - -fs-extra@9.1.0, fs-extra@^9.1.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" - integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== - dependencies: - at-least-node "^1.0.0" - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs-extra@^11.1.0: - version "11.3.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.3.0.tgz#0daced136bbaf65a555a326719af931adc7a314d" - integrity sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs-minipass@^2.0.0, fs-minipass@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" - integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== - dependencies: - minipass "^3.0.0" - -fs-minipass@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-3.0.3.tgz#79a85981c4dc120065e96f62086bf6f9dc26cc54" - integrity sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw== - dependencies: - minipass "^7.0.3" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - -fsevents@^2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" - integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== - -function-bind@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" - integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== - -gauge@^4.0.3: - version "4.0.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-4.0.4.tgz#52ff0652f2bbf607a989793d53b751bef2328dce" - integrity sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg== - dependencies: - aproba "^1.0.3 || ^2.0.0" - color-support "^1.1.3" - console-control-strings "^1.1.0" - has-unicode "^2.0.1" - signal-exit "^3.0.7" - string-width "^4.2.3" - strip-ansi "^6.0.1" - wide-align "^1.1.5" - -gauge@^5.0.0: - version "5.0.2" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-5.0.2.tgz#7ab44c11181da9766333f10db8cd1e4b17fd6c46" - integrity sha512-pMaFftXPtiGIHCJHdcUUx9Rby/rFT/Kkt3fIIGCs+9PMDIljSyRiqraTlxNtBReJRDfUefpa263RQ3vnp5G/LQ== - dependencies: - aproba "^1.0.3 || ^2.0.0" - color-support "^1.1.3" - console-control-strings "^1.1.0" - has-unicode "^2.0.1" - signal-exit "^4.0.1" - string-width "^4.2.3" - strip-ansi "^6.0.1" - wide-align "^1.1.5" - -gensync@^1.0.0-beta.2: - version "1.0.0-beta.2" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" - integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== - -get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-intrinsic@^1.2.6: - version "1.3.0" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01" - integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ== - dependencies: - call-bind-apply-helpers "^1.0.2" - es-define-property "^1.0.1" - es-errors "^1.3.0" - es-object-atoms "^1.1.1" - function-bind "^1.1.2" - get-proto "^1.0.1" - gopd "^1.2.0" - has-symbols "^1.1.0" - hasown "^2.0.2" - math-intrinsics "^1.1.0" - -get-package-type@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" - integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== - -get-pkg-repo@^4.0.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz#75973e1c8050c73f48190c52047c4cee3acbf385" - integrity sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA== - dependencies: - "@hutson/parse-repository-url" "^3.0.0" - hosted-git-info "^4.0.0" - through2 "^2.0.0" - yargs "^16.2.0" - -get-port@5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/get-port/-/get-port-5.1.1.tgz#0469ed07563479de6efb986baf053dcd7d4e3193" - integrity sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ== - -get-proto@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1" - integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g== - dependencies: - dunder-proto "^1.0.1" - es-object-atoms "^1.0.0" - -get-stream@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.0.tgz#3e0012cb6827319da2706e601a1583e8629a6718" - integrity sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg== - -get-stream@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== - -git-raw-commits@^2.0.8: - version "2.0.11" - resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-2.0.11.tgz#bc3576638071d18655e1cc60d7f524920008d723" - integrity sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A== - dependencies: - dargs "^7.0.0" - lodash "^4.17.15" - meow "^8.0.0" - split2 "^3.0.0" - through2 "^4.0.0" - -git-remote-origin-url@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz#5282659dae2107145a11126112ad3216ec5fa65f" - integrity sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw== - dependencies: - gitconfiglocal "^1.0.0" - pify "^2.3.0" - -git-semver-tags@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/git-semver-tags/-/git-semver-tags-4.1.1.tgz#63191bcd809b0ec3e151ba4751c16c444e5b5780" - integrity sha512-OWyMt5zBe7xFs8vglMmhM9lRQzCWL3WjHtxNNfJTMngGym7pC1kh8sP6jevfydJ6LP3ZvGxfb6ABYgPUM0mtsA== - dependencies: - meow "^8.0.0" - semver "^6.0.0" - -git-up@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/git-up/-/git-up-7.0.0.tgz#bace30786e36f56ea341b6f69adfd83286337467" - integrity sha512-ONdIrbBCFusq1Oy0sC71F5azx8bVkvtZtMJAsv+a6lz5YAmbNnLD6HAB4gptHZVLPR8S2/kVN6Gab7lryq5+lQ== - dependencies: - is-ssh "^1.4.0" - parse-url "^8.1.0" - -git-url-parse@13.1.0: - version "13.1.0" - resolved "https://registry.yarnpkg.com/git-url-parse/-/git-url-parse-13.1.0.tgz#07e136b5baa08d59fabdf0e33170de425adf07b4" - integrity sha512-5FvPJP/70WkIprlUZ33bm4UAaFdjcLkJLpWft1BeZKqwR0uhhNGoKwlUaPtVb4LxCSQ++erHapRak9kWGj+FCA== - dependencies: - git-up "^7.0.0" - -gitconfiglocal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz#41d045f3851a5ea88f03f24ca1c6178114464b9b" - integrity sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ== - dependencies: - ini "^1.3.2" - -glob-parent@5.1.2, glob-parent@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob-parent@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" - integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== - dependencies: - is-glob "^4.0.3" - -glob@7.1.4: - version "7.1.4" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" - integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@8.1.0, glob@^8.0.1: - version "8.1.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" - integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^5.0.1" - once "^1.3.0" - -glob@^10.0.0, glob@^10.2.2: - version "10.4.5" - resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956" - integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg== - dependencies: - foreground-child "^3.1.0" - jackspeak "^3.1.2" - minimatch "^9.0.4" - minipass "^7.1.2" - package-json-from-dist "^1.0.0" - path-scurry "^1.11.1" - -glob@^7.0.5, glob@^7.1.3, glob@^7.1.4: - version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== - 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" - -glob@^9.2.0: - version "9.3.5" - resolved "https://registry.yarnpkg.com/glob/-/glob-9.3.5.tgz#ca2ed8ca452781a3009685607fdf025a899dfe21" - integrity sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q== - dependencies: - fs.realpath "^1.0.0" - minimatch "^8.0.2" - minipass "^4.2.4" - path-scurry "^1.6.1" - -globals@^11.1.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - -globals@^13.19.0: - version "13.24.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.24.0.tgz#8432a19d78ce0c1e833949c36adb345400bb1171" - integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ== - dependencies: - type-fest "^0.20.2" - -globby@11.1.0, globby@^11.0.1, globby@^11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" - integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.2.9" - ignore "^5.2.0" - merge2 "^1.4.1" - slash "^3.0.0" - -gopd@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1" - integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== - -graceful-fs@4.2.10: - version "4.2.10" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" - integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== - -graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: - version "4.2.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" - integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== - -graphemer@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" - integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== - -handlebars@^4.7.7: - version "4.7.8" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.8.tgz#41c42c18b1be2365439188c77c6afae71c0cd9e9" - integrity sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ== - dependencies: - minimist "^1.2.5" - neo-async "^2.6.2" - source-map "^0.6.1" - wordwrap "^1.0.0" - optionalDependencies: - uglify-js "^3.1.4" - -hard-rejection@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/hard-rejection/-/hard-rejection-2.1.0.tgz#1c6eda5c1685c63942766d79bb40ae773cecd883" - integrity sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA== - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-symbols@^1.0.3, has-symbols@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338" - integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== - -has-tostringtag@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" - integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== - dependencies: - has-symbols "^1.0.3" - -has-unicode@2.0.1, has-unicode@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== - -hasown@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" - integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== - dependencies: - function-bind "^1.1.2" - -hosted-git-info@^2.1.4: - version "2.8.9" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" - integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== - -hosted-git-info@^3.0.6: - version "3.0.8" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-3.0.8.tgz#6e35d4cc87af2c5f816e4cb9ce350ba87a3f370d" - integrity sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw== - dependencies: - lru-cache "^6.0.0" - -hosted-git-info@^4.0.0, hosted-git-info@^4.0.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.1.0.tgz#827b82867e9ff1c8d0c4d9d53880397d2c86d224" - integrity sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA== - dependencies: - lru-cache "^6.0.0" - -hosted-git-info@^5.0.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-5.2.1.tgz#0ba1c97178ef91f3ab30842ae63d6a272341156f" - integrity sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw== - dependencies: - lru-cache "^7.5.1" - -hosted-git-info@^6.0.0, hosted-git-info@^6.1.1: - version "6.1.3" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-6.1.3.tgz#2ee1a14a097a1236bddf8672c35b613c46c55946" - integrity sha512-HVJyzUrLIL1c0QmviVh5E8VGyUS7xCFPS6yydaVd1UegW+ibV/CohqTH9MkOLDp5o+rb82DMo77PTuc9F/8GKw== - dependencies: - lru-cache "^7.5.1" - -html-escaper@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" - integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== - -http-cache-semantics@^4.1.0, http-cache-semantics@^4.1.1: - version "4.2.0" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz#205f4db64f8562b76a4ff9235aa5279839a09dd5" - integrity sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ== - -http-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" - integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== - dependencies: - "@tootallnate/once" "2" - agent-base "6" - debug "4" - -https-proxy-agent@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" - integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== - dependencies: - agent-base "6" - debug "4" - -human-signals@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" - integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== - -humanize-ms@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" - integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== - dependencies: - ms "^2.0.0" - -iconv-lite@^0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -iconv-lite@^0.6.2: - version "0.6.3" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" - integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== - dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" - -ieee754@^1.1.13: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - -ignore-walk@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-5.0.1.tgz#5f199e23e1288f518d90358d461387788a154776" - integrity sha512-yemi4pMf51WKT7khInJqAvsIGzoqYXblnsz0ql8tM+yi1EKYTY1evX4NAbJrLL/Aanr2HyZeluqU+Oi7MGHokw== - dependencies: - minimatch "^5.0.1" - -ignore-walk@^6.0.0: - version "6.0.5" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-6.0.5.tgz#ef8d61eab7da169078723d1f82833b36e200b0dd" - integrity sha512-VuuG0wCnjhnylG1ABXT3dAuIpTNDs/G8jlpmwXY03fXoXy/8ZK8/T+hMzt8L4WnrLCJgdybqgPagnF/f97cg3A== - dependencies: - minimatch "^9.0.0" - -ignore@^5.0.4, ignore@^5.2.0, ignore@^5.3.1: - version "5.3.2" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" - integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== - -import-fresh@^3.2.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.1.tgz#9cecb56503c0ada1f2741dbbd6546e4b13b57ccf" - integrity sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -import-local@^3.0.2: - version "3.2.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.2.0.tgz#c3d5c745798c02a6f8b897726aba5100186ee260" - integrity sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA== - dependencies: - pkg-dir "^4.2.0" - resolve-cwd "^3.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== - -indent-string@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" - integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== - -infer-owner@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" - integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -ini@^1.3.2, ini@^1.3.4: - version "1.3.8" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" - integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== - -init-package-json@3.0.2, init-package-json@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/init-package-json/-/init-package-json-3.0.2.tgz#f5bc9bac93f2bdc005778bc2271be642fecfcd69" - integrity sha512-YhlQPEjNFqlGdzrBfDNRLhvoSgX7iQRgSxgsNknRQ9ITXFT7UMfVMWhBTOh2Y+25lRnGrv5Xz8yZwQ3ACR6T3A== - dependencies: - npm-package-arg "^9.0.1" - promzard "^0.3.0" - read "^1.0.7" - read-package-json "^5.0.0" - semver "^7.3.5" - validate-npm-package-license "^3.0.4" - validate-npm-package-name "^4.0.0" - -inquirer@8.2.4: - version "8.2.4" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.4.tgz#ddbfe86ca2f67649a67daa6f1051c128f684f0b4" - integrity sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg== - dependencies: - ansi-escapes "^4.2.1" - chalk "^4.1.1" - cli-cursor "^3.1.0" - cli-width "^3.0.0" - external-editor "^3.0.3" - figures "^3.0.0" - lodash "^4.17.21" - mute-stream "0.0.8" - ora "^5.4.1" - run-async "^2.4.0" - rxjs "^7.5.5" - string-width "^4.1.0" - strip-ansi "^6.0.0" - through "^2.3.6" - wrap-ansi "^7.0.0" - -inquirer@^8.2.4: - version "8.2.6" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.6.tgz#733b74888195d8d400a67ac332011b5fae5ea562" - integrity sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg== - dependencies: - ansi-escapes "^4.2.1" - chalk "^4.1.1" - cli-cursor "^3.1.0" - cli-width "^3.0.0" - external-editor "^3.0.3" - figures "^3.0.0" - lodash "^4.17.21" - mute-stream "0.0.8" - ora "^5.4.1" - run-async "^2.4.0" - rxjs "^7.5.5" - string-width "^4.1.0" - strip-ansi "^6.0.0" - through "^2.3.6" - wrap-ansi "^6.0.1" - -inquirerer@^2.0.8: - version "2.0.8" - resolved "https://registry.yarnpkg.com/inquirerer/-/inquirerer-2.0.8.tgz#bf2d22dcf105d1b3145edc8e3437800981f97c31" - integrity sha512-/LfmACfRG/pCg0C/Ll1matjeFWUQoyiHNJTgZqxpqw20mDg/9bdzcRQ/6PFRANKaC+BUf9J/bXvsQ6FEXJV3Xw== - dependencies: - chalk "^4.1.0" - deepmerge "^4.3.1" - js-yaml "^4.1.0" - minimist "^1.2.8" - -ip-address@^9.0.5: - version "9.0.5" - resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-9.0.5.tgz#117a960819b08780c3bd1f14ef3c1cc1d3f3ea5a" - integrity sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g== - dependencies: - jsbn "1.1.0" - sprintf-js "^1.1.3" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== - -is-ci@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" - integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== - dependencies: - ci-info "^2.0.0" - -is-core-module@^2.16.0, is-core-module@^2.5.0, is-core-module@^2.8.1: - version "2.16.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4" - integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w== - dependencies: - hasown "^2.0.2" - -is-docker@^2.0.0, is-docker@^2.1.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" - integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-generator-fn@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" - integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== - -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-interactive@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" - integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== - -is-lambda@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" - integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ== - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-obj@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" - integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== - -is-path-cwd@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" - integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== - -is-path-inside@^3.0.2, is-path-inside@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" - integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== - -is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" - integrity sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg== - -is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== - dependencies: - isobject "^3.0.1" - -is-plain-object@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" - integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== - -is-ssh@^1.4.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/is-ssh/-/is-ssh-1.4.1.tgz#76de1cdbe8f92a8b905d1a172b6bc09704c20396" - integrity sha512-JNeu1wQsHjyHgn9NcWTaXq6zWSR6hqE0++zhfZlkFBbScNkyvxCdeV8sRkSBaeLKxmbpR21brail63ACNxJ0Tg== - dependencies: - protocols "^2.0.1" - -is-stream@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" - integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== - -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - -is-text-path@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-text-path/-/is-text-path-1.0.1.tgz#4e1aa0fb51bfbcb3e92688001397202c1775b66e" - integrity sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w== - dependencies: - text-extensions "^1.0.0" - -is-unicode-supported@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" - integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== - -is-wsl@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" - integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== - dependencies: - is-docker "^2.0.0" - -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== - -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - -isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== - -isomorphic-fetch@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz#0267b005049046d2421207215d45d6a262b8b8b4" - integrity sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA== - dependencies: - node-fetch "^2.6.1" - whatwg-fetch "^3.4.1" - -istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" - integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg== - -istanbul-lib-instrument@^5.0.4: - version "5.2.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" - integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== - 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" - -istanbul-lib-instrument@^6.0.0: - version "6.0.3" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz#fa15401df6c15874bcb2105f773325d78c666765" - integrity sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q== - dependencies: - "@babel/core" "^7.23.9" - "@babel/parser" "^7.23.9" - "@istanbuljs/schema" "^0.1.3" - istanbul-lib-coverage "^3.2.0" - semver "^7.5.4" - -istanbul-lib-report@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d" - integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== - dependencies: - istanbul-lib-coverage "^3.0.0" - make-dir "^4.0.0" - supports-color "^7.1.0" - -istanbul-lib-source-maps@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" - integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== - dependencies: - debug "^4.1.1" - istanbul-lib-coverage "^3.0.0" - source-map "^0.6.1" - -istanbul-reports@^3.1.3: - version "3.1.7" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.7.tgz#daed12b9e1dca518e15c056e1e537e741280fa0b" - integrity sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g== - dependencies: - html-escaper "^2.0.0" - istanbul-lib-report "^3.0.0" - -jackspeak@^3.1.2: - version "3.4.3" - resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.4.3.tgz#8833a9d89ab4acde6188942bd1c53b6390ed5a8a" - integrity sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw== - dependencies: - "@isaacs/cliui" "^8.0.2" - optionalDependencies: - "@pkgjs/parseargs" "^0.11.0" - -jake@^10.8.5: - version "10.9.2" - resolved "https://registry.yarnpkg.com/jake/-/jake-10.9.2.tgz#6ae487e6a69afec3a5e167628996b59f35ae2b7f" - integrity sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA== - dependencies: - async "^3.2.3" - chalk "^4.0.2" - filelist "^1.0.4" - minimatch "^3.1.2" - -jest-changed-files@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.7.0.tgz#1c06d07e77c78e1585d020424dedc10d6e17ac3a" - integrity sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w== - dependencies: - execa "^5.0.0" - jest-util "^29.7.0" - p-limit "^3.1.0" - -jest-circus@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.7.0.tgz#b6817a45fcc835d8b16d5962d0c026473ee3668a" - integrity sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw== - dependencies: - "@jest/environment" "^29.7.0" - "@jest/expect" "^29.7.0" - "@jest/test-result" "^29.7.0" - "@jest/types" "^29.6.3" - "@types/node" "*" - chalk "^4.0.0" - co "^4.6.0" - dedent "^1.0.0" - is-generator-fn "^2.0.0" - jest-each "^29.7.0" - jest-matcher-utils "^29.7.0" - jest-message-util "^29.7.0" - jest-runtime "^29.7.0" - jest-snapshot "^29.7.0" - jest-util "^29.7.0" - p-limit "^3.1.0" - pretty-format "^29.7.0" - pure-rand "^6.0.0" - slash "^3.0.0" - stack-utils "^2.0.3" - -jest-cli@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.7.0.tgz#5592c940798e0cae677eec169264f2d839a37995" - integrity sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg== - dependencies: - "@jest/core" "^29.7.0" - "@jest/test-result" "^29.7.0" - "@jest/types" "^29.6.3" - chalk "^4.0.0" - create-jest "^29.7.0" - exit "^0.1.2" - import-local "^3.0.2" - jest-config "^29.7.0" - jest-util "^29.7.0" - jest-validate "^29.7.0" - yargs "^17.3.1" - -jest-config@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.7.0.tgz#bcbda8806dbcc01b1e316a46bb74085a84b0245f" - integrity sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ== - dependencies: - "@babel/core" "^7.11.6" - "@jest/test-sequencer" "^29.7.0" - "@jest/types" "^29.6.3" - babel-jest "^29.7.0" - chalk "^4.0.0" - ci-info "^3.2.0" - deepmerge "^4.2.2" - glob "^7.1.3" - graceful-fs "^4.2.9" - jest-circus "^29.7.0" - jest-environment-node "^29.7.0" - jest-get-type "^29.6.3" - jest-regex-util "^29.6.3" - jest-resolve "^29.7.0" - jest-runner "^29.7.0" - jest-util "^29.7.0" - jest-validate "^29.7.0" - micromatch "^4.0.4" - parse-json "^5.2.0" - pretty-format "^29.7.0" - slash "^3.0.0" - strip-json-comments "^3.1.1" - -jest-diff@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.7.0.tgz#017934a66ebb7ecf6f205e84699be10afd70458a" - integrity sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw== - dependencies: - chalk "^4.0.0" - diff-sequences "^29.6.3" - jest-get-type "^29.6.3" - pretty-format "^29.7.0" - -jest-docblock@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.7.0.tgz#8fddb6adc3cdc955c93e2a87f61cfd350d5d119a" - integrity sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g== - dependencies: - detect-newline "^3.0.0" - -jest-each@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.7.0.tgz#162a9b3f2328bdd991beaabffbb74745e56577d1" - integrity sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ== - dependencies: - "@jest/types" "^29.6.3" - chalk "^4.0.0" - jest-get-type "^29.6.3" - jest-util "^29.7.0" - pretty-format "^29.7.0" - -jest-environment-node@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.7.0.tgz#0b93e111dda8ec120bc8300e6d1fb9576e164376" - integrity sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw== - dependencies: - "@jest/environment" "^29.7.0" - "@jest/fake-timers" "^29.7.0" - "@jest/types" "^29.6.3" - "@types/node" "*" - jest-mock "^29.7.0" - jest-util "^29.7.0" - -jest-get-type@^29.6.3: - version "29.6.3" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1" - integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== - -jest-haste-map@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.7.0.tgz#3c2396524482f5a0506376e6c858c3bbcc17b104" - integrity sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA== - dependencies: - "@jest/types" "^29.6.3" - "@types/graceful-fs" "^4.1.3" - "@types/node" "*" - anymatch "^3.0.3" - fb-watchman "^2.0.0" - graceful-fs "^4.2.9" - jest-regex-util "^29.6.3" - jest-util "^29.7.0" - jest-worker "^29.7.0" - micromatch "^4.0.4" - walker "^1.0.8" - optionalDependencies: - fsevents "^2.3.2" - -jest-leak-detector@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz#5b7ec0dadfdfec0ca383dc9aa016d36b5ea4c728" - integrity sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw== - dependencies: - jest-get-type "^29.6.3" - pretty-format "^29.7.0" - -jest-matcher-utils@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz#ae8fec79ff249fd592ce80e3ee474e83a6c44f12" - integrity sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g== - dependencies: - chalk "^4.0.0" - jest-diff "^29.7.0" - jest-get-type "^29.6.3" - pretty-format "^29.7.0" - -jest-message-util@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.7.0.tgz#8bc392e204e95dfe7564abbe72a404e28e51f7f3" - integrity sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w== - dependencies: - "@babel/code-frame" "^7.12.13" - "@jest/types" "^29.6.3" - "@types/stack-utils" "^2.0.0" - chalk "^4.0.0" - graceful-fs "^4.2.9" - micromatch "^4.0.4" - pretty-format "^29.7.0" - slash "^3.0.0" - stack-utils "^2.0.3" - -jest-mock@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.7.0.tgz#4e836cf60e99c6fcfabe9f99d017f3fdd50a6347" - integrity sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw== - dependencies: - "@jest/types" "^29.6.3" - "@types/node" "*" - jest-util "^29.7.0" - -jest-pnp-resolver@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e" - integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== - -jest-regex-util@^29.6.3: - version "29.6.3" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.6.3.tgz#4a556d9c776af68e1c5f48194f4d0327d24e8a52" - integrity sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg== - -jest-resolve-dependencies@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz#1b04f2c095f37fc776ff40803dc92921b1e88428" - integrity sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA== - dependencies: - jest-regex-util "^29.6.3" - jest-snapshot "^29.7.0" - -jest-resolve@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.7.0.tgz#64d6a8992dd26f635ab0c01e5eef4399c6bcbc30" - integrity sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA== - dependencies: - chalk "^4.0.0" - graceful-fs "^4.2.9" - jest-haste-map "^29.7.0" - jest-pnp-resolver "^1.2.2" - jest-util "^29.7.0" - jest-validate "^29.7.0" - resolve "^1.20.0" - resolve.exports "^2.0.0" - slash "^3.0.0" - -jest-runner@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.7.0.tgz#809af072d408a53dcfd2e849a4c976d3132f718e" - integrity sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ== - dependencies: - "@jest/console" "^29.7.0" - "@jest/environment" "^29.7.0" - "@jest/test-result" "^29.7.0" - "@jest/transform" "^29.7.0" - "@jest/types" "^29.6.3" - "@types/node" "*" - chalk "^4.0.0" - emittery "^0.13.1" - graceful-fs "^4.2.9" - jest-docblock "^29.7.0" - jest-environment-node "^29.7.0" - jest-haste-map "^29.7.0" - jest-leak-detector "^29.7.0" - jest-message-util "^29.7.0" - jest-resolve "^29.7.0" - jest-runtime "^29.7.0" - jest-util "^29.7.0" - jest-watcher "^29.7.0" - jest-worker "^29.7.0" - p-limit "^3.1.0" - source-map-support "0.5.13" - -jest-runtime@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.7.0.tgz#efecb3141cf7d3767a3a0cc8f7c9990587d3d817" - integrity sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ== - dependencies: - "@jest/environment" "^29.7.0" - "@jest/fake-timers" "^29.7.0" - "@jest/globals" "^29.7.0" - "@jest/source-map" "^29.6.3" - "@jest/test-result" "^29.7.0" - "@jest/transform" "^29.7.0" - "@jest/types" "^29.6.3" - "@types/node" "*" - chalk "^4.0.0" - cjs-module-lexer "^1.0.0" - collect-v8-coverage "^1.0.0" - glob "^7.1.3" - graceful-fs "^4.2.9" - jest-haste-map "^29.7.0" - jest-message-util "^29.7.0" - jest-mock "^29.7.0" - jest-regex-util "^29.6.3" - jest-resolve "^29.7.0" - jest-snapshot "^29.7.0" - jest-util "^29.7.0" - slash "^3.0.0" - strip-bom "^4.0.0" - -jest-snapshot@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.7.0.tgz#c2c574c3f51865da1bb329036778a69bf88a6be5" - integrity sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw== - dependencies: - "@babel/core" "^7.11.6" - "@babel/generator" "^7.7.2" - "@babel/plugin-syntax-jsx" "^7.7.2" - "@babel/plugin-syntax-typescript" "^7.7.2" - "@babel/types" "^7.3.3" - "@jest/expect-utils" "^29.7.0" - "@jest/transform" "^29.7.0" - "@jest/types" "^29.6.3" - babel-preset-current-node-syntax "^1.0.0" - chalk "^4.0.0" - expect "^29.7.0" - graceful-fs "^4.2.9" - jest-diff "^29.7.0" - jest-get-type "^29.6.3" - jest-matcher-utils "^29.7.0" - jest-message-util "^29.7.0" - jest-util "^29.7.0" - natural-compare "^1.4.0" - pretty-format "^29.7.0" - semver "^7.5.3" - -jest-util@^29.0.0, jest-util@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc" - integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== - dependencies: - "@jest/types" "^29.6.3" - "@types/node" "*" - chalk "^4.0.0" - ci-info "^3.2.0" - graceful-fs "^4.2.9" - picomatch "^2.2.3" - -jest-validate@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.7.0.tgz#7bf705511c64da591d46b15fce41400d52147d9c" - integrity sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw== - dependencies: - "@jest/types" "^29.6.3" - camelcase "^6.2.0" - chalk "^4.0.0" - jest-get-type "^29.6.3" - leven "^3.1.0" - pretty-format "^29.7.0" - -jest-watcher@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.7.0.tgz#7810d30d619c3a62093223ce6bb359ca1b28a2f2" - integrity sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g== - dependencies: - "@jest/test-result" "^29.7.0" - "@jest/types" "^29.6.3" - "@types/node" "*" - ansi-escapes "^4.2.1" - chalk "^4.0.0" - emittery "^0.13.1" - jest-util "^29.7.0" - string-length "^4.0.1" - -jest-worker@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.7.0.tgz#acad073acbbaeb7262bd5389e1bcf43e10058d4a" - integrity sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw== - dependencies: - "@types/node" "*" - jest-util "^29.7.0" - merge-stream "^2.0.0" - supports-color "^8.0.0" - -jest@^29.6.2: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest/-/jest-29.7.0.tgz#994676fc24177f088f1c5e3737f5697204ff2613" - integrity sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw== - dependencies: - "@jest/core" "^29.7.0" - "@jest/types" "^29.6.3" - import-local "^3.0.2" - jest-cli "^29.7.0" - -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@4.1.0, js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -js-yaml@^3.10.0, js-yaml@^3.13.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -jsbn@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-1.1.0.tgz#b01307cb29b618a1ed26ec79e911f803c4da0040" - integrity sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A== - -jsesc@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d" - integrity sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA== - -json-buffer@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" - integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== - -json-parse-better-errors@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - -json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - -json-parse-even-better-errors@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz#b43d35e89c0f3be6b5fbbe9dc6c82467b30c28da" - integrity sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== - -json-stringify-nice@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/json-stringify-nice/-/json-stringify-nice-1.1.4.tgz#2c937962b80181d3f317dd39aa323e14f5a60a67" - integrity sha512-5Z5RFW63yxReJ7vANgW6eZFGWaQvnPE3WNmZoOJrSkGju2etKA2L5rrOa1sm877TVTFt57A80BH1bArcmlLfPw== - -json-stringify-safe@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== - -json5@^2.2.2, json5@^2.2.3: - version "2.2.3" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" - integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== - -jsonc-parser@3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" - integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w== - -jsonfile@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" - integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== - dependencies: - universalify "^2.0.0" - optionalDependencies: - graceful-fs "^4.1.6" - -jsonparse@^1.2.0, jsonparse@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" - integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== - -just-diff-apply@^5.2.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/just-diff-apply/-/just-diff-apply-5.5.0.tgz#771c2ca9fa69f3d2b54e7c3f5c1dfcbcc47f9f0f" - integrity sha512-OYTthRfSh55WOItVqwpefPtNt2VdKsq5AnAK6apdtR6yCH8pr0CmSr710J0Mf+WdQy7K/OzMy7K2MgAfdQURDw== - -just-diff@^6.0.0: - version "6.0.2" - resolved "https://registry.yarnpkg.com/just-diff/-/just-diff-6.0.2.tgz#03b65908543ac0521caf6d8eb85035f7d27ea285" - integrity sha512-S59eriX5u3/QhMNq3v/gm8Kd0w8OS6Tz2FS1NG4blv+z0MuQcBRJyFWjdovM0Rad4/P4aUPFtnkNjMjyMlMSYA== - -keyv@^4.5.3: - version "4.5.4" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" - integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== - dependencies: - json-buffer "3.0.1" - -kind-of@^6.0.2, kind-of@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" - integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== - -kleur@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" - integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== - -lerna@^6: - version "6.6.2" - resolved "https://registry.yarnpkg.com/lerna/-/lerna-6.6.2.tgz#ad921f913aca4e7307123a598768b6f15ca5804f" - integrity sha512-W4qrGhcdutkRdHEaDf9eqp7u4JvI+1TwFy5woX6OI8WPe4PYBdxuILAsvhp614fUG41rKSGDKlOh+AWzdSidTg== - dependencies: - "@lerna/child-process" "6.6.2" - "@lerna/create" "6.6.2" - "@lerna/legacy-package-management" "6.6.2" - "@npmcli/arborist" "6.2.3" - "@npmcli/run-script" "4.1.7" - "@nrwl/devkit" ">=15.5.2 < 16" - "@octokit/plugin-enterprise-rest" "6.0.1" - "@octokit/rest" "19.0.3" - byte-size "7.0.0" - chalk "4.1.0" - clone-deep "4.0.1" - cmd-shim "5.0.0" - columnify "1.6.0" - config-chain "1.1.12" - conventional-changelog-angular "5.0.12" - conventional-changelog-core "4.2.4" - conventional-recommended-bump "6.1.0" - cosmiconfig "7.0.0" - dedent "0.7.0" - dot-prop "6.0.1" - envinfo "^7.7.4" - execa "5.0.0" - fs-extra "9.1.0" - get-port "5.1.1" - get-stream "6.0.0" - git-url-parse "13.1.0" - glob-parent "5.1.2" - globby "11.1.0" - graceful-fs "4.2.10" - has-unicode "2.0.1" - import-local "^3.0.2" - init-package-json "3.0.2" - inquirer "^8.2.4" - is-ci "2.0.0" - is-stream "2.0.0" - js-yaml "^4.1.0" - libnpmaccess "^6.0.3" - libnpmpublish "7.1.4" - load-json-file "6.2.0" - make-dir "3.1.0" - minimatch "3.0.5" - multimatch "5.0.0" - node-fetch "2.6.7" - npm-package-arg "8.1.1" - npm-packlist "5.1.1" - npm-registry-fetch "^14.0.3" - npmlog "^6.0.2" - nx ">=15.5.2 < 16" - p-map "4.0.0" - p-map-series "2.1.0" - p-pipe "3.1.0" - p-queue "6.6.2" - p-reduce "2.1.0" - p-waterfall "2.1.1" - pacote "15.1.1" - pify "5.0.0" - read-cmd-shim "3.0.0" - read-package-json "5.0.1" - resolve-from "5.0.0" - rimraf "^4.4.1" - semver "^7.3.8" - signal-exit "3.0.7" - slash "3.0.0" - ssri "9.0.1" - strong-log-transformer "2.1.0" - tar "6.1.11" - temp-dir "1.0.0" - typescript "^3 || ^4" - upath "^2.0.1" - uuid "8.3.2" - validate-npm-package-license "3.0.4" - validate-npm-package-name "4.0.0" - write-file-atomic "4.0.1" - write-pkg "4.0.0" - yargs "16.2.0" - yargs-parser "20.2.4" - -leven@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" - integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== - -levn@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" - integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== - dependencies: - prelude-ls "^1.2.1" - type-check "~0.4.0" - -libnpmaccess@^6.0.3: - version "6.0.4" - resolved "https://registry.yarnpkg.com/libnpmaccess/-/libnpmaccess-6.0.4.tgz#2dd158bd8a071817e2207d3b201d37cf1ad6ae6b" - integrity sha512-qZ3wcfIyUoW0+qSFkMBovcTrSGJ3ZeyvpR7d5N9pEYv/kXs8sHP2wiqEIXBKLFrZlmM0kR0RJD7mtfLngtlLag== - dependencies: - aproba "^2.0.0" - minipass "^3.1.1" - npm-package-arg "^9.0.1" - npm-registry-fetch "^13.0.0" - -libnpmpublish@7.1.4: - version "7.1.4" - resolved "https://registry.yarnpkg.com/libnpmpublish/-/libnpmpublish-7.1.4.tgz#a0d138e00e52a0c71ffc82273acf0082fc2dfb36" - integrity sha512-mMntrhVwut5prP4rJ228eEbEyvIzLWhqFuY90j5QeXBCTT2pWSMno7Yo2S2qplPUr02zPurGH4heGLZ+wORczg== - dependencies: - ci-info "^3.6.1" - normalize-package-data "^5.0.0" - npm-package-arg "^10.1.0" - npm-registry-fetch "^14.0.3" - proc-log "^3.0.0" - semver "^7.3.7" - sigstore "^1.4.0" - ssri "^10.0.1" - -lines-and-columns@^1.1.6: - version "1.2.4" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" - integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== - -lines-and-columns@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-2.0.4.tgz#d00318855905d2660d8c0822e3f5a4715855fc42" - integrity sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A== - -load-json-file@6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-6.2.0.tgz#5c7770b42cafa97074ca2848707c61662f4251a1" - integrity sha512-gUD/epcRms75Cw8RT1pUdHugZYM5ce64ucs2GEISABwkRsOQr0q2wm/MV2TKThycIe5e0ytRweW2RZxclogCdQ== - dependencies: - graceful-fs "^4.1.15" - parse-json "^5.0.0" - strip-bom "^4.0.0" - type-fest "^0.6.0" - -load-json-file@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" - integrity sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw== - dependencies: - graceful-fs "^4.1.2" - parse-json "^4.0.0" - pify "^3.0.0" - strip-bom "^3.0.0" - -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA== - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -lodash.ismatch@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37" - integrity sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g== - -lodash.memoize@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" - integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== - -lodash.merge@^4.6.2: - version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" - integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== - -lodash@^4.17.15, lodash@^4.17.21: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -log-symbols@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" - integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== - dependencies: - chalk "^4.1.0" - is-unicode-supported "^0.1.0" - -loose-envify@^1.1.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - -lru-cache@^10.2.0: - version "10.4.3" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" - integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== - -lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== - dependencies: - yallist "^3.0.2" - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -lru-cache@^7.4.4, lru-cache@^7.5.1, lru-cache@^7.7.1: - version "7.18.3" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" - integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== - -make-dir@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" - integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== - dependencies: - semver "^6.0.0" - -make-dir@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" - integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== - dependencies: - pify "^4.0.1" - semver "^5.6.0" - -make-dir@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" - integrity sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw== - dependencies: - semver "^7.5.3" - -make-error@^1.1.1, make-error@^1.3.6: - version "1.3.6" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" - integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== - -make-fetch-happen@^10.0.3, make-fetch-happen@^10.0.6: - version "10.2.1" - resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz#f5e3835c5e9817b617f2770870d9492d28678164" - integrity sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w== - dependencies: - agentkeepalive "^4.2.1" - cacache "^16.1.0" - http-cache-semantics "^4.1.0" - http-proxy-agent "^5.0.0" - https-proxy-agent "^5.0.0" - is-lambda "^1.0.1" - lru-cache "^7.7.1" - minipass "^3.1.6" - minipass-collect "^1.0.2" - minipass-fetch "^2.0.3" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - negotiator "^0.6.3" - promise-retry "^2.0.1" - socks-proxy-agent "^7.0.0" - ssri "^9.0.0" - -make-fetch-happen@^11.0.0, make-fetch-happen@^11.0.1, make-fetch-happen@^11.1.1: - version "11.1.1" - resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz#85ceb98079584a9523d4bf71d32996e7e208549f" - integrity sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w== - dependencies: - agentkeepalive "^4.2.1" - cacache "^17.0.0" - http-cache-semantics "^4.1.1" - http-proxy-agent "^5.0.0" - https-proxy-agent "^5.0.0" - is-lambda "^1.0.1" - lru-cache "^7.7.1" - minipass "^5.0.0" - minipass-fetch "^3.0.0" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - negotiator "^0.6.3" - promise-retry "^2.0.1" - socks-proxy-agent "^7.0.0" - ssri "^10.0.0" - -makeerror@1.0.12: - version "1.0.12" - resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" - integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== - dependencies: - tmpl "1.0.5" - -map-obj@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" - integrity sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg== - -map-obj@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.3.0.tgz#9304f906e93faae70880da102a9f1df0ea8bb05a" - integrity sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ== - -math-intrinsics@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9" - integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== - -meow@^8.0.0: - version "8.1.2" - resolved "https://registry.yarnpkg.com/meow/-/meow-8.1.2.tgz#bcbe45bda0ee1729d350c03cffc8395a36c4e897" - integrity sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q== - dependencies: - "@types/minimist" "^1.2.0" - camelcase-keys "^6.2.2" - decamelize-keys "^1.1.0" - hard-rejection "^2.1.0" - minimist-options "4.1.0" - normalize-package-data "^3.0.0" - read-pkg-up "^7.0.1" - redent "^3.0.0" - trim-newlines "^3.0.0" - type-fest "^0.18.0" - yargs-parser "^20.2.3" - -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== - -merge2@^1.3.0, merge2@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -micromatch@^4.0.4, micromatch@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" - integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== - dependencies: - braces "^3.0.3" - picomatch "^2.3.1" - -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -mime-types@^2.1.12: - version "2.1.35" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== - dependencies: - mime-db "1.52.0" - -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -min-indent@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" - integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== - -minimatch@3.0.5: - version "3.0.5" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.5.tgz#4da8f1290ee0f0f8e83d60ca69f8f134068604a3" - integrity sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^3.0.3, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^5.0.1: - version "5.1.6" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" - integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== - dependencies: - brace-expansion "^2.0.1" - -minimatch@^6.1.6: - version "6.2.0" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-6.2.0.tgz#2b70fd13294178c69c04dfc05aebdb97a4e79e42" - integrity sha512-sauLxniAmvnhhRjFwPNnJKaPFYyddAgbYdeUpHULtCT/GhzdCx/MDNy+Y40lBxTQUrMzDE8e0S43Z5uqfO0REg== - dependencies: - brace-expansion "^2.0.1" - -minimatch@^8.0.2: - version "8.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-8.0.4.tgz#847c1b25c014d4e9a7f68aaf63dedd668a626229" - integrity sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA== - dependencies: - brace-expansion "^2.0.1" - -minimatch@^9.0.0, minimatch@^9.0.4: - version "9.0.5" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" - integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== - dependencies: - brace-expansion "^2.0.1" - -minimist-options@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-4.1.0.tgz#c0655713c53a8a2ebd77ffa247d342c40f010619" - integrity sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A== - dependencies: - arrify "^1.0.1" - is-plain-obj "^1.1.0" - kind-of "^6.0.3" - -minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6, minimist@^1.2.8: - version "1.2.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" - integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== - -minipass-collect@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" - integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== - dependencies: - minipass "^3.0.0" - -minipass-fetch@^2.0.3: - version "2.1.2" - resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-2.1.2.tgz#95560b50c472d81a3bc76f20ede80eaed76d8add" - integrity sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA== - dependencies: - minipass "^3.1.6" - minipass-sized "^1.0.3" - minizlib "^2.1.2" - optionalDependencies: - encoding "^0.1.13" - -minipass-fetch@^3.0.0: - version "3.0.5" - resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-3.0.5.tgz#f0f97e40580affc4a35cc4a1349f05ae36cb1e4c" - integrity sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg== - dependencies: - minipass "^7.0.3" - minipass-sized "^1.0.3" - minizlib "^2.1.2" - optionalDependencies: - encoding "^0.1.13" - -minipass-flush@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" - integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== - dependencies: - minipass "^3.0.0" - -minipass-json-stream@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/minipass-json-stream/-/minipass-json-stream-1.0.2.tgz#5121616c77a11c406c3ffa77509e0b77bb267ec3" - integrity sha512-myxeeTm57lYs8pH2nxPzmEEg8DGIgW+9mv6D4JZD2pa81I/OBjeU7PtICXV6c9eRGTA5JMDsuIPUZRCyBMYNhg== - dependencies: - jsonparse "^1.3.1" - minipass "^3.0.0" - -minipass-pipeline@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" - integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== - dependencies: - minipass "^3.0.0" - -minipass-sized@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-1.0.3.tgz#70ee5a7c5052070afacfbc22977ea79def353b70" - integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== - dependencies: - minipass "^3.0.0" - -minipass@^3.0.0, minipass@^3.1.1, minipass@^3.1.6: - version "3.3.6" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" - integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== - dependencies: - yallist "^4.0.0" - -minipass@^4.0.0, minipass@^4.2.4: - version "4.2.8" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-4.2.8.tgz#f0010f64393ecfc1d1ccb5f582bcaf45f48e1a3a" - integrity sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ== - -minipass@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" - integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== - -"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.3, minipass@^7.1.2: - version "7.1.2" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707" - integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== - -minizlib@^2.1.1, minizlib@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" - integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== - dependencies: - minipass "^3.0.0" - yallist "^4.0.0" - -mkdirp-infer-owner@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/mkdirp-infer-owner/-/mkdirp-infer-owner-2.0.0.tgz#55d3b368e7d89065c38f32fd38e638f0ab61d316" - integrity sha512-sdqtiFt3lkOaYvTXSRIUjkIdPTcxgv5+fgqYE/5qgwdw12cOrAuzzgzvVExIkH/ul1oeHN3bCLOWSG3XOqbKKw== - dependencies: - chownr "^2.0.0" - infer-owner "^1.0.4" - mkdirp "^1.0.3" - -mkdirp@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-3.0.0.tgz#758101231418bda24435c0888a91d9bd91f1372d" - integrity sha512-7+JDnNsyCvZXoUJdkMR0oUE2AmAdsNXGTmRbiOjYIwQ6q+bL6NwrozGQdPcmYaNcrhH37F50HHBUzoaBV6FITQ== - -mkdirp@^1.0.3, mkdirp@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - -modify-values@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" - integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw== - -ms@^2.0.0, ms@^2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -multimatch@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-5.0.0.tgz#932b800963cea7a31a033328fa1e0c3a1874dbe6" - integrity sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA== - dependencies: - "@types/minimatch" "^3.0.3" - array-differ "^3.0.0" - array-union "^2.1.0" - arrify "^2.0.1" - minimatch "^3.0.4" - -mute-stream@0.0.8, mute-stream@~0.0.4: - version "0.0.8" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" - integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== - -negotiator@^0.6.3: - version "0.6.4" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.4.tgz#777948e2452651c570b712dd01c23e262713fff7" - integrity sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w== - -neo-async@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" - integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== - -node-addon-api@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161" - integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A== - -node-fetch@2.6.7: - version "2.6.7" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" - integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== - dependencies: - whatwg-url "^5.0.0" - -node-fetch@^2.6.1, node-fetch@^2.6.7: - version "2.7.0" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" - integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== - dependencies: - whatwg-url "^5.0.0" - -node-gyp-build@^4.3.0: - version "4.8.4" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.4.tgz#8a70ee85464ae52327772a90d66c6077a900cfc8" - integrity sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ== - -node-gyp@^9.0.0: - version "9.4.1" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-9.4.1.tgz#8a1023e0d6766ecb52764cc3a734b36ff275e185" - integrity sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ== - dependencies: - env-paths "^2.2.0" - exponential-backoff "^3.1.1" - glob "^7.1.4" - graceful-fs "^4.2.6" - make-fetch-happen "^10.0.3" - nopt "^6.0.0" - npmlog "^6.0.0" - rimraf "^3.0.2" - semver "^7.3.5" - tar "^6.1.2" - which "^2.0.2" - -node-int64@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" - integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== - -node-releases@^2.0.19: - version "2.0.19" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.19.tgz#9e445a52950951ec4d177d843af370b411caf314" - integrity sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw== - -noms@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/noms/-/noms-0.0.0.tgz#da8ebd9f3af9d6760919b27d9cdc8092a7332859" - integrity sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow== - dependencies: - inherits "^2.0.1" - readable-stream "~1.0.31" - -nopt@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-6.0.0.tgz#245801d8ebf409c6df22ab9d95b65e1309cdb16d" - integrity sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g== - dependencies: - abbrev "^1.0.0" - -nopt@^7.0.0: - version "7.2.1" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-7.2.1.tgz#1cac0eab9b8e97c9093338446eddd40b2c8ca1e7" - integrity sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w== - dependencies: - abbrev "^2.0.0" - -normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-package-data@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-3.0.3.tgz#dbcc3e2da59509a0983422884cd172eefdfa525e" - integrity sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA== - dependencies: - hosted-git-info "^4.0.1" - is-core-module "^2.5.0" - semver "^7.3.4" - validate-npm-package-license "^3.0.1" - -normalize-package-data@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-4.0.1.tgz#b46b24e0616d06cadf9d5718b29b6d445a82a62c" - integrity sha512-EBk5QKKuocMJhB3BILuKhmaPjI8vNRSpIfO9woLC6NyHVkKKdVEdAO1mrT0ZfxNR1lKwCcTkuZfmGIFdizZ8Pg== - dependencies: - hosted-git-info "^5.0.0" - is-core-module "^2.8.1" - semver "^7.3.5" - validate-npm-package-license "^3.0.4" - -normalize-package-data@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-5.0.0.tgz#abcb8d7e724c40d88462b84982f7cbf6859b4588" - integrity sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q== - dependencies: - hosted-git-info "^6.0.0" - is-core-module "^2.8.1" - semver "^7.3.5" - validate-npm-package-license "^3.0.4" - -normalize-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -npm-bundled@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.2.tgz#944c78789bd739035b70baa2ca5cc32b8d860bc1" - integrity sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ== - dependencies: - npm-normalize-package-bin "^1.0.1" - -npm-bundled@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-3.0.1.tgz#cca73e15560237696254b10170d8f86dad62da25" - integrity sha512-+AvaheE/ww1JEwRHOrn4WHNzOxGtVp+adrg2AeZS/7KuxGUYFuBta98wYpfHBbJp6Tg6j1NKSEVHNcfZzJHQwQ== - dependencies: - npm-normalize-package-bin "^3.0.0" - -npm-install-checks@^6.0.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-6.3.0.tgz#046552d8920e801fa9f919cad569545d60e826fe" - integrity sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw== - dependencies: - semver "^7.1.1" - -npm-normalize-package-bin@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" - integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== - -npm-normalize-package-bin@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-2.0.0.tgz#9447a1adaaf89d8ad0abe24c6c84ad614a675fff" - integrity sha512-awzfKUO7v0FscrSpRoogyNm0sajikhBWpU0QMrW09AMi9n1PoKU6WaIqUzuJSQnpciZZmJ/jMZ2Egfmb/9LiWQ== - -npm-normalize-package-bin@^3.0.0, npm-normalize-package-bin@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz#25447e32a9a7de1f51362c61a559233b89947832" - integrity sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ== - -npm-package-arg@8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.1.1.tgz#00ebf16ac395c63318e67ce66780a06db6df1b04" - integrity sha512-CsP95FhWQDwNqiYS+Q0mZ7FAEDytDZAkNxQqea6IaAFJTAY9Lhhqyl0irU/6PMc7BGfUmnsbHcqxJD7XuVM/rg== - dependencies: - hosted-git-info "^3.0.6" - semver "^7.0.0" - validate-npm-package-name "^3.0.0" - -npm-package-arg@^10.0.0, npm-package-arg@^10.1.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-10.1.0.tgz#827d1260a683806685d17193073cc152d3c7e9b1" - integrity sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA== - dependencies: - hosted-git-info "^6.0.0" - proc-log "^3.0.0" - semver "^7.3.5" - validate-npm-package-name "^5.0.0" - -npm-package-arg@^9.0.1: - version "9.1.2" - resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-9.1.2.tgz#fc8acecb00235f42270dda446f36926ddd9ac2bc" - integrity sha512-pzd9rLEx4TfNJkovvlBSLGhq31gGu2QDexFPWT19yCDh0JgnRhlBLNo5759N0AJmBk+kQ9Y/hXoLnlgFD+ukmg== - dependencies: - hosted-git-info "^5.0.0" - proc-log "^2.0.1" - semver "^7.3.5" - validate-npm-package-name "^4.0.0" - -npm-packlist@5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-5.1.1.tgz#79bcaf22a26b6c30aa4dd66b976d69cc286800e0" - integrity sha512-UfpSvQ5YKwctmodvPPkK6Fwk603aoVsf8AEbmVKAEECrfvL8SSe1A2YIwrJ6xmTHAITKPwwZsWo7WwEbNk0kxw== - dependencies: - glob "^8.0.1" - ignore-walk "^5.0.1" - npm-bundled "^1.1.2" - npm-normalize-package-bin "^1.0.1" - -npm-packlist@^7.0.0: - version "7.0.4" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-7.0.4.tgz#033bf74110eb74daf2910dc75144411999c5ff32" - integrity sha512-d6RGEuRrNS5/N84iglPivjaJPxhDbZmlbTwTDX2IbcRHG5bZCdtysYMhwiPvcF4GisXHGn7xsxv+GQ7T/02M5Q== - dependencies: - ignore-walk "^6.0.0" - -npm-pick-manifest@^8.0.0, npm-pick-manifest@^8.0.1: - version "8.0.2" - resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-8.0.2.tgz#2159778d9c7360420c925c1a2287b5a884c713aa" - integrity sha512-1dKY+86/AIiq1tkKVD3l0WI+Gd3vkknVGAggsFeBkTvbhMQ1OND/LKkYv4JtXPKUJ8bOTCyLiqEg2P6QNdK+Gg== - dependencies: - npm-install-checks "^6.0.0" - npm-normalize-package-bin "^3.0.0" - npm-package-arg "^10.0.0" - semver "^7.3.5" - -npm-registry-fetch@14.0.3: - version "14.0.3" - resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-14.0.3.tgz#8545e321c2b36d2c6fe6e009e77e9f0e527f547b" - integrity sha512-YaeRbVNpnWvsGOjX2wk5s85XJ7l1qQBGAp724h8e2CZFFhMSuw9enom7K1mWVUtvXO1uUSFIAPofQK0pPN0ZcA== - dependencies: - make-fetch-happen "^11.0.0" - minipass "^4.0.0" - minipass-fetch "^3.0.0" - minipass-json-stream "^1.0.1" - minizlib "^2.1.2" - npm-package-arg "^10.0.0" - proc-log "^3.0.0" - -npm-registry-fetch@^13.0.0: - version "13.3.1" - resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-13.3.1.tgz#bb078b5fa6c52774116ae501ba1af2a33166af7e" - integrity sha512-eukJPi++DKRTjSBRcDZSDDsGqRK3ehbxfFUcgaRd0Yp6kRwOwh2WVn0r+8rMB4nnuzvAk6rQVzl6K5CkYOmnvw== - dependencies: - make-fetch-happen "^10.0.6" - minipass "^3.1.6" - minipass-fetch "^2.0.3" - minipass-json-stream "^1.0.1" - minizlib "^2.1.2" - npm-package-arg "^9.0.1" - proc-log "^2.0.0" - -npm-registry-fetch@^14.0.0, npm-registry-fetch@^14.0.3: - version "14.0.5" - resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-14.0.5.tgz#fe7169957ba4986a4853a650278ee02e568d115d" - integrity sha512-kIDMIo4aBm6xg7jOttupWZamsZRkAqMqwqqbVXnUqstY5+tapvv6bkH/qMR76jdgV+YljEUCyWx3hRYMrJiAgA== - dependencies: - make-fetch-happen "^11.0.0" - minipass "^5.0.0" - minipass-fetch "^3.0.0" - minipass-json-stream "^1.0.1" - minizlib "^2.1.2" - npm-package-arg "^10.0.0" - proc-log "^3.0.0" - -npm-run-path@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== - dependencies: - path-key "^3.0.0" - -npmlog@6.0.2, npmlog@^6.0.0, npmlog@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-6.0.2.tgz#c8166017a42f2dea92d6453168dd865186a70830" - integrity sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg== - dependencies: - are-we-there-yet "^3.0.0" - console-control-strings "^1.1.0" - gauge "^4.0.3" - set-blocking "^2.0.0" - -npmlog@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-7.0.1.tgz#7372151a01ccb095c47d8bf1d0771a4ff1f53ac8" - integrity sha512-uJ0YFk/mCQpLBt+bxN88AKd+gyqZvZDbtiNxk6Waqcj2aPRyfVx8ITawkyQynxUagInjdYT1+qj4NfA5KJJUxg== - dependencies: - are-we-there-yet "^4.0.0" - console-control-strings "^1.1.0" - gauge "^5.0.0" - set-blocking "^2.0.0" - -nx@15.9.7, "nx@>=15.5.2 < 16": - version "15.9.7" - resolved "https://registry.yarnpkg.com/nx/-/nx-15.9.7.tgz#f0e713cedb8637a517d9c4795c99afec4959a1b6" - integrity sha512-1qlEeDjX9OKZEryC8i4bA+twNg+lB5RKrozlNwWx/lLJHqWPUfvUTvxh+uxlPYL9KzVReQjUuxMLFMsHNqWUrA== - dependencies: - "@nrwl/cli" "15.9.7" - "@nrwl/tao" "15.9.7" - "@parcel/watcher" "2.0.4" - "@yarnpkg/lockfile" "^1.1.0" - "@yarnpkg/parsers" "3.0.0-rc.46" - "@zkochan/js-yaml" "0.0.6" - axios "^1.0.0" - chalk "^4.1.0" - cli-cursor "3.1.0" - cli-spinners "2.6.1" - cliui "^7.0.2" - dotenv "~10.0.0" - enquirer "~2.3.6" - fast-glob "3.2.7" - figures "3.2.0" - flat "^5.0.2" - fs-extra "^11.1.0" - glob "7.1.4" - ignore "^5.0.4" - js-yaml "4.1.0" - jsonc-parser "3.2.0" - lines-and-columns "~2.0.3" - minimatch "3.0.5" - npm-run-path "^4.0.1" - open "^8.4.0" - semver "7.5.4" - string-width "^4.2.3" - strong-log-transformer "^2.1.0" - tar-stream "~2.2.0" - tmp "~0.2.1" - tsconfig-paths "^4.1.2" - tslib "^2.3.0" - v8-compile-cache "2.3.0" - yargs "^17.6.2" - yargs-parser "21.1.1" - optionalDependencies: - "@nrwl/nx-darwin-arm64" "15.9.7" - "@nrwl/nx-darwin-x64" "15.9.7" - "@nrwl/nx-linux-arm-gnueabihf" "15.9.7" - "@nrwl/nx-linux-arm64-gnu" "15.9.7" - "@nrwl/nx-linux-arm64-musl" "15.9.7" - "@nrwl/nx-linux-x64-gnu" "15.9.7" - "@nrwl/nx-linux-x64-musl" "15.9.7" - "@nrwl/nx-win32-arm64-msvc" "15.9.7" - "@nrwl/nx-win32-x64-msvc" "15.9.7" - -once@^1.3.0, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== - dependencies: - wrappy "1" - -onetime@^5.1.0, onetime@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - -open@^8.4.0: - version "8.4.2" - resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" - integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== - dependencies: - define-lazy-prop "^2.0.0" - is-docker "^2.1.1" - is-wsl "^2.2.0" - -optionator@^0.9.3: - version "0.9.4" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.4.tgz#7ea1c1a5d91d764fb282139c88fe11e182a3a734" - integrity sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g== - dependencies: - deep-is "^0.1.3" - fast-levenshtein "^2.0.6" - levn "^0.4.1" - prelude-ls "^1.2.1" - type-check "^0.4.0" - word-wrap "^1.2.5" - -ora@^5.4.1: - version "5.4.1" - resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" - integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== - dependencies: - bl "^4.1.0" - chalk "^4.1.0" - cli-cursor "^3.1.0" - cli-spinners "^2.5.0" - is-interactive "^1.0.0" - is-unicode-supported "^0.1.0" - log-symbols "^4.1.0" - strip-ansi "^6.0.0" - wcwidth "^1.0.1" - -os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== - -p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== - dependencies: - p-try "^1.0.0" - -p-limit@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-limit@^3.0.2, p-limit@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg== - dependencies: - p-limit "^1.1.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - -p-map-series@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-map-series/-/p-map-series-2.1.0.tgz#7560d4c452d9da0c07e692fdbfe6e2c81a2a91f2" - integrity sha512-RpYIIK1zXSNEOdwxcfe7FdvGcs7+y5n8rifMhMNWvaxRNMPINJHF5GDeuVxWqnfrcHPSCnp7Oo5yNXHId9Av2Q== - -p-map@4.0.0, p-map@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" - integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== - dependencies: - aggregate-error "^3.0.0" - -p-pipe@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-pipe/-/p-pipe-3.1.0.tgz#48b57c922aa2e1af6a6404cb7c6bf0eb9cc8e60e" - integrity sha512-08pj8ATpzMR0Y80x50yJHn37NF6vjrqHutASaX5LiH5npS9XPvrUmscd9MF5R4fuYRHOxQR1FfMIlF7AzwoPqw== - -p-queue@6.6.2: - version "6.6.2" - resolved "https://registry.yarnpkg.com/p-queue/-/p-queue-6.6.2.tgz#2068a9dcf8e67dd0ec3e7a2bcb76810faa85e426" - integrity sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ== - dependencies: - eventemitter3 "^4.0.4" - p-timeout "^3.2.0" - -p-reduce@2.1.0, p-reduce@^2.0.0, p-reduce@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-2.1.0.tgz#09408da49507c6c274faa31f28df334bc712b64a" - integrity sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw== - -p-timeout@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" - integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== - dependencies: - p-finally "^1.0.0" - -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww== - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -p-waterfall@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/p-waterfall/-/p-waterfall-2.1.1.tgz#63153a774f472ccdc4eb281cdb2967fcf158b2ee" - integrity sha512-RRTnDb2TBG/epPRI2yYXsimO0v3BXC8Yd3ogr1545IaqKK17VGhbWVeGGN+XfCm/08OK8635nH31c8bATkHuSw== - dependencies: - p-reduce "^2.0.0" - -package-json-from-dist@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz#4f1471a010827a86f94cfd9b0727e36d267de505" - integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw== - -pacote@15.1.1: - version "15.1.1" - resolved "https://registry.yarnpkg.com/pacote/-/pacote-15.1.1.tgz#94d8c6e0605e04d427610b3aacb0357073978348" - integrity sha512-eeqEe77QrA6auZxNHIp+1TzHQ0HBKf5V6c8zcaYZ134EJe1lCi+fjXATkNiEEfbG+e50nu02GLvUtmZcGOYabQ== - dependencies: - "@npmcli/git" "^4.0.0" - "@npmcli/installed-package-contents" "^2.0.1" - "@npmcli/promise-spawn" "^6.0.1" - "@npmcli/run-script" "^6.0.0" - cacache "^17.0.0" - fs-minipass "^3.0.0" - minipass "^4.0.0" - npm-package-arg "^10.0.0" - npm-packlist "^7.0.0" - npm-pick-manifest "^8.0.0" - npm-registry-fetch "^14.0.0" - proc-log "^3.0.0" - promise-retry "^2.0.1" - read-package-json "^6.0.0" - read-package-json-fast "^3.0.0" - sigstore "^1.0.0" - ssri "^10.0.0" - tar "^6.1.11" - -pacote@^15.0.0, pacote@^15.0.8: - version "15.2.0" - resolved "https://registry.yarnpkg.com/pacote/-/pacote-15.2.0.tgz#0f0dfcc3e60c7b39121b2ac612bf8596e95344d3" - integrity sha512-rJVZeIwHTUta23sIZgEIM62WYwbmGbThdbnkt81ravBplQv+HjyroqnLRNH2+sLJHcGZmLRmhPwACqhfTcOmnA== - dependencies: - "@npmcli/git" "^4.0.0" - "@npmcli/installed-package-contents" "^2.0.1" - "@npmcli/promise-spawn" "^6.0.1" - "@npmcli/run-script" "^6.0.0" - cacache "^17.0.0" - fs-minipass "^3.0.0" - minipass "^5.0.0" - npm-package-arg "^10.0.0" - npm-packlist "^7.0.0" - npm-pick-manifest "^8.0.0" - npm-registry-fetch "^14.0.0" - proc-log "^3.0.0" - promise-retry "^2.0.1" - read-package-json "^6.0.0" - read-package-json-fast "^3.0.0" - sigstore "^1.3.0" - ssri "^10.0.0" - tar "^6.1.11" - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -parse-conflict-json@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/parse-conflict-json/-/parse-conflict-json-3.0.1.tgz#67dc55312781e62aa2ddb91452c7606d1969960c" - integrity sha512-01TvEktc68vwbJOtWZluyWeVGWjP+bZwXtPDMQVbBKzbJ/vZBif0L69KH1+cHv1SZ6e0FKLvjyHe8mqsIqYOmw== - dependencies: - json-parse-even-better-errors "^3.0.0" - just-diff "^6.0.0" - just-diff-apply "^5.2.0" - -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw== - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - -parse-json@^5.0.0, parse-json@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" - integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== - 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" - -parse-path@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/parse-path/-/parse-path-7.1.0.tgz#41fb513cb122831807a4c7b29c8727947a09d8c6" - integrity sha512-EuCycjZtfPcjWk7KTksnJ5xPMvWGA/6i4zrLYhRG0hGvC3GPU/jGUj3Cy+ZR0v30duV3e23R95T1lE2+lsndSw== - dependencies: - protocols "^2.0.0" - -parse-url@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/parse-url/-/parse-url-8.1.0.tgz#972e0827ed4b57fc85f0ea6b0d839f0d8a57a57d" - integrity sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w== - dependencies: - parse-path "^7.0.0" - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== - -path-key@^3.0.0, path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-parse@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-scurry@^1.11.1, path-scurry@^1.6.1: - version "1.11.1" - resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2" - integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA== - dependencies: - lru-cache "^10.2.0" - minipass "^5.0.0 || ^6.0.2 || ^7.0.0" - -path-type@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" - integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== - dependencies: - pify "^3.0.0" - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -picocolors@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" - integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== - -picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -pify@5.0.0, pify@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-5.0.0.tgz#1f5eca3f5e87ebec28cc6d54a0e4aaf00acc127f" - integrity sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA== - -pify@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== - -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg== - -pify@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" - integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== - -pirates@^4.0.4: - version "4.0.7" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.7.tgz#643b4a18c4257c8a65104b73f3049ce9a0a15e22" - integrity sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA== - -pkg-dir@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== - dependencies: - find-up "^4.0.0" - -postcss-selector-parser@^6.0.10: - version "6.1.2" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz#27ecb41fb0e3b6ba7a1ec84fff347f734c7929de" - integrity sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg== - dependencies: - cssesc "^3.0.0" - util-deprecate "^1.0.2" - -prelude-ls@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" - integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== - -prettier@^3.0.2: - version "3.5.3" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.5.3.tgz#4fc2ce0d657e7a02e602549f053b239cb7dfe1b5" - integrity sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw== - -pretty-format@29.4.3: - version "29.4.3" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.4.3.tgz#25500ada21a53c9e8423205cf0337056b201244c" - integrity sha512-cvpcHTc42lcsvOOAzd3XuNWTcvk1Jmnzqeu+WsOuiPmxUJTnkbAcFNsRKvEpBEUFVUgy/GTZLulZDcDEi+CIlA== - dependencies: - "@jest/schemas" "^29.4.3" - ansi-styles "^5.0.0" - react-is "^18.0.0" - -pretty-format@^29.0.0, pretty-format@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" - integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== - dependencies: - "@jest/schemas" "^29.6.3" - ansi-styles "^5.0.0" - react-is "^18.0.0" - -proc-log@^2.0.0, proc-log@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-2.0.1.tgz#8f3f69a1f608de27878f91f5c688b225391cb685" - integrity sha512-Kcmo2FhfDTXdcbfDH76N7uBYHINxc/8GW7UAVuVP9I+Va3uHSerrnKV6dLooga/gh7GlgzuCCr/eoldnL1muGw== - -proc-log@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-3.0.0.tgz#fb05ef83ccd64fd7b20bbe9c8c1070fc08338dd8" - integrity sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A== - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -promise-all-reject-late@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz#f8ebf13483e5ca91ad809ccc2fcf25f26f8643c2" - integrity sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw== - -promise-call-limit@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/promise-call-limit/-/promise-call-limit-1.0.2.tgz#f64b8dd9ef7693c9c7613e7dfe8d6d24de3031ea" - integrity sha512-1vTUnfI2hzui8AEIixbdAJlFY4LFDXqQswy/2eOlThAscXCY4It8FdVuI0fMJGAB2aWGbdQf/gv0skKYXmdrHA== - -promise-inflight@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" - integrity sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g== - -promise-retry@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" - integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== - dependencies: - err-code "^2.0.2" - retry "^0.12.0" - -prompts@^2.0.1: - version "2.4.2" - resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" - integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== - dependencies: - kleur "^3.0.3" - sisteransi "^1.0.5" - -promzard@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/promzard/-/promzard-0.3.0.tgz#26a5d6ee8c7dee4cb12208305acfb93ba382a9ee" - integrity sha512-JZeYqd7UAcHCwI+sTOeUDYkvEU+1bQ7iE0UT1MgB/tERkAPkesW46MrpIySzODi+owTjZtiF8Ay5j9m60KmMBw== - dependencies: - read "1" - -proto-list@~1.2.1: - version "1.2.4" - resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" - integrity sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA== - -protocols@^2.0.0, protocols@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/protocols/-/protocols-2.0.2.tgz#822e8fcdcb3df5356538b3e91bfd890b067fd0a4" - integrity sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ== - -proxy-from-env@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" - integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== - -punycode@^2.1.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" - integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== - -pure-rand@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.1.0.tgz#d173cf23258231976ccbdb05247c9787957604f2" - integrity sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA== - -q@^1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" - integrity sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw== - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -quick-lru@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" - integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== - -react-is@^18.0.0: - version "18.3.1" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e" - integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== - -react@^18.2.0: - version "18.3.1" - resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891" - integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== - dependencies: - loose-envify "^1.1.0" - -read-cmd-shim@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-3.0.0.tgz#62b8c638225c61e6cc607f8f4b779f3b8238f155" - integrity sha512-KQDVjGqhZk92PPNRj9ZEXEuqg8bUobSKRw+q0YQ3TKI5xkce7bUJobL4Z/OtiEbAAv70yEpYIXp4iQ9L8oPVog== - -read-cmd-shim@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-4.0.0.tgz#640a08b473a49043e394ae0c7a34dd822c73b9bb" - integrity sha512-yILWifhaSEEytfXI76kB9xEEiG1AiozaCJZ83A87ytjRiN+jVibXjedjCRNjoZviinhG+4UkalO3mWTd8u5O0Q== - -read-package-json-fast@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/read-package-json-fast/-/read-package-json-fast-2.0.3.tgz#323ca529630da82cb34b36cc0b996693c98c2b83" - integrity sha512-W/BKtbL+dUjTuRL2vziuYhp76s5HZ9qQhd/dKfWIZveD0O40453QNyZhC0e63lqZrAQ4jiOapVoeJ7JrszenQQ== - dependencies: - json-parse-even-better-errors "^2.3.0" - npm-normalize-package-bin "^1.0.1" - -read-package-json-fast@^3.0.0, read-package-json-fast@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz#394908a9725dc7a5f14e70c8e7556dff1d2b1049" - integrity sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw== - dependencies: - json-parse-even-better-errors "^3.0.0" - npm-normalize-package-bin "^3.0.0" - -read-package-json@5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-5.0.1.tgz#1ed685d95ce258954596b13e2e0e76c7d0ab4c26" - integrity sha512-MALHuNgYWdGW3gKzuNMuYtcSSZbGQm94fAp16xt8VsYTLBjUSc55bLMKe6gzpWue0Tfi6CBgwCSdDAqutGDhMg== - dependencies: - glob "^8.0.1" - json-parse-even-better-errors "^2.3.1" - normalize-package-data "^4.0.0" - npm-normalize-package-bin "^1.0.1" - -read-package-json@^5.0.0: - version "5.0.2" - resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-5.0.2.tgz#b8779ccfd169f523b67208a89cc912e3f663f3fa" - integrity sha512-BSzugrt4kQ/Z0krro8zhTwV1Kd79ue25IhNN/VtHFy1mG/6Tluyi+msc0UpwaoQzxSHa28mntAjIZY6kEgfR9Q== - dependencies: - glob "^8.0.1" - json-parse-even-better-errors "^2.3.1" - normalize-package-data "^4.0.0" - npm-normalize-package-bin "^2.0.0" - -read-package-json@^6.0.0: - version "6.0.4" - resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-6.0.4.tgz#90318824ec456c287437ea79595f4c2854708836" - integrity sha512-AEtWXYfopBj2z5N5PbkAOeNHRPUg5q+Nen7QLxV8M2zJq1ym6/lCz3fYNTCXe19puu2d06jfHhrP7v/S2PtMMw== - dependencies: - glob "^10.2.2" - json-parse-even-better-errors "^3.0.0" - normalize-package-data "^5.0.0" - npm-normalize-package-bin "^3.0.0" - -read-pkg-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" - integrity sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw== - dependencies: - find-up "^2.0.0" - read-pkg "^3.0.0" - -read-pkg-up@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" - integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg== - dependencies: - find-up "^4.1.0" - read-pkg "^5.2.0" - type-fest "^0.8.1" - -read-pkg@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" - integrity sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA== - dependencies: - load-json-file "^4.0.0" - normalize-package-data "^2.3.2" - path-type "^3.0.0" - -read-pkg@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" - integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== - dependencies: - "@types/normalize-package-data" "^2.4.0" - normalize-package-data "^2.5.0" - parse-json "^5.0.0" - type-fest "^0.6.0" - -read@1, read@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" - integrity sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ== - dependencies: - mute-stream "~0.0.4" - -readable-stream@3, readable-stream@^3.0.0, readable-stream@^3.0.2, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: - version "3.6.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readable-stream@~1.0.31: - version "1.0.34" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" - integrity sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -readable-stream@~2.3.6: - version "2.3.8" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" - integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -redent@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" - integrity sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg== - dependencies: - indent-string "^4.0.0" - strip-indent "^3.0.0" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== - -resolve-cwd@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" - integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== - dependencies: - resolve-from "^5.0.0" - -resolve-from@5.0.0, resolve-from@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" - integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -resolve.exports@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.3.tgz#41955e6f1b4013b7586f873749a635dea07ebe3f" - integrity sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A== - -resolve@^1.10.0, resolve@^1.20.0: - version "1.22.10" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.10.tgz#b663e83ffb09bbf2386944736baae803029b8b39" - integrity sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w== - dependencies: - is-core-module "^2.16.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -restore-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" - integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== - dependencies: - onetime "^5.1.0" - signal-exit "^3.0.2" - -retry@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" - integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== - -reusify@^1.0.4: - version "1.1.0" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.1.0.tgz#0fe13b9522e1473f51b558ee796e08f11f9b489f" - integrity sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw== - -rimraf@4.4.1, rimraf@^4.4.1: - version "4.4.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-4.4.1.tgz#bd33364f67021c5b79e93d7f4fa0568c7c21b755" - integrity sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og== - dependencies: - glob "^9.2.0" - -rimraf@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-5.0.0.tgz#5bda14e410d7e4dd522154891395802ce032c2cb" - integrity sha512-Jf9llaP+RvaEVS5nPShYFhtXIrb3LRKP281ib3So0KkeZKo2wIKyq0Re7TOSwanasA423PSr6CCIL4bP6T040g== - dependencies: - glob "^10.0.0" - -rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -run-async@^2.4.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" - integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -rxjs@^7.5.5: - version "7.8.2" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.2.tgz#955bc473ed8af11a002a2be52071bf475638607b" - integrity sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA== - dependencies: - tslib "^2.1.0" - -safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -schema-sdk@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/schema-sdk/-/schema-sdk-0.12.0.tgz#3d57e5b8642636011ab2c16479a3b019849a9cab" - integrity sha512-Za2kaXpanSioGqkK4cRe/epndQkJc6a037EcJ6ZrvhoFs6N9IW9IRT/IVEv7J0bpyR4WGloB2yk4w+/eSUkMdg== - dependencies: - "@babel/generator" "^7.24.4" - "@babel/types" "^7.24.0" - "@interweb-utils/casing" "^0.2.0" - "@interweb/fetch-api-client" "^0.6.1" - deepmerge "^4.3.1" - fast-json-patch "^3.1.1" - schema-typescript "^0.12.1" - -schema-typescript@^0.12.1: - version "0.12.1" - resolved "https://registry.yarnpkg.com/schema-typescript/-/schema-typescript-0.12.1.tgz#38340e18f23d72f5beb5e4b49387d8be3c27bcde" - integrity sha512-dgfQrLjqsXEAC7vZ3fJDBsIPpUDJ2SrzuQFvXslrEjVjOSQyVykBua2tNmM4uFn4uIL7K3Ux64pXbaUnngkhhw== - dependencies: - "@babel/generator" "^7.24.4" - "@babel/types" "^7.24.0" - "@interweb-utils/casing" "^0.2.0" - deepmerge "^4.3.1" - minimatch "^9.0.4" - -"semver@2 || 3 || 4 || 5", semver@^5.6.0: - version "5.7.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" - integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== - -semver@7.3.8: - version "7.3.8" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" - integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== - dependencies: - lru-cache "^6.0.0" - -semver@7.5.4: - version "7.5.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" - integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== - dependencies: - lru-cache "^6.0.0" - -semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: - version "6.3.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" - integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== - -semver@^7.0.0, semver@^7.1.1, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4, semver@^7.6.0, semver@^7.7.2: - version "7.7.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.2.tgz#67d99fdcd35cec21e6f8b87a7fd515a33f982b58" - integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA== - -set-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== - -shallow-clone@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" - integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== - dependencies: - kind-of "^6.0.2" - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -signal-exit@3.0.7, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - -signal-exit@^4.0.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" - integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== - -sigstore@^1.0.0, sigstore@^1.3.0, sigstore@^1.4.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/sigstore/-/sigstore-1.9.0.tgz#1e7ad8933aa99b75c6898ddd0eeebc3eb0d59875" - integrity sha512-0Zjz0oe37d08VeOtBIuB6cRriqXse2e8w+7yIy2XSXjshRKxbc2KkhXjL229jXSxEm7UbcjS76wcJDGQddVI9A== - dependencies: - "@sigstore/bundle" "^1.1.0" - "@sigstore/protobuf-specs" "^0.2.0" - "@sigstore/sign" "^1.0.0" - "@sigstore/tuf" "^1.0.3" - make-fetch-happen "^11.0.1" - -sisteransi@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" - integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== - -slash@3.0.0, slash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -smart-buffer@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" - integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== - -socks-proxy-agent@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz#dc069ecf34436621acb41e3efa66ca1b5fed15b6" - integrity sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww== - dependencies: - agent-base "^6.0.2" - debug "^4.3.3" - socks "^2.6.2" - -socks@^2.6.2: - version "2.8.4" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.8.4.tgz#07109755cdd4da03269bda4725baa061ab56d5cc" - integrity sha512-D3YaD0aRxR3mEcqnidIs7ReYJFVzWdd6fXJYUM8ixcQcJRGTka/b3saV0KflYhyVJXKhb947GndU35SxYNResQ== - dependencies: - ip-address "^9.0.5" - smart-buffer "^4.2.0" - -sort-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" - integrity sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg== - dependencies: - is-plain-obj "^1.0.0" - -source-map-support@0.5.13: - version "0.5.13" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" - integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.6.0, source-map@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -spdx-correct@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.2.0.tgz#4f5ab0668f0059e34f9c00dce331784a12de4e9c" - integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz#5d607d27fc806f66d7b64a766650fa890f04ed66" - integrity sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w== - -spdx-expression-parse@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" - integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.21" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz#6d6e980c9df2b6fc905343a3b2d702a6239536c3" - integrity sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg== - -split2@^3.0.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/split2/-/split2-3.2.2.tgz#bf2cf2a37d838312c249c89206fd7a17dd12365f" - integrity sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg== - dependencies: - readable-stream "^3.0.0" - -split@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" - integrity sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg== - dependencies: - through "2" - -sprintf-js@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.3.tgz#4914b903a2f8b685d17fdf78a70e917e872e444a" - integrity sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA== - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== - -ssri@9.0.1, ssri@^9.0.0: - version "9.0.1" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-9.0.1.tgz#544d4c357a8d7b71a19700074b6883fcb4eae057" - integrity sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q== - dependencies: - minipass "^3.1.1" - -ssri@^10.0.0, ssri@^10.0.1: - version "10.0.6" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-10.0.6.tgz#a8aade2de60ba2bce8688e3fa349bad05c7dc1e5" - integrity sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ== - dependencies: - minipass "^7.0.3" - -stack-utils@^2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" - integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ== - dependencies: - escape-string-regexp "^2.0.0" - -string-length@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" - integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== - dependencies: - char-regex "^1.0.2" - strip-ansi "^6.0.0" - -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - 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" - -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - 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" - -string-width@^5.0.1, string-width@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" - integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== - dependencies: - eastasianwidth "^0.2.0" - emoji-regex "^9.2.2" - strip-ansi "^7.0.1" - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - integrity sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ== - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^6, strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^7.0.1: - version "7.1.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" - integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== - dependencies: - ansi-regex "^6.0.1" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== - -strip-bom@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" - integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== - -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== - -strip-indent@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" - integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ== - dependencies: - min-indent "^1.0.0" - -strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -strong-log-transformer@2.1.0, strong-log-transformer@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz#0f5ed78d325e0421ac6f90f7f10e691d6ae3ae10" - integrity sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA== - dependencies: - duplexer "^0.1.1" - minimist "^1.2.0" - through "^2.3.4" - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -supports-color@^8.0.0: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - -supports-preserve-symlinks-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" - integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== - -symlink-workspace@^1.9.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/symlink-workspace/-/symlink-workspace-1.9.0.tgz#df4c5ce48bd55e54580e813126c643a86e29e759" - integrity sha512-eKSISj/3r5gLU4NCY5Ir16PLPavHYb2s2DMN7wGheaZAMlUGEuq8qUhlmbBMR8J32Yq9PCtcA+yritgHpwUDfw== - dependencies: - chalk "4.1.2" - glob "8.1.0" - minimist "^1.2.8" - mkdirp "3.0.0" - rimraf "5.0.0" - -tar-stream@~2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" - integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== - dependencies: - bl "^4.0.3" - end-of-stream "^1.4.1" - fs-constants "^1.0.0" - inherits "^2.0.3" - readable-stream "^3.1.1" - -tar@6.1.11: - version "6.1.11" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621" - integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA== - dependencies: - chownr "^2.0.0" - fs-minipass "^2.0.0" - minipass "^3.0.0" - minizlib "^2.1.1" - mkdirp "^1.0.3" - yallist "^4.0.0" - -tar@^6.1.11, tar@^6.1.2: - version "6.2.1" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a" - integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A== - dependencies: - chownr "^2.0.0" - fs-minipass "^2.0.0" - minipass "^5.0.0" - minizlib "^2.1.1" - mkdirp "^1.0.3" - yallist "^4.0.0" - -temp-dir@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" - integrity sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ== - -temp-dir@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-2.0.0.tgz#bde92b05bdfeb1516e804c9c00ad45177f31321e" - integrity sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg== - -tempy@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/tempy/-/tempy-1.0.0.tgz#4f192b3ee3328a2684d0e3fc5c491425395aab65" - integrity sha512-eLXG5B1G0mRPHmgH2WydPl5v4jH35qEn3y/rA/aahKhIa91Pn119SsU7n7v/433gtT9ONzC8ISvNHIh2JSTm0w== - dependencies: - del "^6.0.0" - is-stream "^2.0.0" - temp-dir "^2.0.0" - type-fest "^0.16.0" - unique-string "^2.0.0" - -test-exclude@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" - integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== - dependencies: - "@istanbuljs/schema" "^0.1.2" - glob "^7.1.4" - minimatch "^3.0.4" - -text-extensions@^1.0.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26" - integrity sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ== - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== - -through2@^2.0.0, through2@^2.0.1: - version "2.0.5" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" - integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== - dependencies: - readable-stream "~2.3.6" - xtend "~4.0.1" - -through2@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/through2/-/through2-4.0.2.tgz#a7ce3ac2a7a8b0b966c80e7c49f0484c3b239764" - integrity sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw== - dependencies: - readable-stream "3" - -through@2, "through@>=2.2.7 <3", through@^2.3.4, through@^2.3.6: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== - -tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== - dependencies: - os-tmpdir "~1.0.2" - -tmp@~0.2.1: - version "0.2.3" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.3.tgz#eb783cc22bc1e8bebd0671476d46ea4eb32a79ae" - integrity sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w== - -tmpl@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" - integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - -treeverse@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/treeverse/-/treeverse-3.0.0.tgz#dd82de9eb602115c6ebd77a574aae67003cb48c8" - integrity sha512-gcANaAnd2QDZFmHFEOF4k7uc1J/6a6z3DJMd/QwEyxLoKGiptJRwid582r7QIsFlFMIZ3SnxfS52S4hm2DHkuQ== - -trim-newlines@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144" - integrity sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw== - -ts-api-utils@^1.3.0: - version "1.4.3" - resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.4.3.tgz#bfc2215fe6528fecab2b0fba570a2e8a4263b064" - integrity sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw== - -ts-jest@^29.1.1: - version "29.3.4" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.3.4.tgz#9354472aceae1d3867a80e8e02014ea5901aee41" - integrity sha512-Iqbrm8IXOmV+ggWHOTEbjwyCf2xZlUMv5npExksXohL+tk8va4Fjhb+X2+Rt9NBmgO7bJ8WpnMLOwih/DnMlFA== - dependencies: - bs-logger "^0.2.6" - ejs "^3.1.10" - fast-json-stable-stringify "^2.1.0" - jest-util "^29.0.0" - json5 "^2.2.3" - lodash.memoize "^4.1.2" - make-error "^1.3.6" - semver "^7.7.2" - type-fest "^4.41.0" - yargs-parser "^21.1.1" - -ts-node@^10.9.2: - version "10.9.2" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.2.tgz#70f021c9e185bccdca820e26dc413805c101c71f" - 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" - -tsconfig-paths@^4.1.2: - version "4.2.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz#ef78e19039133446d244beac0fd6a1632e2d107c" - integrity sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg== - dependencies: - json5 "^2.2.2" - minimist "^1.2.6" - strip-bom "^3.0.0" - -tslib@^2.1.0, tslib@^2.3.0, tslib@^2.4.0: - version "2.8.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" - integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== - -tuf-js@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/tuf-js/-/tuf-js-1.1.7.tgz#21b7ae92a9373015be77dfe0cb282a80ec3bbe43" - integrity sha512-i3P9Kgw3ytjELUfpuKVDNBJvk4u5bXL6gskv572mcevPbSKCV3zt3djhmlEQ65yERjIbOSncy7U4cQJaB1CBCg== - dependencies: - "@tufjs/models" "1.0.4" - debug "^4.3.4" - make-fetch-happen "^11.1.1" - -type-check@^0.4.0, type-check@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" - integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== - dependencies: - prelude-ls "^1.2.1" - -type-detect@4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" - integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== - -type-fest@^0.16.0: - version "0.16.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.16.0.tgz#3240b891a78b0deae910dbeb86553e552a148860" - integrity sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg== - -type-fest@^0.18.0: - version "0.18.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.18.1.tgz#db4bc151a4a2cf4eebf9add5db75508db6cc841f" - integrity sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw== - -type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" - integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== - -type-fest@^0.21.3: - version "0.21.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" - integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== - -type-fest@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.4.1.tgz#8bdf77743385d8a4f13ba95f610f5ccd68c728f8" - integrity sha512-IwzA/LSfD2vC1/YDYMv/zHP4rDF1usCwllsDpbolT3D4fUepIO7f9K70jjmUewU/LmGUKJcwcVtDCpnKk4BPMw== - -type-fest@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" - integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== - -type-fest@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" - integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== - -type-fest@^4.41.0: - version "4.41.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.41.0.tgz#6ae1c8e5731273c2bf1f58ad39cbae2c91a46c58" - integrity sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA== - -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== - -"typescript@^3 || ^4": - version "4.9.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" - integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== - -typescript@^5.1.6: - version "5.8.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.3.tgz#92f8a3e5e3cf497356f4178c34cd65a7f5e8440e" - integrity sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ== - -uglify-js@^3.1.4: - version "3.19.3" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.19.3.tgz#82315e9bbc6f2b25888858acd1fff8441035b77f" - integrity sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ== - -undici-types@~6.19.2: - version "6.19.8" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" - integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== - -undici-types@~6.21.0: - version "6.21.0" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.21.0.tgz#691d00af3909be93a7faa13be61b3a5b50ef12cb" - integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ== - -unique-filename@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-2.0.1.tgz#e785f8675a9a7589e0ac77e0b5c34d2eaeac6da2" - integrity sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A== - dependencies: - unique-slug "^3.0.0" - -unique-filename@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-3.0.0.tgz#48ba7a5a16849f5080d26c760c86cf5cf05770ea" - integrity sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g== - dependencies: - unique-slug "^4.0.0" - -unique-slug@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-3.0.0.tgz#6d347cf57c8a7a7a6044aabd0e2d74e4d76dc7c9" - integrity sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w== - dependencies: - imurmurhash "^0.1.4" - -unique-slug@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-4.0.0.tgz#6bae6bb16be91351badd24cdce741f892a6532e3" - integrity sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ== - dependencies: - imurmurhash "^0.1.4" - -unique-string@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" - integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg== - dependencies: - crypto-random-string "^2.0.0" - -universal-user-agent@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.1.tgz#15f20f55da3c930c57bddbf1734c6654d5fd35aa" - integrity sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ== - -universalify@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" - integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== - -untildify@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" - integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== - -upath@2.0.1, upath@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/upath/-/upath-2.0.1.tgz#50c73dea68d6f6b990f51d279ce6081665d61a8b" - integrity sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w== - -update-browserslist-db@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz#348377dd245216f9e7060ff50b15a1b740b75420" - integrity sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw== - dependencies: - escalade "^3.2.0" - picocolors "^1.1.1" - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== - -uuid@8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" - integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== - -v8-compile-cache-lib@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" - integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== - -v8-compile-cache@2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== - -v8-to-istanbul@^9.0.1: - version "9.3.0" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz#b9572abfa62bd556c16d75fdebc1a411d5ff3175" - integrity sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA== - dependencies: - "@jridgewell/trace-mapping" "^0.3.12" - "@types/istanbul-lib-coverage" "^2.0.1" - convert-source-map "^2.0.0" - -validate-npm-package-license@3.0.4, validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - -validate-npm-package-name@4.0.0, validate-npm-package-name@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-4.0.0.tgz#fe8f1c50ac20afdb86f177da85b3600f0ac0d747" - integrity sha512-mzR0L8ZDktZjpX4OB46KT+56MAhl4EIazWP/+G/HPGuvfdaqg4YsCdtOm6U9+LOFyYDoh4dpnpxZRB9MQQns5Q== - dependencies: - builtins "^5.0.0" - -validate-npm-package-name@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" - integrity sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw== - dependencies: - builtins "^1.0.3" - -validate-npm-package-name@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz#a316573e9b49f3ccd90dbb6eb52b3f06c6d604e8" - integrity sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ== - -walk-up-path@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/walk-up-path/-/walk-up-path-1.0.0.tgz#d4745e893dd5fd0dbb58dd0a4c6a33d9c9fec53e" - integrity sha512-hwj/qMDUEjCU5h0xr90KGCf0tg0/LgJbmOWgrWKYlcJZM7XvquvUJZ0G/HMGr7F7OQMOUuPHWP9JpriinkAlkg== - -walker@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" - integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== - dependencies: - makeerror "1.0.12" - -wcwidth@^1.0.0, wcwidth@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" - integrity sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg== - dependencies: - defaults "^1.0.3" - -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - -whatwg-fetch@^3.4.1: - version "3.6.20" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz#580ce6d791facec91d37c72890995a0b48d31c70" - integrity sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg== - -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - -which@^2.0.1, which@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -which@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/which/-/which-3.0.1.tgz#89f1cd0c23f629a8105ffe69b8172791c87b4be1" - integrity sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg== - dependencies: - isexe "^2.0.0" - -wide-align@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" - integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== - dependencies: - string-width "^1.0.2 || 2 || 3 || 4" - -word-wrap@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" - integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== - -wordwrap@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== - -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^6.0.1: - version "6.2.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" - integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" - integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== - dependencies: - ansi-styles "^6.1.0" - string-width "^5.0.1" - strip-ansi "^7.0.1" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - -write-file-atomic@4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.1.tgz#9faa33a964c1c85ff6f849b80b42a88c2c537c8f" - integrity sha512-nSKUxgAbyioruk6hU87QzVbY279oYT6uiwgDoujth2ju4mJ+TZau7SQBhtbTmUyuNYTuXnSyRn66FV0+eCgcrQ== - dependencies: - imurmurhash "^0.1.4" - signal-exit "^3.0.7" - -write-file-atomic@^2.4.2: - version "2.4.3" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481" - integrity sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ== - dependencies: - graceful-fs "^4.1.11" - imurmurhash "^0.1.4" - signal-exit "^3.0.2" - -write-file-atomic@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" - integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== - dependencies: - imurmurhash "^0.1.4" - signal-exit "^3.0.7" - -write-file-atomic@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-5.0.1.tgz#68df4717c55c6fa4281a7860b4c2ba0a6d2b11e7" - integrity sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw== - dependencies: - imurmurhash "^0.1.4" - signal-exit "^4.0.1" - -write-json-file@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/write-json-file/-/write-json-file-3.2.0.tgz#65bbdc9ecd8a1458e15952770ccbadfcff5fe62a" - integrity sha512-3xZqT7Byc2uORAatYiP3DHUUAVEkNOswEWNs9H5KXiicRTvzYzYqKjYc4G7p+8pltvAw641lVByKVtMpf+4sYQ== - dependencies: - detect-indent "^5.0.0" - graceful-fs "^4.1.15" - make-dir "^2.1.0" - pify "^4.0.1" - sort-keys "^2.0.0" - write-file-atomic "^2.4.2" - -write-pkg@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/write-pkg/-/write-pkg-4.0.0.tgz#675cc04ef6c11faacbbc7771b24c0abbf2a20039" - integrity sha512-v2UQ+50TNf2rNHJ8NyWttfm/EJUBWMJcx6ZTYZr6Qp52uuegWw/lBkCtCbnYZEmPRNL61m+u67dAmGxo+HTULA== - dependencies: - sort-keys "^2.0.0" - type-fest "^0.4.1" - write-json-file "^3.2.0" - -xtend@~4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - -yallist@^3.0.2: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" - integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yaml@^1.10.0: - version "1.10.2" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" - integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== - -yargs-parser@20.2.4: - version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== - -yargs-parser@21.1.1, yargs-parser@^21.1.1: - version "21.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" - integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== - -yargs-parser@^20.2.2, yargs-parser@^20.2.3: - version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - -yargs@16.2.0, yargs@^16.1.0, yargs@^16.2.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - -yargs@^17.3.1, yargs@^17.6.2: - version "17.7.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" - 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" - -yn@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" - integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== From c262be8f5b6cead75906c15b61b67b165d89eebb Mon Sep 17 00:00:00 2001 From: Anmol1696 Date: Sat, 8 Nov 2025 09:49:32 +0400 Subject: [PATCH 02/11] fix packages and move them to kubernetejs packages --- .github/workflows/ci.yml | 12 ++++-- .github/workflows/test-client.yml | 8 ++-- .github/workflows/test-e2e-client.yml | 12 +++--- .github/workflows/test-e2e-dashboard.yml | 14 +++--- .github/workflows/test-unit-dashboard.yml | 40 +++++++++--------- .github/workflows/tests.yml | 2 +- .../.claude/settings.local.json | 0 .../ops-dashboard}/.env.example | 0 .../ops-dashboard}/.gitignore | 0 .../ops-dashboard}/CLAUDE-agentic-kit.md | 0 .../ops-dashboard}/CLAUDE-bradie.md | 0 .../ops-dashboard}/CLAUDE-ollama.md | 0 .../ops-dashboard}/CLAUDE.md | 0 .../dashboard => apps/ops-dashboard}/LICENSE | 0 .../ops-dashboard}/README.md | 0 .../ops-dashboard}/__mocks__/browser.ts | 0 .../ops-dashboard}/__mocks__/handlers.ts | 0 .../__mocks__/handlers/backups.ts | 0 .../__mocks__/handlers/cluster.ts | 0 .../__mocks__/handlers/common.ts | 0 .../__mocks__/handlers/configmaps.ts | 2 +- .../__mocks__/handlers/cronjobs.ts | 2 +- .../__mocks__/handlers/daemonsets.ts | 2 +- .../__mocks__/handlers/databases.ts | 0 .../__mocks__/handlers/deployments.ts | 2 +- .../__mocks__/handlers/endpoints.ts | 2 +- .../__mocks__/handlers/endpointslices.ts | 2 +- .../ops-dashboard}/__mocks__/handlers/hpas.ts | 2 +- .../__mocks__/handlers/index.ts | 0 .../__mocks__/handlers/ingresses.ts | 2 +- .../ops-dashboard}/__mocks__/handlers/jobs.ts | 2 +- .../__mocks__/handlers/namespaces.ts | 2 +- .../__mocks__/handlers/networkpolicies.ts | 2 +- .../__mocks__/handlers/operators.ts | 0 .../ops-dashboard}/__mocks__/handlers/pdbs.ts | 2 +- .../ops-dashboard}/__mocks__/handlers/pods.ts | 2 +- .../__mocks__/handlers/priorityclasses.ts | 2 +- .../ops-dashboard}/__mocks__/handlers/pvcs.ts | 0 .../ops-dashboard}/__mocks__/handlers/pvs.ts | 0 .../__mocks__/handlers/replicasets.ts | 2 +- .../__mocks__/handlers/resourcequotas.ts | 0 .../__mocks__/handlers/rolebindings.ts | 0 .../__mocks__/handlers/roles.ts | 2 +- .../__mocks__/handlers/runtimeclasses.ts | 2 +- .../__mocks__/handlers/secrets.ts | 2 +- .../__mocks__/handlers/serviceaccounts.ts | 2 +- .../__mocks__/handlers/services.ts | 2 +- .../__mocks__/handlers/statefulsets.ts | 2 +- .../__mocks__/handlers/storageclasses.ts | 0 .../__mocks__/handlers/volumeattachments.ts | 0 .../ops-dashboard}/__mocks__/next/server.ts | 0 .../ops-dashboard}/__mocks__/server.ts | 0 .../__tests__/app/admin/backups/page.test.tsx | 0 .../app/admin/databases/page.test.tsx | 0 .../app/admin/operators/page.test.tsx | 0 .../__tests__/app/admin/page.test.tsx | 0 .../__tests__/app/admin/pods/page.test.tsx | 0 .../app/admin/services/page.test.tsx | 0 .../__tests__/app/api/cluster/status.test.ts | 0 .../[namespace]/[name]/backups.test.ts | 20 ++++----- .../[namespace]/[name]/deploy.test.ts | 12 +++--- .../[namespace]/[name]/status.test.ts | 20 ++++----- .../__tests__/app/api/init.test.ts | 0 .../__tests__/app/api/instance-id.test.ts | 0 .../__tests__/app/api/operators.test.ts | 0 .../api/operators/[operator]/debug.test.ts | 0 .../api/operators/[operator]/install.test.ts | 0 .../api/operators/[operator]/status.test.ts | 0 .../__tests__/app/d/chains/page.test.tsx | 0 .../__tests__/app/d/databases/page.test.tsx | 0 .../__tests__/app/d/functions/page.test.tsx | 0 .../__tests__/app/d/page.test.tsx | 0 .../__tests__/app/d/registry/page.test.tsx | 0 .../__tests__/app/d/relayers/page.test.tsx | 0 .../__tests__/app/d/settings/page.test.tsx | 0 .../__tests__/app/databases/page.test.tsx | 0 .../__tests__/app/functions/page.test.tsx | 0 .../__tests__/app/i/all/page.test.tsx | 0 .../__tests__/app/i/configmaps/page.test.tsx | 0 .../__tests__/app/i/cronjobs/page.test.tsx | 0 .../__tests__/app/i/daemonsets/page.test.tsx | 0 .../__tests__/app/i/deployments/page.test.tsx | 0 .../__tests__/app/i/endpoints/page.test.tsx | 0 .../app/i/endpointslices/page.test.tsx | 0 .../__tests__/app/i/events/page.test.tsx | 0 .../__tests__/app/i/hpas/page.test.tsx | 0 .../__tests__/app/i/ingresses/page.test.tsx | 0 .../__tests__/app/i/jobs/page.test.tsx | 0 .../app/i/networkpolicies/page.test.tsx | 0 .../__tests__/app/i/page.test.tsx | 0 .../__tests__/app/i/pdbs/page.test.tsx | 0 .../__tests__/app/i/pods/page.test.tsx | 0 .../app/i/priorityclasses/page.test.tsx | 0 .../__tests__/app/i/pvcs/page.test.tsx | 0 .../__tests__/app/i/pvs/page.test.tsx | 0 .../__tests__/app/i/replicasets/page.test.tsx | 0 .../app/i/resourcequotas/page.test.tsx | 0 .../app/i/rolebindings/page.test.tsx | 0 .../__tests__/app/i/roles/page.test.tsx | 0 .../app/i/runtimeclasses/page.test.tsx | 0 .../__tests__/app/i/secrets/page.test.tsx | 0 .../app/i/serviceaccounts/page.test.tsx | 0 .../__tests__/app/i/services/page.test.tsx | 0 .../app/i/statefulsets/page.test.tsx | 0 .../app/i/storageclasses/page.test.tsx | 0 .../__tests__/app/i/templates/page.test.tsx | 0 .../app/i/volumeattachments/page.test.tsx | 0 .../__tests__/app/layout.test.tsx | 0 .../__tests__/app/page.test.tsx | 0 .../__tests__/app/providers.test.tsx | 0 .../components/adaptive-layout.test.tsx | 0 .../admin/cluster-overview.test.tsx | 0 .../components/admin/operator-card.test.tsx | 2 +- .../admin/operator-filters.test.tsx | 0 .../components/admin/operator-grid.test.tsx | 2 +- .../components/admin/quick-actions.test.tsx | 0 .../components/admin/recent-activity.test.tsx | 0 .../admin/resource-summary.test.tsx | 0 .../admin/status-indicator.test.tsx | 0 .../__tests__/components/app-layout.test.tsx | 0 .../components/common/spinner.test.tsx | 0 .../components/context-switcher.test.tsx | 0 .../components/create-backup-dialog.test.tsx | 0 .../create-databases-dialog.test.tsx | 0 .../create-deployment-dialog.test.tsx | 0 .../components/dashboard-layout.test.tsx | 0 .../components/headers/admin-header.test.tsx | 0 .../components/headers/infra-header.test.tsx | 0 .../headers/smart-objects-header.test.tsx | 0 .../components/namespace-switcher.test.tsx | 0 .../resources/all-resources.test.tsx | 2 +- .../components/resources/configmaps.test.tsx | 0 .../components/resources/cronjobs.test.tsx | 0 .../components/resources/daemonsets.test.tsx | 0 .../components/resources/deployments.test.tsx | 0 .../components/resources/endpoints.test.tsx | 0 .../resources/endpointslices.test.tsx | 0 .../components/resources/events.test.tsx | 0 .../components/resources/hpas.test.tsx | 0 .../components/resources/ingresses.test.tsx | 0 .../components/resources/jobs.test.tsx | 0 .../resources/networkpolicies.test.tsx | 0 .../components/resources/pdbs.test.tsx | 0 .../components/resources/pods.test.tsx | 0 .../resources/priorityclasses.test.tsx | 0 .../components/resources/pvcs.test.tsx | 0 .../components/resources/pvs.test.tsx | 0 .../components/resources/replicasets.test.tsx | 0 .../resources/resourcequotas.test.tsx | 0 .../resources/rolebindings.test.tsx | 0 .../components/resources/roles.test.tsx | 0 .../resources/runtimeclasses.test.tsx | 0 .../components/resources/secrets.test.tsx | 0 .../resources/serviceaccounts.test.tsx | 0 .../components/resources/services.test.tsx | 0 .../resources/statefulsets.test.tsx | 0 .../resources/storageclasses.test.tsx | 0 .../resources/volumeattachments.test.tsx | 0 .../scale-deployment-dialog.test.tsx | 2 +- .../components/template-dialog.test.tsx | 0 .../__tests__/components/templates.test.tsx | 0 .../components/theme-toggle.test.tsx | 0 .../view-edit-deployment-dialog.test.tsx | 2 +- .../__tests__/components/yaml-editor.test.tsx | 0 .../ops-dashboard}/__tests__/e2e/README.md | 0 .../e2e/UNIT-DASHBOARD-TEST-CI-CD-README.md | 0 .../__tests__/e2e/global-setup.ts | 0 .../__tests__/e2e/global-teardown.ts | 0 .../ops-dashboard}/__tests__/e2e/setup.ts | 0 .../e2e/utils/cluster-verification.ts | 0 .../__tests__/e2e/utils/deployment-helpers.ts | 0 .../__tests__/e2e/utils/page-objects.ts | 0 .../__tests__/e2e/utils/page-verification.ts | 0 .../__tests__/e2e/utils/test-helpers.ts | 0 .../__tests__/e2e/utils/workflow-helpers.ts | 2 +- .../e2e/workflow-deployment-lifecycle.spec.ts | 0 ...workflow-operator-database-focused.spec.ts | 0 .../admin-dashboard-chromium-darwin.png | Bin .../__tests__/hooks/use-breakpoint.test.ts | 0 .../hooks/use-cluster-status.test.tsx | 0 .../hooks/use-copy-to-clipboard.test.ts | 0 .../hooks/use-database-status.test.tsx | 0 .../hooks/use-google-analytics.test.tsx | 0 .../__tests__/hooks/use-image-cache.test.tsx | 0 .../__tests__/hooks/use-is-mounted.test.ts | 0 .../__tests__/hooks/use-media-query.test.ts | 0 .../__tests__/hooks/use-pagination.test.ts | 0 .../__tests__/hooks/use-routes.test.ts | 0 .../__tests__/hooks/use-search-data.test.ts | 0 .../__tests__/hooks/use-show-more.test.ts | 0 .../__tests__/hooks/use-toast.test.ts | 0 .../hooks/use-window-dimensions.test.ts | 0 .../__tests__/hooks/useAppMode.test.tsx | 0 .../__tests__/hooks/useConfigMaps.test.tsx | 0 .../__tests__/hooks/useConfirm.test.tsx | 0 .../__tests__/hooks/useDaemonSets.test.tsx | 0 .../__tests__/hooks/useDatabases.test.tsx | 0 .../__tests__/hooks/useDebounce.test.ts | 0 .../__tests__/hooks/useDeployments.test.tsx | 0 .../__tests__/hooks/useNamespaces.test.tsx | 0 .../__tests__/hooks/useOperators.test.tsx | 0 .../__tests__/hooks/usePods.test.tsx | 0 .../hooks/usePreferredNamespace.test.tsx | 0 .../__tests__/hooks/useReplicaSets.test.tsx | 0 .../__tests__/hooks/useSecrets.test.tsx | 0 .../__tests__/hooks/useServices.test.tsx | 0 .../__tests__/lib/agent/ollama.test.ts | 0 .../__tests__/lib/agents/bradie.test.ts | 0 .../__tests__/lib/agents/index.test.ts | 0 .../__tests__/lib/agents/ollama.test.ts | 0 .../__tests__/lib/agents/types.test.ts | 0 .../__tests__/lib/agents/utils-simple.test.ts | 0 .../__tests__/lib/agents/utils.test.ts | 0 .../__tests__/lib/color.test.ts | 0 .../__tests__/lib/constants.test.ts | 0 .../__tests__/lib/create-fluid-value.test.ts | 0 .../ops-dashboard}/__tests__/lib/dom.test.ts | 0 .../__tests__/lib/format.test.ts | 0 .../__tests__/lib/logger.test.ts | 0 .../__tests__/lib/lookup.test.ts | 0 .../__tests__/lib/markdown.test.ts | 0 .../ops-dashboard}/__tests__/lib/setup.ts | 0 .../__tests__/lib/utils.test.ts | 0 .../__tests__/msw-basic.test.ts | 0 .../ops-dashboard}/__tests__/setup.test.ts | 0 .../ops-dashboard}/__tests__/setup.test.tsx | 0 .../__tests__/utils/test-utils.tsx | 0 .../ops-dashboard}/app/admin/backups/page.tsx | 0 .../app/admin/databases/page.tsx | 0 .../app/admin/operators/page.tsx | 0 .../ops-dashboard}/app/admin/page.tsx | 0 .../ops-dashboard}/app/admin/pods/page.tsx | 0 .../app/admin/services/page.tsx | 0 .../app/admin/templates/page.tsx | 0 .../app/api/cluster/status/route.ts | 0 .../[namespace]/[name]/backups/route.ts | 6 +-- .../[namespace]/[name]/deploy/route.ts | 2 +- .../[namespace]/[name]/status/route.ts | 2 +- .../ops-dashboard}/app/api/init/route.ts | 0 .../app/api/instance-id/route.ts | 0 .../app/api/k8s/[...path]/route.ts | 0 .../api/operators/[operator]/debug/route.ts | 0 .../api/operators/[operator]/install/route.ts | 6 +-- .../api/operators/[operator]/status/route.ts | 0 .../ops-dashboard}/app/api/operators/route.ts | 4 +- .../app/api/templates/[template]/route.ts | 4 +- .../ops-dashboard}/app/d/chains/page.tsx | 0 .../ops-dashboard}/app/d/databases/page.tsx | 0 .../ops-dashboard}/app/d/functions/page.tsx | 0 .../ops-dashboard}/app/d/layout.tsx | 0 .../ops-dashboard}/app/d/page.tsx | 0 .../ops-dashboard}/app/d/registry/page.tsx | 0 .../ops-dashboard}/app/d/relayers/page.tsx | 0 .../ops-dashboard}/app/d/settings/page.tsx | 0 .../ops-dashboard}/app/databases/page.tsx | 0 .../ops-dashboard}/app/functions/page.tsx | 0 .../ops-dashboard}/app/globals.css | 0 .../ops-dashboard}/app/i/all/page.tsx | 0 .../ops-dashboard}/app/i/configmaps/page.tsx | 0 .../ops-dashboard}/app/i/cronjobs/page.tsx | 0 .../ops-dashboard}/app/i/daemonsets/page.tsx | 0 .../ops-dashboard}/app/i/deployments/page.tsx | 0 .../ops-dashboard}/app/i/endpoints/page.tsx | 0 .../app/i/endpointslices/page.tsx | 0 .../ops-dashboard}/app/i/events/page.tsx | 0 .../ops-dashboard}/app/i/hpas/page.tsx | 0 .../ops-dashboard}/app/i/ingresses/page.tsx | 0 .../ops-dashboard}/app/i/jobs/page.tsx | 0 .../app/i/networkpolicies/page.tsx | 0 .../ops-dashboard}/app/i/page.tsx | 0 .../ops-dashboard}/app/i/pdbs/page.tsx | 0 .../ops-dashboard}/app/i/pods/page.tsx | 0 .../app/i/priorityclasses/page.tsx | 0 .../ops-dashboard}/app/i/pvcs/page.tsx | 0 .../ops-dashboard}/app/i/pvs/page.tsx | 0 .../ops-dashboard}/app/i/replicasets/page.tsx | 0 .../app/i/resourcequotas/page.tsx | 0 .../app/i/rolebindings/page.tsx | 0 .../ops-dashboard}/app/i/roles/page.tsx | 0 .../app/i/runtimeclasses/page.tsx | 0 .../ops-dashboard}/app/i/secrets/page.tsx | 0 .../app/i/serviceaccounts/page.tsx | 0 .../ops-dashboard}/app/i/services/page.tsx | 0 .../app/i/statefulsets/page.tsx | 0 .../app/i/storageclasses/page.tsx | 0 .../app/i/volumeattachments/page.tsx | 0 .../ops-dashboard}/app/layout.tsx | 0 .../ops-dashboard}/app/not-found.tsx | 0 .../ops-dashboard}/app/page.tsx | 0 .../ops-dashboard}/app/providers.tsx | 0 .../assets/hyperweb-dash-dark-bg.svg | 0 .../assets/hyperweb-dash-light-bg.svg | 0 .../ops-dashboard}/assets/screenshot.png | Bin .../components/adaptive-layout.tsx | 0 .../components/admin/cluster-overview.tsx | 0 .../components/admin/operator-card.tsx | 2 +- .../components/admin/operator-filters.tsx | 0 .../components/admin/operator-grid.tsx | 0 .../components/admin/quick-actions.tsx | 0 .../components/admin/recent-activity.tsx | 0 .../components/admin/resource-summary.tsx | 0 .../components/admin/status-indicator.tsx | 0 .../components/admin/template-card.tsx | 0 .../components/admin/template-filters.tsx | 0 .../components/agent-manager-agentic.tsx | 0 .../components/agent-manager-global.tsx | 0 .../components/ai-chat-agentic.tsx | 0 .../components/ai-chat-global.tsx | 0 .../ops-dashboard}/components/app-layout.tsx | 0 .../components/common/spinner.tsx | 0 .../components/context-switcher.tsx | 0 .../components/create-backup-dialog.tsx | 0 .../components/create-databases-dialog.tsx | 0 .../components/create-deployment-dialog.tsx | 0 .../components/dashboard-layout.tsx | 0 .../components/headers/admin-header.tsx | 0 .../components/headers/infra-header.tsx | 0 .../headers/smart-objects-header.tsx | 0 .../components/namespace-switcher.tsx | 0 .../components/resources/all-resources.tsx | 2 +- .../components/resources/configmaps.tsx | 2 +- .../components/resources/cronjobs.tsx | 2 +- .../components/resources/daemonsets.tsx | 2 +- .../components/resources/deployments.tsx | 2 +- .../components/resources/endpoints.tsx | 2 +- .../components/resources/endpointslices.tsx | 2 +- .../components/resources/events.tsx | 2 +- .../components/resources/hpas.tsx | 2 +- .../components/resources/ingresses.tsx | 2 +- .../components/resources/jobs.tsx | 2 +- .../components/resources/networkpolicies.tsx | 2 +- .../components/resources/pdbs.tsx | 2 +- .../components/resources/pods.tsx | 2 +- .../components/resources/priorityclasses.tsx | 2 +- .../components/resources/pvcs.tsx | 2 +- .../components/resources/pvs.tsx | 2 +- .../components/resources/replicasets.tsx | 2 +- .../components/resources/resourcequotas.tsx | 2 +- .../components/resources/rolebindings.tsx | 2 +- .../components/resources/roles.tsx | 2 +- .../components/resources/runtimeclasses.tsx | 2 +- .../components/resources/secrets.tsx | 2 +- .../components/resources/serviceaccounts.tsx | 2 +- .../components/resources/services.tsx | 2 +- .../components/resources/statefulsets.tsx | 2 +- .../components/resources/storageclasses.tsx | 2 +- .../resources/volumeattachments.tsx | 2 +- .../components/scale-deployment-dialog.tsx | 2 +- .../components/templates/template-dialog.tsx | 0 .../components/templates/templates.tsx | 2 +- .../components/ui/accordion.tsx | 0 .../components/ui/alert-dialog.tsx | 0 .../ops-dashboard}/components/ui/alert.tsx | 0 .../ops-dashboard}/components/ui/avatar.tsx | 0 .../ops-dashboard}/components/ui/badge.tsx | 0 .../components/ui/breadcrumb.tsx | 0 .../ops-dashboard}/components/ui/button.tsx | 0 .../ops-dashboard}/components/ui/card.tsx | 0 .../ops-dashboard}/components/ui/carousel.tsx | 0 .../ops-dashboard}/components/ui/checkbox.tsx | 0 .../components/ui/confirm-dialog.tsx | 0 .../components/ui/context-menu.tsx | 0 .../ops-dashboard}/components/ui/dialog.tsx | 0 .../ops-dashboard}/components/ui/divider.tsx | 0 .../components/ui/dropdown-menu.tsx | 0 .../ops-dashboard}/components/ui/form.tsx | 0 .../ops-dashboard}/components/ui/input.tsx | 0 .../ops-dashboard}/components/ui/kbd.tsx | 0 .../ops-dashboard}/components/ui/label.tsx | 0 .../ops-dashboard}/components/ui/lightbox.tsx | 0 .../components/ui/overflow-list.tsx | 0 .../components/ui/pagination.tsx | 0 .../ops-dashboard}/components/ui/popover.tsx | 0 .../components/ui/radio-group.tsx | 0 .../components/ui/scroll-area.tsx | 0 .../ops-dashboard}/components/ui/select.tsx | 0 .../ops-dashboard}/components/ui/skeleton.tsx | 0 .../ops-dashboard}/components/ui/switch.tsx | 0 .../components/ui/tab-scroller.tsx | 0 .../ops-dashboard}/components/ui/table.tsx | 0 .../ops-dashboard}/components/ui/tabs.tsx | 0 .../ops-dashboard}/components/ui/textarea.tsx | 0 .../components/ui/theme-toggle.tsx | 0 .../ops-dashboard}/components/ui/toast.tsx | 0 .../ops-dashboard}/components/ui/toaster.tsx | 0 .../ops-dashboard}/components/ui/tooltip.tsx | 0 .../ops-dashboard}/components/ui/treeview.tsx | 0 .../view-edit-deployment-dialog.tsx | 2 +- .../ops-dashboard}/components/yaml-editor.tsx | 0 .../ops-dashboard}/contexts/AppContext.tsx | 0 .../contexts/NamespaceContext.tsx | 0 .../dashboard => apps/ops-dashboard}/env.d.ts | 0 .../ops-dashboard}/eslint.config.js | 0 .../ops-dashboard}/hooks/index.ts | 0 .../ops-dashboard}/hooks/use-breakpoint.ts | 0 .../hooks/use-cluster-status.ts | 2 +- .../hooks/use-copy-to-clipboard.ts | 0 .../hooks/use-database-status.ts | 0 .../ops-dashboard}/hooks/use-debounce.ts | 0 .../hooks/use-google-analytics.ts | 0 .../ops-dashboard}/hooks/use-image-cache.ts | 0 .../ops-dashboard}/hooks/use-is-mounted.ts | 0 .../ops-dashboard}/hooks/use-media-query.ts | 0 .../ops-dashboard}/hooks/use-operators.ts | 2 +- .../ops-dashboard}/hooks/use-pagination.ts | 0 .../ops-dashboard}/hooks/use-routes.ts | 0 .../ops-dashboard}/hooks/use-search-data.ts | 0 .../ops-dashboard}/hooks/use-show-more.ts | 0 .../ops-dashboard}/hooks/use-templates.ts | 0 .../ops-dashboard}/hooks/use-toast.ts | 0 .../hooks/use-window-dimensions.ts | 0 .../ops-dashboard}/hooks/useConfigMaps.ts | 2 +- .../ops-dashboard}/hooks/useConfirm.tsx | 0 .../ops-dashboard}/hooks/useDaemonSets.ts | 0 .../ops-dashboard}/hooks/useDatabases.ts | 0 .../ops-dashboard}/hooks/useDeployments.ts | 2 +- .../ops-dashboard}/hooks/useNamespaces.ts | 2 +- .../ops-dashboard}/hooks/usePods.ts | 2 +- .../ops-dashboard}/hooks/useReplicaSets.ts | 2 +- .../ops-dashboard}/hooks/useSecrets.ts | 2 +- .../ops-dashboard}/hooks/useServices.ts | 2 +- .../ops-dashboard}/jest.config.js | 0 .../ops-dashboard}/jest.polyfills.js | 0 .../ops-dashboard}/jest.setup.js | 0 .../ops-dashboard}/k8s/client.tsx | 4 +- .../ops-dashboard}/k8s/context.tsx | 2 +- .../ops-dashboard}/k8s/index.ts | 4 +- .../ops-dashboard}/lib/agent/ollama.ts | 0 .../ops-dashboard}/lib/agents/bradie.ts | 0 .../ops-dashboard}/lib/agents/index.ts | 0 .../ops-dashboard}/lib/agents/ollama.ts | 0 .../ops-dashboard}/lib/agents/types.ts | 0 .../ops-dashboard}/lib/agents/utils.ts | 0 .../ops-dashboard}/lib/color.ts | 0 .../ops-dashboard}/lib/constants.ts | 0 .../ops-dashboard}/lib/create-fluid-value.ts | 0 .../ops-dashboard}/lib/dom.ts | 0 .../ops-dashboard}/lib/format.ts | 0 .../ops-dashboard}/lib/logger.ts | 0 .../ops-dashboard}/lib/lookup.ts | 0 .../ops-dashboard}/lib/markdown.ts | 0 .../ops-dashboard}/lib/utils.ts | 0 .../ops-dashboard}/next.config.js | 8 ++-- .../ops-dashboard}/package.json | 10 ++--- .../ops-dashboard}/playwright.config.ts | 0 .../ops-dashboard}/postcss.config.js | 0 .../services/kubernetes-client.ts | 2 +- .../ops-dashboard}/tailwind.config.ts | 0 .../ops-dashboard}/tsconfig.json | 8 ++-- package.json | 3 +- .../packages => packages}/client/README.md | 4 +- .../__fixtures__/config/setup.cnpg-minio.yaml | 0 .../__fixtures__/config/setup.config.yaml | 0 .../__fixtures__/config/setup.simple.yaml | 0 .../manifests/apply.configmap.yaml | 0 .../__tests__/e2e/apply.ingress-nginx.test.ts | 4 +- .../client/__tests__/e2e/apply.test.ts | 4 +- .../__tests__/e2e/e2e.delete.client.test.ts | 4 +- .../client/__tests__/e2e/e2e.postgres.test.ts | 2 +- .../__tests__/e2e/e2e.setup.client.test.ts | 4 +- .../__tests__/e2e/e2e.setup.operator.test.ts | 2 +- .../integration/apply.cert-manager.test.ts | 2 +- .../integration/apply.manifests.test.ts | 2 +- .../client/__tests__/setup/e2e-setup.ts | 0 .../__tests__/unit/config-loader.test.ts | 0 .../client/__tests__/unit/manifests.test.ts | 2 +- .../client/__tests__/utils/test-utils.ts | 2 +- .../client/jest.config.js | 0 .../packages => packages}/client/package.json | 10 ++--- .../client/scripts/setup-operators.ts | 4 +- .../packages => packages}/client/src/apply.ts | 2 +- .../client/src/client.ts | 2 +- .../client/src/config-loader.ts | 0 .../client/src/deployers/index.ts | 0 .../client/src/deployers/minio.ts | 2 +- .../client/src/deployers/ollama.ts | 2 +- .../client/src/deployers/postgres.ts | 2 +- .../client/src/deployers/presets/base.ts | 2 +- .../client/src/deployers/presets/metadata.ts | 0 .../client/src/deployers/presets/minio.ts | 2 +- .../client/src/deployers/presets/ollama.ts | 2 +- .../client/src/deployers/presets/postgres.ts | 2 +- .../client/src/deployers/presets/simple.ts | 2 +- .../packages => packages}/client/src/hack.ts | 0 .../packages => packages}/client/src/index.ts | 0 .../packages => packages}/client/src/setup.ts | 4 +- .../packages => packages}/client/src/types.ts | 0 .../cli => packages/client}/tsconfig.esm.json | 0 .../client/tsconfig.json | 0 .../manifests/.gitignore | 0 .../packages => packages}/manifests/README.md | 10 ++--- .../__tests__/unit/generated-vs-yaml.test.ts | 2 +- .../manifests/jest.config.js | 0 .../manifests/operators/cert-manager.yaml | 0 .../operators/cert-manager/v1.17.0.yaml | 0 .../manifests/operators/cloudnative-pg.yaml | 0 .../operators/cloudnative-pg/1.25.2.yaml | 0 .../manifests/operators/ingress-nginx.yaml | 0 .../operators/ingress-nginx/4.11.2.yaml | 0 .../manifests/operators/knative-serving.yaml | 0 .../operators/knative-serving/v1.15.0.yaml | 0 .../operators/kube-prometheus-stack.yaml | 0 .../kube-prometheus-stack/77.5.0.yaml | 0 .../manifests/operators/minio-operator.yaml | 0 .../operators/minio-operator/7.1.1.yaml | 0 .../manifests/package.json | 8 ++-- .../manifests/scripts/codegen-operators.ts | 6 +-- .../manifests/scripts/pull-manifests.ts | 0 .../manifests/src/generated/cert-manager.ts | 2 +- .../manifests/src/generated/cloudnative-pg.ts | 2 +- .../manifests/src/generated/index.ts | 2 +- .../manifests/src/generated/ingress-nginx.ts | 2 +- .../src/generated/knative-serving.ts | 2 +- .../src/generated/kube-prometheus-stack.ts | 2 +- .../manifests/src/generated/minio-operator.ts | 2 +- .../manifests/src/index.ts | 2 +- .../manifests/tsconfig.esm.json | 0 .../manifests/tsconfig.json | 0 .../cli => packages/ops-cli}/README.md | 0 .../__fixtures__/config/deploy.config.yaml | 0 .../__fixtures__/config/setup.config.yaml | 0 .../ops-cli}/__tests__/k8s-utils.test.ts | 0 .../ops-cli}/__tests__/setup.test.ts | 4 +- .../ops-cli}/__tests__/teardown.test.ts | 4 +- .../ops-cli}/interweb.setup.yaml | 0 .../cli => packages/ops-cli}/jest.config.js | 0 .../cli => packages/ops-cli}/package.json | 12 +++--- .../ops-cli}/src/commands/delete.ts | 16 +++---- .../ops-cli}/src/commands/deploy.ts | 6 +-- .../ops-cli}/src/commands/index.ts | 0 .../ops-cli}/src/commands/setup.ts | 8 ++-- .../ops-cli}/src/commands/status.ts | 6 +-- .../ops-cli}/src/commands/teardown.ts | 8 ++-- .../cli => packages/ops-cli}/src/index.ts | 22 +++++----- .../ops-cli}/src/utils/k8s-utils.ts | 0 .../ops-cli}/tsconfig.esm.json | 0 .../cli => packages/ops-cli}/tsconfig.json | 0 .../interwebjs => packages/ops}/README.md | 0 .../ops}/__tests__/test.ts | 0 .../ops}/jest.config.js | 0 .../interwebjs => packages/ops}/package.json | 6 +-- .../ops}/scripts/codegen.ts | 0 .../ops}/scripts/fetch-swagger.ts | 0 .../ops}/scripts/swagger.json | 0 .../interwebjs => packages/ops}/src/client.ts | 0 .../interwebjs => packages/ops}/src/index.ts | 0 .../ops}/tsconfig.esm.json | 0 .../interwebjs => packages/ops}/tsconfig.json | 0 pnpm-workspace.yaml | 2 +- 549 files changed, 277 insertions(+), 270 deletions(-) rename {interweb/packages/dashboard => apps/ops-dashboard}/.claude/settings.local.json (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/.env.example (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/.gitignore (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/CLAUDE-agentic-kit.md (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/CLAUDE-bradie.md (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/CLAUDE-ollama.md (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/CLAUDE.md (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/LICENSE (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/README.md (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/browser.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers/backups.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers/cluster.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers/common.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers/configmaps.ts (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers/cronjobs.ts (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers/daemonsets.ts (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers/databases.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers/deployments.ts (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers/endpoints.ts (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers/endpointslices.ts (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers/hpas.ts (98%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers/index.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers/ingresses.ts (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers/jobs.ts (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers/namespaces.ts (98%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers/networkpolicies.ts (98%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers/operators.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers/pdbs.ts (98%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers/pods.ts (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers/priorityclasses.ts (97%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers/pvcs.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers/pvs.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers/replicasets.ts (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers/resourcequotas.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers/rolebindings.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers/roles.ts (98%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers/runtimeclasses.ts (97%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers/secrets.ts (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers/serviceaccounts.ts (98%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers/services.ts (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers/statefulsets.ts (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers/storageclasses.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/handlers/volumeattachments.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/next/server.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__mocks__/server.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/admin/backups/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/admin/databases/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/admin/operators/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/admin/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/admin/pods/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/admin/services/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/api/cluster/status.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/api/databases/[namespace]/[name]/backups.test.ts (94%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/api/databases/[namespace]/[name]/deploy.test.ts (97%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/api/databases/[namespace]/[name]/status.test.ts (95%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/api/init.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/api/instance-id.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/api/operators.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/api/operators/[operator]/debug.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/api/operators/[operator]/install.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/api/operators/[operator]/status.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/d/chains/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/d/databases/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/d/functions/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/d/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/d/registry/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/d/relayers/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/d/settings/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/databases/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/functions/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/i/all/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/i/configmaps/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/i/cronjobs/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/i/daemonsets/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/i/deployments/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/i/endpoints/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/i/endpointslices/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/i/events/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/i/hpas/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/i/ingresses/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/i/jobs/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/i/networkpolicies/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/i/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/i/pdbs/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/i/pods/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/i/priorityclasses/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/i/pvcs/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/i/pvs/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/i/replicasets/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/i/resourcequotas/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/i/rolebindings/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/i/roles/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/i/runtimeclasses/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/i/secrets/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/i/serviceaccounts/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/i/services/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/i/statefulsets/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/i/storageclasses/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/i/templates/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/i/volumeattachments/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/layout.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/page.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/app/providers.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/adaptive-layout.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/admin/cluster-overview.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/admin/operator-card.test.tsx (98%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/admin/operator-filters.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/admin/operator-grid.test.tsx (98%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/admin/quick-actions.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/admin/recent-activity.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/admin/resource-summary.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/admin/status-indicator.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/app-layout.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/common/spinner.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/context-switcher.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/create-backup-dialog.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/create-databases-dialog.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/create-deployment-dialog.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/dashboard-layout.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/headers/admin-header.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/headers/infra-header.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/headers/smart-objects-header.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/namespace-switcher.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/resources/all-resources.test.tsx (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/resources/configmaps.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/resources/cronjobs.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/resources/daemonsets.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/resources/deployments.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/resources/endpoints.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/resources/endpointslices.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/resources/events.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/resources/hpas.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/resources/ingresses.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/resources/jobs.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/resources/networkpolicies.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/resources/pdbs.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/resources/pods.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/resources/priorityclasses.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/resources/pvcs.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/resources/pvs.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/resources/replicasets.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/resources/resourcequotas.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/resources/rolebindings.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/resources/roles.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/resources/runtimeclasses.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/resources/secrets.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/resources/serviceaccounts.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/resources/services.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/resources/statefulsets.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/resources/storageclasses.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/resources/volumeattachments.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/scale-deployment-dialog.test.tsx (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/template-dialog.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/templates.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/theme-toggle.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/view-edit-deployment-dialog.test.tsx (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/components/yaml-editor.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/e2e/README.md (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/e2e/UNIT-DASHBOARD-TEST-CI-CD-README.md (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/e2e/global-setup.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/e2e/global-teardown.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/e2e/setup.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/e2e/utils/cluster-verification.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/e2e/utils/deployment-helpers.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/e2e/utils/page-objects.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/e2e/utils/page-verification.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/e2e/utils/test-helpers.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/e2e/utils/workflow-helpers.ts (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/e2e/workflow-deployment-lifecycle.spec.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/e2e/workflow-operator-database-focused.spec.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/e2e/workflow-operator-database-focused.spec.ts-snapshots/admin-dashboard-chromium-darwin.png (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/hooks/use-breakpoint.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/hooks/use-cluster-status.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/hooks/use-copy-to-clipboard.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/hooks/use-database-status.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/hooks/use-google-analytics.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/hooks/use-image-cache.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/hooks/use-is-mounted.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/hooks/use-media-query.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/hooks/use-pagination.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/hooks/use-routes.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/hooks/use-search-data.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/hooks/use-show-more.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/hooks/use-toast.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/hooks/use-window-dimensions.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/hooks/useAppMode.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/hooks/useConfigMaps.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/hooks/useConfirm.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/hooks/useDaemonSets.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/hooks/useDatabases.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/hooks/useDebounce.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/hooks/useDeployments.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/hooks/useNamespaces.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/hooks/useOperators.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/hooks/usePods.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/hooks/usePreferredNamespace.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/hooks/useReplicaSets.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/hooks/useSecrets.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/hooks/useServices.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/lib/agent/ollama.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/lib/agents/bradie.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/lib/agents/index.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/lib/agents/ollama.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/lib/agents/types.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/lib/agents/utils-simple.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/lib/agents/utils.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/lib/color.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/lib/constants.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/lib/create-fluid-value.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/lib/dom.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/lib/format.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/lib/logger.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/lib/lookup.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/lib/markdown.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/lib/setup.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/lib/utils.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/msw-basic.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/setup.test.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/setup.test.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/__tests__/utils/test-utils.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/admin/backups/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/admin/databases/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/admin/operators/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/admin/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/admin/pods/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/admin/services/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/admin/templates/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/api/cluster/status/route.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/api/databases/[namespace]/[name]/backups/route.ts (96%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/api/databases/[namespace]/[name]/deploy/route.ts (97%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/api/databases/[namespace]/[name]/status/route.ts (98%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/api/init/route.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/api/instance-id/route.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/api/k8s/[...path]/route.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/api/operators/[operator]/debug/route.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/api/operators/[operator]/install/route.ts (93%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/api/operators/[operator]/status/route.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/api/operators/route.ts (89%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/api/templates/[template]/route.ts (97%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/d/chains/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/d/databases/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/d/functions/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/d/layout.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/d/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/d/registry/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/d/relayers/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/d/settings/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/databases/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/functions/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/globals.css (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/i/all/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/i/configmaps/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/i/cronjobs/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/i/daemonsets/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/i/deployments/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/i/endpoints/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/i/endpointslices/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/i/events/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/i/hpas/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/i/ingresses/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/i/jobs/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/i/networkpolicies/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/i/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/i/pdbs/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/i/pods/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/i/priorityclasses/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/i/pvcs/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/i/pvs/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/i/replicasets/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/i/resourcequotas/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/i/rolebindings/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/i/roles/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/i/runtimeclasses/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/i/secrets/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/i/serviceaccounts/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/i/services/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/i/statefulsets/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/i/storageclasses/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/i/volumeattachments/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/layout.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/not-found.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/page.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/app/providers.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/assets/hyperweb-dash-dark-bg.svg (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/assets/hyperweb-dash-light-bg.svg (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/assets/screenshot.png (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/adaptive-layout.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/admin/cluster-overview.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/admin/operator-card.tsx (98%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/admin/operator-filters.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/admin/operator-grid.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/admin/quick-actions.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/admin/recent-activity.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/admin/resource-summary.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/admin/status-indicator.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/admin/template-card.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/admin/template-filters.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/agent-manager-agentic.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/agent-manager-global.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ai-chat-agentic.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ai-chat-global.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/app-layout.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/common/spinner.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/context-switcher.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/create-backup-dialog.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/create-databases-dialog.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/create-deployment-dialog.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/dashboard-layout.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/headers/admin-header.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/headers/infra-header.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/headers/smart-objects-header.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/namespace-switcher.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/resources/all-resources.tsx (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/resources/configmaps.tsx (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/resources/cronjobs.tsx (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/resources/daemonsets.tsx (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/resources/deployments.tsx (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/resources/endpoints.tsx (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/resources/endpointslices.tsx (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/resources/events.tsx (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/resources/hpas.tsx (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/resources/ingresses.tsx (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/resources/jobs.tsx (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/resources/networkpolicies.tsx (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/resources/pdbs.tsx (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/resources/pods.tsx (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/resources/priorityclasses.tsx (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/resources/pvcs.tsx (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/resources/pvs.tsx (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/resources/replicasets.tsx (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/resources/resourcequotas.tsx (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/resources/rolebindings.tsx (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/resources/roles.tsx (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/resources/runtimeclasses.tsx (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/resources/secrets.tsx (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/resources/serviceaccounts.tsx (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/resources/services.tsx (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/resources/statefulsets.tsx (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/resources/storageclasses.tsx (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/resources/volumeattachments.tsx (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/scale-deployment-dialog.tsx (98%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/templates/template-dialog.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/templates/templates.tsx (94%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/accordion.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/alert-dialog.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/alert.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/avatar.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/badge.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/breadcrumb.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/button.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/card.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/carousel.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/checkbox.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/confirm-dialog.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/context-menu.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/dialog.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/divider.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/dropdown-menu.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/form.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/input.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/kbd.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/label.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/lightbox.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/overflow-list.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/pagination.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/popover.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/radio-group.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/scroll-area.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/select.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/skeleton.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/switch.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/tab-scroller.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/table.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/tabs.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/textarea.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/theme-toggle.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/toast.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/toaster.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/tooltip.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/ui/treeview.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/view-edit-deployment-dialog.tsx (98%) rename {interweb/packages/dashboard => apps/ops-dashboard}/components/yaml-editor.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/contexts/AppContext.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/contexts/NamespaceContext.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/env.d.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/eslint.config.js (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/hooks/index.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/hooks/use-breakpoint.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/hooks/use-cluster-status.ts (89%) rename {interweb/packages/dashboard => apps/ops-dashboard}/hooks/use-copy-to-clipboard.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/hooks/use-database-status.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/hooks/use-debounce.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/hooks/use-google-analytics.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/hooks/use-image-cache.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/hooks/use-is-mounted.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/hooks/use-media-query.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/hooks/use-operators.ts (97%) rename {interweb/packages/dashboard => apps/ops-dashboard}/hooks/use-pagination.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/hooks/use-routes.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/hooks/use-search-data.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/hooks/use-show-more.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/hooks/use-templates.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/hooks/use-toast.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/hooks/use-window-dimensions.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/hooks/useConfigMaps.ts (97%) rename {interweb/packages/dashboard => apps/ops-dashboard}/hooks/useConfirm.tsx (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/hooks/useDaemonSets.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/hooks/useDatabases.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/hooks/useDeployments.ts (98%) rename {interweb/packages/dashboard => apps/ops-dashboard}/hooks/useNamespaces.ts (96%) rename {interweb/packages/dashboard => apps/ops-dashboard}/hooks/usePods.ts (97%) rename {interweb/packages/dashboard => apps/ops-dashboard}/hooks/useReplicaSets.ts (97%) rename {interweb/packages/dashboard => apps/ops-dashboard}/hooks/useSecrets.ts (98%) rename {interweb/packages/dashboard => apps/ops-dashboard}/hooks/useServices.ts (98%) rename {interweb/packages/dashboard => apps/ops-dashboard}/jest.config.js (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/jest.polyfills.js (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/jest.setup.js (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/k8s/client.tsx (71%) rename {interweb/packages/dashboard => apps/ops-dashboard}/k8s/context.tsx (97%) rename {interweb/packages/dashboard => apps/ops-dashboard}/k8s/index.ts (99%) rename {interweb/packages/dashboard => apps/ops-dashboard}/lib/agent/ollama.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/lib/agents/bradie.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/lib/agents/index.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/lib/agents/ollama.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/lib/agents/types.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/lib/agents/utils.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/lib/color.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/lib/constants.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/lib/create-fluid-value.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/lib/dom.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/lib/format.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/lib/logger.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/lib/lookup.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/lib/markdown.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/lib/utils.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/next.config.js (58%) rename {interweb/packages/dashboard => apps/ops-dashboard}/package.json (95%) rename {interweb/packages/dashboard => apps/ops-dashboard}/playwright.config.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/postcss.config.js (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/services/kubernetes-client.ts (98%) rename {interweb/packages/dashboard => apps/ops-dashboard}/tailwind.config.ts (100%) rename {interweb/packages/dashboard => apps/ops-dashboard}/tsconfig.json (76%) rename {interweb/packages => packages}/client/README.md (93%) rename {interweb/packages => packages}/client/__fixtures__/config/setup.cnpg-minio.yaml (100%) rename {interweb/packages => packages}/client/__fixtures__/config/setup.config.yaml (100%) rename {interweb/packages => packages}/client/__fixtures__/config/setup.simple.yaml (100%) rename {interweb/packages => packages}/client/__fixtures__/manifests/apply.configmap.yaml (100%) rename {interweb/packages => packages}/client/__tests__/e2e/apply.ingress-nginx.test.ts (92%) rename {interweb/packages => packages}/client/__tests__/e2e/apply.test.ts (94%) rename {interweb/packages => packages}/client/__tests__/e2e/e2e.delete.client.test.ts (90%) rename {interweb/packages => packages}/client/__tests__/e2e/e2e.postgres.test.ts (98%) rename {interweb/packages => packages}/client/__tests__/e2e/e2e.setup.client.test.ts (93%) rename {interweb/packages => packages}/client/__tests__/e2e/e2e.setup.operator.test.ts (97%) rename {interweb/packages => packages}/client/__tests__/integration/apply.cert-manager.test.ts (98%) rename {interweb/packages => packages}/client/__tests__/integration/apply.manifests.test.ts (97%) rename {interweb/packages => packages}/client/__tests__/setup/e2e-setup.ts (100%) rename {interweb/packages => packages}/client/__tests__/unit/config-loader.test.ts (100%) rename {interweb/packages => packages}/client/__tests__/unit/manifests.test.ts (91%) rename {interweb/packages => packages}/client/__tests__/utils/test-utils.ts (98%) rename {interweb/packages => packages}/client/jest.config.js (100%) rename {interweb/packages => packages}/client/package.json (87%) rename {interweb/packages => packages}/client/scripts/setup-operators.ts (98%) rename {interweb/packages => packages}/client/src/apply.ts (99%) rename {interweb/packages => packages}/client/src/client.ts (99%) rename {interweb/packages => packages}/client/src/config-loader.ts (100%) rename {interweb/packages => packages}/client/src/deployers/index.ts (100%) rename {interweb/packages => packages}/client/src/deployers/minio.ts (99%) rename {interweb/packages => packages}/client/src/deployers/ollama.ts (99%) rename {interweb/packages => packages}/client/src/deployers/postgres.ts (99%) rename {interweb/packages => packages}/client/src/deployers/presets/base.ts (97%) rename {interweb/packages => packages}/client/src/deployers/presets/metadata.ts (100%) rename {interweb/packages => packages}/client/src/deployers/presets/minio.ts (94%) rename {interweb/packages => packages}/client/src/deployers/presets/ollama.ts (91%) rename {interweb/packages => packages}/client/src/deployers/presets/postgres.ts (98%) rename {interweb/packages => packages}/client/src/deployers/presets/simple.ts (99%) rename {interweb/packages => packages}/client/src/hack.ts (100%) rename {interweb/packages => packages}/client/src/index.ts (100%) rename {interweb/packages => packages}/client/src/setup.ts (99%) rename {interweb/packages => packages}/client/src/types.ts (100%) rename {interweb/packages/cli => packages/client}/tsconfig.esm.json (100%) rename {interweb/packages => packages}/client/tsconfig.json (100%) rename {interweb/packages => packages}/manifests/.gitignore (100%) rename {interweb/packages => packages}/manifests/README.md (76%) rename {interweb/packages => packages}/manifests/__tests__/unit/generated-vs-yaml.test.ts (98%) rename {interweb/packages => packages}/manifests/jest.config.js (100%) rename {interweb/packages => packages}/manifests/operators/cert-manager.yaml (100%) rename {interweb/packages => packages}/manifests/operators/cert-manager/v1.17.0.yaml (100%) rename {interweb/packages => packages}/manifests/operators/cloudnative-pg.yaml (100%) rename {interweb/packages => packages}/manifests/operators/cloudnative-pg/1.25.2.yaml (100%) rename {interweb/packages => packages}/manifests/operators/ingress-nginx.yaml (100%) rename {interweb/packages => packages}/manifests/operators/ingress-nginx/4.11.2.yaml (100%) rename {interweb/packages => packages}/manifests/operators/knative-serving.yaml (100%) rename {interweb/packages => packages}/manifests/operators/knative-serving/v1.15.0.yaml (100%) rename {interweb/packages => packages}/manifests/operators/kube-prometheus-stack.yaml (100%) rename {interweb/packages => packages}/manifests/operators/kube-prometheus-stack/77.5.0.yaml (100%) rename {interweb/packages => packages}/manifests/operators/minio-operator.yaml (100%) rename {interweb/packages => packages}/manifests/operators/minio-operator/7.1.1.yaml (100%) rename {interweb/packages => packages}/manifests/package.json (85%) rename {interweb/packages => packages}/manifests/scripts/codegen-operators.ts (99%) rename {interweb/packages => packages}/manifests/scripts/pull-manifests.ts (100%) rename {interweb/packages => packages}/manifests/src/generated/cert-manager.ts (99%) rename {interweb/packages => packages}/manifests/src/generated/cloudnative-pg.ts (99%) rename {interweb/packages => packages}/manifests/src/generated/index.ts (96%) rename {interweb/packages => packages}/manifests/src/generated/ingress-nginx.ts (99%) rename {interweb/packages => packages}/manifests/src/generated/knative-serving.ts (99%) rename {interweb/packages => packages}/manifests/src/generated/kube-prometheus-stack.ts (99%) rename {interweb/packages => packages}/manifests/src/generated/minio-operator.ts (99%) rename {interweb/packages => packages}/manifests/src/index.ts (97%) rename {interweb/packages => packages}/manifests/tsconfig.esm.json (100%) rename {interweb/packages => packages}/manifests/tsconfig.json (100%) rename {interweb/packages/cli => packages/ops-cli}/README.md (100%) rename {interweb/packages/cli => packages/ops-cli}/__fixtures__/config/deploy.config.yaml (100%) rename {interweb/packages/cli => packages/ops-cli}/__fixtures__/config/setup.config.yaml (100%) rename {interweb/packages/cli => packages/ops-cli}/__tests__/k8s-utils.test.ts (100%) rename {interweb/packages/cli => packages/ops-cli}/__tests__/setup.test.ts (99%) rename {interweb/packages/cli => packages/ops-cli}/__tests__/teardown.test.ts (99%) rename {interweb/packages/cli => packages/ops-cli}/interweb.setup.yaml (100%) rename {interweb/packages/cli => packages/ops-cli}/jest.config.js (100%) rename {interweb/packages/cli => packages/ops-cli}/package.json (77%) rename {interweb/packages/cli => packages/ops-cli}/src/commands/delete.ts (93%) rename {interweb/packages/cli => packages/ops-cli}/src/commands/deploy.ts (97%) rename {interweb/packages/cli => packages/ops-cli}/src/commands/index.ts (100%) rename {interweb/packages/cli => packages/ops-cli}/src/commands/setup.ts (98%) rename {interweb/packages/cli => packages/ops-cli}/src/commands/status.ts (97%) rename {interweb/packages/cli => packages/ops-cli}/src/commands/teardown.ts (96%) rename {interweb/packages/cli => packages/ops-cli}/src/index.ts (80%) rename {interweb/packages/cli => packages/ops-cli}/src/utils/k8s-utils.ts (100%) rename {interweb/packages/client => packages/ops-cli}/tsconfig.esm.json (100%) rename {interweb/packages/cli => packages/ops-cli}/tsconfig.json (100%) rename {interweb/packages/interwebjs => packages/ops}/README.md (100%) rename {interweb/packages/interwebjs => packages/ops}/__tests__/test.ts (100%) rename {interweb/packages/interwebjs => packages/ops}/jest.config.js (100%) rename {interweb/packages/interwebjs => packages/ops}/package.json (89%) rename {interweb/packages/interwebjs => packages/ops}/scripts/codegen.ts (100%) rename {interweb/packages/interwebjs => packages/ops}/scripts/fetch-swagger.ts (100%) rename {interweb/packages/interwebjs => packages/ops}/scripts/swagger.json (100%) rename {interweb/packages/interwebjs => packages/ops}/src/client.ts (100%) rename {interweb/packages/interwebjs => packages/ops}/src/index.ts (100%) rename {interweb/packages/interwebjs => packages/ops}/tsconfig.esm.json (100%) rename {interweb/packages/interwebjs => packages/ops}/tsconfig.json (100%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7b77144..0553c1b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,16 +16,22 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Setup pnpm + uses: pnpm/action-setup@v2 + with: + version: 10.12.2 + - name: Use Node.js 20.x uses: actions/setup-node@v4 with: node-version: '20.x' + cache: 'pnpm' - name: Install dependencies - run: yarn install --frozen-lockfile + run: pnpm install --frozen-lockfile - name: Build packages - run: yarn build + run: pnpm build - name: Install kubectl run: | @@ -63,4 +69,4 @@ jobs: - name: Run kubernetesjs tests working-directory: packages/kubernetesjs - run: yarn test + run: pnpm test diff --git a/.github/workflows/test-client.yml b/.github/workflows/test-client.yml index dcf50de..9024122 100644 --- a/.github/workflows/test-client.yml +++ b/.github/workflows/test-client.yml @@ -5,14 +5,14 @@ on: branches: [ main ] paths: - 'packages/client/**' - - 'packages/interwebjs/**' + - 'packages/ops/**' - 'packages/manifests/**' - '.github/workflows/test-client.yml' pull_request: branches: [ main ] paths: - 'packages/client/**' - - 'packages/interwebjs/**' + - 'packages/ops/**' - 'packages/manifests/**' - '.github/workflows/test-client.yml' workflow_dispatch: @@ -62,8 +62,8 @@ jobs: - name: Install dependencies run: pnpm install --frozen-lockfile - - name: Build packages (excluding dashboard - TEMP) - run: pnpm --filter='!@interweb/dashboard' build + - name: Build packages (excluding ops dashboard) + run: pnpm --filter='!@kubernetesjs/ops-dashboard' build - name: Verify cluster connection run: | diff --git a/.github/workflows/test-e2e-client.yml b/.github/workflows/test-e2e-client.yml index 0ca4f9a..8533bb6 100644 --- a/.github/workflows/test-e2e-client.yml +++ b/.github/workflows/test-e2e-client.yml @@ -5,14 +5,14 @@ on: branches: [main] paths: - "packages/client/**" - - "packages/interwebjs/**" + - "packages/ops/**" - "packages/manifests/**" - ".github/workflows/test-e2e-client.yml" pull_request: branches: [main] paths: - "packages/client/**" - - "packages/interwebjs/**" + - "packages/ops/**" - "packages/manifests/**" - ".github/workflows/test-e2e-client.yml" workflow_dispatch: @@ -62,8 +62,8 @@ jobs: - name: Install dependencies run: pnpm install --frozen-lockfile - - name: Build packages (excluding dashboard - TEMP) - run: pnpm --filter='!@interweb/dashboard' build + - name: Build packages (excluding ops dashboard) + run: pnpm --filter='!@kubernetesjs/ops-dashboard' build - name: Verify cluster connection run: | @@ -128,8 +128,8 @@ jobs: - name: Install dependencies run: pnpm install --frozen-lockfile - - name: Build packages (excluding dashboard - TEMP) - run: pnpm --filter='!@interweb/dashboard' build + - name: Build packages (excluding ops dashboard) + run: pnpm --filter='!@kubernetesjs/ops-dashboard' build - name: Verify cluster connection run: | diff --git a/.github/workflows/test-e2e-dashboard.yml b/.github/workflows/test-e2e-dashboard.yml index f9c36fd..0fc031a 100644 --- a/.github/workflows/test-e2e-dashboard.yml +++ b/.github/workflows/test-e2e-dashboard.yml @@ -4,12 +4,12 @@ on: push: branches: [main] paths: - - "packages/dashboard/**" + - "apps/ops-dashboard/**" - ".github/workflows/test-e2e-dashboard.yml" pull_request: branches: [main] paths: - - "packages/dashboard/**" + - "apps/ops-dashboard/**" - ".github/workflows/test-e2e-dashboard.yml" workflow_dispatch: inputs: @@ -54,12 +54,12 @@ jobs: - name: Build dashboard run: | - cd packages/dashboard + cd apps/ops-dashboard pnpm build - name: Install Playwright browsers run: | - cd packages/dashboard + cd apps/ops-dashboard npx playwright install --with-deps - name: Setup Kind cluster @@ -78,7 +78,7 @@ jobs: - name: Run all E2E tests run: | - cd packages/dashboard + cd apps/ops-dashboard pnpm run test:e2e env: K8S_API: http://127.0.0.1:8001 @@ -90,7 +90,7 @@ jobs: uses: actions/upload-artifact@v4 with: name: test-results - path: packages/dashboard/test-results/ + path: apps/ops-dashboard/test-results/ retention-days: 7 - name: Upload screenshots on failure @@ -98,7 +98,7 @@ jobs: uses: actions/upload-artifact@v4 with: name: screenshots - path: packages/dashboard/test-results/screenshots/ + path: apps/ops-dashboard/test-results/screenshots/ retention-days: 7 - name: Cleanup Kind cluster diff --git a/.github/workflows/test-unit-dashboard.yml b/.github/workflows/test-unit-dashboard.yml index 4164c77..18af68d 100644 --- a/.github/workflows/test-unit-dashboard.yml +++ b/.github/workflows/test-unit-dashboard.yml @@ -4,26 +4,26 @@ on: push: branches: [main] paths: - - "packages/**/__tests__/**" - - "packages/**/src/**" - - "packages/**/components/**" - - "packages/**/hooks/**" - - "packages/**/lib/**" - - "packages/**/app/**" - - "packages/**/jest.config.js" - - "packages/**/package.json" + - "apps/ops-dashboard/**/__tests__/**" + - "apps/ops-dashboard/**/src/**" + - "apps/ops-dashboard/**/components/**" + - "apps/ops-dashboard/**/hooks/**" + - "apps/ops-dashboard/**/lib/**" + - "apps/ops-dashboard/**/app/**" + - "apps/ops-dashboard/**/jest.config.js" + - "apps/ops-dashboard/**/package.json" - ".github/workflows/test-unit-dashboard.yml" pull_request: branches: [main] paths: - - "packages/**/__tests__/**" - - "packages/**/src/**" - - "packages/**/components/**" - - "packages/**/hooks/**" - - "packages/**/lib/**" - - "packages/**/app/**" - - "packages/**/jest.config.js" - - "packages/**/package.json" + - "apps/ops-dashboard/**/__tests__/**" + - "apps/ops-dashboard/**/src/**" + - "apps/ops-dashboard/**/components/**" + - "apps/ops-dashboard/**/hooks/**" + - "apps/ops-dashboard/**/lib/**" + - "apps/ops-dashboard/**/app/**" + - "apps/ops-dashboard/**/jest.config.js" + - "apps/ops-dashboard/**/package.json" - ".github/workflows/test-unit-dashboard.yml" workflow_dispatch: inputs: @@ -65,7 +65,7 @@ jobs: - name: Run dashboard unit tests run: | - cd packages/dashboard + cd apps/ops-dashboard pnpm test --coverage --watchAll=false env: CI: true @@ -73,7 +73,7 @@ jobs: - name: Upload coverage reports uses: codecov/codecov-action@v4 with: - file: packages/dashboard/coverage/lcov.info + file: apps/ops-dashboard/coverage/lcov.info flags: dashboard name: dashboard-coverage fail_ci_if_error: false @@ -83,7 +83,7 @@ jobs: uses: actions/upload-artifact@v4 with: name: dashboard-unit-test-results - path: packages/dashboard/coverage/ + path: apps/ops-dashboard/coverage/ retention-days: 7 # Other packages unit tests (only when "all" is selected) @@ -98,7 +98,7 @@ jobs: package: - client - manifests - - interwebjs + - ops - cli steps: diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 15fcef4..9fb119a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -41,7 +41,7 @@ jobs: - name: Build packages run: pnpm build - - name: Run @interweb/manifests tests + - name: Run @kubernetesjs/manifests tests run: | cd packages/manifests pnpm test --verbose diff --git a/interweb/packages/dashboard/.claude/settings.local.json b/apps/ops-dashboard/.claude/settings.local.json similarity index 100% rename from interweb/packages/dashboard/.claude/settings.local.json rename to apps/ops-dashboard/.claude/settings.local.json diff --git a/interweb/packages/dashboard/.env.example b/apps/ops-dashboard/.env.example similarity index 100% rename from interweb/packages/dashboard/.env.example rename to apps/ops-dashboard/.env.example diff --git a/interweb/packages/dashboard/.gitignore b/apps/ops-dashboard/.gitignore similarity index 100% rename from interweb/packages/dashboard/.gitignore rename to apps/ops-dashboard/.gitignore diff --git a/interweb/packages/dashboard/CLAUDE-agentic-kit.md b/apps/ops-dashboard/CLAUDE-agentic-kit.md similarity index 100% rename from interweb/packages/dashboard/CLAUDE-agentic-kit.md rename to apps/ops-dashboard/CLAUDE-agentic-kit.md diff --git a/interweb/packages/dashboard/CLAUDE-bradie.md b/apps/ops-dashboard/CLAUDE-bradie.md similarity index 100% rename from interweb/packages/dashboard/CLAUDE-bradie.md rename to apps/ops-dashboard/CLAUDE-bradie.md diff --git a/interweb/packages/dashboard/CLAUDE-ollama.md b/apps/ops-dashboard/CLAUDE-ollama.md similarity index 100% rename from interweb/packages/dashboard/CLAUDE-ollama.md rename to apps/ops-dashboard/CLAUDE-ollama.md diff --git a/interweb/packages/dashboard/CLAUDE.md b/apps/ops-dashboard/CLAUDE.md similarity index 100% rename from interweb/packages/dashboard/CLAUDE.md rename to apps/ops-dashboard/CLAUDE.md diff --git a/interweb/packages/dashboard/LICENSE b/apps/ops-dashboard/LICENSE similarity index 100% rename from interweb/packages/dashboard/LICENSE rename to apps/ops-dashboard/LICENSE diff --git a/interweb/packages/dashboard/README.md b/apps/ops-dashboard/README.md similarity index 100% rename from interweb/packages/dashboard/README.md rename to apps/ops-dashboard/README.md diff --git a/interweb/packages/dashboard/__mocks__/browser.ts b/apps/ops-dashboard/__mocks__/browser.ts similarity index 100% rename from interweb/packages/dashboard/__mocks__/browser.ts rename to apps/ops-dashboard/__mocks__/browser.ts diff --git a/interweb/packages/dashboard/__mocks__/handlers.ts b/apps/ops-dashboard/__mocks__/handlers.ts similarity index 100% rename from interweb/packages/dashboard/__mocks__/handlers.ts rename to apps/ops-dashboard/__mocks__/handlers.ts diff --git a/interweb/packages/dashboard/__mocks__/handlers/backups.ts b/apps/ops-dashboard/__mocks__/handlers/backups.ts similarity index 100% rename from interweb/packages/dashboard/__mocks__/handlers/backups.ts rename to apps/ops-dashboard/__mocks__/handlers/backups.ts diff --git a/interweb/packages/dashboard/__mocks__/handlers/cluster.ts b/apps/ops-dashboard/__mocks__/handlers/cluster.ts similarity index 100% rename from interweb/packages/dashboard/__mocks__/handlers/cluster.ts rename to apps/ops-dashboard/__mocks__/handlers/cluster.ts diff --git a/interweb/packages/dashboard/__mocks__/handlers/common.ts b/apps/ops-dashboard/__mocks__/handlers/common.ts similarity index 100% rename from interweb/packages/dashboard/__mocks__/handlers/common.ts rename to apps/ops-dashboard/__mocks__/handlers/common.ts diff --git a/interweb/packages/dashboard/__mocks__/handlers/configmaps.ts b/apps/ops-dashboard/__mocks__/handlers/configmaps.ts similarity index 99% rename from interweb/packages/dashboard/__mocks__/handlers/configmaps.ts rename to apps/ops-dashboard/__mocks__/handlers/configmaps.ts index 649e188..4c55f55 100644 --- a/interweb/packages/dashboard/__mocks__/handlers/configmaps.ts +++ b/apps/ops-dashboard/__mocks__/handlers/configmaps.ts @@ -1,6 +1,6 @@ import { http, HttpResponse } from "msw" import { API_BASE } from "./common" -import { V1ConfigMap } from "@interweb/interwebjs" +import { V1ConfigMap } from "@kubernetesjs/ops" export const createConfigMapsListData = (): V1ConfigMap[] => { return [ diff --git a/interweb/packages/dashboard/__mocks__/handlers/cronjobs.ts b/apps/ops-dashboard/__mocks__/handlers/cronjobs.ts similarity index 99% rename from interweb/packages/dashboard/__mocks__/handlers/cronjobs.ts rename to apps/ops-dashboard/__mocks__/handlers/cronjobs.ts index ae5bc9f..67d7939 100644 --- a/interweb/packages/dashboard/__mocks__/handlers/cronjobs.ts +++ b/apps/ops-dashboard/__mocks__/handlers/cronjobs.ts @@ -1,6 +1,6 @@ import { http, HttpResponse } from "msw" import { API_BASE } from "./common" -import { BatchV1CronJob } from "@interweb/interwebjs" +import { BatchV1CronJob } from "@kubernetesjs/ops" export const createCronJobsListData = (): BatchV1CronJob[] => { return [ diff --git a/interweb/packages/dashboard/__mocks__/handlers/daemonsets.ts b/apps/ops-dashboard/__mocks__/handlers/daemonsets.ts similarity index 99% rename from interweb/packages/dashboard/__mocks__/handlers/daemonsets.ts rename to apps/ops-dashboard/__mocks__/handlers/daemonsets.ts index a2ea15b..537249a 100644 --- a/interweb/packages/dashboard/__mocks__/handlers/daemonsets.ts +++ b/apps/ops-dashboard/__mocks__/handlers/daemonsets.ts @@ -1,6 +1,6 @@ import { http, HttpResponse } from "msw" import { API_BASE } from "./common" -import { V1DaemonSet } from "@interweb/interwebjs" +import { V1DaemonSet } from "@kubernetesjs/ops" export const createDaemonSetsListData = (): V1DaemonSet[] => { return [ diff --git a/interweb/packages/dashboard/__mocks__/handlers/databases.ts b/apps/ops-dashboard/__mocks__/handlers/databases.ts similarity index 100% rename from interweb/packages/dashboard/__mocks__/handlers/databases.ts rename to apps/ops-dashboard/__mocks__/handlers/databases.ts diff --git a/interweb/packages/dashboard/__mocks__/handlers/deployments.ts b/apps/ops-dashboard/__mocks__/handlers/deployments.ts similarity index 99% rename from interweb/packages/dashboard/__mocks__/handlers/deployments.ts rename to apps/ops-dashboard/__mocks__/handlers/deployments.ts index 7870b42..0b1e3c7 100644 --- a/interweb/packages/dashboard/__mocks__/handlers/deployments.ts +++ b/apps/ops-dashboard/__mocks__/handlers/deployments.ts @@ -1,6 +1,6 @@ import { http, HttpResponse } from "msw" import { API_BASE } from "./common" -import { AppsV1Deployment } from "@interweb/interwebjs" +import { AppsV1Deployment } from "@kubernetesjs/ops" export const createDeploymentsListData = ():AppsV1Deployment[] => { return [ diff --git a/interweb/packages/dashboard/__mocks__/handlers/endpoints.ts b/apps/ops-dashboard/__mocks__/handlers/endpoints.ts similarity index 99% rename from interweb/packages/dashboard/__mocks__/handlers/endpoints.ts rename to apps/ops-dashboard/__mocks__/handlers/endpoints.ts index 68f3a1d..ca967c3 100644 --- a/interweb/packages/dashboard/__mocks__/handlers/endpoints.ts +++ b/apps/ops-dashboard/__mocks__/handlers/endpoints.ts @@ -1,6 +1,6 @@ import { http, HttpResponse } from "msw" import { API_BASE } from "./common" -import { Endpoints } from "@interweb/interwebjs" +import { Endpoints } from "@kubernetesjs/ops" export const createEndpointsListData = (): Endpoints[] => { return [ diff --git a/interweb/packages/dashboard/__mocks__/handlers/endpointslices.ts b/apps/ops-dashboard/__mocks__/handlers/endpointslices.ts similarity index 99% rename from interweb/packages/dashboard/__mocks__/handlers/endpointslices.ts rename to apps/ops-dashboard/__mocks__/handlers/endpointslices.ts index 6cd588a..8dc81df 100644 --- a/interweb/packages/dashboard/__mocks__/handlers/endpointslices.ts +++ b/apps/ops-dashboard/__mocks__/handlers/endpointslices.ts @@ -1,5 +1,5 @@ import { http, HttpResponse } from 'msw' -import { type DiscoveryK8sIoV1EndpointSlice as EndpointSlice } from '@interweb/interwebjs' +import { type DiscoveryK8sIoV1EndpointSlice as EndpointSlice } from '@kubernetesjs/ops' export function createEndpointSlicesListData(): EndpointSlice[] { return [ diff --git a/interweb/packages/dashboard/__mocks__/handlers/hpas.ts b/apps/ops-dashboard/__mocks__/handlers/hpas.ts similarity index 98% rename from interweb/packages/dashboard/__mocks__/handlers/hpas.ts rename to apps/ops-dashboard/__mocks__/handlers/hpas.ts index b94234f..a4eba8a 100644 --- a/interweb/packages/dashboard/__mocks__/handlers/hpas.ts +++ b/apps/ops-dashboard/__mocks__/handlers/hpas.ts @@ -1,6 +1,6 @@ import { http, HttpResponse } from "msw" import { API_BASE } from "./common" -import { AutoscalingV2HorizontalPodAutoscaler } from "@interweb/interwebjs" +import { AutoscalingV2HorizontalPodAutoscaler } from "@kubernetesjs/ops" export const createHPAsListData = (): AutoscalingV2HorizontalPodAutoscaler[] => { return [ diff --git a/interweb/packages/dashboard/__mocks__/handlers/index.ts b/apps/ops-dashboard/__mocks__/handlers/index.ts similarity index 100% rename from interweb/packages/dashboard/__mocks__/handlers/index.ts rename to apps/ops-dashboard/__mocks__/handlers/index.ts diff --git a/interweb/packages/dashboard/__mocks__/handlers/ingresses.ts b/apps/ops-dashboard/__mocks__/handlers/ingresses.ts similarity index 99% rename from interweb/packages/dashboard/__mocks__/handlers/ingresses.ts rename to apps/ops-dashboard/__mocks__/handlers/ingresses.ts index d8b4d38..6718149 100644 --- a/interweb/packages/dashboard/__mocks__/handlers/ingresses.ts +++ b/apps/ops-dashboard/__mocks__/handlers/ingresses.ts @@ -1,6 +1,6 @@ import { http, HttpResponse } from "msw" import { API_BASE } from "./common" -import { NetworkingK8sIoV1Ingress } from "@interweb/interwebjs" +import { NetworkingK8sIoV1Ingress } from "@kubernetesjs/ops" export const createIngressesListData = (): NetworkingK8sIoV1Ingress[] => { return [ diff --git a/interweb/packages/dashboard/__mocks__/handlers/jobs.ts b/apps/ops-dashboard/__mocks__/handlers/jobs.ts similarity index 99% rename from interweb/packages/dashboard/__mocks__/handlers/jobs.ts rename to apps/ops-dashboard/__mocks__/handlers/jobs.ts index cbacb00..0dad871 100644 --- a/interweb/packages/dashboard/__mocks__/handlers/jobs.ts +++ b/apps/ops-dashboard/__mocks__/handlers/jobs.ts @@ -1,6 +1,6 @@ import { http, HttpResponse } from "msw" import { API_BASE } from "./common" -import { BatchV1Job } from "@interweb/interwebjs" +import { BatchV1Job } from "@kubernetesjs/ops" export const createJobsListData = (): BatchV1Job[] => { return [ diff --git a/interweb/packages/dashboard/__mocks__/handlers/namespaces.ts b/apps/ops-dashboard/__mocks__/handlers/namespaces.ts similarity index 98% rename from interweb/packages/dashboard/__mocks__/handlers/namespaces.ts rename to apps/ops-dashboard/__mocks__/handlers/namespaces.ts index 1516b15..7e79e2b 100644 --- a/interweb/packages/dashboard/__mocks__/handlers/namespaces.ts +++ b/apps/ops-dashboard/__mocks__/handlers/namespaces.ts @@ -1,6 +1,6 @@ import { http, HttpResponse } from "msw" import { API_BASE } from "./common" -import { V1Namespace } from "@interweb/interwebjs" +import { V1Namespace } from "@kubernetesjs/ops" export const createNamespacesListData = (): V1Namespace[] => { return [ diff --git a/interweb/packages/dashboard/__mocks__/handlers/networkpolicies.ts b/apps/ops-dashboard/__mocks__/handlers/networkpolicies.ts similarity index 98% rename from interweb/packages/dashboard/__mocks__/handlers/networkpolicies.ts rename to apps/ops-dashboard/__mocks__/handlers/networkpolicies.ts index e4c6d1f..d69f1ff 100644 --- a/interweb/packages/dashboard/__mocks__/handlers/networkpolicies.ts +++ b/apps/ops-dashboard/__mocks__/handlers/networkpolicies.ts @@ -1,6 +1,6 @@ import { http, HttpResponse } from "msw" import { API_BASE } from "./common" -import { NetworkingK8sIoV1NetworkPolicy } from "@interweb/interwebjs" +import { NetworkingK8sIoV1NetworkPolicy } from "@kubernetesjs/ops" export const createNetworkPoliciesListData = (): NetworkingK8sIoV1NetworkPolicy[] => { return [ diff --git a/interweb/packages/dashboard/__mocks__/handlers/operators.ts b/apps/ops-dashboard/__mocks__/handlers/operators.ts similarity index 100% rename from interweb/packages/dashboard/__mocks__/handlers/operators.ts rename to apps/ops-dashboard/__mocks__/handlers/operators.ts diff --git a/interweb/packages/dashboard/__mocks__/handlers/pdbs.ts b/apps/ops-dashboard/__mocks__/handlers/pdbs.ts similarity index 98% rename from interweb/packages/dashboard/__mocks__/handlers/pdbs.ts rename to apps/ops-dashboard/__mocks__/handlers/pdbs.ts index 2c6425d..877b946 100644 --- a/interweb/packages/dashboard/__mocks__/handlers/pdbs.ts +++ b/apps/ops-dashboard/__mocks__/handlers/pdbs.ts @@ -1,6 +1,6 @@ import { http, HttpResponse } from "msw" import { API_BASE } from "./common" -import { PolicyV1PodDisruptionBudget } from "@interweb/interwebjs" +import { PolicyV1PodDisruptionBudget } from "@kubernetesjs/ops" export const createPDBsListData = (): PolicyV1PodDisruptionBudget[] => { return [ diff --git a/interweb/packages/dashboard/__mocks__/handlers/pods.ts b/apps/ops-dashboard/__mocks__/handlers/pods.ts similarity index 99% rename from interweb/packages/dashboard/__mocks__/handlers/pods.ts rename to apps/ops-dashboard/__mocks__/handlers/pods.ts index 2a01755..fe77c03 100644 --- a/interweb/packages/dashboard/__mocks__/handlers/pods.ts +++ b/apps/ops-dashboard/__mocks__/handlers/pods.ts @@ -1,6 +1,6 @@ import { http, HttpResponse } from "msw" import { API_BASE } from "./common" -import { V1Pod } from "@interweb/interwebjs" +import { V1Pod } from "@kubernetesjs/ops" export const createPodsListData = (): V1Pod[] => { return [ diff --git a/interweb/packages/dashboard/__mocks__/handlers/priorityclasses.ts b/apps/ops-dashboard/__mocks__/handlers/priorityclasses.ts similarity index 97% rename from interweb/packages/dashboard/__mocks__/handlers/priorityclasses.ts rename to apps/ops-dashboard/__mocks__/handlers/priorityclasses.ts index 8b0c68e..732196f 100644 --- a/interweb/packages/dashboard/__mocks__/handlers/priorityclasses.ts +++ b/apps/ops-dashboard/__mocks__/handlers/priorityclasses.ts @@ -1,6 +1,6 @@ import { http, HttpResponse } from "msw" import { API_BASE } from "./common" -import { SchedulingK8sIoV1PriorityClass } from "@interweb/interwebjs" +import { SchedulingK8sIoV1PriorityClass } from "@kubernetesjs/ops" export const createPriorityClassesListData = (): SchedulingK8sIoV1PriorityClass[] => { return [ diff --git a/interweb/packages/dashboard/__mocks__/handlers/pvcs.ts b/apps/ops-dashboard/__mocks__/handlers/pvcs.ts similarity index 100% rename from interweb/packages/dashboard/__mocks__/handlers/pvcs.ts rename to apps/ops-dashboard/__mocks__/handlers/pvcs.ts diff --git a/interweb/packages/dashboard/__mocks__/handlers/pvs.ts b/apps/ops-dashboard/__mocks__/handlers/pvs.ts similarity index 100% rename from interweb/packages/dashboard/__mocks__/handlers/pvs.ts rename to apps/ops-dashboard/__mocks__/handlers/pvs.ts diff --git a/interweb/packages/dashboard/__mocks__/handlers/replicasets.ts b/apps/ops-dashboard/__mocks__/handlers/replicasets.ts similarity index 99% rename from interweb/packages/dashboard/__mocks__/handlers/replicasets.ts rename to apps/ops-dashboard/__mocks__/handlers/replicasets.ts index 4993d14..73264cb 100644 --- a/interweb/packages/dashboard/__mocks__/handlers/replicasets.ts +++ b/apps/ops-dashboard/__mocks__/handlers/replicasets.ts @@ -1,6 +1,6 @@ import { http, HttpResponse } from "msw" import { API_BASE } from "./common" -import { V1ReplicaSet } from "@interweb/interwebjs" +import { V1ReplicaSet } from "@kubernetesjs/ops" export const createReplicaSetsListData = (): V1ReplicaSet[] => { return [ diff --git a/interweb/packages/dashboard/__mocks__/handlers/resourcequotas.ts b/apps/ops-dashboard/__mocks__/handlers/resourcequotas.ts similarity index 100% rename from interweb/packages/dashboard/__mocks__/handlers/resourcequotas.ts rename to apps/ops-dashboard/__mocks__/handlers/resourcequotas.ts diff --git a/interweb/packages/dashboard/__mocks__/handlers/rolebindings.ts b/apps/ops-dashboard/__mocks__/handlers/rolebindings.ts similarity index 100% rename from interweb/packages/dashboard/__mocks__/handlers/rolebindings.ts rename to apps/ops-dashboard/__mocks__/handlers/rolebindings.ts diff --git a/interweb/packages/dashboard/__mocks__/handlers/roles.ts b/apps/ops-dashboard/__mocks__/handlers/roles.ts similarity index 98% rename from interweb/packages/dashboard/__mocks__/handlers/roles.ts rename to apps/ops-dashboard/__mocks__/handlers/roles.ts index 94d8c1d..b1c39db 100644 --- a/interweb/packages/dashboard/__mocks__/handlers/roles.ts +++ b/apps/ops-dashboard/__mocks__/handlers/roles.ts @@ -1,5 +1,5 @@ import { http, HttpResponse } from 'msw' -import type { RbacAuthorizationK8sIoV1Role as Role, RbacAuthorizationK8sIoV1ClusterRole as ClusterRole } from '@interweb/interwebjs' +import type { RbacAuthorizationK8sIoV1Role as Role, RbacAuthorizationK8sIoV1ClusterRole as ClusterRole } from '@kubernetesjs/ops' export function createRolesListData(): Role[] { return [ diff --git a/interweb/packages/dashboard/__mocks__/handlers/runtimeclasses.ts b/apps/ops-dashboard/__mocks__/handlers/runtimeclasses.ts similarity index 97% rename from interweb/packages/dashboard/__mocks__/handlers/runtimeclasses.ts rename to apps/ops-dashboard/__mocks__/handlers/runtimeclasses.ts index fb224c7..f5ac073 100644 --- a/interweb/packages/dashboard/__mocks__/handlers/runtimeclasses.ts +++ b/apps/ops-dashboard/__mocks__/handlers/runtimeclasses.ts @@ -1,6 +1,6 @@ import { http, HttpResponse } from "msw" import { API_BASE } from "./common" -import { NodeK8sIoV1RuntimeClass } from "@interweb/interwebjs" +import { NodeK8sIoV1RuntimeClass } from "@kubernetesjs/ops" export const createRuntimeClassesListData = (): NodeK8sIoV1RuntimeClass[] => { return [ diff --git a/interweb/packages/dashboard/__mocks__/handlers/secrets.ts b/apps/ops-dashboard/__mocks__/handlers/secrets.ts similarity index 99% rename from interweb/packages/dashboard/__mocks__/handlers/secrets.ts rename to apps/ops-dashboard/__mocks__/handlers/secrets.ts index 453fe20..eb619b9 100644 --- a/interweb/packages/dashboard/__mocks__/handlers/secrets.ts +++ b/apps/ops-dashboard/__mocks__/handlers/secrets.ts @@ -1,6 +1,6 @@ import { http, HttpResponse } from "msw" import { API_BASE } from "./common" -import { V1Secret } from "@interweb/interwebjs" +import { V1Secret } from "@kubernetesjs/ops" export const createSecretsListData = (): V1Secret[] => { return [ diff --git a/interweb/packages/dashboard/__mocks__/handlers/serviceaccounts.ts b/apps/ops-dashboard/__mocks__/handlers/serviceaccounts.ts similarity index 98% rename from interweb/packages/dashboard/__mocks__/handlers/serviceaccounts.ts rename to apps/ops-dashboard/__mocks__/handlers/serviceaccounts.ts index 759456a..42f2ed1 100644 --- a/interweb/packages/dashboard/__mocks__/handlers/serviceaccounts.ts +++ b/apps/ops-dashboard/__mocks__/handlers/serviceaccounts.ts @@ -1,5 +1,5 @@ import { http, HttpResponse } from 'msw' -import type { ServiceAccount } from '@interweb/interwebjs' +import type { ServiceAccount } from '@kubernetesjs/ops' export function createServiceAccountsListData(): ServiceAccount[] { return [ diff --git a/interweb/packages/dashboard/__mocks__/handlers/services.ts b/apps/ops-dashboard/__mocks__/handlers/services.ts similarity index 99% rename from interweb/packages/dashboard/__mocks__/handlers/services.ts rename to apps/ops-dashboard/__mocks__/handlers/services.ts index a883e03..79f3cf3 100644 --- a/interweb/packages/dashboard/__mocks__/handlers/services.ts +++ b/apps/ops-dashboard/__mocks__/handlers/services.ts @@ -1,6 +1,6 @@ import { http, HttpResponse } from "msw" import { API_BASE } from "./common" -import { V1Service } from "@interweb/interwebjs" +import { V1Service } from "@kubernetesjs/ops" export const createServicesListData = (): V1Service[] => { return [ diff --git a/interweb/packages/dashboard/__mocks__/handlers/statefulsets.ts b/apps/ops-dashboard/__mocks__/handlers/statefulsets.ts similarity index 99% rename from interweb/packages/dashboard/__mocks__/handlers/statefulsets.ts rename to apps/ops-dashboard/__mocks__/handlers/statefulsets.ts index ad81ad9..c81ad8f 100644 --- a/interweb/packages/dashboard/__mocks__/handlers/statefulsets.ts +++ b/apps/ops-dashboard/__mocks__/handlers/statefulsets.ts @@ -1,6 +1,6 @@ import { http, HttpResponse } from "msw" import { API_BASE } from "./common" -import { V1StatefulSet } from "@interweb/interwebjs" +import { V1StatefulSet } from "@kubernetesjs/ops" export const createStatefulSetsListData = (): V1StatefulSet[] => { return [ diff --git a/interweb/packages/dashboard/__mocks__/handlers/storageclasses.ts b/apps/ops-dashboard/__mocks__/handlers/storageclasses.ts similarity index 100% rename from interweb/packages/dashboard/__mocks__/handlers/storageclasses.ts rename to apps/ops-dashboard/__mocks__/handlers/storageclasses.ts diff --git a/interweb/packages/dashboard/__mocks__/handlers/volumeattachments.ts b/apps/ops-dashboard/__mocks__/handlers/volumeattachments.ts similarity index 100% rename from interweb/packages/dashboard/__mocks__/handlers/volumeattachments.ts rename to apps/ops-dashboard/__mocks__/handlers/volumeattachments.ts diff --git a/interweb/packages/dashboard/__mocks__/next/server.ts b/apps/ops-dashboard/__mocks__/next/server.ts similarity index 100% rename from interweb/packages/dashboard/__mocks__/next/server.ts rename to apps/ops-dashboard/__mocks__/next/server.ts diff --git a/interweb/packages/dashboard/__mocks__/server.ts b/apps/ops-dashboard/__mocks__/server.ts similarity index 100% rename from interweb/packages/dashboard/__mocks__/server.ts rename to apps/ops-dashboard/__mocks__/server.ts diff --git a/interweb/packages/dashboard/__tests__/app/admin/backups/page.test.tsx b/apps/ops-dashboard/__tests__/app/admin/backups/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/admin/backups/page.test.tsx rename to apps/ops-dashboard/__tests__/app/admin/backups/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/admin/databases/page.test.tsx b/apps/ops-dashboard/__tests__/app/admin/databases/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/admin/databases/page.test.tsx rename to apps/ops-dashboard/__tests__/app/admin/databases/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/admin/operators/page.test.tsx b/apps/ops-dashboard/__tests__/app/admin/operators/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/admin/operators/page.test.tsx rename to apps/ops-dashboard/__tests__/app/admin/operators/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/admin/page.test.tsx b/apps/ops-dashboard/__tests__/app/admin/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/admin/page.test.tsx rename to apps/ops-dashboard/__tests__/app/admin/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/admin/pods/page.test.tsx b/apps/ops-dashboard/__tests__/app/admin/pods/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/admin/pods/page.test.tsx rename to apps/ops-dashboard/__tests__/app/admin/pods/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/admin/services/page.test.tsx b/apps/ops-dashboard/__tests__/app/admin/services/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/admin/services/page.test.tsx rename to apps/ops-dashboard/__tests__/app/admin/services/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/api/cluster/status.test.ts b/apps/ops-dashboard/__tests__/app/api/cluster/status.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/app/api/cluster/status.test.ts rename to apps/ops-dashboard/__tests__/app/api/cluster/status.test.ts diff --git a/interweb/packages/dashboard/__tests__/app/api/databases/[namespace]/[name]/backups.test.ts b/apps/ops-dashboard/__tests__/app/api/databases/[namespace]/[name]/backups.test.ts similarity index 94% rename from interweb/packages/dashboard/__tests__/app/api/databases/[namespace]/[name]/backups.test.ts rename to apps/ops-dashboard/__tests__/app/api/databases/[namespace]/[name]/backups.test.ts index b281b30..3dba203 100644 --- a/interweb/packages/dashboard/__tests__/app/api/databases/[namespace]/[name]/backups.test.ts +++ b/apps/ops-dashboard/__tests__/app/api/databases/[namespace]/[name]/backups.test.ts @@ -2,7 +2,7 @@ import { NextRequest } from 'next/server'; import { GET, POST } from '@/app/api/databases/[namespace]/[name]/backups/route'; // Mock the dependencies -jest.mock('@interweb/interwebjs', () => ({ +jest.mock('@kubernetesjs/ops', () => ({ InterwebClient: jest.fn().mockImplementation(() => ({ readPostgresqlCnpgIoV1NamespacedCluster: jest.fn(), listPostgresqlCnpgIoV1NamespacedBackup: jest.fn(), @@ -10,7 +10,7 @@ jest.mock('@interweb/interwebjs', () => ({ })), })); -jest.mock('@interweb/client', () => ({ +jest.mock('@kubernetesjs/client', () => ({ SetupClient: jest.fn().mockImplementation(() => ({})), PostgresDeployer: jest.fn().mockImplementation(() => ({ createBackup: jest.fn(), @@ -55,7 +55,7 @@ describe('/api/databases/[namespace]/[name]/backups', () => { }; // Mock the InterwebClient constructor - const { InterwebClient } = require('@interweb/interwebjs'); + const { InterwebClient } = require('@kubernetesjs/ops'); InterwebClient.mockImplementation(() => mockKube); const request = new NextRequest('http://localhost:3000/api/databases/test-ns/test-cluster/backups'); @@ -83,7 +83,7 @@ describe('/api/databases/[namespace]/[name]/backups', () => { .mockResolvedValueOnce({}) }; - const { InterwebClient } = require('@interweb/interwebjs'); + const { InterwebClient } = require('@kubernetesjs/ops'); InterwebClient.mockImplementation(() => mockKube); const request = new NextRequest('http://localhost:3000/api/databases/test-ns/test-cluster/backups'); @@ -107,7 +107,7 @@ describe('/api/databases/[namespace]/[name]/backups', () => { .mockResolvedValueOnce({}) }; - const { InterwebClient } = require('@interweb/interwebjs'); + const { InterwebClient } = require('@kubernetesjs/ops'); InterwebClient.mockImplementation(() => mockKube); const request = new NextRequest('http://localhost:3000/api/databases/test-ns/test-cluster/backups'); @@ -134,8 +134,8 @@ describe('/api/databases/[namespace]/[name]/backups', () => { createBackup: jest.fn().mockResolvedValue({ name: 'backup-123' }) }; - const { InterwebClient } = require('@interweb/interwebjs'); - const { PostgresDeployer } = require('@interweb/client'); + const { InterwebClient } = require('@kubernetesjs/ops'); + const { PostgresDeployer } = require('@kubernetesjs/client'); InterwebClient.mockImplementation(() => mockKube); PostgresDeployer.mockImplementation(() => mockPg); @@ -170,7 +170,7 @@ describe('/api/databases/[namespace]/[name]/backups', () => { post: jest.fn().mockResolvedValue({ name: 'scheduled-backup-123' }) }; - const { InterwebClient } = require('@interweb/interwebjs'); + const { InterwebClient } = require('@kubernetesjs/ops'); InterwebClient.mockImplementation(() => mockKube); const request = new NextRequest('http://localhost:3000/api/databases/test-ns/test-cluster/backups', { @@ -241,7 +241,7 @@ describe('/api/databases/[namespace]/[name]/backups', () => { get: jest.fn().mockResolvedValue(null) // no snapshot API }; - const { InterwebClient } = require('@interweb/interwebjs'); + const { InterwebClient } = require('@kubernetesjs/ops'); InterwebClient.mockImplementation(() => mockKube); const request = new NextRequest('http://localhost:3000/api/databases/test-ns/test-cluster/backups', { @@ -293,7 +293,7 @@ describe('/api/databases/[namespace]/[name]/backups', () => { readPostgresqlCnpgIoV1NamespacedCluster: jest.fn().mockRejectedValue(new Error('Unexpected error')) }; - const { InterwebClient } = require('@interweb/interwebjs'); + const { InterwebClient } = require('@kubernetesjs/ops'); InterwebClient.mockImplementation(() => mockKube); const request = new NextRequest('http://localhost:3000/api/databases/test-ns/test-cluster/backups', { diff --git a/interweb/packages/dashboard/__tests__/app/api/databases/[namespace]/[name]/deploy.test.ts b/apps/ops-dashboard/__tests__/app/api/databases/[namespace]/[name]/deploy.test.ts similarity index 97% rename from interweb/packages/dashboard/__tests__/app/api/databases/[namespace]/[name]/deploy.test.ts rename to apps/ops-dashboard/__tests__/app/api/databases/[namespace]/[name]/deploy.test.ts index ff53478..17d6285 100644 --- a/interweb/packages/dashboard/__tests__/app/api/databases/[namespace]/[name]/deploy.test.ts +++ b/apps/ops-dashboard/__tests__/app/api/databases/[namespace]/[name]/deploy.test.ts @@ -2,7 +2,7 @@ import { NextRequest } from 'next/server'; import { POST } from '@/app/api/databases/[namespace]/[name]/deploy/route'; // Mock the dependencies -jest.mock('@interweb/client', () => ({ +jest.mock('@kubernetesjs/client', () => ({ Client: jest.fn().mockImplementation(() => ({ deployPostgres: jest.fn(), })), @@ -27,7 +27,7 @@ describe('/api/databases/[namespace]/[name]/deploy', () => { deployPostgres: jest.fn().mockResolvedValue({ success: true, name: 'test-db' }) }; - const { Client } = require('@interweb/client'); + const { Client } = require('@kubernetesjs/client'); Client.mockImplementation(() => mockClient); const request = new NextRequest('http://localhost:3000/api/databases/test-ns/test-db/deploy', { @@ -75,7 +75,7 @@ describe('/api/databases/[namespace]/[name]/deploy', () => { deployPostgres: jest.fn().mockResolvedValue({ success: true }) }; - const { Client } = require('@interweb/client'); + const { Client } = require('@kubernetesjs/client'); Client.mockImplementation(() => mockClient); const request = new NextRequest('http://localhost:3000/api/databases/test-ns/test-db/deploy', { @@ -295,7 +295,7 @@ describe('/api/databases/[namespace]/[name]/deploy', () => { deployPostgres: jest.fn().mockRejectedValue(new Error('Deployment failed')) }; - const { Client } = require('@interweb/client'); + const { Client } = require('@kubernetesjs/client'); Client.mockImplementation(() => mockClient); const request = new NextRequest('http://localhost:3000/api/databases/test-ns/test-db/deploy', { @@ -323,7 +323,7 @@ describe('/api/databases/[namespace]/[name]/deploy', () => { deployPostgres: jest.fn().mockRejectedValue('String error') }; - const { Client } = require('@interweb/client'); + const { Client } = require('@kubernetesjs/client'); Client.mockImplementation(() => mockClient); const request = new NextRequest('http://localhost:3000/api/databases/test-ns/test-db/deploy', { @@ -353,7 +353,7 @@ describe('/api/databases/[namespace]/[name]/deploy', () => { deployPostgres: jest.fn().mockResolvedValue({ success: true }) }; - const { Client } = require('@interweb/client'); + const { Client } = require('@kubernetesjs/client'); Client.mockImplementation((config) => { expect(config.restEndpoint).toBe('http://custom-proxy:8001'); return mockClient; diff --git a/interweb/packages/dashboard/__tests__/app/api/databases/[namespace]/[name]/status.test.ts b/apps/ops-dashboard/__tests__/app/api/databases/[namespace]/[name]/status.test.ts similarity index 95% rename from interweb/packages/dashboard/__tests__/app/api/databases/[namespace]/[name]/status.test.ts rename to apps/ops-dashboard/__tests__/app/api/databases/[namespace]/[name]/status.test.ts index 02f3284..b8ba9f7 100644 --- a/interweb/packages/dashboard/__tests__/app/api/databases/[namespace]/[name]/status.test.ts +++ b/apps/ops-dashboard/__tests__/app/api/databases/[namespace]/[name]/status.test.ts @@ -2,7 +2,7 @@ import { NextRequest } from 'next/server'; import { GET } from '@/app/api/databases/[namespace]/[name]/status/route'; // Mock the dependencies -jest.mock('@interweb/interwebjs', () => ({ +jest.mock('@kubernetesjs/ops', () => ({ InterwebClient: jest.fn().mockImplementation(() => ({ get: jest.fn(), readCoreV1NamespacedPod: jest.fn(), @@ -96,7 +96,7 @@ describe('/api/databases/[namespace]/[name]/status', () => { }) // pooler pods }; - const { InterwebClient } = require('@interweb/interwebjs'); + const { InterwebClient } = require('@kubernetesjs/ops'); InterwebClient.mockImplementation(() => mockKube); const request = new NextRequest('http://localhost:3000/api/databases/test-ns/test-cluster/status'); @@ -140,7 +140,7 @@ describe('/api/databases/[namespace]/[name]/status', () => { get: jest.fn().mockRejectedValue(new Error('status: 404')) }; - const { InterwebClient } = require('@interweb/interwebjs'); + const { InterwebClient } = require('@kubernetesjs/ops'); InterwebClient.mockImplementation(() => mockKube); const request = new NextRequest('http://localhost:3000/api/databases/test-ns/test-cluster/status'); @@ -163,7 +163,7 @@ describe('/api/databases/[namespace]/[name]/status', () => { get: jest.fn().mockRejectedValue(new Error('not found')) }; - const { InterwebClient } = require('@interweb/interwebjs'); + const { InterwebClient } = require('@kubernetesjs/ops'); InterwebClient.mockImplementation(() => mockKube); const request = new NextRequest('http://localhost:3000/api/databases/test-ns/test-cluster/status'); @@ -204,7 +204,7 @@ describe('/api/databases/[namespace]/[name]/status', () => { listCoreV1NamespacedPod: jest.fn().mockResolvedValue({ items: [] }) }; - const { InterwebClient } = require('@interweb/interwebjs'); + const { InterwebClient } = require('@kubernetesjs/ops'); InterwebClient.mockImplementation(() => mockKube); const request = new NextRequest('http://localhost:3000/api/databases/test-ns/test-cluster/status'); @@ -242,7 +242,7 @@ describe('/api/databases/[namespace]/[name]/status', () => { listCoreV1NamespacedPod: jest.fn().mockResolvedValue({ items: [] }) }; - const { InterwebClient } = require('@interweb/interwebjs'); + const { InterwebClient } = require('@kubernetesjs/ops'); InterwebClient.mockImplementation(() => mockKube); const request = new NextRequest('http://localhost:3000/api/databases/test-ns/test-cluster/status'); @@ -280,7 +280,7 @@ describe('/api/databases/[namespace]/[name]/status', () => { listCoreV1NamespacedPod: jest.fn().mockResolvedValue({ items: [] }) }; - const { InterwebClient } = require('@interweb/interwebjs'); + const { InterwebClient } = require('@kubernetesjs/ops'); InterwebClient.mockImplementation(() => mockKube); const request = new NextRequest('http://localhost:3000/api/databases/test-ns/test-cluster/status'); @@ -302,7 +302,7 @@ describe('/api/databases/[namespace]/[name]/status', () => { get: jest.fn().mockRejectedValue(new Error('Unexpected error')) }; - const { InterwebClient } = require('@interweb/interwebjs'); + const { InterwebClient } = require('@kubernetesjs/ops'); InterwebClient.mockImplementation(() => mockKube); const request = new NextRequest('http://localhost:3000/api/databases/test-ns/test-cluster/status'); @@ -323,7 +323,7 @@ describe('/api/databases/[namespace]/[name]/status', () => { get: jest.fn().mockRejectedValue(new Error('Unexpected error')) }; - const { InterwebClient } = require('@interweb/interwebjs'); + const { InterwebClient } = require('@kubernetesjs/ops'); InterwebClient.mockImplementation((config) => { expect(config.restEndpoint).toBe('http://custom-proxy:8001'); return mockKube; @@ -380,7 +380,7 @@ describe('/api/databases/[namespace]/[name]/status', () => { listCoreV1NamespacedPod: jest.fn().mockResolvedValue({ items: [] }) }; - const { InterwebClient } = require('@interweb/interwebjs'); + const { InterwebClient } = require('@kubernetesjs/ops'); InterwebClient.mockImplementation(() => mockKube); const request = new NextRequest('http://localhost:3000/api/databases/test-ns/test-cluster/status'); diff --git a/interweb/packages/dashboard/__tests__/app/api/init.test.ts b/apps/ops-dashboard/__tests__/app/api/init.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/app/api/init.test.ts rename to apps/ops-dashboard/__tests__/app/api/init.test.ts diff --git a/interweb/packages/dashboard/__tests__/app/api/instance-id.test.ts b/apps/ops-dashboard/__tests__/app/api/instance-id.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/app/api/instance-id.test.ts rename to apps/ops-dashboard/__tests__/app/api/instance-id.test.ts diff --git a/interweb/packages/dashboard/__tests__/app/api/operators.test.ts b/apps/ops-dashboard/__tests__/app/api/operators.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/app/api/operators.test.ts rename to apps/ops-dashboard/__tests__/app/api/operators.test.ts diff --git a/interweb/packages/dashboard/__tests__/app/api/operators/[operator]/debug.test.ts b/apps/ops-dashboard/__tests__/app/api/operators/[operator]/debug.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/app/api/operators/[operator]/debug.test.ts rename to apps/ops-dashboard/__tests__/app/api/operators/[operator]/debug.test.ts diff --git a/interweb/packages/dashboard/__tests__/app/api/operators/[operator]/install.test.ts b/apps/ops-dashboard/__tests__/app/api/operators/[operator]/install.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/app/api/operators/[operator]/install.test.ts rename to apps/ops-dashboard/__tests__/app/api/operators/[operator]/install.test.ts diff --git a/interweb/packages/dashboard/__tests__/app/api/operators/[operator]/status.test.ts b/apps/ops-dashboard/__tests__/app/api/operators/[operator]/status.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/app/api/operators/[operator]/status.test.ts rename to apps/ops-dashboard/__tests__/app/api/operators/[operator]/status.test.ts diff --git a/interweb/packages/dashboard/__tests__/app/d/chains/page.test.tsx b/apps/ops-dashboard/__tests__/app/d/chains/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/d/chains/page.test.tsx rename to apps/ops-dashboard/__tests__/app/d/chains/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/d/databases/page.test.tsx b/apps/ops-dashboard/__tests__/app/d/databases/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/d/databases/page.test.tsx rename to apps/ops-dashboard/__tests__/app/d/databases/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/d/functions/page.test.tsx b/apps/ops-dashboard/__tests__/app/d/functions/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/d/functions/page.test.tsx rename to apps/ops-dashboard/__tests__/app/d/functions/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/d/page.test.tsx b/apps/ops-dashboard/__tests__/app/d/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/d/page.test.tsx rename to apps/ops-dashboard/__tests__/app/d/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/d/registry/page.test.tsx b/apps/ops-dashboard/__tests__/app/d/registry/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/d/registry/page.test.tsx rename to apps/ops-dashboard/__tests__/app/d/registry/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/d/relayers/page.test.tsx b/apps/ops-dashboard/__tests__/app/d/relayers/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/d/relayers/page.test.tsx rename to apps/ops-dashboard/__tests__/app/d/relayers/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/d/settings/page.test.tsx b/apps/ops-dashboard/__tests__/app/d/settings/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/d/settings/page.test.tsx rename to apps/ops-dashboard/__tests__/app/d/settings/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/databases/page.test.tsx b/apps/ops-dashboard/__tests__/app/databases/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/databases/page.test.tsx rename to apps/ops-dashboard/__tests__/app/databases/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/functions/page.test.tsx b/apps/ops-dashboard/__tests__/app/functions/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/functions/page.test.tsx rename to apps/ops-dashboard/__tests__/app/functions/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/i/all/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/all/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/i/all/page.test.tsx rename to apps/ops-dashboard/__tests__/app/i/all/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/i/configmaps/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/configmaps/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/i/configmaps/page.test.tsx rename to apps/ops-dashboard/__tests__/app/i/configmaps/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/i/cronjobs/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/cronjobs/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/i/cronjobs/page.test.tsx rename to apps/ops-dashboard/__tests__/app/i/cronjobs/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/i/daemonsets/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/daemonsets/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/i/daemonsets/page.test.tsx rename to apps/ops-dashboard/__tests__/app/i/daemonsets/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/i/deployments/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/deployments/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/i/deployments/page.test.tsx rename to apps/ops-dashboard/__tests__/app/i/deployments/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/i/endpoints/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/endpoints/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/i/endpoints/page.test.tsx rename to apps/ops-dashboard/__tests__/app/i/endpoints/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/i/endpointslices/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/endpointslices/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/i/endpointslices/page.test.tsx rename to apps/ops-dashboard/__tests__/app/i/endpointslices/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/i/events/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/events/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/i/events/page.test.tsx rename to apps/ops-dashboard/__tests__/app/i/events/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/i/hpas/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/hpas/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/i/hpas/page.test.tsx rename to apps/ops-dashboard/__tests__/app/i/hpas/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/i/ingresses/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/ingresses/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/i/ingresses/page.test.tsx rename to apps/ops-dashboard/__tests__/app/i/ingresses/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/i/jobs/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/jobs/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/i/jobs/page.test.tsx rename to apps/ops-dashboard/__tests__/app/i/jobs/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/i/networkpolicies/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/networkpolicies/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/i/networkpolicies/page.test.tsx rename to apps/ops-dashboard/__tests__/app/i/networkpolicies/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/i/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/i/page.test.tsx rename to apps/ops-dashboard/__tests__/app/i/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/i/pdbs/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/pdbs/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/i/pdbs/page.test.tsx rename to apps/ops-dashboard/__tests__/app/i/pdbs/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/i/pods/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/pods/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/i/pods/page.test.tsx rename to apps/ops-dashboard/__tests__/app/i/pods/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/i/priorityclasses/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/priorityclasses/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/i/priorityclasses/page.test.tsx rename to apps/ops-dashboard/__tests__/app/i/priorityclasses/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/i/pvcs/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/pvcs/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/i/pvcs/page.test.tsx rename to apps/ops-dashboard/__tests__/app/i/pvcs/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/i/pvs/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/pvs/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/i/pvs/page.test.tsx rename to apps/ops-dashboard/__tests__/app/i/pvs/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/i/replicasets/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/replicasets/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/i/replicasets/page.test.tsx rename to apps/ops-dashboard/__tests__/app/i/replicasets/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/i/resourcequotas/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/resourcequotas/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/i/resourcequotas/page.test.tsx rename to apps/ops-dashboard/__tests__/app/i/resourcequotas/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/i/rolebindings/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/rolebindings/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/i/rolebindings/page.test.tsx rename to apps/ops-dashboard/__tests__/app/i/rolebindings/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/i/roles/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/roles/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/i/roles/page.test.tsx rename to apps/ops-dashboard/__tests__/app/i/roles/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/i/runtimeclasses/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/runtimeclasses/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/i/runtimeclasses/page.test.tsx rename to apps/ops-dashboard/__tests__/app/i/runtimeclasses/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/i/secrets/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/secrets/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/i/secrets/page.test.tsx rename to apps/ops-dashboard/__tests__/app/i/secrets/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/i/serviceaccounts/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/serviceaccounts/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/i/serviceaccounts/page.test.tsx rename to apps/ops-dashboard/__tests__/app/i/serviceaccounts/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/i/services/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/services/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/i/services/page.test.tsx rename to apps/ops-dashboard/__tests__/app/i/services/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/i/statefulsets/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/statefulsets/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/i/statefulsets/page.test.tsx rename to apps/ops-dashboard/__tests__/app/i/statefulsets/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/i/storageclasses/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/storageclasses/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/i/storageclasses/page.test.tsx rename to apps/ops-dashboard/__tests__/app/i/storageclasses/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/i/templates/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/templates/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/i/templates/page.test.tsx rename to apps/ops-dashboard/__tests__/app/i/templates/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/i/volumeattachments/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/volumeattachments/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/i/volumeattachments/page.test.tsx rename to apps/ops-dashboard/__tests__/app/i/volumeattachments/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/layout.test.tsx b/apps/ops-dashboard/__tests__/app/layout.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/layout.test.tsx rename to apps/ops-dashboard/__tests__/app/layout.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/page.test.tsx b/apps/ops-dashboard/__tests__/app/page.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/page.test.tsx rename to apps/ops-dashboard/__tests__/app/page.test.tsx diff --git a/interweb/packages/dashboard/__tests__/app/providers.test.tsx b/apps/ops-dashboard/__tests__/app/providers.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/app/providers.test.tsx rename to apps/ops-dashboard/__tests__/app/providers.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/adaptive-layout.test.tsx b/apps/ops-dashboard/__tests__/components/adaptive-layout.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/adaptive-layout.test.tsx rename to apps/ops-dashboard/__tests__/components/adaptive-layout.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/admin/cluster-overview.test.tsx b/apps/ops-dashboard/__tests__/components/admin/cluster-overview.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/admin/cluster-overview.test.tsx rename to apps/ops-dashboard/__tests__/components/admin/cluster-overview.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/admin/operator-card.test.tsx b/apps/ops-dashboard/__tests__/components/admin/operator-card.test.tsx similarity index 98% rename from interweb/packages/dashboard/__tests__/components/admin/operator-card.test.tsx rename to apps/ops-dashboard/__tests__/components/admin/operator-card.test.tsx index e5a9a7e..e28e6a3 100644 --- a/interweb/packages/dashboard/__tests__/components/admin/operator-card.test.tsx +++ b/apps/ops-dashboard/__tests__/components/admin/operator-card.test.tsx @@ -2,7 +2,7 @@ import React from 'react' import { render, screen, waitFor } from '../../utils/test-utils' import userEvent from '@testing-library/user-event' import { OperatorCard } from '../../../components/admin/operator-card' -import type { OperatorInfo } from '@interweb/client' +import type { OperatorInfo } from '@kubernetesjs/client' // Mock useOperatorMutation to control install/uninstall behavior const installMock = jest.fn() diff --git a/interweb/packages/dashboard/__tests__/components/admin/operator-filters.test.tsx b/apps/ops-dashboard/__tests__/components/admin/operator-filters.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/admin/operator-filters.test.tsx rename to apps/ops-dashboard/__tests__/components/admin/operator-filters.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/admin/operator-grid.test.tsx b/apps/ops-dashboard/__tests__/components/admin/operator-grid.test.tsx similarity index 98% rename from interweb/packages/dashboard/__tests__/components/admin/operator-grid.test.tsx rename to apps/ops-dashboard/__tests__/components/admin/operator-grid.test.tsx index a1e75d8..22c2de1 100644 --- a/interweb/packages/dashboard/__tests__/components/admin/operator-grid.test.tsx +++ b/apps/ops-dashboard/__tests__/components/admin/operator-grid.test.tsx @@ -1,7 +1,7 @@ import React from 'react' import { render, screen } from '../../utils/test-utils' import { OperatorGrid } from '../../../components/admin/operator-grid' -import type { OperatorInfo } from '@interweb/client' +import type { OperatorInfo } from '@kubernetesjs/client' // Mock useOperators hook const mockUseOperators = jest.fn() diff --git a/interweb/packages/dashboard/__tests__/components/admin/quick-actions.test.tsx b/apps/ops-dashboard/__tests__/components/admin/quick-actions.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/admin/quick-actions.test.tsx rename to apps/ops-dashboard/__tests__/components/admin/quick-actions.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/admin/recent-activity.test.tsx b/apps/ops-dashboard/__tests__/components/admin/recent-activity.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/admin/recent-activity.test.tsx rename to apps/ops-dashboard/__tests__/components/admin/recent-activity.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/admin/resource-summary.test.tsx b/apps/ops-dashboard/__tests__/components/admin/resource-summary.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/admin/resource-summary.test.tsx rename to apps/ops-dashboard/__tests__/components/admin/resource-summary.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/admin/status-indicator.test.tsx b/apps/ops-dashboard/__tests__/components/admin/status-indicator.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/admin/status-indicator.test.tsx rename to apps/ops-dashboard/__tests__/components/admin/status-indicator.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/app-layout.test.tsx b/apps/ops-dashboard/__tests__/components/app-layout.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/app-layout.test.tsx rename to apps/ops-dashboard/__tests__/components/app-layout.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/common/spinner.test.tsx b/apps/ops-dashboard/__tests__/components/common/spinner.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/common/spinner.test.tsx rename to apps/ops-dashboard/__tests__/components/common/spinner.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/context-switcher.test.tsx b/apps/ops-dashboard/__tests__/components/context-switcher.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/context-switcher.test.tsx rename to apps/ops-dashboard/__tests__/components/context-switcher.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/create-backup-dialog.test.tsx b/apps/ops-dashboard/__tests__/components/create-backup-dialog.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/create-backup-dialog.test.tsx rename to apps/ops-dashboard/__tests__/components/create-backup-dialog.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/create-databases-dialog.test.tsx b/apps/ops-dashboard/__tests__/components/create-databases-dialog.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/create-databases-dialog.test.tsx rename to apps/ops-dashboard/__tests__/components/create-databases-dialog.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/create-deployment-dialog.test.tsx b/apps/ops-dashboard/__tests__/components/create-deployment-dialog.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/create-deployment-dialog.test.tsx rename to apps/ops-dashboard/__tests__/components/create-deployment-dialog.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/dashboard-layout.test.tsx b/apps/ops-dashboard/__tests__/components/dashboard-layout.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/dashboard-layout.test.tsx rename to apps/ops-dashboard/__tests__/components/dashboard-layout.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/headers/admin-header.test.tsx b/apps/ops-dashboard/__tests__/components/headers/admin-header.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/headers/admin-header.test.tsx rename to apps/ops-dashboard/__tests__/components/headers/admin-header.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/headers/infra-header.test.tsx b/apps/ops-dashboard/__tests__/components/headers/infra-header.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/headers/infra-header.test.tsx rename to apps/ops-dashboard/__tests__/components/headers/infra-header.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/headers/smart-objects-header.test.tsx b/apps/ops-dashboard/__tests__/components/headers/smart-objects-header.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/headers/smart-objects-header.test.tsx rename to apps/ops-dashboard/__tests__/components/headers/smart-objects-header.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/namespace-switcher.test.tsx b/apps/ops-dashboard/__tests__/components/namespace-switcher.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/namespace-switcher.test.tsx rename to apps/ops-dashboard/__tests__/components/namespace-switcher.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/resources/all-resources.test.tsx b/apps/ops-dashboard/__tests__/components/resources/all-resources.test.tsx similarity index 99% rename from interweb/packages/dashboard/__tests__/components/resources/all-resources.test.tsx rename to apps/ops-dashboard/__tests__/components/resources/all-resources.test.tsx index 3075664..c1361d3 100644 --- a/interweb/packages/dashboard/__tests__/components/resources/all-resources.test.tsx +++ b/apps/ops-dashboard/__tests__/components/resources/all-resources.test.tsx @@ -27,7 +27,7 @@ import { createReplicaSetsListError, createReplicaSetsListData } from '@/__mocks__/handlers/replicasets' -import { AppsV1Deployment, Service, Pod, AppsV1DaemonSet, AppsV1ReplicaSet } from '@interweb/interwebjs' +import { AppsV1Deployment, Service, Pod, AppsV1DaemonSet, AppsV1ReplicaSet } from '@kubernetesjs/ops' // Helper functions to create custom test data const createCustomDeployment = (name: string, replicas: number, readyReplicas: number, image: string): AppsV1Deployment => ({ diff --git a/interweb/packages/dashboard/__tests__/components/resources/configmaps.test.tsx b/apps/ops-dashboard/__tests__/components/resources/configmaps.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/resources/configmaps.test.tsx rename to apps/ops-dashboard/__tests__/components/resources/configmaps.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/resources/cronjobs.test.tsx b/apps/ops-dashboard/__tests__/components/resources/cronjobs.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/resources/cronjobs.test.tsx rename to apps/ops-dashboard/__tests__/components/resources/cronjobs.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/resources/daemonsets.test.tsx b/apps/ops-dashboard/__tests__/components/resources/daemonsets.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/resources/daemonsets.test.tsx rename to apps/ops-dashboard/__tests__/components/resources/daemonsets.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/resources/deployments.test.tsx b/apps/ops-dashboard/__tests__/components/resources/deployments.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/resources/deployments.test.tsx rename to apps/ops-dashboard/__tests__/components/resources/deployments.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/resources/endpoints.test.tsx b/apps/ops-dashboard/__tests__/components/resources/endpoints.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/resources/endpoints.test.tsx rename to apps/ops-dashboard/__tests__/components/resources/endpoints.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/resources/endpointslices.test.tsx b/apps/ops-dashboard/__tests__/components/resources/endpointslices.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/resources/endpointslices.test.tsx rename to apps/ops-dashboard/__tests__/components/resources/endpointslices.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/resources/events.test.tsx b/apps/ops-dashboard/__tests__/components/resources/events.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/resources/events.test.tsx rename to apps/ops-dashboard/__tests__/components/resources/events.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/resources/hpas.test.tsx b/apps/ops-dashboard/__tests__/components/resources/hpas.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/resources/hpas.test.tsx rename to apps/ops-dashboard/__tests__/components/resources/hpas.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/resources/ingresses.test.tsx b/apps/ops-dashboard/__tests__/components/resources/ingresses.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/resources/ingresses.test.tsx rename to apps/ops-dashboard/__tests__/components/resources/ingresses.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/resources/jobs.test.tsx b/apps/ops-dashboard/__tests__/components/resources/jobs.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/resources/jobs.test.tsx rename to apps/ops-dashboard/__tests__/components/resources/jobs.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/resources/networkpolicies.test.tsx b/apps/ops-dashboard/__tests__/components/resources/networkpolicies.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/resources/networkpolicies.test.tsx rename to apps/ops-dashboard/__tests__/components/resources/networkpolicies.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/resources/pdbs.test.tsx b/apps/ops-dashboard/__tests__/components/resources/pdbs.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/resources/pdbs.test.tsx rename to apps/ops-dashboard/__tests__/components/resources/pdbs.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/resources/pods.test.tsx b/apps/ops-dashboard/__tests__/components/resources/pods.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/resources/pods.test.tsx rename to apps/ops-dashboard/__tests__/components/resources/pods.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/resources/priorityclasses.test.tsx b/apps/ops-dashboard/__tests__/components/resources/priorityclasses.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/resources/priorityclasses.test.tsx rename to apps/ops-dashboard/__tests__/components/resources/priorityclasses.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/resources/pvcs.test.tsx b/apps/ops-dashboard/__tests__/components/resources/pvcs.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/resources/pvcs.test.tsx rename to apps/ops-dashboard/__tests__/components/resources/pvcs.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/resources/pvs.test.tsx b/apps/ops-dashboard/__tests__/components/resources/pvs.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/resources/pvs.test.tsx rename to apps/ops-dashboard/__tests__/components/resources/pvs.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/resources/replicasets.test.tsx b/apps/ops-dashboard/__tests__/components/resources/replicasets.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/resources/replicasets.test.tsx rename to apps/ops-dashboard/__tests__/components/resources/replicasets.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/resources/resourcequotas.test.tsx b/apps/ops-dashboard/__tests__/components/resources/resourcequotas.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/resources/resourcequotas.test.tsx rename to apps/ops-dashboard/__tests__/components/resources/resourcequotas.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/resources/rolebindings.test.tsx b/apps/ops-dashboard/__tests__/components/resources/rolebindings.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/resources/rolebindings.test.tsx rename to apps/ops-dashboard/__tests__/components/resources/rolebindings.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/resources/roles.test.tsx b/apps/ops-dashboard/__tests__/components/resources/roles.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/resources/roles.test.tsx rename to apps/ops-dashboard/__tests__/components/resources/roles.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/resources/runtimeclasses.test.tsx b/apps/ops-dashboard/__tests__/components/resources/runtimeclasses.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/resources/runtimeclasses.test.tsx rename to apps/ops-dashboard/__tests__/components/resources/runtimeclasses.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/resources/secrets.test.tsx b/apps/ops-dashboard/__tests__/components/resources/secrets.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/resources/secrets.test.tsx rename to apps/ops-dashboard/__tests__/components/resources/secrets.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/resources/serviceaccounts.test.tsx b/apps/ops-dashboard/__tests__/components/resources/serviceaccounts.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/resources/serviceaccounts.test.tsx rename to apps/ops-dashboard/__tests__/components/resources/serviceaccounts.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/resources/services.test.tsx b/apps/ops-dashboard/__tests__/components/resources/services.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/resources/services.test.tsx rename to apps/ops-dashboard/__tests__/components/resources/services.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/resources/statefulsets.test.tsx b/apps/ops-dashboard/__tests__/components/resources/statefulsets.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/resources/statefulsets.test.tsx rename to apps/ops-dashboard/__tests__/components/resources/statefulsets.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/resources/storageclasses.test.tsx b/apps/ops-dashboard/__tests__/components/resources/storageclasses.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/resources/storageclasses.test.tsx rename to apps/ops-dashboard/__tests__/components/resources/storageclasses.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/resources/volumeattachments.test.tsx b/apps/ops-dashboard/__tests__/components/resources/volumeattachments.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/resources/volumeattachments.test.tsx rename to apps/ops-dashboard/__tests__/components/resources/volumeattachments.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/scale-deployment-dialog.test.tsx b/apps/ops-dashboard/__tests__/components/scale-deployment-dialog.test.tsx similarity index 99% rename from interweb/packages/dashboard/__tests__/components/scale-deployment-dialog.test.tsx rename to apps/ops-dashboard/__tests__/components/scale-deployment-dialog.test.tsx index 16a7fe6..8424d3c 100644 --- a/interweb/packages/dashboard/__tests__/components/scale-deployment-dialog.test.tsx +++ b/apps/ops-dashboard/__tests__/components/scale-deployment-dialog.test.tsx @@ -2,7 +2,7 @@ import React from 'react' import { render, screen, waitFor } from '../utils/test-utils' import userEvent from '@testing-library/user-event' import { ScaleDeploymentDialog } from '@/components/scale-deployment-dialog' -import type { AppsV1Deployment as Deployment } from '@interweb/interwebjs' +import type { AppsV1Deployment as Deployment } from '@kubernetesjs/ops' // Mock deployment data const mockDeployment: Deployment = { diff --git a/interweb/packages/dashboard/__tests__/components/template-dialog.test.tsx b/apps/ops-dashboard/__tests__/components/template-dialog.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/template-dialog.test.tsx rename to apps/ops-dashboard/__tests__/components/template-dialog.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/templates.test.tsx b/apps/ops-dashboard/__tests__/components/templates.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/templates.test.tsx rename to apps/ops-dashboard/__tests__/components/templates.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/theme-toggle.test.tsx b/apps/ops-dashboard/__tests__/components/theme-toggle.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/theme-toggle.test.tsx rename to apps/ops-dashboard/__tests__/components/theme-toggle.test.tsx diff --git a/interweb/packages/dashboard/__tests__/components/view-edit-deployment-dialog.test.tsx b/apps/ops-dashboard/__tests__/components/view-edit-deployment-dialog.test.tsx similarity index 99% rename from interweb/packages/dashboard/__tests__/components/view-edit-deployment-dialog.test.tsx rename to apps/ops-dashboard/__tests__/components/view-edit-deployment-dialog.test.tsx index b5aae82..ca99eb7 100644 --- a/interweb/packages/dashboard/__tests__/components/view-edit-deployment-dialog.test.tsx +++ b/apps/ops-dashboard/__tests__/components/view-edit-deployment-dialog.test.tsx @@ -2,7 +2,7 @@ import React from 'react' import { render, screen, waitFor, cleanup } from '../utils/test-utils' import userEvent from '@testing-library/user-event' import { ViewEditDeploymentDialog } from '@/components/view-edit-deployment-dialog' -import type { AppsV1Deployment as Deployment } from '@interweb/interwebjs' +import type { AppsV1Deployment as Deployment } from '@kubernetesjs/ops' // Mock the YAMLEditor component jest.mock('../../components/yaml-editor', () => ({ diff --git a/interweb/packages/dashboard/__tests__/components/yaml-editor.test.tsx b/apps/ops-dashboard/__tests__/components/yaml-editor.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/components/yaml-editor.test.tsx rename to apps/ops-dashboard/__tests__/components/yaml-editor.test.tsx diff --git a/interweb/packages/dashboard/__tests__/e2e/README.md b/apps/ops-dashboard/__tests__/e2e/README.md similarity index 100% rename from interweb/packages/dashboard/__tests__/e2e/README.md rename to apps/ops-dashboard/__tests__/e2e/README.md diff --git a/interweb/packages/dashboard/__tests__/e2e/UNIT-DASHBOARD-TEST-CI-CD-README.md b/apps/ops-dashboard/__tests__/e2e/UNIT-DASHBOARD-TEST-CI-CD-README.md similarity index 100% rename from interweb/packages/dashboard/__tests__/e2e/UNIT-DASHBOARD-TEST-CI-CD-README.md rename to apps/ops-dashboard/__tests__/e2e/UNIT-DASHBOARD-TEST-CI-CD-README.md diff --git a/interweb/packages/dashboard/__tests__/e2e/global-setup.ts b/apps/ops-dashboard/__tests__/e2e/global-setup.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/e2e/global-setup.ts rename to apps/ops-dashboard/__tests__/e2e/global-setup.ts diff --git a/interweb/packages/dashboard/__tests__/e2e/global-teardown.ts b/apps/ops-dashboard/__tests__/e2e/global-teardown.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/e2e/global-teardown.ts rename to apps/ops-dashboard/__tests__/e2e/global-teardown.ts diff --git a/interweb/packages/dashboard/__tests__/e2e/setup.ts b/apps/ops-dashboard/__tests__/e2e/setup.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/e2e/setup.ts rename to apps/ops-dashboard/__tests__/e2e/setup.ts diff --git a/interweb/packages/dashboard/__tests__/e2e/utils/cluster-verification.ts b/apps/ops-dashboard/__tests__/e2e/utils/cluster-verification.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/e2e/utils/cluster-verification.ts rename to apps/ops-dashboard/__tests__/e2e/utils/cluster-verification.ts diff --git a/interweb/packages/dashboard/__tests__/e2e/utils/deployment-helpers.ts b/apps/ops-dashboard/__tests__/e2e/utils/deployment-helpers.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/e2e/utils/deployment-helpers.ts rename to apps/ops-dashboard/__tests__/e2e/utils/deployment-helpers.ts diff --git a/interweb/packages/dashboard/__tests__/e2e/utils/page-objects.ts b/apps/ops-dashboard/__tests__/e2e/utils/page-objects.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/e2e/utils/page-objects.ts rename to apps/ops-dashboard/__tests__/e2e/utils/page-objects.ts diff --git a/interweb/packages/dashboard/__tests__/e2e/utils/page-verification.ts b/apps/ops-dashboard/__tests__/e2e/utils/page-verification.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/e2e/utils/page-verification.ts rename to apps/ops-dashboard/__tests__/e2e/utils/page-verification.ts diff --git a/interweb/packages/dashboard/__tests__/e2e/utils/test-helpers.ts b/apps/ops-dashboard/__tests__/e2e/utils/test-helpers.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/e2e/utils/test-helpers.ts rename to apps/ops-dashboard/__tests__/e2e/utils/test-helpers.ts diff --git a/interweb/packages/dashboard/__tests__/e2e/utils/workflow-helpers.ts b/apps/ops-dashboard/__tests__/e2e/utils/workflow-helpers.ts similarity index 99% rename from interweb/packages/dashboard/__tests__/e2e/utils/workflow-helpers.ts rename to apps/ops-dashboard/__tests__/e2e/utils/workflow-helpers.ts index 1249c9f..96bc0df 100644 --- a/interweb/packages/dashboard/__tests__/e2e/utils/workflow-helpers.ts +++ b/apps/ops-dashboard/__tests__/e2e/utils/workflow-helpers.ts @@ -1,6 +1,6 @@ import { Page, expect } from '@playwright/test'; import { verifyPageLoadedSuccessfully } from './page-verification'; -import { InterwebClient } from '@interweb/interwebjs'; +import { InterwebClient } from '@kubernetesjs/ops'; const interweb = new InterwebClient({ restEndpoint: 'http://127.0.0.1:8001', diff --git a/interweb/packages/dashboard/__tests__/e2e/workflow-deployment-lifecycle.spec.ts b/apps/ops-dashboard/__tests__/e2e/workflow-deployment-lifecycle.spec.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/e2e/workflow-deployment-lifecycle.spec.ts rename to apps/ops-dashboard/__tests__/e2e/workflow-deployment-lifecycle.spec.ts diff --git a/interweb/packages/dashboard/__tests__/e2e/workflow-operator-database-focused.spec.ts b/apps/ops-dashboard/__tests__/e2e/workflow-operator-database-focused.spec.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/e2e/workflow-operator-database-focused.spec.ts rename to apps/ops-dashboard/__tests__/e2e/workflow-operator-database-focused.spec.ts diff --git a/interweb/packages/dashboard/__tests__/e2e/workflow-operator-database-focused.spec.ts-snapshots/admin-dashboard-chromium-darwin.png b/apps/ops-dashboard/__tests__/e2e/workflow-operator-database-focused.spec.ts-snapshots/admin-dashboard-chromium-darwin.png similarity index 100% rename from interweb/packages/dashboard/__tests__/e2e/workflow-operator-database-focused.spec.ts-snapshots/admin-dashboard-chromium-darwin.png rename to apps/ops-dashboard/__tests__/e2e/workflow-operator-database-focused.spec.ts-snapshots/admin-dashboard-chromium-darwin.png diff --git a/interweb/packages/dashboard/__tests__/hooks/use-breakpoint.test.ts b/apps/ops-dashboard/__tests__/hooks/use-breakpoint.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/hooks/use-breakpoint.test.ts rename to apps/ops-dashboard/__tests__/hooks/use-breakpoint.test.ts diff --git a/interweb/packages/dashboard/__tests__/hooks/use-cluster-status.test.tsx b/apps/ops-dashboard/__tests__/hooks/use-cluster-status.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/hooks/use-cluster-status.test.tsx rename to apps/ops-dashboard/__tests__/hooks/use-cluster-status.test.tsx diff --git a/interweb/packages/dashboard/__tests__/hooks/use-copy-to-clipboard.test.ts b/apps/ops-dashboard/__tests__/hooks/use-copy-to-clipboard.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/hooks/use-copy-to-clipboard.test.ts rename to apps/ops-dashboard/__tests__/hooks/use-copy-to-clipboard.test.ts diff --git a/interweb/packages/dashboard/__tests__/hooks/use-database-status.test.tsx b/apps/ops-dashboard/__tests__/hooks/use-database-status.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/hooks/use-database-status.test.tsx rename to apps/ops-dashboard/__tests__/hooks/use-database-status.test.tsx diff --git a/interweb/packages/dashboard/__tests__/hooks/use-google-analytics.test.tsx b/apps/ops-dashboard/__tests__/hooks/use-google-analytics.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/hooks/use-google-analytics.test.tsx rename to apps/ops-dashboard/__tests__/hooks/use-google-analytics.test.tsx diff --git a/interweb/packages/dashboard/__tests__/hooks/use-image-cache.test.tsx b/apps/ops-dashboard/__tests__/hooks/use-image-cache.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/hooks/use-image-cache.test.tsx rename to apps/ops-dashboard/__tests__/hooks/use-image-cache.test.tsx diff --git a/interweb/packages/dashboard/__tests__/hooks/use-is-mounted.test.ts b/apps/ops-dashboard/__tests__/hooks/use-is-mounted.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/hooks/use-is-mounted.test.ts rename to apps/ops-dashboard/__tests__/hooks/use-is-mounted.test.ts diff --git a/interweb/packages/dashboard/__tests__/hooks/use-media-query.test.ts b/apps/ops-dashboard/__tests__/hooks/use-media-query.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/hooks/use-media-query.test.ts rename to apps/ops-dashboard/__tests__/hooks/use-media-query.test.ts diff --git a/interweb/packages/dashboard/__tests__/hooks/use-pagination.test.ts b/apps/ops-dashboard/__tests__/hooks/use-pagination.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/hooks/use-pagination.test.ts rename to apps/ops-dashboard/__tests__/hooks/use-pagination.test.ts diff --git a/interweb/packages/dashboard/__tests__/hooks/use-routes.test.ts b/apps/ops-dashboard/__tests__/hooks/use-routes.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/hooks/use-routes.test.ts rename to apps/ops-dashboard/__tests__/hooks/use-routes.test.ts diff --git a/interweb/packages/dashboard/__tests__/hooks/use-search-data.test.ts b/apps/ops-dashboard/__tests__/hooks/use-search-data.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/hooks/use-search-data.test.ts rename to apps/ops-dashboard/__tests__/hooks/use-search-data.test.ts diff --git a/interweb/packages/dashboard/__tests__/hooks/use-show-more.test.ts b/apps/ops-dashboard/__tests__/hooks/use-show-more.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/hooks/use-show-more.test.ts rename to apps/ops-dashboard/__tests__/hooks/use-show-more.test.ts diff --git a/interweb/packages/dashboard/__tests__/hooks/use-toast.test.ts b/apps/ops-dashboard/__tests__/hooks/use-toast.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/hooks/use-toast.test.ts rename to apps/ops-dashboard/__tests__/hooks/use-toast.test.ts diff --git a/interweb/packages/dashboard/__tests__/hooks/use-window-dimensions.test.ts b/apps/ops-dashboard/__tests__/hooks/use-window-dimensions.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/hooks/use-window-dimensions.test.ts rename to apps/ops-dashboard/__tests__/hooks/use-window-dimensions.test.ts diff --git a/interweb/packages/dashboard/__tests__/hooks/useAppMode.test.tsx b/apps/ops-dashboard/__tests__/hooks/useAppMode.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/hooks/useAppMode.test.tsx rename to apps/ops-dashboard/__tests__/hooks/useAppMode.test.tsx diff --git a/interweb/packages/dashboard/__tests__/hooks/useConfigMaps.test.tsx b/apps/ops-dashboard/__tests__/hooks/useConfigMaps.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/hooks/useConfigMaps.test.tsx rename to apps/ops-dashboard/__tests__/hooks/useConfigMaps.test.tsx diff --git a/interweb/packages/dashboard/__tests__/hooks/useConfirm.test.tsx b/apps/ops-dashboard/__tests__/hooks/useConfirm.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/hooks/useConfirm.test.tsx rename to apps/ops-dashboard/__tests__/hooks/useConfirm.test.tsx diff --git a/interweb/packages/dashboard/__tests__/hooks/useDaemonSets.test.tsx b/apps/ops-dashboard/__tests__/hooks/useDaemonSets.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/hooks/useDaemonSets.test.tsx rename to apps/ops-dashboard/__tests__/hooks/useDaemonSets.test.tsx diff --git a/interweb/packages/dashboard/__tests__/hooks/useDatabases.test.tsx b/apps/ops-dashboard/__tests__/hooks/useDatabases.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/hooks/useDatabases.test.tsx rename to apps/ops-dashboard/__tests__/hooks/useDatabases.test.tsx diff --git a/interweb/packages/dashboard/__tests__/hooks/useDebounce.test.ts b/apps/ops-dashboard/__tests__/hooks/useDebounce.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/hooks/useDebounce.test.ts rename to apps/ops-dashboard/__tests__/hooks/useDebounce.test.ts diff --git a/interweb/packages/dashboard/__tests__/hooks/useDeployments.test.tsx b/apps/ops-dashboard/__tests__/hooks/useDeployments.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/hooks/useDeployments.test.tsx rename to apps/ops-dashboard/__tests__/hooks/useDeployments.test.tsx diff --git a/interweb/packages/dashboard/__tests__/hooks/useNamespaces.test.tsx b/apps/ops-dashboard/__tests__/hooks/useNamespaces.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/hooks/useNamespaces.test.tsx rename to apps/ops-dashboard/__tests__/hooks/useNamespaces.test.tsx diff --git a/interweb/packages/dashboard/__tests__/hooks/useOperators.test.tsx b/apps/ops-dashboard/__tests__/hooks/useOperators.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/hooks/useOperators.test.tsx rename to apps/ops-dashboard/__tests__/hooks/useOperators.test.tsx diff --git a/interweb/packages/dashboard/__tests__/hooks/usePods.test.tsx b/apps/ops-dashboard/__tests__/hooks/usePods.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/hooks/usePods.test.tsx rename to apps/ops-dashboard/__tests__/hooks/usePods.test.tsx diff --git a/interweb/packages/dashboard/__tests__/hooks/usePreferredNamespace.test.tsx b/apps/ops-dashboard/__tests__/hooks/usePreferredNamespace.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/hooks/usePreferredNamespace.test.tsx rename to apps/ops-dashboard/__tests__/hooks/usePreferredNamespace.test.tsx diff --git a/interweb/packages/dashboard/__tests__/hooks/useReplicaSets.test.tsx b/apps/ops-dashboard/__tests__/hooks/useReplicaSets.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/hooks/useReplicaSets.test.tsx rename to apps/ops-dashboard/__tests__/hooks/useReplicaSets.test.tsx diff --git a/interweb/packages/dashboard/__tests__/hooks/useSecrets.test.tsx b/apps/ops-dashboard/__tests__/hooks/useSecrets.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/hooks/useSecrets.test.tsx rename to apps/ops-dashboard/__tests__/hooks/useSecrets.test.tsx diff --git a/interweb/packages/dashboard/__tests__/hooks/useServices.test.tsx b/apps/ops-dashboard/__tests__/hooks/useServices.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/hooks/useServices.test.tsx rename to apps/ops-dashboard/__tests__/hooks/useServices.test.tsx diff --git a/interweb/packages/dashboard/__tests__/lib/agent/ollama.test.ts b/apps/ops-dashboard/__tests__/lib/agent/ollama.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/lib/agent/ollama.test.ts rename to apps/ops-dashboard/__tests__/lib/agent/ollama.test.ts diff --git a/interweb/packages/dashboard/__tests__/lib/agents/bradie.test.ts b/apps/ops-dashboard/__tests__/lib/agents/bradie.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/lib/agents/bradie.test.ts rename to apps/ops-dashboard/__tests__/lib/agents/bradie.test.ts diff --git a/interweb/packages/dashboard/__tests__/lib/agents/index.test.ts b/apps/ops-dashboard/__tests__/lib/agents/index.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/lib/agents/index.test.ts rename to apps/ops-dashboard/__tests__/lib/agents/index.test.ts diff --git a/interweb/packages/dashboard/__tests__/lib/agents/ollama.test.ts b/apps/ops-dashboard/__tests__/lib/agents/ollama.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/lib/agents/ollama.test.ts rename to apps/ops-dashboard/__tests__/lib/agents/ollama.test.ts diff --git a/interweb/packages/dashboard/__tests__/lib/agents/types.test.ts b/apps/ops-dashboard/__tests__/lib/agents/types.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/lib/agents/types.test.ts rename to apps/ops-dashboard/__tests__/lib/agents/types.test.ts diff --git a/interweb/packages/dashboard/__tests__/lib/agents/utils-simple.test.ts b/apps/ops-dashboard/__tests__/lib/agents/utils-simple.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/lib/agents/utils-simple.test.ts rename to apps/ops-dashboard/__tests__/lib/agents/utils-simple.test.ts diff --git a/interweb/packages/dashboard/__tests__/lib/agents/utils.test.ts b/apps/ops-dashboard/__tests__/lib/agents/utils.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/lib/agents/utils.test.ts rename to apps/ops-dashboard/__tests__/lib/agents/utils.test.ts diff --git a/interweb/packages/dashboard/__tests__/lib/color.test.ts b/apps/ops-dashboard/__tests__/lib/color.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/lib/color.test.ts rename to apps/ops-dashboard/__tests__/lib/color.test.ts diff --git a/interweb/packages/dashboard/__tests__/lib/constants.test.ts b/apps/ops-dashboard/__tests__/lib/constants.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/lib/constants.test.ts rename to apps/ops-dashboard/__tests__/lib/constants.test.ts diff --git a/interweb/packages/dashboard/__tests__/lib/create-fluid-value.test.ts b/apps/ops-dashboard/__tests__/lib/create-fluid-value.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/lib/create-fluid-value.test.ts rename to apps/ops-dashboard/__tests__/lib/create-fluid-value.test.ts diff --git a/interweb/packages/dashboard/__tests__/lib/dom.test.ts b/apps/ops-dashboard/__tests__/lib/dom.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/lib/dom.test.ts rename to apps/ops-dashboard/__tests__/lib/dom.test.ts diff --git a/interweb/packages/dashboard/__tests__/lib/format.test.ts b/apps/ops-dashboard/__tests__/lib/format.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/lib/format.test.ts rename to apps/ops-dashboard/__tests__/lib/format.test.ts diff --git a/interweb/packages/dashboard/__tests__/lib/logger.test.ts b/apps/ops-dashboard/__tests__/lib/logger.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/lib/logger.test.ts rename to apps/ops-dashboard/__tests__/lib/logger.test.ts diff --git a/interweb/packages/dashboard/__tests__/lib/lookup.test.ts b/apps/ops-dashboard/__tests__/lib/lookup.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/lib/lookup.test.ts rename to apps/ops-dashboard/__tests__/lib/lookup.test.ts diff --git a/interweb/packages/dashboard/__tests__/lib/markdown.test.ts b/apps/ops-dashboard/__tests__/lib/markdown.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/lib/markdown.test.ts rename to apps/ops-dashboard/__tests__/lib/markdown.test.ts diff --git a/interweb/packages/dashboard/__tests__/lib/setup.ts b/apps/ops-dashboard/__tests__/lib/setup.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/lib/setup.ts rename to apps/ops-dashboard/__tests__/lib/setup.ts diff --git a/interweb/packages/dashboard/__tests__/lib/utils.test.ts b/apps/ops-dashboard/__tests__/lib/utils.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/lib/utils.test.ts rename to apps/ops-dashboard/__tests__/lib/utils.test.ts diff --git a/interweb/packages/dashboard/__tests__/msw-basic.test.ts b/apps/ops-dashboard/__tests__/msw-basic.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/msw-basic.test.ts rename to apps/ops-dashboard/__tests__/msw-basic.test.ts diff --git a/interweb/packages/dashboard/__tests__/setup.test.ts b/apps/ops-dashboard/__tests__/setup.test.ts similarity index 100% rename from interweb/packages/dashboard/__tests__/setup.test.ts rename to apps/ops-dashboard/__tests__/setup.test.ts diff --git a/interweb/packages/dashboard/__tests__/setup.test.tsx b/apps/ops-dashboard/__tests__/setup.test.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/setup.test.tsx rename to apps/ops-dashboard/__tests__/setup.test.tsx diff --git a/interweb/packages/dashboard/__tests__/utils/test-utils.tsx b/apps/ops-dashboard/__tests__/utils/test-utils.tsx similarity index 100% rename from interweb/packages/dashboard/__tests__/utils/test-utils.tsx rename to apps/ops-dashboard/__tests__/utils/test-utils.tsx diff --git a/interweb/packages/dashboard/app/admin/backups/page.tsx b/apps/ops-dashboard/app/admin/backups/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/admin/backups/page.tsx rename to apps/ops-dashboard/app/admin/backups/page.tsx diff --git a/interweb/packages/dashboard/app/admin/databases/page.tsx b/apps/ops-dashboard/app/admin/databases/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/admin/databases/page.tsx rename to apps/ops-dashboard/app/admin/databases/page.tsx diff --git a/interweb/packages/dashboard/app/admin/operators/page.tsx b/apps/ops-dashboard/app/admin/operators/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/admin/operators/page.tsx rename to apps/ops-dashboard/app/admin/operators/page.tsx diff --git a/interweb/packages/dashboard/app/admin/page.tsx b/apps/ops-dashboard/app/admin/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/admin/page.tsx rename to apps/ops-dashboard/app/admin/page.tsx diff --git a/interweb/packages/dashboard/app/admin/pods/page.tsx b/apps/ops-dashboard/app/admin/pods/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/admin/pods/page.tsx rename to apps/ops-dashboard/app/admin/pods/page.tsx diff --git a/interweb/packages/dashboard/app/admin/services/page.tsx b/apps/ops-dashboard/app/admin/services/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/admin/services/page.tsx rename to apps/ops-dashboard/app/admin/services/page.tsx diff --git a/interweb/packages/dashboard/app/admin/templates/page.tsx b/apps/ops-dashboard/app/admin/templates/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/admin/templates/page.tsx rename to apps/ops-dashboard/app/admin/templates/page.tsx diff --git a/interweb/packages/dashboard/app/api/cluster/status/route.ts b/apps/ops-dashboard/app/api/cluster/status/route.ts similarity index 100% rename from interweb/packages/dashboard/app/api/cluster/status/route.ts rename to apps/ops-dashboard/app/api/cluster/status/route.ts diff --git a/interweb/packages/dashboard/app/api/databases/[namespace]/[name]/backups/route.ts b/apps/ops-dashboard/app/api/databases/[namespace]/[name]/backups/route.ts similarity index 96% rename from interweb/packages/dashboard/app/api/databases/[namespace]/[name]/backups/route.ts rename to apps/ops-dashboard/app/api/databases/[namespace]/[name]/backups/route.ts index 98e7ac5..cdf8ddf 100644 --- a/interweb/packages/dashboard/app/api/databases/[namespace]/[name]/backups/route.ts +++ b/apps/ops-dashboard/app/api/databases/[namespace]/[name]/backups/route.ts @@ -1,7 +1,7 @@ import { NextRequest, NextResponse } from 'next/server'; -import { InterwebClient as InterwebKubernetesClient } from '@interweb/interwebjs'; -import { SetupClient } from '@interweb/client'; -import { PostgresDeployer } from '@interweb/client'; +import { InterwebClient as InterwebKubernetesClient } from '@kubernetesjs/ops'; +import { SetupClient } from '@kubernetesjs/client'; +import { PostgresDeployer } from '@kubernetesjs/client'; export const dynamic = 'force-dynamic'; diff --git a/interweb/packages/dashboard/app/api/databases/[namespace]/[name]/deploy/route.ts b/apps/ops-dashboard/app/api/databases/[namespace]/[name]/deploy/route.ts similarity index 97% rename from interweb/packages/dashboard/app/api/databases/[namespace]/[name]/deploy/route.ts rename to apps/ops-dashboard/app/api/databases/[namespace]/[name]/deploy/route.ts index 36aee6f..35bd88a 100644 --- a/interweb/packages/dashboard/app/api/databases/[namespace]/[name]/deploy/route.ts +++ b/apps/ops-dashboard/app/api/databases/[namespace]/[name]/deploy/route.ts @@ -1,5 +1,5 @@ import { NextRequest, NextResponse } from 'next/server'; -import { Client } from '@interweb/client'; +import { Client } from '@kubernetesjs/client'; export const dynamic = 'force-dynamic'; diff --git a/interweb/packages/dashboard/app/api/databases/[namespace]/[name]/status/route.ts b/apps/ops-dashboard/app/api/databases/[namespace]/[name]/status/route.ts similarity index 98% rename from interweb/packages/dashboard/app/api/databases/[namespace]/[name]/status/route.ts rename to apps/ops-dashboard/app/api/databases/[namespace]/[name]/status/route.ts index 431bd24..25b12b9 100644 --- a/interweb/packages/dashboard/app/api/databases/[namespace]/[name]/status/route.ts +++ b/apps/ops-dashboard/app/api/databases/[namespace]/[name]/status/route.ts @@ -1,5 +1,5 @@ import { NextResponse } from 'next/server'; -import { InterwebClient as InterwebKubernetesClient } from '@interweb/interwebjs'; +import { InterwebClient as InterwebKubernetesClient } from '@kubernetesjs/ops'; export const dynamic = 'force-dynamic'; diff --git a/interweb/packages/dashboard/app/api/init/route.ts b/apps/ops-dashboard/app/api/init/route.ts similarity index 100% rename from interweb/packages/dashboard/app/api/init/route.ts rename to apps/ops-dashboard/app/api/init/route.ts diff --git a/interweb/packages/dashboard/app/api/instance-id/route.ts b/apps/ops-dashboard/app/api/instance-id/route.ts similarity index 100% rename from interweb/packages/dashboard/app/api/instance-id/route.ts rename to apps/ops-dashboard/app/api/instance-id/route.ts diff --git a/interweb/packages/dashboard/app/api/k8s/[...path]/route.ts b/apps/ops-dashboard/app/api/k8s/[...path]/route.ts similarity index 100% rename from interweb/packages/dashboard/app/api/k8s/[...path]/route.ts rename to apps/ops-dashboard/app/api/k8s/[...path]/route.ts diff --git a/interweb/packages/dashboard/app/api/operators/[operator]/debug/route.ts b/apps/ops-dashboard/app/api/operators/[operator]/debug/route.ts similarity index 100% rename from interweb/packages/dashboard/app/api/operators/[operator]/debug/route.ts rename to apps/ops-dashboard/app/api/operators/[operator]/debug/route.ts diff --git a/interweb/packages/dashboard/app/api/operators/[operator]/install/route.ts b/apps/ops-dashboard/app/api/operators/[operator]/install/route.ts similarity index 93% rename from interweb/packages/dashboard/app/api/operators/[operator]/install/route.ts rename to apps/ops-dashboard/app/api/operators/[operator]/install/route.ts index 17bdc29..b031ccd 100644 --- a/interweb/packages/dashboard/app/api/operators/[operator]/install/route.ts +++ b/apps/ops-dashboard/app/api/operators/[operator]/install/route.ts @@ -11,8 +11,8 @@ export async function POST( try { try { const req = createRequire(import.meta.url); - const clientResolved = req.resolve('@interweb/client'); - const manifestsPkgPath = req.resolve('@interweb/manifests/package.json'); + const clientResolved = req.resolve('@kubernetesjs/client'); + const manifestsPkgPath = req.resolve('@kubernetesjs/manifests/package.json'); const operatorsDir = path.join(path.dirname(manifestsPkgPath), 'operators'); console.debug('[operators.install] resolve', { clientResolved, @@ -60,7 +60,7 @@ export async function DELETE( try { try { const req = createRequire(import.meta.url); - const manifestsPkgPath = req.resolve('@interweb/manifests/package.json'); + const manifestsPkgPath = req.resolve('@kubernetesjs/manifests/package.json'); const operatorsDir = path.join(path.dirname(manifestsPkgPath), 'operators'); console.debug('[operators.uninstall] operatorsDirExists', fs.existsSync(operatorsDir)); } catch {} diff --git a/interweb/packages/dashboard/app/api/operators/[operator]/status/route.ts b/apps/ops-dashboard/app/api/operators/[operator]/status/route.ts similarity index 100% rename from interweb/packages/dashboard/app/api/operators/[operator]/status/route.ts rename to apps/ops-dashboard/app/api/operators/[operator]/status/route.ts diff --git a/interweb/packages/dashboard/app/api/operators/route.ts b/apps/ops-dashboard/app/api/operators/route.ts similarity index 89% rename from interweb/packages/dashboard/app/api/operators/route.ts rename to apps/ops-dashboard/app/api/operators/route.ts index 891b5a8..fa22f1d 100644 --- a/interweb/packages/dashboard/app/api/operators/route.ts +++ b/apps/ops-dashboard/app/api/operators/route.ts @@ -11,8 +11,8 @@ export async function GET() { // Debug: confirm module resolution and available methods at runtime try { const req = createRequire(import.meta.url); - const clientResolved = req.resolve('@interweb/client'); - const manifestsPkgPath = req.resolve('@interweb/manifests/package.json'); + const clientResolved = req.resolve('@kubernetesjs/client'); + const manifestsPkgPath = req.resolve('@kubernetesjs/manifests/package.json'); const operatorsDir = path.join(path.dirname(manifestsPkgPath), 'operators'); console.debug('[operators.GET] resolve', { clientResolved, diff --git a/interweb/packages/dashboard/app/api/templates/[template]/route.ts b/apps/ops-dashboard/app/api/templates/[template]/route.ts similarity index 97% rename from interweb/packages/dashboard/app/api/templates/[template]/route.ts rename to apps/ops-dashboard/app/api/templates/[template]/route.ts index 1ccf337..a83972d 100644 --- a/interweb/packages/dashboard/app/api/templates/[template]/route.ts +++ b/apps/ops-dashboard/app/api/templates/[template]/route.ts @@ -1,6 +1,6 @@ import { NextRequest, NextResponse } from 'next/server' -import { Client, SetupClient } from '@interweb/client' -import { InterwebClient as InterwebKubernetesClient } from '@interweb/interwebjs' +import { Client, SetupClient } from '@kubernetesjs/client' +import { InterwebClient as InterwebKubernetesClient } from '@kubernetesjs/ops' // Initialize client with dashboard context function createClient() { diff --git a/interweb/packages/dashboard/app/d/chains/page.tsx b/apps/ops-dashboard/app/d/chains/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/d/chains/page.tsx rename to apps/ops-dashboard/app/d/chains/page.tsx diff --git a/interweb/packages/dashboard/app/d/databases/page.tsx b/apps/ops-dashboard/app/d/databases/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/d/databases/page.tsx rename to apps/ops-dashboard/app/d/databases/page.tsx diff --git a/interweb/packages/dashboard/app/d/functions/page.tsx b/apps/ops-dashboard/app/d/functions/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/d/functions/page.tsx rename to apps/ops-dashboard/app/d/functions/page.tsx diff --git a/interweb/packages/dashboard/app/d/layout.tsx b/apps/ops-dashboard/app/d/layout.tsx similarity index 100% rename from interweb/packages/dashboard/app/d/layout.tsx rename to apps/ops-dashboard/app/d/layout.tsx diff --git a/interweb/packages/dashboard/app/d/page.tsx b/apps/ops-dashboard/app/d/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/d/page.tsx rename to apps/ops-dashboard/app/d/page.tsx diff --git a/interweb/packages/dashboard/app/d/registry/page.tsx b/apps/ops-dashboard/app/d/registry/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/d/registry/page.tsx rename to apps/ops-dashboard/app/d/registry/page.tsx diff --git a/interweb/packages/dashboard/app/d/relayers/page.tsx b/apps/ops-dashboard/app/d/relayers/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/d/relayers/page.tsx rename to apps/ops-dashboard/app/d/relayers/page.tsx diff --git a/interweb/packages/dashboard/app/d/settings/page.tsx b/apps/ops-dashboard/app/d/settings/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/d/settings/page.tsx rename to apps/ops-dashboard/app/d/settings/page.tsx diff --git a/interweb/packages/dashboard/app/databases/page.tsx b/apps/ops-dashboard/app/databases/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/databases/page.tsx rename to apps/ops-dashboard/app/databases/page.tsx diff --git a/interweb/packages/dashboard/app/functions/page.tsx b/apps/ops-dashboard/app/functions/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/functions/page.tsx rename to apps/ops-dashboard/app/functions/page.tsx diff --git a/interweb/packages/dashboard/app/globals.css b/apps/ops-dashboard/app/globals.css similarity index 100% rename from interweb/packages/dashboard/app/globals.css rename to apps/ops-dashboard/app/globals.css diff --git a/interweb/packages/dashboard/app/i/all/page.tsx b/apps/ops-dashboard/app/i/all/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/i/all/page.tsx rename to apps/ops-dashboard/app/i/all/page.tsx diff --git a/interweb/packages/dashboard/app/i/configmaps/page.tsx b/apps/ops-dashboard/app/i/configmaps/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/i/configmaps/page.tsx rename to apps/ops-dashboard/app/i/configmaps/page.tsx diff --git a/interweb/packages/dashboard/app/i/cronjobs/page.tsx b/apps/ops-dashboard/app/i/cronjobs/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/i/cronjobs/page.tsx rename to apps/ops-dashboard/app/i/cronjobs/page.tsx diff --git a/interweb/packages/dashboard/app/i/daemonsets/page.tsx b/apps/ops-dashboard/app/i/daemonsets/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/i/daemonsets/page.tsx rename to apps/ops-dashboard/app/i/daemonsets/page.tsx diff --git a/interweb/packages/dashboard/app/i/deployments/page.tsx b/apps/ops-dashboard/app/i/deployments/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/i/deployments/page.tsx rename to apps/ops-dashboard/app/i/deployments/page.tsx diff --git a/interweb/packages/dashboard/app/i/endpoints/page.tsx b/apps/ops-dashboard/app/i/endpoints/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/i/endpoints/page.tsx rename to apps/ops-dashboard/app/i/endpoints/page.tsx diff --git a/interweb/packages/dashboard/app/i/endpointslices/page.tsx b/apps/ops-dashboard/app/i/endpointslices/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/i/endpointslices/page.tsx rename to apps/ops-dashboard/app/i/endpointslices/page.tsx diff --git a/interweb/packages/dashboard/app/i/events/page.tsx b/apps/ops-dashboard/app/i/events/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/i/events/page.tsx rename to apps/ops-dashboard/app/i/events/page.tsx diff --git a/interweb/packages/dashboard/app/i/hpas/page.tsx b/apps/ops-dashboard/app/i/hpas/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/i/hpas/page.tsx rename to apps/ops-dashboard/app/i/hpas/page.tsx diff --git a/interweb/packages/dashboard/app/i/ingresses/page.tsx b/apps/ops-dashboard/app/i/ingresses/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/i/ingresses/page.tsx rename to apps/ops-dashboard/app/i/ingresses/page.tsx diff --git a/interweb/packages/dashboard/app/i/jobs/page.tsx b/apps/ops-dashboard/app/i/jobs/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/i/jobs/page.tsx rename to apps/ops-dashboard/app/i/jobs/page.tsx diff --git a/interweb/packages/dashboard/app/i/networkpolicies/page.tsx b/apps/ops-dashboard/app/i/networkpolicies/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/i/networkpolicies/page.tsx rename to apps/ops-dashboard/app/i/networkpolicies/page.tsx diff --git a/interweb/packages/dashboard/app/i/page.tsx b/apps/ops-dashboard/app/i/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/i/page.tsx rename to apps/ops-dashboard/app/i/page.tsx diff --git a/interweb/packages/dashboard/app/i/pdbs/page.tsx b/apps/ops-dashboard/app/i/pdbs/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/i/pdbs/page.tsx rename to apps/ops-dashboard/app/i/pdbs/page.tsx diff --git a/interweb/packages/dashboard/app/i/pods/page.tsx b/apps/ops-dashboard/app/i/pods/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/i/pods/page.tsx rename to apps/ops-dashboard/app/i/pods/page.tsx diff --git a/interweb/packages/dashboard/app/i/priorityclasses/page.tsx b/apps/ops-dashboard/app/i/priorityclasses/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/i/priorityclasses/page.tsx rename to apps/ops-dashboard/app/i/priorityclasses/page.tsx diff --git a/interweb/packages/dashboard/app/i/pvcs/page.tsx b/apps/ops-dashboard/app/i/pvcs/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/i/pvcs/page.tsx rename to apps/ops-dashboard/app/i/pvcs/page.tsx diff --git a/interweb/packages/dashboard/app/i/pvs/page.tsx b/apps/ops-dashboard/app/i/pvs/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/i/pvs/page.tsx rename to apps/ops-dashboard/app/i/pvs/page.tsx diff --git a/interweb/packages/dashboard/app/i/replicasets/page.tsx b/apps/ops-dashboard/app/i/replicasets/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/i/replicasets/page.tsx rename to apps/ops-dashboard/app/i/replicasets/page.tsx diff --git a/interweb/packages/dashboard/app/i/resourcequotas/page.tsx b/apps/ops-dashboard/app/i/resourcequotas/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/i/resourcequotas/page.tsx rename to apps/ops-dashboard/app/i/resourcequotas/page.tsx diff --git a/interweb/packages/dashboard/app/i/rolebindings/page.tsx b/apps/ops-dashboard/app/i/rolebindings/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/i/rolebindings/page.tsx rename to apps/ops-dashboard/app/i/rolebindings/page.tsx diff --git a/interweb/packages/dashboard/app/i/roles/page.tsx b/apps/ops-dashboard/app/i/roles/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/i/roles/page.tsx rename to apps/ops-dashboard/app/i/roles/page.tsx diff --git a/interweb/packages/dashboard/app/i/runtimeclasses/page.tsx b/apps/ops-dashboard/app/i/runtimeclasses/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/i/runtimeclasses/page.tsx rename to apps/ops-dashboard/app/i/runtimeclasses/page.tsx diff --git a/interweb/packages/dashboard/app/i/secrets/page.tsx b/apps/ops-dashboard/app/i/secrets/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/i/secrets/page.tsx rename to apps/ops-dashboard/app/i/secrets/page.tsx diff --git a/interweb/packages/dashboard/app/i/serviceaccounts/page.tsx b/apps/ops-dashboard/app/i/serviceaccounts/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/i/serviceaccounts/page.tsx rename to apps/ops-dashboard/app/i/serviceaccounts/page.tsx diff --git a/interweb/packages/dashboard/app/i/services/page.tsx b/apps/ops-dashboard/app/i/services/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/i/services/page.tsx rename to apps/ops-dashboard/app/i/services/page.tsx diff --git a/interweb/packages/dashboard/app/i/statefulsets/page.tsx b/apps/ops-dashboard/app/i/statefulsets/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/i/statefulsets/page.tsx rename to apps/ops-dashboard/app/i/statefulsets/page.tsx diff --git a/interweb/packages/dashboard/app/i/storageclasses/page.tsx b/apps/ops-dashboard/app/i/storageclasses/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/i/storageclasses/page.tsx rename to apps/ops-dashboard/app/i/storageclasses/page.tsx diff --git a/interweb/packages/dashboard/app/i/volumeattachments/page.tsx b/apps/ops-dashboard/app/i/volumeattachments/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/i/volumeattachments/page.tsx rename to apps/ops-dashboard/app/i/volumeattachments/page.tsx diff --git a/interweb/packages/dashboard/app/layout.tsx b/apps/ops-dashboard/app/layout.tsx similarity index 100% rename from interweb/packages/dashboard/app/layout.tsx rename to apps/ops-dashboard/app/layout.tsx diff --git a/interweb/packages/dashboard/app/not-found.tsx b/apps/ops-dashboard/app/not-found.tsx similarity index 100% rename from interweb/packages/dashboard/app/not-found.tsx rename to apps/ops-dashboard/app/not-found.tsx diff --git a/interweb/packages/dashboard/app/page.tsx b/apps/ops-dashboard/app/page.tsx similarity index 100% rename from interweb/packages/dashboard/app/page.tsx rename to apps/ops-dashboard/app/page.tsx diff --git a/interweb/packages/dashboard/app/providers.tsx b/apps/ops-dashboard/app/providers.tsx similarity index 100% rename from interweb/packages/dashboard/app/providers.tsx rename to apps/ops-dashboard/app/providers.tsx diff --git a/interweb/packages/dashboard/assets/hyperweb-dash-dark-bg.svg b/apps/ops-dashboard/assets/hyperweb-dash-dark-bg.svg similarity index 100% rename from interweb/packages/dashboard/assets/hyperweb-dash-dark-bg.svg rename to apps/ops-dashboard/assets/hyperweb-dash-dark-bg.svg diff --git a/interweb/packages/dashboard/assets/hyperweb-dash-light-bg.svg b/apps/ops-dashboard/assets/hyperweb-dash-light-bg.svg similarity index 100% rename from interweb/packages/dashboard/assets/hyperweb-dash-light-bg.svg rename to apps/ops-dashboard/assets/hyperweb-dash-light-bg.svg diff --git a/interweb/packages/dashboard/assets/screenshot.png b/apps/ops-dashboard/assets/screenshot.png similarity index 100% rename from interweb/packages/dashboard/assets/screenshot.png rename to apps/ops-dashboard/assets/screenshot.png diff --git a/interweb/packages/dashboard/components/adaptive-layout.tsx b/apps/ops-dashboard/components/adaptive-layout.tsx similarity index 100% rename from interweb/packages/dashboard/components/adaptive-layout.tsx rename to apps/ops-dashboard/components/adaptive-layout.tsx diff --git a/interweb/packages/dashboard/components/admin/cluster-overview.tsx b/apps/ops-dashboard/components/admin/cluster-overview.tsx similarity index 100% rename from interweb/packages/dashboard/components/admin/cluster-overview.tsx rename to apps/ops-dashboard/components/admin/cluster-overview.tsx diff --git a/interweb/packages/dashboard/components/admin/operator-card.tsx b/apps/ops-dashboard/components/admin/operator-card.tsx similarity index 98% rename from interweb/packages/dashboard/components/admin/operator-card.tsx rename to apps/ops-dashboard/components/admin/operator-card.tsx index e3850f4..9955786 100644 --- a/interweb/packages/dashboard/components/admin/operator-card.tsx +++ b/apps/ops-dashboard/components/admin/operator-card.tsx @@ -10,7 +10,7 @@ import { Settings, ExternalLink, Loader2 } from 'lucide-react'; import { cn } from '@/lib/utils'; import { StatusIndicator } from './status-indicator'; import { Switch } from '@/components/ui/switch' -import type { OperatorInfo } from '@interweb/client'; +import type { OperatorInfo } from '@kubernetesjs/client'; import { useOperatorMutation } from '@/hooks/use-operators'; import { Button } from '@/components/ui/button'; diff --git a/interweb/packages/dashboard/components/admin/operator-filters.tsx b/apps/ops-dashboard/components/admin/operator-filters.tsx similarity index 100% rename from interweb/packages/dashboard/components/admin/operator-filters.tsx rename to apps/ops-dashboard/components/admin/operator-filters.tsx diff --git a/interweb/packages/dashboard/components/admin/operator-grid.tsx b/apps/ops-dashboard/components/admin/operator-grid.tsx similarity index 100% rename from interweb/packages/dashboard/components/admin/operator-grid.tsx rename to apps/ops-dashboard/components/admin/operator-grid.tsx diff --git a/interweb/packages/dashboard/components/admin/quick-actions.tsx b/apps/ops-dashboard/components/admin/quick-actions.tsx similarity index 100% rename from interweb/packages/dashboard/components/admin/quick-actions.tsx rename to apps/ops-dashboard/components/admin/quick-actions.tsx diff --git a/interweb/packages/dashboard/components/admin/recent-activity.tsx b/apps/ops-dashboard/components/admin/recent-activity.tsx similarity index 100% rename from interweb/packages/dashboard/components/admin/recent-activity.tsx rename to apps/ops-dashboard/components/admin/recent-activity.tsx diff --git a/interweb/packages/dashboard/components/admin/resource-summary.tsx b/apps/ops-dashboard/components/admin/resource-summary.tsx similarity index 100% rename from interweb/packages/dashboard/components/admin/resource-summary.tsx rename to apps/ops-dashboard/components/admin/resource-summary.tsx diff --git a/interweb/packages/dashboard/components/admin/status-indicator.tsx b/apps/ops-dashboard/components/admin/status-indicator.tsx similarity index 100% rename from interweb/packages/dashboard/components/admin/status-indicator.tsx rename to apps/ops-dashboard/components/admin/status-indicator.tsx diff --git a/interweb/packages/dashboard/components/admin/template-card.tsx b/apps/ops-dashboard/components/admin/template-card.tsx similarity index 100% rename from interweb/packages/dashboard/components/admin/template-card.tsx rename to apps/ops-dashboard/components/admin/template-card.tsx diff --git a/interweb/packages/dashboard/components/admin/template-filters.tsx b/apps/ops-dashboard/components/admin/template-filters.tsx similarity index 100% rename from interweb/packages/dashboard/components/admin/template-filters.tsx rename to apps/ops-dashboard/components/admin/template-filters.tsx diff --git a/interweb/packages/dashboard/components/agent-manager-agentic.tsx b/apps/ops-dashboard/components/agent-manager-agentic.tsx similarity index 100% rename from interweb/packages/dashboard/components/agent-manager-agentic.tsx rename to apps/ops-dashboard/components/agent-manager-agentic.tsx diff --git a/interweb/packages/dashboard/components/agent-manager-global.tsx b/apps/ops-dashboard/components/agent-manager-global.tsx similarity index 100% rename from interweb/packages/dashboard/components/agent-manager-global.tsx rename to apps/ops-dashboard/components/agent-manager-global.tsx diff --git a/interweb/packages/dashboard/components/ai-chat-agentic.tsx b/apps/ops-dashboard/components/ai-chat-agentic.tsx similarity index 100% rename from interweb/packages/dashboard/components/ai-chat-agentic.tsx rename to apps/ops-dashboard/components/ai-chat-agentic.tsx diff --git a/interweb/packages/dashboard/components/ai-chat-global.tsx b/apps/ops-dashboard/components/ai-chat-global.tsx similarity index 100% rename from interweb/packages/dashboard/components/ai-chat-global.tsx rename to apps/ops-dashboard/components/ai-chat-global.tsx diff --git a/interweb/packages/dashboard/components/app-layout.tsx b/apps/ops-dashboard/components/app-layout.tsx similarity index 100% rename from interweb/packages/dashboard/components/app-layout.tsx rename to apps/ops-dashboard/components/app-layout.tsx diff --git a/interweb/packages/dashboard/components/common/spinner.tsx b/apps/ops-dashboard/components/common/spinner.tsx similarity index 100% rename from interweb/packages/dashboard/components/common/spinner.tsx rename to apps/ops-dashboard/components/common/spinner.tsx diff --git a/interweb/packages/dashboard/components/context-switcher.tsx b/apps/ops-dashboard/components/context-switcher.tsx similarity index 100% rename from interweb/packages/dashboard/components/context-switcher.tsx rename to apps/ops-dashboard/components/context-switcher.tsx diff --git a/interweb/packages/dashboard/components/create-backup-dialog.tsx b/apps/ops-dashboard/components/create-backup-dialog.tsx similarity index 100% rename from interweb/packages/dashboard/components/create-backup-dialog.tsx rename to apps/ops-dashboard/components/create-backup-dialog.tsx diff --git a/interweb/packages/dashboard/components/create-databases-dialog.tsx b/apps/ops-dashboard/components/create-databases-dialog.tsx similarity index 100% rename from interweb/packages/dashboard/components/create-databases-dialog.tsx rename to apps/ops-dashboard/components/create-databases-dialog.tsx diff --git a/interweb/packages/dashboard/components/create-deployment-dialog.tsx b/apps/ops-dashboard/components/create-deployment-dialog.tsx similarity index 100% rename from interweb/packages/dashboard/components/create-deployment-dialog.tsx rename to apps/ops-dashboard/components/create-deployment-dialog.tsx diff --git a/interweb/packages/dashboard/components/dashboard-layout.tsx b/apps/ops-dashboard/components/dashboard-layout.tsx similarity index 100% rename from interweb/packages/dashboard/components/dashboard-layout.tsx rename to apps/ops-dashboard/components/dashboard-layout.tsx diff --git a/interweb/packages/dashboard/components/headers/admin-header.tsx b/apps/ops-dashboard/components/headers/admin-header.tsx similarity index 100% rename from interweb/packages/dashboard/components/headers/admin-header.tsx rename to apps/ops-dashboard/components/headers/admin-header.tsx diff --git a/interweb/packages/dashboard/components/headers/infra-header.tsx b/apps/ops-dashboard/components/headers/infra-header.tsx similarity index 100% rename from interweb/packages/dashboard/components/headers/infra-header.tsx rename to apps/ops-dashboard/components/headers/infra-header.tsx diff --git a/interweb/packages/dashboard/components/headers/smart-objects-header.tsx b/apps/ops-dashboard/components/headers/smart-objects-header.tsx similarity index 100% rename from interweb/packages/dashboard/components/headers/smart-objects-header.tsx rename to apps/ops-dashboard/components/headers/smart-objects-header.tsx diff --git a/interweb/packages/dashboard/components/namespace-switcher.tsx b/apps/ops-dashboard/components/namespace-switcher.tsx similarity index 100% rename from interweb/packages/dashboard/components/namespace-switcher.tsx rename to apps/ops-dashboard/components/namespace-switcher.tsx diff --git a/interweb/packages/dashboard/components/resources/all-resources.tsx b/apps/ops-dashboard/components/resources/all-resources.tsx similarity index 99% rename from interweb/packages/dashboard/components/resources/all-resources.tsx rename to apps/ops-dashboard/components/resources/all-resources.tsx index cd9d02b..4edb215 100644 --- a/interweb/packages/dashboard/components/resources/all-resources.tsx +++ b/apps/ops-dashboard/components/resources/all-resources.tsx @@ -16,7 +16,7 @@ import { AlertCircle } from 'lucide-react' import { useDeployments, useServices, usePods, useDaemonSets, useReplicaSets } from '@/hooks' -import { type AppsV1Deployment as Deployment, type AppsV1DaemonSet as DaemonSet, type AppsV1ReplicaSet as ReplicaSet, type Pod, type Service } from '@interweb/interwebjs' +import { type AppsV1Deployment as Deployment, type AppsV1DaemonSet as DaemonSet, type AppsV1ReplicaSet as ReplicaSet, type Pod, type Service } from '@kubernetesjs/ops' interface ResourceSectionProps { title: string diff --git a/interweb/packages/dashboard/components/resources/configmaps.tsx b/apps/ops-dashboard/components/resources/configmaps.tsx similarity index 99% rename from interweb/packages/dashboard/components/resources/configmaps.tsx rename to apps/ops-dashboard/components/resources/configmaps.tsx index 2ed9444..5dacefb 100644 --- a/interweb/packages/dashboard/components/resources/configmaps.tsx +++ b/apps/ops-dashboard/components/resources/configmaps.tsx @@ -22,7 +22,7 @@ import { ChevronDown, ChevronRight } from 'lucide-react' -import { type ConfigMap as K8sConfigMap } from '@interweb/interwebjs' +import { type ConfigMap as K8sConfigMap } from '@kubernetesjs/ops' import { useConfigMaps, useDeleteConfigMap, useUpdateConfigMap } from '@/hooks' import { confirmDialog } from '@/hooks/useConfirm' diff --git a/interweb/packages/dashboard/components/resources/cronjobs.tsx b/apps/ops-dashboard/components/resources/cronjobs.tsx similarity index 99% rename from interweb/packages/dashboard/components/resources/cronjobs.tsx rename to apps/ops-dashboard/components/resources/cronjobs.tsx index 9f61b55..dc82018 100644 --- a/interweb/packages/dashboard/components/resources/cronjobs.tsx +++ b/apps/ops-dashboard/components/resources/cronjobs.tsx @@ -23,7 +23,7 @@ import { usePatchBatchV1NamespacedCronJob } from '@/k8s' import { usePreferredNamespace } from '@/contexts/NamespaceContext' -import { type BatchV1CronJob as CronJob } from '@interweb/interwebjs' +import { type BatchV1CronJob as CronJob } from '@kubernetesjs/ops' import { confirmDialog } from '@/hooks/useConfirm' diff --git a/interweb/packages/dashboard/components/resources/daemonsets.tsx b/apps/ops-dashboard/components/resources/daemonsets.tsx similarity index 99% rename from interweb/packages/dashboard/components/resources/daemonsets.tsx rename to apps/ops-dashboard/components/resources/daemonsets.tsx index 58dae4e..0b14b84 100644 --- a/interweb/packages/dashboard/components/resources/daemonsets.tsx +++ b/apps/ops-dashboard/components/resources/daemonsets.tsx @@ -14,7 +14,7 @@ import { CheckCircle, Server } from 'lucide-react' -import { type AppsV1DaemonSet as K8sDaemonSet } from '@interweb/interwebjs' +import { type AppsV1DaemonSet as K8sDaemonSet } from '@kubernetesjs/ops' import { useDaemonSets, useDeleteDaemonSet } from '@/hooks/useDaemonSets' import { confirmDialog } from '@/hooks/useConfirm' diff --git a/interweb/packages/dashboard/components/resources/deployments.tsx b/apps/ops-dashboard/components/resources/deployments.tsx similarity index 99% rename from interweb/packages/dashboard/components/resources/deployments.tsx rename to apps/ops-dashboard/components/resources/deployments.tsx index d2fc220..1be4dad 100644 --- a/interweb/packages/dashboard/components/resources/deployments.tsx +++ b/apps/ops-dashboard/components/resources/deployments.tsx @@ -15,7 +15,7 @@ import { AlertCircle, CheckCircle } from 'lucide-react' -import { type AppsV1Deployment as K8sDeployment } from '@interweb/interwebjs' +import { type AppsV1Deployment as K8sDeployment } from '@kubernetesjs/ops' import { useDeployments, useDeleteDeployment, useScaleDeployment, useCreateDeployment, useUpdateDeployment } from '@/hooks' import { confirmDialog } from '@/hooks/useConfirm' diff --git a/interweb/packages/dashboard/components/resources/endpoints.tsx b/apps/ops-dashboard/components/resources/endpoints.tsx similarity index 99% rename from interweb/packages/dashboard/components/resources/endpoints.tsx rename to apps/ops-dashboard/components/resources/endpoints.tsx index c979cca..ca07d46 100644 --- a/interweb/packages/dashboard/components/resources/endpoints.tsx +++ b/apps/ops-dashboard/components/resources/endpoints.tsx @@ -21,7 +21,7 @@ import { useDeleteCoreV1NamespacedEndpoints } from '@/k8s' import { usePreferredNamespace } from '@/contexts/NamespaceContext' -import type { Endpoints } from '@interweb/interwebjs' +import type { Endpoints } from '@kubernetesjs/ops' import { confirmDialog } from '@/hooks/useConfirm' diff --git a/interweb/packages/dashboard/components/resources/endpointslices.tsx b/apps/ops-dashboard/components/resources/endpointslices.tsx similarity index 99% rename from interweb/packages/dashboard/components/resources/endpointslices.tsx rename to apps/ops-dashboard/components/resources/endpointslices.tsx index e83a20e..7adc98b 100644 --- a/interweb/packages/dashboard/components/resources/endpointslices.tsx +++ b/apps/ops-dashboard/components/resources/endpointslices.tsx @@ -21,7 +21,7 @@ import { useDeleteDiscoveryV1NamespacedEndpointSlice } from '@/k8s' import { usePreferredNamespace } from '@/contexts/NamespaceContext' -import { type DiscoveryK8sIoV1EndpointSlice as EndpointSlice } from '@interweb/interwebjs' +import { type DiscoveryK8sIoV1EndpointSlice as EndpointSlice } from '@kubernetesjs/ops' import { confirmDialog } from '@/hooks/useConfirm' diff --git a/interweb/packages/dashboard/components/resources/events.tsx b/apps/ops-dashboard/components/resources/events.tsx similarity index 99% rename from interweb/packages/dashboard/components/resources/events.tsx rename to apps/ops-dashboard/components/resources/events.tsx index 7625227..b80108f 100644 --- a/interweb/packages/dashboard/components/resources/events.tsx +++ b/apps/ops-dashboard/components/resources/events.tsx @@ -19,7 +19,7 @@ import { useListCoreV1EventForAllNamespacesQuery } from '@/k8s' import { usePreferredNamespace } from '@/contexts/NamespaceContext' -import type { Event } from '@interweb/interwebjs' +import type { Event } from '@kubernetesjs/ops' export function EventsView() { const [typeFilter, setTypeFilter] = useState('All') diff --git a/interweb/packages/dashboard/components/resources/hpas.tsx b/apps/ops-dashboard/components/resources/hpas.tsx similarity index 99% rename from interweb/packages/dashboard/components/resources/hpas.tsx rename to apps/ops-dashboard/components/resources/hpas.tsx index 812f496..9b96269 100644 --- a/interweb/packages/dashboard/components/resources/hpas.tsx +++ b/apps/ops-dashboard/components/resources/hpas.tsx @@ -22,7 +22,7 @@ import { useDeleteAutoscalingV2NamespacedHorizontalPodAutoscaler } from '@/k8s' import { usePreferredNamespace } from '@/contexts/NamespaceContext' -import { type AutoscalingV2HorizontalPodAutoscaler as HorizontalPodAutoscaler } from '@interweb/interwebjs' +import { type AutoscalingV2HorizontalPodAutoscaler as HorizontalPodAutoscaler } from '@kubernetesjs/ops' import { confirmDialog } from '@/hooks/useConfirm' diff --git a/interweb/packages/dashboard/components/resources/ingresses.tsx b/apps/ops-dashboard/components/resources/ingresses.tsx similarity index 99% rename from interweb/packages/dashboard/components/resources/ingresses.tsx rename to apps/ops-dashboard/components/resources/ingresses.tsx index 831800f..0b560ec 100644 --- a/interweb/packages/dashboard/components/resources/ingresses.tsx +++ b/apps/ops-dashboard/components/resources/ingresses.tsx @@ -22,7 +22,7 @@ import { useDeleteNetworkingV1NamespacedIngress } from '@/k8s' import { usePreferredNamespace } from '@/contexts/NamespaceContext' -import { type NetworkingK8sIoV1Ingress as Ingress } from '@interweb/interwebjs' +import { type NetworkingK8sIoV1Ingress as Ingress } from '@kubernetesjs/ops' import { confirmDialog } from '@/hooks/useConfirm' diff --git a/interweb/packages/dashboard/components/resources/jobs.tsx b/apps/ops-dashboard/components/resources/jobs.tsx similarity index 99% rename from interweb/packages/dashboard/components/resources/jobs.tsx rename to apps/ops-dashboard/components/resources/jobs.tsx index 24a6f28..cc46973 100644 --- a/interweb/packages/dashboard/components/resources/jobs.tsx +++ b/apps/ops-dashboard/components/resources/jobs.tsx @@ -21,7 +21,7 @@ import { useDeleteBatchV1NamespacedJob } from '@/k8s' import { usePreferredNamespace } from '@/contexts/NamespaceContext' -import { type BatchV1Job as Job } from '@interweb/interwebjs' +import { type BatchV1Job as Job } from '@kubernetesjs/ops' import { confirmDialog } from '@/hooks/useConfirm' diff --git a/interweb/packages/dashboard/components/resources/networkpolicies.tsx b/apps/ops-dashboard/components/resources/networkpolicies.tsx similarity index 99% rename from interweb/packages/dashboard/components/resources/networkpolicies.tsx rename to apps/ops-dashboard/components/resources/networkpolicies.tsx index 1512da0..0f54a18 100644 --- a/interweb/packages/dashboard/components/resources/networkpolicies.tsx +++ b/apps/ops-dashboard/components/resources/networkpolicies.tsx @@ -22,7 +22,7 @@ import { useDeleteNetworkingV1NamespacedNetworkPolicy } from '@/k8s' import { usePreferredNamespace } from '@/contexts/NamespaceContext' -import { type NetworkingK8sIoV1NetworkPolicy as NetworkPolicy } from '@interweb/interwebjs' +import { type NetworkingK8sIoV1NetworkPolicy as NetworkPolicy } from '@kubernetesjs/ops' import { confirmDialog } from '@/hooks/useConfirm' diff --git a/interweb/packages/dashboard/components/resources/pdbs.tsx b/apps/ops-dashboard/components/resources/pdbs.tsx similarity index 99% rename from interweb/packages/dashboard/components/resources/pdbs.tsx rename to apps/ops-dashboard/components/resources/pdbs.tsx index 2f1053a..b4ae0a2 100644 --- a/interweb/packages/dashboard/components/resources/pdbs.tsx +++ b/apps/ops-dashboard/components/resources/pdbs.tsx @@ -21,7 +21,7 @@ import { useDeletePolicyV1NamespacedPodDisruptionBudget } from '@/k8s' import { usePreferredNamespace } from '@/contexts/NamespaceContext' -import { type PolicyV1PodDisruptionBudget as PodDisruptionBudget } from '@interweb/interwebjs' +import { type PolicyV1PodDisruptionBudget as PodDisruptionBudget } from '@kubernetesjs/ops' import { confirmDialog } from '@/hooks/useConfirm' diff --git a/interweb/packages/dashboard/components/resources/pods.tsx b/apps/ops-dashboard/components/resources/pods.tsx similarity index 99% rename from interweb/packages/dashboard/components/resources/pods.tsx rename to apps/ops-dashboard/components/resources/pods.tsx index e8c2300..6968254 100644 --- a/interweb/packages/dashboard/components/resources/pods.tsx +++ b/apps/ops-dashboard/components/resources/pods.tsx @@ -16,7 +16,7 @@ import { Clock, XCircle } from 'lucide-react' -import { type Pod as K8sPod } from '@interweb/interwebjs' +import { type Pod as K8sPod } from '@kubernetesjs/ops' import { usePods, useDeletePod, usePodLogs } from '@/hooks' import { confirmDialog } from '@/hooks/useConfirm' diff --git a/interweb/packages/dashboard/components/resources/priorityclasses.tsx b/apps/ops-dashboard/components/resources/priorityclasses.tsx similarity index 99% rename from interweb/packages/dashboard/components/resources/priorityclasses.tsx rename to apps/ops-dashboard/components/resources/priorityclasses.tsx index f10bda5..2083932 100644 --- a/interweb/packages/dashboard/components/resources/priorityclasses.tsx +++ b/apps/ops-dashboard/components/resources/priorityclasses.tsx @@ -18,7 +18,7 @@ import { useListSchedulingV1PriorityClassQuery, useDeleteSchedulingV1PriorityClass } from '@/k8s' -import { type SchedulingK8sIoV1PriorityClass as PriorityClass } from '@interweb/interwebjs' +import { type SchedulingK8sIoV1PriorityClass as PriorityClass } from '@kubernetesjs/ops' import { confirmDialog } from '@/hooks/useConfirm' diff --git a/interweb/packages/dashboard/components/resources/pvcs.tsx b/apps/ops-dashboard/components/resources/pvcs.tsx similarity index 99% rename from interweb/packages/dashboard/components/resources/pvcs.tsx rename to apps/ops-dashboard/components/resources/pvcs.tsx index ceb2be2..6a22c89 100644 --- a/interweb/packages/dashboard/components/resources/pvcs.tsx +++ b/apps/ops-dashboard/components/resources/pvcs.tsx @@ -21,7 +21,7 @@ import { useDeleteCoreV1NamespacedPersistentVolumeClaim } from '@/k8s' import { usePreferredNamespace } from '@/contexts/NamespaceContext' -import type { PersistentVolumeClaim } from '@interweb/interwebjs' +import type { PersistentVolumeClaim } from '@kubernetesjs/ops' import { confirmDialog } from '@/hooks/useConfirm' diff --git a/interweb/packages/dashboard/components/resources/pvs.tsx b/apps/ops-dashboard/components/resources/pvs.tsx similarity index 99% rename from interweb/packages/dashboard/components/resources/pvs.tsx rename to apps/ops-dashboard/components/resources/pvs.tsx index aa47720..c5a20ec 100644 --- a/interweb/packages/dashboard/components/resources/pvs.tsx +++ b/apps/ops-dashboard/components/resources/pvs.tsx @@ -20,7 +20,7 @@ import { useListCoreV1PersistentVolumeQuery, useDeleteCoreV1PersistentVolume } from '@/k8s' -import type { PersistentVolume } from '@interweb/interwebjs' +import type { PersistentVolume } from '@kubernetesjs/ops' import { confirmDialog } from '@/hooks/useConfirm' diff --git a/interweb/packages/dashboard/components/resources/replicasets.tsx b/apps/ops-dashboard/components/resources/replicasets.tsx similarity index 99% rename from interweb/packages/dashboard/components/resources/replicasets.tsx rename to apps/ops-dashboard/components/resources/replicasets.tsx index 47a9b5f..bb8bf41 100644 --- a/interweb/packages/dashboard/components/resources/replicasets.tsx +++ b/apps/ops-dashboard/components/resources/replicasets.tsx @@ -16,7 +16,7 @@ import { CheckCircle, Copy } from 'lucide-react' -import { type AppsV1ReplicaSet as K8sReplicaSet } from '@interweb/interwebjs' +import { type AppsV1ReplicaSet as K8sReplicaSet } from '@kubernetesjs/ops' import { useReplicaSets, useDeleteReplicaSet, useScaleReplicaSet } from '@/hooks/useReplicaSets' import { confirmDialog } from '@/hooks/useConfirm' diff --git a/interweb/packages/dashboard/components/resources/resourcequotas.tsx b/apps/ops-dashboard/components/resources/resourcequotas.tsx similarity index 99% rename from interweb/packages/dashboard/components/resources/resourcequotas.tsx rename to apps/ops-dashboard/components/resources/resourcequotas.tsx index 42953ff..477cb51 100644 --- a/interweb/packages/dashboard/components/resources/resourcequotas.tsx +++ b/apps/ops-dashboard/components/resources/resourcequotas.tsx @@ -20,7 +20,7 @@ import { useDeleteCoreV1NamespacedResourceQuota } from '@/k8s' import { usePreferredNamespace } from '@/contexts/NamespaceContext' -import type { ResourceQuota } from '@interweb/interwebjs' +import type { ResourceQuota } from '@kubernetesjs/ops' import { confirmDialog } from '@/hooks/useConfirm' diff --git a/interweb/packages/dashboard/components/resources/rolebindings.tsx b/apps/ops-dashboard/components/resources/rolebindings.tsx similarity index 99% rename from interweb/packages/dashboard/components/resources/rolebindings.tsx rename to apps/ops-dashboard/components/resources/rolebindings.tsx index ea2043a..addb80e 100644 --- a/interweb/packages/dashboard/components/resources/rolebindings.tsx +++ b/apps/ops-dashboard/components/resources/rolebindings.tsx @@ -24,7 +24,7 @@ import { useDeleteRbacAuthorizationV1ClusterRoleBinding } from '@/k8s' import { usePreferredNamespace } from '@/contexts/NamespaceContext' -import { type RbacAuthorizationK8sIoV1RoleBinding as RoleBinding, type RbacAuthorizationK8sIoV1ClusterRoleBinding as ClusterRoleBinding } from '@interweb/interwebjs' +import { type RbacAuthorizationK8sIoV1RoleBinding as RoleBinding, type RbacAuthorizationK8sIoV1ClusterRoleBinding as ClusterRoleBinding } from '@kubernetesjs/ops' import { confirmDialog } from '@/hooks/useConfirm' diff --git a/interweb/packages/dashboard/components/resources/roles.tsx b/apps/ops-dashboard/components/resources/roles.tsx similarity index 99% rename from interweb/packages/dashboard/components/resources/roles.tsx rename to apps/ops-dashboard/components/resources/roles.tsx index 467d0b5..ecafbcb 100644 --- a/interweb/packages/dashboard/components/resources/roles.tsx +++ b/apps/ops-dashboard/components/resources/roles.tsx @@ -23,7 +23,7 @@ import { useDeleteRbacAuthorizationV1ClusterRole } from '@/k8s' import { usePreferredNamespace } from '@/contexts/NamespaceContext' -import { type RbacAuthorizationK8sIoV1Role as Role, type RbacAuthorizationK8sIoV1ClusterRole as ClusterRole } from '@interweb/interwebjs' +import { type RbacAuthorizationK8sIoV1Role as Role, type RbacAuthorizationK8sIoV1ClusterRole as ClusterRole } from '@kubernetesjs/ops' import { confirmDialog } from '@/hooks/useConfirm' diff --git a/interweb/packages/dashboard/components/resources/runtimeclasses.tsx b/apps/ops-dashboard/components/resources/runtimeclasses.tsx similarity index 99% rename from interweb/packages/dashboard/components/resources/runtimeclasses.tsx rename to apps/ops-dashboard/components/resources/runtimeclasses.tsx index 98bf57b..829cb0d 100644 --- a/interweb/packages/dashboard/components/resources/runtimeclasses.tsx +++ b/apps/ops-dashboard/components/resources/runtimeclasses.tsx @@ -18,7 +18,7 @@ import { useListNodeV1RuntimeClassQuery, useDeleteNodeV1RuntimeClass } from '@/k8s' -import { type NodeK8sIoV1RuntimeClass as RuntimeClass } from '@interweb/interwebjs' +import { type NodeK8sIoV1RuntimeClass as RuntimeClass } from '@kubernetesjs/ops' import { confirmDialog } from '@/hooks/useConfirm' diff --git a/interweb/packages/dashboard/components/resources/secrets.tsx b/apps/ops-dashboard/components/resources/secrets.tsx similarity index 99% rename from interweb/packages/dashboard/components/resources/secrets.tsx rename to apps/ops-dashboard/components/resources/secrets.tsx index 4804996..5a592df 100644 --- a/interweb/packages/dashboard/components/resources/secrets.tsx +++ b/apps/ops-dashboard/components/resources/secrets.tsx @@ -20,7 +20,7 @@ import { Upload, AlertCircle } from 'lucide-react' -import { type Secret as K8sSecret } from '@interweb/interwebjs' +import { type Secret as K8sSecret } from '@kubernetesjs/ops' import { useSecrets, useDeleteSecret, useCreateSecret } from '@/hooks' import { confirmDialog } from '@/hooks/useConfirm' diff --git a/interweb/packages/dashboard/components/resources/serviceaccounts.tsx b/apps/ops-dashboard/components/resources/serviceaccounts.tsx similarity index 99% rename from interweb/packages/dashboard/components/resources/serviceaccounts.tsx rename to apps/ops-dashboard/components/resources/serviceaccounts.tsx index 71fd035..6262a12 100644 --- a/interweb/packages/dashboard/components/resources/serviceaccounts.tsx +++ b/apps/ops-dashboard/components/resources/serviceaccounts.tsx @@ -22,7 +22,7 @@ import { useDeleteCoreV1NamespacedServiceAccount } from '@/k8s' import { usePreferredNamespace } from '@/contexts/NamespaceContext' -import type { ServiceAccount } from '@interweb/interwebjs' +import type { ServiceAccount } from '@kubernetesjs/ops' import { confirmDialog } from '@/hooks/useConfirm' diff --git a/interweb/packages/dashboard/components/resources/services.tsx b/apps/ops-dashboard/components/resources/services.tsx similarity index 99% rename from interweb/packages/dashboard/components/resources/services.tsx rename to apps/ops-dashboard/components/resources/services.tsx index b56e6c4..50b60d4 100644 --- a/interweb/packages/dashboard/components/resources/services.tsx +++ b/apps/ops-dashboard/components/resources/services.tsx @@ -16,7 +16,7 @@ import { Server, AlertCircle } from 'lucide-react' -import { type Service as K8sService } from '@interweb/interwebjs' +import { type Service as K8sService } from '@kubernetesjs/ops' import { useServices, useDeleteService } from '@/hooks' import { confirmDialog } from '@/hooks/useConfirm' diff --git a/interweb/packages/dashboard/components/resources/statefulsets.tsx b/apps/ops-dashboard/components/resources/statefulsets.tsx similarity index 99% rename from interweb/packages/dashboard/components/resources/statefulsets.tsx rename to apps/ops-dashboard/components/resources/statefulsets.tsx index cf2b8c5..1337ae8 100644 --- a/interweb/packages/dashboard/components/resources/statefulsets.tsx +++ b/apps/ops-dashboard/components/resources/statefulsets.tsx @@ -22,7 +22,7 @@ import { useReplaceAppsV1NamespacedStatefulSetScale } from '@/k8s' import { usePreferredNamespace } from '@/contexts/NamespaceContext' -import { type AppsV1StatefulSet as StatefulSet } from '@interweb/interwebjs' +import { type AppsV1StatefulSet as StatefulSet } from '@kubernetesjs/ops' import { confirmDialog } from '@/hooks/useConfirm' diff --git a/interweb/packages/dashboard/components/resources/storageclasses.tsx b/apps/ops-dashboard/components/resources/storageclasses.tsx similarity index 99% rename from interweb/packages/dashboard/components/resources/storageclasses.tsx rename to apps/ops-dashboard/components/resources/storageclasses.tsx index 7e17411..7edca78 100644 --- a/interweb/packages/dashboard/components/resources/storageclasses.tsx +++ b/apps/ops-dashboard/components/resources/storageclasses.tsx @@ -20,7 +20,7 @@ import { useListStorageV1StorageClassQuery, useDeleteStorageV1StorageClass } from '@/k8s' -import { type StorageK8sIoV1StorageClass as StorageClass } from '@interweb/interwebjs' +import { type StorageK8sIoV1StorageClass as StorageClass } from '@kubernetesjs/ops' import { confirmDialog } from '@/hooks/useConfirm' diff --git a/interweb/packages/dashboard/components/resources/volumeattachments.tsx b/apps/ops-dashboard/components/resources/volumeattachments.tsx similarity index 99% rename from interweb/packages/dashboard/components/resources/volumeattachments.tsx rename to apps/ops-dashboard/components/resources/volumeattachments.tsx index b708344..4f94101 100644 --- a/interweb/packages/dashboard/components/resources/volumeattachments.tsx +++ b/apps/ops-dashboard/components/resources/volumeattachments.tsx @@ -20,7 +20,7 @@ import { useListStorageV1VolumeAttachmentQuery, useDeleteStorageV1VolumeAttachment } from '@/k8s' -import { type StorageK8sIoV1VolumeAttachment as VolumeAttachment } from '@interweb/interwebjs' +import { type StorageK8sIoV1VolumeAttachment as VolumeAttachment } from '@kubernetesjs/ops' import { confirmDialog } from '@/hooks/useConfirm' diff --git a/interweb/packages/dashboard/components/scale-deployment-dialog.tsx b/apps/ops-dashboard/components/scale-deployment-dialog.tsx similarity index 98% rename from interweb/packages/dashboard/components/scale-deployment-dialog.tsx rename to apps/ops-dashboard/components/scale-deployment-dialog.tsx index da5bd4c..ff36baa 100644 --- a/interweb/packages/dashboard/components/scale-deployment-dialog.tsx +++ b/apps/ops-dashboard/components/scale-deployment-dialog.tsx @@ -7,7 +7,7 @@ import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { AlertCircle, Scale } from 'lucide-react' import { Alert, AlertDescription } from '@/components/ui/alert' -import type { AppsV1Deployment as Deployment } from '@interweb/interwebjs' +import type { AppsV1Deployment as Deployment } from '@kubernetesjs/ops' interface ScaleDeploymentDialogProps { deployment: Deployment | null diff --git a/interweb/packages/dashboard/components/templates/template-dialog.tsx b/apps/ops-dashboard/components/templates/template-dialog.tsx similarity index 100% rename from interweb/packages/dashboard/components/templates/template-dialog.tsx rename to apps/ops-dashboard/components/templates/template-dialog.tsx diff --git a/interweb/packages/dashboard/components/templates/templates.tsx b/apps/ops-dashboard/components/templates/templates.tsx similarity index 94% rename from interweb/packages/dashboard/components/templates/templates.tsx rename to apps/ops-dashboard/components/templates/templates.tsx index 8022cf6..d3270e0 100644 --- a/interweb/packages/dashboard/components/templates/templates.tsx +++ b/apps/ops-dashboard/components/templates/templates.tsx @@ -1,7 +1,7 @@ 'use client' import { Database, Cloud, Cpu } from 'lucide-react' -import { allTemplates, type TemplateMetadata } from '@interweb/client/deployers/presets/metadata' +import { allTemplates, type TemplateMetadata } from '@kubernetesjs/client/deployers/presets/metadata' export interface Template { id: string diff --git a/interweb/packages/dashboard/components/ui/accordion.tsx b/apps/ops-dashboard/components/ui/accordion.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/accordion.tsx rename to apps/ops-dashboard/components/ui/accordion.tsx diff --git a/interweb/packages/dashboard/components/ui/alert-dialog.tsx b/apps/ops-dashboard/components/ui/alert-dialog.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/alert-dialog.tsx rename to apps/ops-dashboard/components/ui/alert-dialog.tsx diff --git a/interweb/packages/dashboard/components/ui/alert.tsx b/apps/ops-dashboard/components/ui/alert.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/alert.tsx rename to apps/ops-dashboard/components/ui/alert.tsx diff --git a/interweb/packages/dashboard/components/ui/avatar.tsx b/apps/ops-dashboard/components/ui/avatar.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/avatar.tsx rename to apps/ops-dashboard/components/ui/avatar.tsx diff --git a/interweb/packages/dashboard/components/ui/badge.tsx b/apps/ops-dashboard/components/ui/badge.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/badge.tsx rename to apps/ops-dashboard/components/ui/badge.tsx diff --git a/interweb/packages/dashboard/components/ui/breadcrumb.tsx b/apps/ops-dashboard/components/ui/breadcrumb.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/breadcrumb.tsx rename to apps/ops-dashboard/components/ui/breadcrumb.tsx diff --git a/interweb/packages/dashboard/components/ui/button.tsx b/apps/ops-dashboard/components/ui/button.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/button.tsx rename to apps/ops-dashboard/components/ui/button.tsx diff --git a/interweb/packages/dashboard/components/ui/card.tsx b/apps/ops-dashboard/components/ui/card.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/card.tsx rename to apps/ops-dashboard/components/ui/card.tsx diff --git a/interweb/packages/dashboard/components/ui/carousel.tsx b/apps/ops-dashboard/components/ui/carousel.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/carousel.tsx rename to apps/ops-dashboard/components/ui/carousel.tsx diff --git a/interweb/packages/dashboard/components/ui/checkbox.tsx b/apps/ops-dashboard/components/ui/checkbox.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/checkbox.tsx rename to apps/ops-dashboard/components/ui/checkbox.tsx diff --git a/interweb/packages/dashboard/components/ui/confirm-dialog.tsx b/apps/ops-dashboard/components/ui/confirm-dialog.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/confirm-dialog.tsx rename to apps/ops-dashboard/components/ui/confirm-dialog.tsx diff --git a/interweb/packages/dashboard/components/ui/context-menu.tsx b/apps/ops-dashboard/components/ui/context-menu.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/context-menu.tsx rename to apps/ops-dashboard/components/ui/context-menu.tsx diff --git a/interweb/packages/dashboard/components/ui/dialog.tsx b/apps/ops-dashboard/components/ui/dialog.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/dialog.tsx rename to apps/ops-dashboard/components/ui/dialog.tsx diff --git a/interweb/packages/dashboard/components/ui/divider.tsx b/apps/ops-dashboard/components/ui/divider.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/divider.tsx rename to apps/ops-dashboard/components/ui/divider.tsx diff --git a/interweb/packages/dashboard/components/ui/dropdown-menu.tsx b/apps/ops-dashboard/components/ui/dropdown-menu.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/dropdown-menu.tsx rename to apps/ops-dashboard/components/ui/dropdown-menu.tsx diff --git a/interweb/packages/dashboard/components/ui/form.tsx b/apps/ops-dashboard/components/ui/form.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/form.tsx rename to apps/ops-dashboard/components/ui/form.tsx diff --git a/interweb/packages/dashboard/components/ui/input.tsx b/apps/ops-dashboard/components/ui/input.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/input.tsx rename to apps/ops-dashboard/components/ui/input.tsx diff --git a/interweb/packages/dashboard/components/ui/kbd.tsx b/apps/ops-dashboard/components/ui/kbd.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/kbd.tsx rename to apps/ops-dashboard/components/ui/kbd.tsx diff --git a/interweb/packages/dashboard/components/ui/label.tsx b/apps/ops-dashboard/components/ui/label.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/label.tsx rename to apps/ops-dashboard/components/ui/label.tsx diff --git a/interweb/packages/dashboard/components/ui/lightbox.tsx b/apps/ops-dashboard/components/ui/lightbox.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/lightbox.tsx rename to apps/ops-dashboard/components/ui/lightbox.tsx diff --git a/interweb/packages/dashboard/components/ui/overflow-list.tsx b/apps/ops-dashboard/components/ui/overflow-list.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/overflow-list.tsx rename to apps/ops-dashboard/components/ui/overflow-list.tsx diff --git a/interweb/packages/dashboard/components/ui/pagination.tsx b/apps/ops-dashboard/components/ui/pagination.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/pagination.tsx rename to apps/ops-dashboard/components/ui/pagination.tsx diff --git a/interweb/packages/dashboard/components/ui/popover.tsx b/apps/ops-dashboard/components/ui/popover.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/popover.tsx rename to apps/ops-dashboard/components/ui/popover.tsx diff --git a/interweb/packages/dashboard/components/ui/radio-group.tsx b/apps/ops-dashboard/components/ui/radio-group.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/radio-group.tsx rename to apps/ops-dashboard/components/ui/radio-group.tsx diff --git a/interweb/packages/dashboard/components/ui/scroll-area.tsx b/apps/ops-dashboard/components/ui/scroll-area.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/scroll-area.tsx rename to apps/ops-dashboard/components/ui/scroll-area.tsx diff --git a/interweb/packages/dashboard/components/ui/select.tsx b/apps/ops-dashboard/components/ui/select.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/select.tsx rename to apps/ops-dashboard/components/ui/select.tsx diff --git a/interweb/packages/dashboard/components/ui/skeleton.tsx b/apps/ops-dashboard/components/ui/skeleton.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/skeleton.tsx rename to apps/ops-dashboard/components/ui/skeleton.tsx diff --git a/interweb/packages/dashboard/components/ui/switch.tsx b/apps/ops-dashboard/components/ui/switch.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/switch.tsx rename to apps/ops-dashboard/components/ui/switch.tsx diff --git a/interweb/packages/dashboard/components/ui/tab-scroller.tsx b/apps/ops-dashboard/components/ui/tab-scroller.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/tab-scroller.tsx rename to apps/ops-dashboard/components/ui/tab-scroller.tsx diff --git a/interweb/packages/dashboard/components/ui/table.tsx b/apps/ops-dashboard/components/ui/table.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/table.tsx rename to apps/ops-dashboard/components/ui/table.tsx diff --git a/interweb/packages/dashboard/components/ui/tabs.tsx b/apps/ops-dashboard/components/ui/tabs.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/tabs.tsx rename to apps/ops-dashboard/components/ui/tabs.tsx diff --git a/interweb/packages/dashboard/components/ui/textarea.tsx b/apps/ops-dashboard/components/ui/textarea.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/textarea.tsx rename to apps/ops-dashboard/components/ui/textarea.tsx diff --git a/interweb/packages/dashboard/components/ui/theme-toggle.tsx b/apps/ops-dashboard/components/ui/theme-toggle.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/theme-toggle.tsx rename to apps/ops-dashboard/components/ui/theme-toggle.tsx diff --git a/interweb/packages/dashboard/components/ui/toast.tsx b/apps/ops-dashboard/components/ui/toast.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/toast.tsx rename to apps/ops-dashboard/components/ui/toast.tsx diff --git a/interweb/packages/dashboard/components/ui/toaster.tsx b/apps/ops-dashboard/components/ui/toaster.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/toaster.tsx rename to apps/ops-dashboard/components/ui/toaster.tsx diff --git a/interweb/packages/dashboard/components/ui/tooltip.tsx b/apps/ops-dashboard/components/ui/tooltip.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/tooltip.tsx rename to apps/ops-dashboard/components/ui/tooltip.tsx diff --git a/interweb/packages/dashboard/components/ui/treeview.tsx b/apps/ops-dashboard/components/ui/treeview.tsx similarity index 100% rename from interweb/packages/dashboard/components/ui/treeview.tsx rename to apps/ops-dashboard/components/ui/treeview.tsx diff --git a/interweb/packages/dashboard/components/view-edit-deployment-dialog.tsx b/apps/ops-dashboard/components/view-edit-deployment-dialog.tsx similarity index 98% rename from interweb/packages/dashboard/components/view-edit-deployment-dialog.tsx rename to apps/ops-dashboard/components/view-edit-deployment-dialog.tsx index b1da9d3..3e57fb5 100644 --- a/interweb/packages/dashboard/components/view-edit-deployment-dialog.tsx +++ b/apps/ops-dashboard/components/view-edit-deployment-dialog.tsx @@ -9,7 +9,7 @@ import { AlertCircle, Eye, Edit } from 'lucide-react' import { Alert, AlertDescription } from '@/components/ui/alert' import yaml from 'js-yaml' import { useReadAppsV1NamespacedDeploymentQuery } from '@/k8s' -import type { AppsV1Deployment as Deployment } from '@interweb/interwebjs' +import type { AppsV1Deployment as Deployment } from '@kubernetesjs/ops' interface ViewEditDeploymentDialogProps { deployment: Deployment | null diff --git a/interweb/packages/dashboard/components/yaml-editor.tsx b/apps/ops-dashboard/components/yaml-editor.tsx similarity index 100% rename from interweb/packages/dashboard/components/yaml-editor.tsx rename to apps/ops-dashboard/components/yaml-editor.tsx diff --git a/interweb/packages/dashboard/contexts/AppContext.tsx b/apps/ops-dashboard/contexts/AppContext.tsx similarity index 100% rename from interweb/packages/dashboard/contexts/AppContext.tsx rename to apps/ops-dashboard/contexts/AppContext.tsx diff --git a/interweb/packages/dashboard/contexts/NamespaceContext.tsx b/apps/ops-dashboard/contexts/NamespaceContext.tsx similarity index 100% rename from interweb/packages/dashboard/contexts/NamespaceContext.tsx rename to apps/ops-dashboard/contexts/NamespaceContext.tsx diff --git a/interweb/packages/dashboard/env.d.ts b/apps/ops-dashboard/env.d.ts similarity index 100% rename from interweb/packages/dashboard/env.d.ts rename to apps/ops-dashboard/env.d.ts diff --git a/interweb/packages/dashboard/eslint.config.js b/apps/ops-dashboard/eslint.config.js similarity index 100% rename from interweb/packages/dashboard/eslint.config.js rename to apps/ops-dashboard/eslint.config.js diff --git a/interweb/packages/dashboard/hooks/index.ts b/apps/ops-dashboard/hooks/index.ts similarity index 100% rename from interweb/packages/dashboard/hooks/index.ts rename to apps/ops-dashboard/hooks/index.ts diff --git a/interweb/packages/dashboard/hooks/use-breakpoint.ts b/apps/ops-dashboard/hooks/use-breakpoint.ts similarity index 100% rename from interweb/packages/dashboard/hooks/use-breakpoint.ts rename to apps/ops-dashboard/hooks/use-breakpoint.ts diff --git a/interweb/packages/dashboard/hooks/use-cluster-status.ts b/apps/ops-dashboard/hooks/use-cluster-status.ts similarity index 89% rename from interweb/packages/dashboard/hooks/use-cluster-status.ts rename to apps/ops-dashboard/hooks/use-cluster-status.ts index cfe8c58..db4b665 100644 --- a/interweb/packages/dashboard/hooks/use-cluster-status.ts +++ b/apps/ops-dashboard/hooks/use-cluster-status.ts @@ -1,5 +1,5 @@ import { useQuery } from '@tanstack/react-query'; -import type { ClusterOverview } from '@interweb/client'; +import type { ClusterOverview } from '@kubernetesjs/client'; export function useClusterStatus() { return useQuery({ diff --git a/interweb/packages/dashboard/hooks/use-copy-to-clipboard.ts b/apps/ops-dashboard/hooks/use-copy-to-clipboard.ts similarity index 100% rename from interweb/packages/dashboard/hooks/use-copy-to-clipboard.ts rename to apps/ops-dashboard/hooks/use-copy-to-clipboard.ts diff --git a/interweb/packages/dashboard/hooks/use-database-status.ts b/apps/ops-dashboard/hooks/use-database-status.ts similarity index 100% rename from interweb/packages/dashboard/hooks/use-database-status.ts rename to apps/ops-dashboard/hooks/use-database-status.ts diff --git a/interweb/packages/dashboard/hooks/use-debounce.ts b/apps/ops-dashboard/hooks/use-debounce.ts similarity index 100% rename from interweb/packages/dashboard/hooks/use-debounce.ts rename to apps/ops-dashboard/hooks/use-debounce.ts diff --git a/interweb/packages/dashboard/hooks/use-google-analytics.ts b/apps/ops-dashboard/hooks/use-google-analytics.ts similarity index 100% rename from interweb/packages/dashboard/hooks/use-google-analytics.ts rename to apps/ops-dashboard/hooks/use-google-analytics.ts diff --git a/interweb/packages/dashboard/hooks/use-image-cache.ts b/apps/ops-dashboard/hooks/use-image-cache.ts similarity index 100% rename from interweb/packages/dashboard/hooks/use-image-cache.ts rename to apps/ops-dashboard/hooks/use-image-cache.ts diff --git a/interweb/packages/dashboard/hooks/use-is-mounted.ts b/apps/ops-dashboard/hooks/use-is-mounted.ts similarity index 100% rename from interweb/packages/dashboard/hooks/use-is-mounted.ts rename to apps/ops-dashboard/hooks/use-is-mounted.ts diff --git a/interweb/packages/dashboard/hooks/use-media-query.ts b/apps/ops-dashboard/hooks/use-media-query.ts similarity index 100% rename from interweb/packages/dashboard/hooks/use-media-query.ts rename to apps/ops-dashboard/hooks/use-media-query.ts diff --git a/interweb/packages/dashboard/hooks/use-operators.ts b/apps/ops-dashboard/hooks/use-operators.ts similarity index 97% rename from interweb/packages/dashboard/hooks/use-operators.ts rename to apps/ops-dashboard/hooks/use-operators.ts index 5fe0c84..af8e58d 100644 --- a/interweb/packages/dashboard/hooks/use-operators.ts +++ b/apps/ops-dashboard/hooks/use-operators.ts @@ -1,5 +1,5 @@ import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; -import type { OperatorInfo } from '@interweb/client'; +import type { OperatorInfo } from '@kubernetesjs/client'; export function useOperators() { return useQuery({ diff --git a/interweb/packages/dashboard/hooks/use-pagination.ts b/apps/ops-dashboard/hooks/use-pagination.ts similarity index 100% rename from interweb/packages/dashboard/hooks/use-pagination.ts rename to apps/ops-dashboard/hooks/use-pagination.ts diff --git a/interweb/packages/dashboard/hooks/use-routes.ts b/apps/ops-dashboard/hooks/use-routes.ts similarity index 100% rename from interweb/packages/dashboard/hooks/use-routes.ts rename to apps/ops-dashboard/hooks/use-routes.ts diff --git a/interweb/packages/dashboard/hooks/use-search-data.ts b/apps/ops-dashboard/hooks/use-search-data.ts similarity index 100% rename from interweb/packages/dashboard/hooks/use-search-data.ts rename to apps/ops-dashboard/hooks/use-search-data.ts diff --git a/interweb/packages/dashboard/hooks/use-show-more.ts b/apps/ops-dashboard/hooks/use-show-more.ts similarity index 100% rename from interweb/packages/dashboard/hooks/use-show-more.ts rename to apps/ops-dashboard/hooks/use-show-more.ts diff --git a/interweb/packages/dashboard/hooks/use-templates.ts b/apps/ops-dashboard/hooks/use-templates.ts similarity index 100% rename from interweb/packages/dashboard/hooks/use-templates.ts rename to apps/ops-dashboard/hooks/use-templates.ts diff --git a/interweb/packages/dashboard/hooks/use-toast.ts b/apps/ops-dashboard/hooks/use-toast.ts similarity index 100% rename from interweb/packages/dashboard/hooks/use-toast.ts rename to apps/ops-dashboard/hooks/use-toast.ts diff --git a/interweb/packages/dashboard/hooks/use-window-dimensions.ts b/apps/ops-dashboard/hooks/use-window-dimensions.ts similarity index 100% rename from interweb/packages/dashboard/hooks/use-window-dimensions.ts rename to apps/ops-dashboard/hooks/use-window-dimensions.ts diff --git a/interweb/packages/dashboard/hooks/useConfigMaps.ts b/apps/ops-dashboard/hooks/useConfigMaps.ts similarity index 97% rename from interweb/packages/dashboard/hooks/useConfigMaps.ts rename to apps/ops-dashboard/hooks/useConfigMaps.ts index b22d920..6ab16d6 100644 --- a/interweb/packages/dashboard/hooks/useConfigMaps.ts +++ b/apps/ops-dashboard/hooks/useConfigMaps.ts @@ -7,7 +7,7 @@ import { useDeleteCoreV1NamespacedConfigMap, } from '../k8s/index' import { usePreferredNamespace } from '../contexts/NamespaceContext' -import type { ConfigMap, ConfigMapList } from '@interweb/interwebjs' +import type { ConfigMap, ConfigMapList } from '@kubernetesjs/ops' // Query keys const CONFIGMAPS_KEY = ['configmaps'] as const diff --git a/interweb/packages/dashboard/hooks/useConfirm.tsx b/apps/ops-dashboard/hooks/useConfirm.tsx similarity index 100% rename from interweb/packages/dashboard/hooks/useConfirm.tsx rename to apps/ops-dashboard/hooks/useConfirm.tsx diff --git a/interweb/packages/dashboard/hooks/useDaemonSets.ts b/apps/ops-dashboard/hooks/useDaemonSets.ts similarity index 100% rename from interweb/packages/dashboard/hooks/useDaemonSets.ts rename to apps/ops-dashboard/hooks/useDaemonSets.ts diff --git a/interweb/packages/dashboard/hooks/useDatabases.ts b/apps/ops-dashboard/hooks/useDatabases.ts similarity index 100% rename from interweb/packages/dashboard/hooks/useDatabases.ts rename to apps/ops-dashboard/hooks/useDatabases.ts diff --git a/interweb/packages/dashboard/hooks/useDeployments.ts b/apps/ops-dashboard/hooks/useDeployments.ts similarity index 98% rename from interweb/packages/dashboard/hooks/useDeployments.ts rename to apps/ops-dashboard/hooks/useDeployments.ts index 56dab85..6495d34 100644 --- a/interweb/packages/dashboard/hooks/useDeployments.ts +++ b/apps/ops-dashboard/hooks/useDeployments.ts @@ -8,7 +8,7 @@ import { useReplaceAppsV1NamespacedDeploymentScale, } from '../k8s/index' import { usePreferredNamespace } from '../contexts/NamespaceContext' -import type { AppsV1Deployment as Deployment, AppsV1DeploymentList as DeploymentList, AutoscalingV1Scale as Scale } from '@interweb/interwebjs' +import type { AppsV1Deployment as Deployment, AppsV1DeploymentList as DeploymentList, AutoscalingV1Scale as Scale } from '@kubernetesjs/ops' // Query keys const DEPLOYMENTS_KEY = ['deployments'] as const diff --git a/interweb/packages/dashboard/hooks/useNamespaces.ts b/apps/ops-dashboard/hooks/useNamespaces.ts similarity index 96% rename from interweb/packages/dashboard/hooks/useNamespaces.ts rename to apps/ops-dashboard/hooks/useNamespaces.ts index 920f2f6..025854c 100644 --- a/interweb/packages/dashboard/hooks/useNamespaces.ts +++ b/apps/ops-dashboard/hooks/useNamespaces.ts @@ -4,7 +4,7 @@ import { useCreateCoreV1Namespace, useDeleteCoreV1Namespace, } from '../k8s/index' -import type { Namespace, NamespaceList } from '@interweb/interwebjs' +import type { Namespace, NamespaceList } from '@kubernetesjs/ops' // Query keys const NAMESPACES_KEY = ['namespaces'] as const diff --git a/interweb/packages/dashboard/hooks/usePods.ts b/apps/ops-dashboard/hooks/usePods.ts similarity index 97% rename from interweb/packages/dashboard/hooks/usePods.ts rename to apps/ops-dashboard/hooks/usePods.ts index 257dde8..e661b16 100644 --- a/interweb/packages/dashboard/hooks/usePods.ts +++ b/apps/ops-dashboard/hooks/usePods.ts @@ -6,7 +6,7 @@ import { useDeleteCoreV1NamespacedPod, } from '../k8s/index' import { usePreferredNamespace } from '../contexts/NamespaceContext' -import type { Pod, PodList } from '@interweb/interwebjs' +import type { Pod, PodList } from '@kubernetesjs/ops' // Query keys const PODS_KEY = ['pods'] as const diff --git a/interweb/packages/dashboard/hooks/useReplicaSets.ts b/apps/ops-dashboard/hooks/useReplicaSets.ts similarity index 97% rename from interweb/packages/dashboard/hooks/useReplicaSets.ts rename to apps/ops-dashboard/hooks/useReplicaSets.ts index 760a85e..e7c4457 100644 --- a/interweb/packages/dashboard/hooks/useReplicaSets.ts +++ b/apps/ops-dashboard/hooks/useReplicaSets.ts @@ -6,7 +6,7 @@ import { useReplaceAppsV1NamespacedReplicaSetScale, } from '../k8s/index' import { usePreferredNamespace } from '../contexts/NamespaceContext' -import type { AppsV1ReplicaSet as ReplicaSet, AppsV1ReplicaSetList as ReplicaSetList, AutoscalingV1Scale as Scale } from '@interweb/interwebjs' +import type { AppsV1ReplicaSet as ReplicaSet, AppsV1ReplicaSetList as ReplicaSetList, AutoscalingV1Scale as Scale } from '@kubernetesjs/ops' // Query keys const REPLICASETS_KEY = ['replicasets'] as const diff --git a/interweb/packages/dashboard/hooks/useSecrets.ts b/apps/ops-dashboard/hooks/useSecrets.ts similarity index 98% rename from interweb/packages/dashboard/hooks/useSecrets.ts rename to apps/ops-dashboard/hooks/useSecrets.ts index 9e11856..b158b17 100644 --- a/interweb/packages/dashboard/hooks/useSecrets.ts +++ b/apps/ops-dashboard/hooks/useSecrets.ts @@ -8,7 +8,7 @@ import { } from '../k8s/index' import { usePreferredNamespace } from '../contexts/NamespaceContext' import { useQueryClient } from '@tanstack/react-query' -import type { Secret, SecretList } from '@interweb/interwebjs' +import type { Secret, SecretList } from '@kubernetesjs/ops' // Query keys const SECRETS_KEY = ['secrets'] as const diff --git a/interweb/packages/dashboard/hooks/useServices.ts b/apps/ops-dashboard/hooks/useServices.ts similarity index 98% rename from interweb/packages/dashboard/hooks/useServices.ts rename to apps/ops-dashboard/hooks/useServices.ts index 18945d7..0eb41c6 100644 --- a/interweb/packages/dashboard/hooks/useServices.ts +++ b/apps/ops-dashboard/hooks/useServices.ts @@ -7,7 +7,7 @@ import { useDeleteCoreV1NamespacedService, } from '../k8s/index' import { usePreferredNamespace } from '../contexts/NamespaceContext' -import type { Service, ServiceList } from '@interweb/interwebjs' +import type { Service, ServiceList } from '@kubernetesjs/ops' // Query keys const SERVICES_KEY = ['services'] as const diff --git a/interweb/packages/dashboard/jest.config.js b/apps/ops-dashboard/jest.config.js similarity index 100% rename from interweb/packages/dashboard/jest.config.js rename to apps/ops-dashboard/jest.config.js diff --git a/interweb/packages/dashboard/jest.polyfills.js b/apps/ops-dashboard/jest.polyfills.js similarity index 100% rename from interweb/packages/dashboard/jest.polyfills.js rename to apps/ops-dashboard/jest.polyfills.js diff --git a/interweb/packages/dashboard/jest.setup.js b/apps/ops-dashboard/jest.setup.js similarity index 100% rename from interweb/packages/dashboard/jest.setup.js rename to apps/ops-dashboard/jest.setup.js diff --git a/interweb/packages/dashboard/k8s/client.tsx b/apps/ops-dashboard/k8s/client.tsx similarity index 71% rename from interweb/packages/dashboard/k8s/client.tsx rename to apps/ops-dashboard/k8s/client.tsx index 3f21db4..1f04443 100644 --- a/interweb/packages/dashboard/k8s/client.tsx +++ b/apps/ops-dashboard/k8s/client.tsx @@ -1,5 +1,5 @@ -import { InterwebClient as InterwebKubernetesClient } from '@interweb/interwebjs'; -import { SetupClient } from '@interweb/client'; +import { InterwebClient as InterwebKubernetesClient } from '@kubernetesjs/ops'; +import { SetupClient } from '@kubernetesjs/client'; export function createSetupClient(): SetupClient { const restEndpoint = process.env.KUBERNETES_PROXY_URL || 'http://127.0.0.1:8001'; diff --git a/interweb/packages/dashboard/k8s/context.tsx b/apps/ops-dashboard/k8s/context.tsx similarity index 97% rename from interweb/packages/dashboard/k8s/context.tsx rename to apps/ops-dashboard/k8s/context.tsx index 235dba1..8e522f7 100644 --- a/interweb/packages/dashboard/k8s/context.tsx +++ b/apps/ops-dashboard/k8s/context.tsx @@ -1,6 +1,6 @@ 'use client' import React, { createContext, useContext, useMemo, useState } from 'react' -import { InterwebClient } from '@interweb/interwebjs' +import { InterwebClient } from '@kubernetesjs/ops' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' // Configuration types diff --git a/interweb/packages/dashboard/k8s/index.ts b/apps/ops-dashboard/k8s/index.ts similarity index 99% rename from interweb/packages/dashboard/k8s/index.ts rename to apps/ops-dashboard/k8s/index.ts index f7d6363..c82000e 100644 --- a/interweb/packages/dashboard/k8s/index.ts +++ b/apps/ops-dashboard/k8s/index.ts @@ -1,6 +1,6 @@ import { useKubernetes } from "./context"; import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; -// Import the types that actually exist in @interweb/interwebjs +// Import the types that actually exist in @kubernetesjs/ops import { AutoscalingV1HorizontalPodAutoscaler as HorizontalPodAutoscaler, AutoscalingV1HorizontalPodAutoscalerList as HorizontalPodAutoscalerList, @@ -780,7 +780,7 @@ import { WatchEventsV1EventListForAllNamespacesRequest, WatchEventsV1NamespacedEventListRequest, WatchEventsV1NamespacedEventRequest, -} from "@interweb/interwebjs"; +} from "@kubernetesjs/ops"; const WELL_KNOWN_OPENID_CONFIGURATION_KEY = ["well_known_openid_configuration"]; const API_KEY = ["api"]; const API_V1_KEY = ["api_v1"]; diff --git a/interweb/packages/dashboard/lib/agent/ollama.ts b/apps/ops-dashboard/lib/agent/ollama.ts similarity index 100% rename from interweb/packages/dashboard/lib/agent/ollama.ts rename to apps/ops-dashboard/lib/agent/ollama.ts diff --git a/interweb/packages/dashboard/lib/agents/bradie.ts b/apps/ops-dashboard/lib/agents/bradie.ts similarity index 100% rename from interweb/packages/dashboard/lib/agents/bradie.ts rename to apps/ops-dashboard/lib/agents/bradie.ts diff --git a/interweb/packages/dashboard/lib/agents/index.ts b/apps/ops-dashboard/lib/agents/index.ts similarity index 100% rename from interweb/packages/dashboard/lib/agents/index.ts rename to apps/ops-dashboard/lib/agents/index.ts diff --git a/interweb/packages/dashboard/lib/agents/ollama.ts b/apps/ops-dashboard/lib/agents/ollama.ts similarity index 100% rename from interweb/packages/dashboard/lib/agents/ollama.ts rename to apps/ops-dashboard/lib/agents/ollama.ts diff --git a/interweb/packages/dashboard/lib/agents/types.ts b/apps/ops-dashboard/lib/agents/types.ts similarity index 100% rename from interweb/packages/dashboard/lib/agents/types.ts rename to apps/ops-dashboard/lib/agents/types.ts diff --git a/interweb/packages/dashboard/lib/agents/utils.ts b/apps/ops-dashboard/lib/agents/utils.ts similarity index 100% rename from interweb/packages/dashboard/lib/agents/utils.ts rename to apps/ops-dashboard/lib/agents/utils.ts diff --git a/interweb/packages/dashboard/lib/color.ts b/apps/ops-dashboard/lib/color.ts similarity index 100% rename from interweb/packages/dashboard/lib/color.ts rename to apps/ops-dashboard/lib/color.ts diff --git a/interweb/packages/dashboard/lib/constants.ts b/apps/ops-dashboard/lib/constants.ts similarity index 100% rename from interweb/packages/dashboard/lib/constants.ts rename to apps/ops-dashboard/lib/constants.ts diff --git a/interweb/packages/dashboard/lib/create-fluid-value.ts b/apps/ops-dashboard/lib/create-fluid-value.ts similarity index 100% rename from interweb/packages/dashboard/lib/create-fluid-value.ts rename to apps/ops-dashboard/lib/create-fluid-value.ts diff --git a/interweb/packages/dashboard/lib/dom.ts b/apps/ops-dashboard/lib/dom.ts similarity index 100% rename from interweb/packages/dashboard/lib/dom.ts rename to apps/ops-dashboard/lib/dom.ts diff --git a/interweb/packages/dashboard/lib/format.ts b/apps/ops-dashboard/lib/format.ts similarity index 100% rename from interweb/packages/dashboard/lib/format.ts rename to apps/ops-dashboard/lib/format.ts diff --git a/interweb/packages/dashboard/lib/logger.ts b/apps/ops-dashboard/lib/logger.ts similarity index 100% rename from interweb/packages/dashboard/lib/logger.ts rename to apps/ops-dashboard/lib/logger.ts diff --git a/interweb/packages/dashboard/lib/lookup.ts b/apps/ops-dashboard/lib/lookup.ts similarity index 100% rename from interweb/packages/dashboard/lib/lookup.ts rename to apps/ops-dashboard/lib/lookup.ts diff --git a/interweb/packages/dashboard/lib/markdown.ts b/apps/ops-dashboard/lib/markdown.ts similarity index 100% rename from interweb/packages/dashboard/lib/markdown.ts rename to apps/ops-dashboard/lib/markdown.ts diff --git a/interweb/packages/dashboard/lib/utils.ts b/apps/ops-dashboard/lib/utils.ts similarity index 100% rename from interweb/packages/dashboard/lib/utils.ts rename to apps/ops-dashboard/lib/utils.ts diff --git a/interweb/packages/dashboard/next.config.js b/apps/ops-dashboard/next.config.js similarity index 58% rename from interweb/packages/dashboard/next.config.js rename to apps/ops-dashboard/next.config.js index 548f61d..f0263bd 100644 --- a/interweb/packages/dashboard/next.config.js +++ b/apps/ops-dashboard/next.config.js @@ -3,7 +3,7 @@ const path = require('path'); const nextConfig = { reactStrictMode: false, - transpilePackages: ['@interweb/client', '@interweb/interwebjs', '@interweb/manifests'], + transpilePackages: ['@kubernetesjs/client', '@kubernetesjs/ops', '@kubernetesjs/manifests'], eslint: { // Temporarily disable lint errors during build to unblock type/module resolution work ignoreDuringBuilds: true, @@ -15,9 +15,9 @@ const nextConfig = { webpack: (config) => { config.resolve = config.resolve || {}; config.resolve.alias = config.resolve.alias || {}; - config.resolve.alias['@interweb/client'] = path.resolve(__dirname, '../client/dist'); - config.resolve.alias['@interweb/interwebjs'] = path.resolve(__dirname, '../interwebjs/dist'); - config.resolve.alias['@interweb/manifests'] = path.resolve(__dirname, '../manifests/dist'); + config.resolve.alias['@kubernetesjs/client'] = path.resolve(__dirname, '../../packages/client/dist'); + config.resolve.alias['@kubernetesjs/ops'] = path.resolve(__dirname, '../../packages/ops/dist'); + config.resolve.alias['@kubernetesjs/manifests'] = path.resolve(__dirname, '../../packages/manifests/dist'); return config; }, }; diff --git a/interweb/packages/dashboard/package.json b/apps/ops-dashboard/package.json similarity index 95% rename from interweb/packages/dashboard/package.json rename to apps/ops-dashboard/package.json index ead0127..dd99f02 100644 --- a/interweb/packages/dashboard/package.json +++ b/apps/ops-dashboard/package.json @@ -1,5 +1,5 @@ { - "name": "@interweb/dashboard", + "name": "@kubernetesjs/ops-dashboard", "version": "0.1.0", "private": true, "scripts": { @@ -20,9 +20,9 @@ "dependencies": { "@agentic-kit/ollama": "^0.1.2", "@ark-ui/react": "^5.0.1", - "@interweb/client": "workspace:*", - "@interweb/interwebjs": "workspace:*", - "@interweb/manifests": "workspace:*", + "@kubernetesjs/client": "workspace:*", + "@kubernetesjs/ops": "workspace:*", + "@kubernetesjs/manifests": "workspace:*", "@radix-ui/react-accordion": "^1.2.3", "@radix-ui/react-alert-dialog": "^1.1.6", "@radix-ui/react-avatar": "^1.1.3", @@ -104,4 +104,4 @@ "typescript": "^5.3.3", "whatwg-fetch": "^3.6.20" } -} \ No newline at end of file +} diff --git a/interweb/packages/dashboard/playwright.config.ts b/apps/ops-dashboard/playwright.config.ts similarity index 100% rename from interweb/packages/dashboard/playwright.config.ts rename to apps/ops-dashboard/playwright.config.ts diff --git a/interweb/packages/dashboard/postcss.config.js b/apps/ops-dashboard/postcss.config.js similarity index 100% rename from interweb/packages/dashboard/postcss.config.js rename to apps/ops-dashboard/postcss.config.js diff --git a/interweb/packages/dashboard/services/kubernetes-client.ts b/apps/ops-dashboard/services/kubernetes-client.ts similarity index 98% rename from interweb/packages/dashboard/services/kubernetes-client.ts rename to apps/ops-dashboard/services/kubernetes-client.ts index bf1ba73..663d2db 100644 --- a/interweb/packages/dashboard/services/kubernetes-client.ts +++ b/apps/ops-dashboard/services/kubernetes-client.ts @@ -1,4 +1,4 @@ -import { InterwebClient } from '@interweb/interwebjs' +import { InterwebClient } from '@kubernetesjs/ops' // Singleton instance let client: InterwebClient | null = null diff --git a/interweb/packages/dashboard/tailwind.config.ts b/apps/ops-dashboard/tailwind.config.ts similarity index 100% rename from interweb/packages/dashboard/tailwind.config.ts rename to apps/ops-dashboard/tailwind.config.ts diff --git a/interweb/packages/dashboard/tsconfig.json b/apps/ops-dashboard/tsconfig.json similarity index 76% rename from interweb/packages/dashboard/tsconfig.json rename to apps/ops-dashboard/tsconfig.json index 2f5419a..7082e23 100644 --- a/interweb/packages/dashboard/tsconfig.json +++ b/apps/ops-dashboard/tsconfig.json @@ -23,13 +23,13 @@ "paths": { "@/*": ["./*"], - "@interweb/client/*": ["../client/dist/*"], + "@kubernetesjs/client/*": ["../../packages/client/dist/*"], - "@interweb/interwebjs/*": ["../interwebjs/dist/*"], + "@kubernetesjs/ops/*": ["../../packages/ops/dist/*"], - "@interweb/manifests/*": ["../manifests/dist/*"] + "@kubernetesjs/manifests/*": ["../../packages/manifests/dist/*"] } }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], "exclude": ["node_modules"] -} \ No newline at end of file +} diff --git a/package.json b/package.json index a823060..7889f76 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ }, "packageManager": "pnpm@10.20.0", "workspaces": [ - "packages/*" + "packages/*", + "apps/*" ], "scripts": { "clean": "pnpm -r clean", diff --git a/interweb/packages/client/README.md b/packages/client/README.md similarity index 93% rename from interweb/packages/client/README.md rename to packages/client/README.md index 07ff286..395799f 100644 --- a/interweb/packages/client/README.md +++ b/packages/client/README.md @@ -1,11 +1,11 @@ -# @interweb/client +# @kubernetesjs/client ## Postgres (CloudNativePG) Quick Deploy Assumes the CloudNativePG CRDs/operator are already installed. Then, from code: ```ts -import { Client } from "@interweb/client"; +import { Client } from "@kubernetesjs/client"; const client = new Client({ // Optionally set kubeconfig/context/namespace/restEndpoint diff --git a/interweb/packages/client/__fixtures__/config/setup.cnpg-minio.yaml b/packages/client/__fixtures__/config/setup.cnpg-minio.yaml similarity index 100% rename from interweb/packages/client/__fixtures__/config/setup.cnpg-minio.yaml rename to packages/client/__fixtures__/config/setup.cnpg-minio.yaml diff --git a/interweb/packages/client/__fixtures__/config/setup.config.yaml b/packages/client/__fixtures__/config/setup.config.yaml similarity index 100% rename from interweb/packages/client/__fixtures__/config/setup.config.yaml rename to packages/client/__fixtures__/config/setup.config.yaml diff --git a/interweb/packages/client/__fixtures__/config/setup.simple.yaml b/packages/client/__fixtures__/config/setup.simple.yaml similarity index 100% rename from interweb/packages/client/__fixtures__/config/setup.simple.yaml rename to packages/client/__fixtures__/config/setup.simple.yaml diff --git a/interweb/packages/client/__fixtures__/manifests/apply.configmap.yaml b/packages/client/__fixtures__/manifests/apply.configmap.yaml similarity index 100% rename from interweb/packages/client/__fixtures__/manifests/apply.configmap.yaml rename to packages/client/__fixtures__/manifests/apply.configmap.yaml diff --git a/interweb/packages/client/__tests__/e2e/apply.ingress-nginx.test.ts b/packages/client/__tests__/e2e/apply.ingress-nginx.test.ts similarity index 92% rename from interweb/packages/client/__tests__/e2e/apply.ingress-nginx.test.ts rename to packages/client/__tests__/e2e/apply.ingress-nginx.test.ts index 3ad1d08..102279a 100644 --- a/interweb/packages/client/__tests__/e2e/apply.ingress-nginx.test.ts +++ b/packages/client/__tests__/e2e/apply.ingress-nginx.test.ts @@ -1,5 +1,5 @@ -import { InterwebClient as InterwebKubernetesClient } from "@interweb/interwebjs"; -import { getOperatorResources } from "@interweb/manifests"; +import { InterwebClient as InterwebKubernetesClient } from "@kubernetesjs/ops"; +import { getOperatorResources } from "@kubernetesjs/manifests"; import { SetupClient } from "../../src/setup"; import { ensureNamespaceReady, ensureNamespaceExists, forceDeleteNamespace } from "../utils/test-utils"; import { globalCleanup } from "../setup/e2e-setup"; diff --git a/interweb/packages/client/__tests__/e2e/apply.test.ts b/packages/client/__tests__/e2e/apply.test.ts similarity index 94% rename from interweb/packages/client/__tests__/e2e/apply.test.ts rename to packages/client/__tests__/e2e/apply.test.ts index f704782..d36251c 100644 --- a/interweb/packages/client/__tests__/e2e/apply.test.ts +++ b/packages/client/__tests__/e2e/apply.test.ts @@ -1,11 +1,11 @@ import * as fs from "fs"; import * as path from "path"; import * as yaml from "js-yaml"; -import { InterwebClient as InterwebKubernetesClient } from "@interweb/interwebjs"; +import { InterwebClient as InterwebKubernetesClient } from "@kubernetesjs/ops"; import { SetupClient } from "../../src/setup"; // Assumes a local cluster is reachable via kubectl proxy. -// Start proxy before running: pnpm --filter @interweb/client proxy +// Start proxy before running: pnpm --filter @kubernetesjs/client proxy // Optionally set K8S_API to your API server URL. jest.setTimeout(120_000); diff --git a/interweb/packages/client/__tests__/e2e/e2e.delete.client.test.ts b/packages/client/__tests__/e2e/e2e.delete.client.test.ts similarity index 90% rename from interweb/packages/client/__tests__/e2e/e2e.delete.client.test.ts rename to packages/client/__tests__/e2e/e2e.delete.client.test.ts index 8ba69e0..b01de28 100644 --- a/interweb/packages/client/__tests__/e2e/e2e.delete.client.test.ts +++ b/packages/client/__tests__/e2e/e2e.delete.client.test.ts @@ -1,11 +1,11 @@ import * as path from "path"; -import { InterwebClient as InterwebKubernetesClient } from "@interweb/interwebjs"; +import { InterwebClient as InterwebKubernetesClient } from "@kubernetesjs/ops"; import { SetupClient } from "../../src/setup"; import { ConfigLoader } from "../../src/config-loader"; import type { ClusterSetupConfig } from "../../src/types"; // Lightweight e2e wiring against a running cluster (via kubectl proxy). -// Start proxy before running: pnpm --filter @interweb/client proxy +// Start proxy before running: pnpm --filter @kubernetesjs/client proxy // Optionally set K8S_API to your API server URL. jest.setTimeout(60_000); diff --git a/interweb/packages/client/__tests__/e2e/e2e.postgres.test.ts b/packages/client/__tests__/e2e/e2e.postgres.test.ts similarity index 98% rename from interweb/packages/client/__tests__/e2e/e2e.postgres.test.ts rename to packages/client/__tests__/e2e/e2e.postgres.test.ts index dce9789..221b00b 100644 --- a/interweb/packages/client/__tests__/e2e/e2e.postgres.test.ts +++ b/packages/client/__tests__/e2e/e2e.postgres.test.ts @@ -1,4 +1,4 @@ -import { InterwebClient as InterwebKubernetesClient } from "@interweb/interwebjs"; +import { InterwebClient as InterwebKubernetesClient } from "@kubernetesjs/ops"; import { SetupClient } from "../../src/setup"; import { Client } from "../../src/client"; import { PostgresDeployer } from "../../src/deployers/postgres"; diff --git a/interweb/packages/client/__tests__/e2e/e2e.setup.client.test.ts b/packages/client/__tests__/e2e/e2e.setup.client.test.ts similarity index 93% rename from interweb/packages/client/__tests__/e2e/e2e.setup.client.test.ts rename to packages/client/__tests__/e2e/e2e.setup.client.test.ts index 210b45b..3a87f7c 100644 --- a/interweb/packages/client/__tests__/e2e/e2e.setup.client.test.ts +++ b/packages/client/__tests__/e2e/e2e.setup.client.test.ts @@ -1,5 +1,5 @@ import * as path from "path"; -import { InterwebClient as InterwebKubernetesClient } from "@interweb/interwebjs"; +import { InterwebClient as InterwebKubernetesClient } from "@kubernetesjs/ops"; import { SetupClient } from "../../src/setup"; import { ConfigLoader } from "../../src/config-loader"; import type { ClusterSetupConfig } from "../../src/types"; @@ -7,7 +7,7 @@ import { TestCleanupRegistry } from "../utils/test-utils"; import { globalCleanup } from "../setup/e2e-setup"; // Lightweight e2e wiring against a running cluster (via kubectl proxy). -// Start proxy before running: pnpm --filter @interweb/client proxy +// Start proxy before running: pnpm --filter @kubernetesjs/client proxy // Optionally set K8S_API to your API server URL. jest.setTimeout(15 * 60 * 1000); // 15 minutes for setup operations diff --git a/interweb/packages/client/__tests__/e2e/e2e.setup.operator.test.ts b/packages/client/__tests__/e2e/e2e.setup.operator.test.ts similarity index 97% rename from interweb/packages/client/__tests__/e2e/e2e.setup.operator.test.ts rename to packages/client/__tests__/e2e/e2e.setup.operator.test.ts index ff73fdc..014c6d2 100644 --- a/interweb/packages/client/__tests__/e2e/e2e.setup.operator.test.ts +++ b/packages/client/__tests__/e2e/e2e.setup.operator.test.ts @@ -1,4 +1,4 @@ -import { InterwebClient as InterwebKubernetesClient } from "@interweb/interwebjs"; +import { InterwebClient as InterwebKubernetesClient } from "@kubernetesjs/ops"; import { SetupClient } from "../../src/setup"; import type { ClusterSetupConfig, OperatorConfig } from "../../src/types"; diff --git a/interweb/packages/client/__tests__/integration/apply.cert-manager.test.ts b/packages/client/__tests__/integration/apply.cert-manager.test.ts similarity index 98% rename from interweb/packages/client/__tests__/integration/apply.cert-manager.test.ts rename to packages/client/__tests__/integration/apply.cert-manager.test.ts index ae9b8ed..9f558c2 100644 --- a/interweb/packages/client/__tests__/integration/apply.cert-manager.test.ts +++ b/packages/client/__tests__/integration/apply.cert-manager.test.ts @@ -1,6 +1,6 @@ import { SetupClient } from "../../src/setup"; import type { ClusterSetupConfig } from "../../src/types"; -import { getOperatorResources } from "@interweb/manifests"; +import { getOperatorResources } from "@kubernetesjs/manifests"; describe("SetupClient.installOperators integration", () => { const operatorDetails: Record< diff --git a/interweb/packages/client/__tests__/integration/apply.manifests.test.ts b/packages/client/__tests__/integration/apply.manifests.test.ts similarity index 97% rename from interweb/packages/client/__tests__/integration/apply.manifests.test.ts rename to packages/client/__tests__/integration/apply.manifests.test.ts index 1727333..4716f51 100644 --- a/interweb/packages/client/__tests__/integration/apply.manifests.test.ts +++ b/packages/client/__tests__/integration/apply.manifests.test.ts @@ -1,5 +1,5 @@ import { K8sApplier } from "../../src/apply"; -import type { KubernetesResource } from "@interweb/interwebjs"; +import type { KubernetesResource } from "@kubernetesjs/ops"; describe("K8sApplier integration with discovery", () => { const kubeClient = { diff --git a/interweb/packages/client/__tests__/setup/e2e-setup.ts b/packages/client/__tests__/setup/e2e-setup.ts similarity index 100% rename from interweb/packages/client/__tests__/setup/e2e-setup.ts rename to packages/client/__tests__/setup/e2e-setup.ts diff --git a/interweb/packages/client/__tests__/unit/config-loader.test.ts b/packages/client/__tests__/unit/config-loader.test.ts similarity index 100% rename from interweb/packages/client/__tests__/unit/config-loader.test.ts rename to packages/client/__tests__/unit/config-loader.test.ts diff --git a/interweb/packages/client/__tests__/unit/manifests.test.ts b/packages/client/__tests__/unit/manifests.test.ts similarity index 91% rename from interweb/packages/client/__tests__/unit/manifests.test.ts rename to packages/client/__tests__/unit/manifests.test.ts index 230379d..c85227d 100644 --- a/interweb/packages/client/__tests__/unit/manifests.test.ts +++ b/packages/client/__tests__/unit/manifests.test.ts @@ -1,4 +1,4 @@ -import { getOperatorResources } from "@interweb/manifests"; +import { getOperatorResources } from "@kubernetesjs/manifests"; describe("manifests: metadata coverage", () => { const operatorNamespaceMap = { diff --git a/interweb/packages/client/__tests__/utils/test-utils.ts b/packages/client/__tests__/utils/test-utils.ts similarity index 98% rename from interweb/packages/client/__tests__/utils/test-utils.ts rename to packages/client/__tests__/utils/test-utils.ts index fafada2..c799d9e 100644 --- a/interweb/packages/client/__tests__/utils/test-utils.ts +++ b/packages/client/__tests__/utils/test-utils.ts @@ -1,4 +1,4 @@ -import { InterwebClient as InterwebKubernetesClient } from '@interweb/interwebjs'; +import { InterwebClient as InterwebKubernetesClient } from '@kubernetesjs/ops'; /** * Ensures a namespace is ready for use by waiting for any terminating namespace to be fully deleted diff --git a/interweb/packages/client/jest.config.js b/packages/client/jest.config.js similarity index 100% rename from interweb/packages/client/jest.config.js rename to packages/client/jest.config.js diff --git a/interweb/packages/client/package.json b/packages/client/package.json similarity index 87% rename from interweb/packages/client/package.json rename to packages/client/package.json index 25df043..7e73d12 100644 --- a/interweb/packages/client/package.json +++ b/packages/client/package.json @@ -1,7 +1,7 @@ { - "name": "@interweb/client", + "name": "@kubernetesjs/client", "version": "0.0.1", - "description": "Client for interweb", + "description": "Client for KubernetesJS ops workflows", "main": "./index.js", "types": "./index.d.ts", "module": "./esm/index.js", @@ -24,8 +24,8 @@ "operators:teardown": "ts-node --swc scripts/setup-operators.ts teardown --config __fixtures__/config/setup.cnpg-minio.yaml" }, "dependencies": { - "@interweb/interwebjs": "workspace:^", - "@interweb/manifests": "workspace:^", + "@kubernetesjs/ops": "workspace:^", + "@kubernetesjs/manifests": "workspace:^", "axios": "^1.7.2", "chalk": "^4.1.0", "js-yaml": "^4.1.0", @@ -36,4 +36,4 @@ "@types/pg": "^8.11.10", "ts-node": "^10.9.2" } -} \ No newline at end of file +} diff --git a/interweb/packages/client/scripts/setup-operators.ts b/packages/client/scripts/setup-operators.ts similarity index 98% rename from interweb/packages/client/scripts/setup-operators.ts rename to packages/client/scripts/setup-operators.ts index fecba09..afa619b 100644 --- a/interweb/packages/client/scripts/setup-operators.ts +++ b/packages/client/scripts/setup-operators.ts @@ -2,8 +2,8 @@ import { promises as fs } from 'fs'; import path from 'path'; import { load as loadYaml } from 'js-yaml'; import { spawnSync } from 'child_process'; -import { InterwebClient as InterwebKubernetesClient } from '@interweb/interwebjs'; -import { getOperatorIds } from '@interweb/manifests'; +import { InterwebClient as InterwebKubernetesClient } from '@kubernetesjs/ops'; +import { getOperatorIds } from '@kubernetesjs/manifests'; import { SetupClient } from '../src/setup'; import { ClusterSetupConfig, OperatorConfig } from '../src/types'; diff --git a/interweb/packages/client/src/apply.ts b/packages/client/src/apply.ts similarity index 99% rename from interweb/packages/client/src/apply.ts rename to packages/client/src/apply.ts index 94e3cbc..72bef9b 100644 --- a/interweb/packages/client/src/apply.ts +++ b/packages/client/src/apply.ts @@ -1,4 +1,4 @@ -import { InterwebClient as InterwebKubernetesClient, APIResourceList, APIResource, KubernetesResource, ObjectMeta } from '@interweb/interwebjs'; +import { InterwebClient as InterwebKubernetesClient, APIResourceList, APIResource, KubernetesResource, ObjectMeta } from '@kubernetesjs/ops'; type GroupVersion = { group: string | null; version: string; key: string }; diff --git a/interweb/packages/client/src/client.ts b/packages/client/src/client.ts similarity index 99% rename from interweb/packages/client/src/client.ts rename to packages/client/src/client.ts index 20bad06..ffacf16 100644 --- a/interweb/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -1,5 +1,5 @@ import chalk from "chalk"; -import { InterwebClient as InterwebKubernetesClient } from "@interweb/interwebjs"; +import { InterwebClient as InterwebKubernetesClient } from "@kubernetesjs/ops"; import { ConfigLoader } from "./config-loader"; import { SetupClient } from "./setup"; import { diff --git a/interweb/packages/client/src/config-loader.ts b/packages/client/src/config-loader.ts similarity index 100% rename from interweb/packages/client/src/config-loader.ts rename to packages/client/src/config-loader.ts diff --git a/interweb/packages/client/src/deployers/index.ts b/packages/client/src/deployers/index.ts similarity index 100% rename from interweb/packages/client/src/deployers/index.ts rename to packages/client/src/deployers/index.ts diff --git a/interweb/packages/client/src/deployers/minio.ts b/packages/client/src/deployers/minio.ts similarity index 99% rename from interweb/packages/client/src/deployers/minio.ts rename to packages/client/src/deployers/minio.ts index 2814ad6..b911c72 100644 --- a/interweb/packages/client/src/deployers/minio.ts +++ b/packages/client/src/deployers/minio.ts @@ -5,7 +5,7 @@ import { AppsV1Deployment, Service, KubernetesResource, -} from '@interweb/interwebjs'; +} from '@kubernetesjs/ops'; import { SetupClient } from '../setup'; export interface MinioDeployOptions { diff --git a/interweb/packages/client/src/deployers/ollama.ts b/packages/client/src/deployers/ollama.ts similarity index 99% rename from interweb/packages/client/src/deployers/ollama.ts rename to packages/client/src/deployers/ollama.ts index e417518..e0e1edb 100644 --- a/interweb/packages/client/src/deployers/ollama.ts +++ b/packages/client/src/deployers/ollama.ts @@ -4,7 +4,7 @@ import { AppsV1Deployment, Service, KubernetesResource, -} from '@interweb/interwebjs'; +} from '@kubernetesjs/ops'; import { SetupClient } from '../setup'; export interface OllamaDeployOptions { diff --git a/interweb/packages/client/src/deployers/postgres.ts b/packages/client/src/deployers/postgres.ts similarity index 99% rename from interweb/packages/client/src/deployers/postgres.ts rename to packages/client/src/deployers/postgres.ts index f5576bb..6e39653 100644 --- a/interweb/packages/client/src/deployers/postgres.ts +++ b/packages/client/src/deployers/postgres.ts @@ -5,7 +5,7 @@ import { PostgresqlCnpgIoV1Cluster, PostgresqlCnpgIoV1Pooler, KubernetesResource, -} from '@interweb/interwebjs'; +} from '@kubernetesjs/ops'; import { SetupClient } from '../setup'; import { escapeIdentifier, escapeLiteral } from 'pg'; diff --git a/interweb/packages/client/src/deployers/presets/base.ts b/packages/client/src/deployers/presets/base.ts similarity index 97% rename from interweb/packages/client/src/deployers/presets/base.ts rename to packages/client/src/deployers/presets/base.ts index 8b9ffed..f65566f 100644 --- a/interweb/packages/client/src/deployers/presets/base.ts +++ b/packages/client/src/deployers/presets/base.ts @@ -1,4 +1,4 @@ -import { InterwebClient as InterwebKubernetesClient } from '@interweb/interwebjs'; +import { InterwebClient as InterwebKubernetesClient } from '@kubernetesjs/ops'; export interface TemplateDeployOptions { name?: string; diff --git a/interweb/packages/client/src/deployers/presets/metadata.ts b/packages/client/src/deployers/presets/metadata.ts similarity index 100% rename from interweb/packages/client/src/deployers/presets/metadata.ts rename to packages/client/src/deployers/presets/metadata.ts diff --git a/interweb/packages/client/src/deployers/presets/minio.ts b/packages/client/src/deployers/presets/minio.ts similarity index 94% rename from interweb/packages/client/src/deployers/presets/minio.ts rename to packages/client/src/deployers/presets/minio.ts index fc80fe5..c12239e 100644 --- a/interweb/packages/client/src/deployers/presets/minio.ts +++ b/packages/client/src/deployers/presets/minio.ts @@ -1,5 +1,5 @@ import { SimpleTemplateDeployer, SimpleTemplateConfig } from './simple'; -import { InterwebClient as InterwebKubernetesClient } from '@interweb/interwebjs'; +import { InterwebClient as InterwebKubernetesClient } from '@kubernetesjs/ops'; const minioConfig: SimpleTemplateConfig = { image: 'minio/minio:latest', diff --git a/interweb/packages/client/src/deployers/presets/ollama.ts b/packages/client/src/deployers/presets/ollama.ts similarity index 91% rename from interweb/packages/client/src/deployers/presets/ollama.ts rename to packages/client/src/deployers/presets/ollama.ts index 86a16b5..7e95caa 100644 --- a/interweb/packages/client/src/deployers/presets/ollama.ts +++ b/packages/client/src/deployers/presets/ollama.ts @@ -1,5 +1,5 @@ import { SimpleTemplateDeployer, SimpleTemplateConfig } from './simple'; -import { InterwebClient as InterwebKubernetesClient } from '@interweb/interwebjs'; +import { InterwebClient as InterwebKubernetesClient } from '@kubernetesjs/ops'; const ollamaConfig: SimpleTemplateConfig = { image: 'ollama/ollama:latest', diff --git a/interweb/packages/client/src/deployers/presets/postgres.ts b/packages/client/src/deployers/presets/postgres.ts similarity index 98% rename from interweb/packages/client/src/deployers/presets/postgres.ts rename to packages/client/src/deployers/presets/postgres.ts index 8a1a327..14de535 100644 --- a/interweb/packages/client/src/deployers/presets/postgres.ts +++ b/packages/client/src/deployers/presets/postgres.ts @@ -6,7 +6,7 @@ import { TemplateUninstallResult, } from './base'; import { PostgresDeployer, PostgresDeployOptions, DeployResult, connectionInfo } from '../postgres'; -import { InterwebClient as InterwebKubernetesClient } from '@interweb/interwebjs'; +import { InterwebClient as InterwebKubernetesClient } from '@kubernetesjs/ops'; /** * Wrapper to adapt PostgresDeployer to the template interface diff --git a/interweb/packages/client/src/deployers/presets/simple.ts b/packages/client/src/deployers/presets/simple.ts similarity index 99% rename from interweb/packages/client/src/deployers/presets/simple.ts rename to packages/client/src/deployers/presets/simple.ts index 2df0bea..2efc163 100644 --- a/interweb/packages/client/src/deployers/presets/simple.ts +++ b/packages/client/src/deployers/presets/simple.ts @@ -1,4 +1,4 @@ -import { KubernetesResource } from '@interweb/interwebjs'; +import { KubernetesResource } from '@kubernetesjs/ops'; import { applyKubernetesResource, deleteKubernetesResource } from '../../apply'; import { BaseTemplateDeployer, TemplateDeployOptions, TemplateDeployResult, TemplateUninstallOptions, TemplateUninstallResult } from './base'; diff --git a/interweb/packages/client/src/hack.ts b/packages/client/src/hack.ts similarity index 100% rename from interweb/packages/client/src/hack.ts rename to packages/client/src/hack.ts diff --git a/interweb/packages/client/src/index.ts b/packages/client/src/index.ts similarity index 100% rename from interweb/packages/client/src/index.ts rename to packages/client/src/index.ts diff --git a/interweb/packages/client/src/setup.ts b/packages/client/src/setup.ts similarity index 99% rename from interweb/packages/client/src/setup.ts rename to packages/client/src/setup.ts index 5e59ce7..0cc7db4 100644 --- a/interweb/packages/client/src/setup.ts +++ b/packages/client/src/setup.ts @@ -1,13 +1,13 @@ import { InterwebClient as InterwebKubernetesClient, KubernetesResource, -} from "@interweb/interwebjs"; +} from "@kubernetesjs/ops"; import { getOperatorIds, getOperatorResources, getOperatorVersions, getOperatorInfo, -} from "@interweb/manifests"; +} from "@kubernetesjs/manifests"; import { ClusterSetupConfig, ApplicationConfig, diff --git a/interweb/packages/client/src/types.ts b/packages/client/src/types.ts similarity index 100% rename from interweb/packages/client/src/types.ts rename to packages/client/src/types.ts diff --git a/interweb/packages/cli/tsconfig.esm.json b/packages/client/tsconfig.esm.json similarity index 100% rename from interweb/packages/cli/tsconfig.esm.json rename to packages/client/tsconfig.esm.json diff --git a/interweb/packages/client/tsconfig.json b/packages/client/tsconfig.json similarity index 100% rename from interweb/packages/client/tsconfig.json rename to packages/client/tsconfig.json diff --git a/interweb/packages/manifests/.gitignore b/packages/manifests/.gitignore similarity index 100% rename from interweb/packages/manifests/.gitignore rename to packages/manifests/.gitignore diff --git a/interweb/packages/manifests/README.md b/packages/manifests/README.md similarity index 76% rename from interweb/packages/manifests/README.md rename to packages/manifests/README.md index e9ce1b4..bae7aa2 100644 --- a/interweb/packages/manifests/README.md +++ b/packages/manifests/README.md @@ -1,13 +1,13 @@ -# @interweb/manifests +# @kubernetesjs/manifests Utilities and pinned Kubernetes operator manifests used by Interweb. Usage -- List operators: `pnpm --filter @interweb/manifests run pull -- --list` -- Pull all: `pnpm --filter @interweb/manifests run pull -- --all` -- Pull one: `pnpm --filter @interweb/manifests run pull -- --operator knative-serving --version v1.15.0` -- Generate JS manifests: `pnpm --filter @interweb/manifests run codegen` +- List operators: `pnpm --filter @kubernetesjs/manifests run pull -- --list` +- Pull all: `pnpm --filter @kubernetesjs/manifests run pull -- --all` +- Pull one: `pnpm --filter @kubernetesjs/manifests run pull -- --operator knative-serving --version v1.15.0` +- Generate JS manifests: `pnpm --filter @kubernetesjs/manifests run codegen` Layout diff --git a/interweb/packages/manifests/__tests__/unit/generated-vs-yaml.test.ts b/packages/manifests/__tests__/unit/generated-vs-yaml.test.ts similarity index 98% rename from interweb/packages/manifests/__tests__/unit/generated-vs-yaml.test.ts rename to packages/manifests/__tests__/unit/generated-vs-yaml.test.ts index 26f7ed3..28c15f5 100644 --- a/interweb/packages/manifests/__tests__/unit/generated-vs-yaml.test.ts +++ b/packages/manifests/__tests__/unit/generated-vs-yaml.test.ts @@ -28,7 +28,7 @@ function loadYamlDocsIfExists(file: string): K8s[] | undefined { } } -describe("@interweb/manifests generated artifacts", () => { +describe("@kubernetesjs/manifests generated artifacts", () => { it("exports consistent IDs and map shape", () => { const idsFromObjects = Object.keys(OPERATOR_OBJECTS).sort(); const idsFromIds = (OPERATOR_IDS || []).slice().sort(); diff --git a/interweb/packages/manifests/jest.config.js b/packages/manifests/jest.config.js similarity index 100% rename from interweb/packages/manifests/jest.config.js rename to packages/manifests/jest.config.js diff --git a/interweb/packages/manifests/operators/cert-manager.yaml b/packages/manifests/operators/cert-manager.yaml similarity index 100% rename from interweb/packages/manifests/operators/cert-manager.yaml rename to packages/manifests/operators/cert-manager.yaml diff --git a/interweb/packages/manifests/operators/cert-manager/v1.17.0.yaml b/packages/manifests/operators/cert-manager/v1.17.0.yaml similarity index 100% rename from interweb/packages/manifests/operators/cert-manager/v1.17.0.yaml rename to packages/manifests/operators/cert-manager/v1.17.0.yaml diff --git a/interweb/packages/manifests/operators/cloudnative-pg.yaml b/packages/manifests/operators/cloudnative-pg.yaml similarity index 100% rename from interweb/packages/manifests/operators/cloudnative-pg.yaml rename to packages/manifests/operators/cloudnative-pg.yaml diff --git a/interweb/packages/manifests/operators/cloudnative-pg/1.25.2.yaml b/packages/manifests/operators/cloudnative-pg/1.25.2.yaml similarity index 100% rename from interweb/packages/manifests/operators/cloudnative-pg/1.25.2.yaml rename to packages/manifests/operators/cloudnative-pg/1.25.2.yaml diff --git a/interweb/packages/manifests/operators/ingress-nginx.yaml b/packages/manifests/operators/ingress-nginx.yaml similarity index 100% rename from interweb/packages/manifests/operators/ingress-nginx.yaml rename to packages/manifests/operators/ingress-nginx.yaml diff --git a/interweb/packages/manifests/operators/ingress-nginx/4.11.2.yaml b/packages/manifests/operators/ingress-nginx/4.11.2.yaml similarity index 100% rename from interweb/packages/manifests/operators/ingress-nginx/4.11.2.yaml rename to packages/manifests/operators/ingress-nginx/4.11.2.yaml diff --git a/interweb/packages/manifests/operators/knative-serving.yaml b/packages/manifests/operators/knative-serving.yaml similarity index 100% rename from interweb/packages/manifests/operators/knative-serving.yaml rename to packages/manifests/operators/knative-serving.yaml diff --git a/interweb/packages/manifests/operators/knative-serving/v1.15.0.yaml b/packages/manifests/operators/knative-serving/v1.15.0.yaml similarity index 100% rename from interweb/packages/manifests/operators/knative-serving/v1.15.0.yaml rename to packages/manifests/operators/knative-serving/v1.15.0.yaml diff --git a/interweb/packages/manifests/operators/kube-prometheus-stack.yaml b/packages/manifests/operators/kube-prometheus-stack.yaml similarity index 100% rename from interweb/packages/manifests/operators/kube-prometheus-stack.yaml rename to packages/manifests/operators/kube-prometheus-stack.yaml diff --git a/interweb/packages/manifests/operators/kube-prometheus-stack/77.5.0.yaml b/packages/manifests/operators/kube-prometheus-stack/77.5.0.yaml similarity index 100% rename from interweb/packages/manifests/operators/kube-prometheus-stack/77.5.0.yaml rename to packages/manifests/operators/kube-prometheus-stack/77.5.0.yaml diff --git a/interweb/packages/manifests/operators/minio-operator.yaml b/packages/manifests/operators/minio-operator.yaml similarity index 100% rename from interweb/packages/manifests/operators/minio-operator.yaml rename to packages/manifests/operators/minio-operator.yaml diff --git a/interweb/packages/manifests/operators/minio-operator/7.1.1.yaml b/packages/manifests/operators/minio-operator/7.1.1.yaml similarity index 100% rename from interweb/packages/manifests/operators/minio-operator/7.1.1.yaml rename to packages/manifests/operators/minio-operator/7.1.1.yaml diff --git a/interweb/packages/manifests/package.json b/packages/manifests/package.json similarity index 85% rename from interweb/packages/manifests/package.json rename to packages/manifests/package.json index 83a2868..124debd 100644 --- a/interweb/packages/manifests/package.json +++ b/packages/manifests/package.json @@ -1,7 +1,7 @@ { - "name": "@interweb/manifests", + "name": "@kubernetesjs/manifests", "version": "0.0.1", - "description": "Kubernetes manifests for interweb operators", + "description": "Curated operator manifests for KubernetesJS ops", "main": "./index.js", "types": "./index.d.ts", "module": "./esm/index.js", @@ -23,7 +23,7 @@ }, "dependencies": { "js-yaml": "^4.1.0", - "@interweb/interwebjs": "workspace:*" + "@kubernetesjs/ops": "workspace:*" }, "devDependencies": { "@types/js-yaml": "^4.0.5", @@ -31,4 +31,4 @@ "@babel/types": "^7.25.0", "@types/babel__generator": "^7.6.8" } -} \ No newline at end of file +} diff --git a/interweb/packages/manifests/scripts/codegen-operators.ts b/packages/manifests/scripts/codegen-operators.ts similarity index 99% rename from interweb/packages/manifests/scripts/codegen-operators.ts rename to packages/manifests/scripts/codegen-operators.ts index 05ed4db..80a7b2d 100755 --- a/interweb/packages/manifests/scripts/codegen-operators.ts +++ b/packages/manifests/scripts/codegen-operators.ts @@ -282,7 +282,7 @@ function buildOperatorObjectsAst(op: OperatorDocs, typeMap: Map) specifiers.unshift( t.importSpecifier(t.identifier('KubernetesResource'), t.identifier('KubernetesResource')) ); - const importDecl = t.importDeclaration(specifiers, t.stringLiteral('@interweb/interwebjs')); + const importDecl = t.importDeclaration(specifiers, t.stringLiteral('@kubernetesjs/ops')); importDecl.importKind = 'type'; body.push(importDecl); @@ -391,10 +391,10 @@ function emitOperatorObjectModules(typeMap: Map, models?: Operat const indexBody: t.Statement[] = []; // Header comment const header = `* Auto-generated aggregator of operator objects`; - // import type { KubernetesResource } from '@interweb/interwebjs' + // import type { KubernetesResource } from '@kubernetesjs/ops' const typeImport = t.importDeclaration( [t.importSpecifier(t.identifier('KubernetesResource'), t.identifier('KubernetesResource'))], - t.stringLiteral('@interweb/interwebjs') + t.stringLiteral('@kubernetesjs/ops') ); typeImport.importKind = 'type'; indexBody.push(typeImport); diff --git a/interweb/packages/manifests/scripts/pull-manifests.ts b/packages/manifests/scripts/pull-manifests.ts similarity index 100% rename from interweb/packages/manifests/scripts/pull-manifests.ts rename to packages/manifests/scripts/pull-manifests.ts diff --git a/interweb/packages/manifests/src/generated/cert-manager.ts b/packages/manifests/src/generated/cert-manager.ts similarity index 99% rename from interweb/packages/manifests/src/generated/cert-manager.ts rename to packages/manifests/src/generated/cert-manager.ts index c0d94e2..a1ad5dd 100644 --- a/interweb/packages/manifests/src/generated/cert-manager.ts +++ b/packages/manifests/src/generated/cert-manager.ts @@ -1,5 +1,5 @@ /** Auto-generated typed resources for operator: cert-manager*/ -import type { KubernetesResource, AdmissionregistrationK8sIoV1MutatingWebhookConfiguration, AdmissionregistrationK8sIoV1ValidatingWebhookConfiguration, ApiextensionsK8sIoV1CustomResourceDefinition, AppsV1Deployment, BatchV1Job, Namespace, RbacAuthorizationK8sIoV1ClusterRole, RbacAuthorizationK8sIoV1ClusterRoleBinding, RbacAuthorizationK8sIoV1Role, RbacAuthorizationK8sIoV1RoleBinding, Service, ServiceAccount } from "@interweb/interwebjs"; +import type { KubernetesResource, AdmissionregistrationK8sIoV1MutatingWebhookConfiguration, AdmissionregistrationK8sIoV1ValidatingWebhookConfiguration, ApiextensionsK8sIoV1CustomResourceDefinition, AppsV1Deployment, BatchV1Job, Namespace, RbacAuthorizationK8sIoV1ClusterRole, RbacAuthorizationK8sIoV1ClusterRoleBinding, RbacAuthorizationK8sIoV1Role, RbacAuthorizationK8sIoV1RoleBinding, Service, ServiceAccount } from "@kubernetesjs/ops"; export const Namespace_CertManager: Namespace = { apiVersion: "v1", kind: "Namespace", diff --git a/interweb/packages/manifests/src/generated/cloudnative-pg.ts b/packages/manifests/src/generated/cloudnative-pg.ts similarity index 99% rename from interweb/packages/manifests/src/generated/cloudnative-pg.ts rename to packages/manifests/src/generated/cloudnative-pg.ts index 44d6316..0d98282 100644 --- a/interweb/packages/manifests/src/generated/cloudnative-pg.ts +++ b/packages/manifests/src/generated/cloudnative-pg.ts @@ -1,5 +1,5 @@ /** Auto-generated typed resources for operator: cloudnative-pg*/ -import type { KubernetesResource, AdmissionregistrationK8sIoV1MutatingWebhookConfiguration, AdmissionregistrationK8sIoV1ValidatingWebhookConfiguration, ApiextensionsK8sIoV1CustomResourceDefinition, AppsV1Deployment, ConfigMap, Namespace, RbacAuthorizationK8sIoV1ClusterRole, RbacAuthorizationK8sIoV1ClusterRoleBinding, Service, ServiceAccount } from "@interweb/interwebjs"; +import type { KubernetesResource, AdmissionregistrationK8sIoV1MutatingWebhookConfiguration, AdmissionregistrationK8sIoV1ValidatingWebhookConfiguration, ApiextensionsK8sIoV1CustomResourceDefinition, AppsV1Deployment, ConfigMap, Namespace, RbacAuthorizationK8sIoV1ClusterRole, RbacAuthorizationK8sIoV1ClusterRoleBinding, Service, ServiceAccount } from "@kubernetesjs/ops"; export const Namespace_CnpgSystem: Namespace = { apiVersion: "v1", kind: "Namespace", diff --git a/interweb/packages/manifests/src/generated/index.ts b/packages/manifests/src/generated/index.ts similarity index 96% rename from interweb/packages/manifests/src/generated/index.ts rename to packages/manifests/src/generated/index.ts index 98a7a9c..a5635ff 100644 --- a/interweb/packages/manifests/src/generated/index.ts +++ b/packages/manifests/src/generated/index.ts @@ -1,5 +1,5 @@ /** Auto-generated aggregator of operator objects*/ -import type { KubernetesResource } from "@interweb/interwebjs"; +import type { KubernetesResource } from "@kubernetesjs/ops"; import CertManager from "./cert-manager"; import CloudnativePg from "./cloudnative-pg"; import IngressNginx from "./ingress-nginx"; diff --git a/interweb/packages/manifests/src/generated/ingress-nginx.ts b/packages/manifests/src/generated/ingress-nginx.ts similarity index 99% rename from interweb/packages/manifests/src/generated/ingress-nginx.ts rename to packages/manifests/src/generated/ingress-nginx.ts index 8da671f..7584226 100644 --- a/interweb/packages/manifests/src/generated/ingress-nginx.ts +++ b/packages/manifests/src/generated/ingress-nginx.ts @@ -1,5 +1,5 @@ /** Auto-generated typed resources for operator: ingress-nginx*/ -import type { KubernetesResource, AdmissionregistrationK8sIoV1ValidatingWebhookConfiguration, AppsV1Deployment, BatchV1Job, ConfigMap, Namespace, NetworkingK8sIoV1IngressClass, RbacAuthorizationK8sIoV1ClusterRole, RbacAuthorizationK8sIoV1ClusterRoleBinding, RbacAuthorizationK8sIoV1Role, RbacAuthorizationK8sIoV1RoleBinding, Service, ServiceAccount } from "@interweb/interwebjs"; +import type { KubernetesResource, AdmissionregistrationK8sIoV1ValidatingWebhookConfiguration, AppsV1Deployment, BatchV1Job, ConfigMap, Namespace, NetworkingK8sIoV1IngressClass, RbacAuthorizationK8sIoV1ClusterRole, RbacAuthorizationK8sIoV1ClusterRoleBinding, RbacAuthorizationK8sIoV1Role, RbacAuthorizationK8sIoV1RoleBinding, Service, ServiceAccount } from "@kubernetesjs/ops"; export const Namespace_IngressNginx: Namespace = { apiVersion: "v1", kind: "Namespace", diff --git a/interweb/packages/manifests/src/generated/knative-serving.ts b/packages/manifests/src/generated/knative-serving.ts similarity index 99% rename from interweb/packages/manifests/src/generated/knative-serving.ts rename to packages/manifests/src/generated/knative-serving.ts index b507577..228743a 100644 --- a/interweb/packages/manifests/src/generated/knative-serving.ts +++ b/packages/manifests/src/generated/knative-serving.ts @@ -1,5 +1,5 @@ /** Auto-generated typed resources for operator: knative-serving*/ -import type { KubernetesResource, AdmissionregistrationK8sIoV1MutatingWebhookConfiguration, AdmissionregistrationK8sIoV1ValidatingWebhookConfiguration, ApiextensionsK8sIoV1CustomResourceDefinition, AppsV1Deployment, AutoscalingV2HorizontalPodAutoscaler, CachingInternalKnativeDevV1alpha1Image, ConfigMap, Namespace, NetworkingInternalKnativeDevV1alpha1Certificate, PolicyV1PodDisruptionBudget, RbacAuthorizationK8sIoV1ClusterRole, RbacAuthorizationK8sIoV1ClusterRoleBinding, RbacAuthorizationK8sIoV1Role, RbacAuthorizationK8sIoV1RoleBinding, Secret, Service, ServiceAccount } from "@interweb/interwebjs"; +import type { KubernetesResource, AdmissionregistrationK8sIoV1MutatingWebhookConfiguration, AdmissionregistrationK8sIoV1ValidatingWebhookConfiguration, ApiextensionsK8sIoV1CustomResourceDefinition, AppsV1Deployment, AutoscalingV2HorizontalPodAutoscaler, CachingInternalKnativeDevV1alpha1Image, ConfigMap, Namespace, NetworkingInternalKnativeDevV1alpha1Certificate, PolicyV1PodDisruptionBudget, RbacAuthorizationK8sIoV1ClusterRole, RbacAuthorizationK8sIoV1ClusterRoleBinding, RbacAuthorizationK8sIoV1Role, RbacAuthorizationK8sIoV1RoleBinding, Secret, Service, ServiceAccount } from "@kubernetesjs/ops"; export const CustomResourceDefinition_CertificatesNetworkingInternalKnativeDev: ApiextensionsK8sIoV1CustomResourceDefinition = { apiVersion: "apiextensions.k8s.io/v1", kind: "CustomResourceDefinition", diff --git a/interweb/packages/manifests/src/generated/kube-prometheus-stack.ts b/packages/manifests/src/generated/kube-prometheus-stack.ts similarity index 99% rename from interweb/packages/manifests/src/generated/kube-prometheus-stack.ts rename to packages/manifests/src/generated/kube-prometheus-stack.ts index c3c1b01..d5cc9ae 100644 --- a/interweb/packages/manifests/src/generated/kube-prometheus-stack.ts +++ b/packages/manifests/src/generated/kube-prometheus-stack.ts @@ -1,5 +1,5 @@ /** Auto-generated typed resources for operator: kube-prometheus-stack*/ -import type { KubernetesResource, AdmissionregistrationK8sIoV1MutatingWebhookConfiguration, AdmissionregistrationK8sIoV1ValidatingWebhookConfiguration, ApiextensionsK8sIoV1CustomResourceDefinition, AppsV1DaemonSet, AppsV1Deployment, BatchV1Job, ConfigMap, MonitoringCoreosComV1Alertmanager, MonitoringCoreosComV1Prometheus, MonitoringCoreosComV1PrometheusRule, MonitoringCoreosComV1ServiceMonitor, Namespace, PersistentVolumeClaim, Pod, RbacAuthorizationK8sIoV1ClusterRole, RbacAuthorizationK8sIoV1ClusterRoleBinding, RbacAuthorizationK8sIoV1Role, RbacAuthorizationK8sIoV1RoleBinding, Secret, Service, ServiceAccount } from "@interweb/interwebjs"; +import type { KubernetesResource, AdmissionregistrationK8sIoV1MutatingWebhookConfiguration, AdmissionregistrationK8sIoV1ValidatingWebhookConfiguration, ApiextensionsK8sIoV1CustomResourceDefinition, AppsV1DaemonSet, AppsV1Deployment, BatchV1Job, ConfigMap, MonitoringCoreosComV1Alertmanager, MonitoringCoreosComV1Prometheus, MonitoringCoreosComV1PrometheusRule, MonitoringCoreosComV1ServiceMonitor, Namespace, PersistentVolumeClaim, Pod, RbacAuthorizationK8sIoV1ClusterRole, RbacAuthorizationK8sIoV1ClusterRoleBinding, RbacAuthorizationK8sIoV1Role, RbacAuthorizationK8sIoV1RoleBinding, Secret, Service, ServiceAccount } from "@kubernetesjs/ops"; export const Namespace_Monitoring: Namespace = { apiVersion: "v1", kind: "Namespace", diff --git a/interweb/packages/manifests/src/generated/minio-operator.ts b/packages/manifests/src/generated/minio-operator.ts similarity index 99% rename from interweb/packages/manifests/src/generated/minio-operator.ts rename to packages/manifests/src/generated/minio-operator.ts index df0dafb..caac0c0 100644 --- a/interweb/packages/manifests/src/generated/minio-operator.ts +++ b/packages/manifests/src/generated/minio-operator.ts @@ -1,5 +1,5 @@ /** Auto-generated typed resources for operator: minio-operator*/ -import type { KubernetesResource, ApiextensionsK8sIoV1CustomResourceDefinition, AppsV1Deployment, Namespace, RbacAuthorizationK8sIoV1ClusterRole, RbacAuthorizationK8sIoV1ClusterRoleBinding, Service, ServiceAccount } from "@interweb/interwebjs"; +import type { KubernetesResource, ApiextensionsK8sIoV1CustomResourceDefinition, AppsV1Deployment, Namespace, RbacAuthorizationK8sIoV1ClusterRole, RbacAuthorizationK8sIoV1ClusterRoleBinding, Service, ServiceAccount } from "@kubernetesjs/ops"; export const Namespace_MinioOperator: Namespace = { apiVersion: "v1", kind: "Namespace", diff --git a/interweb/packages/manifests/src/index.ts b/packages/manifests/src/index.ts similarity index 97% rename from interweb/packages/manifests/src/index.ts rename to packages/manifests/src/index.ts index cac9ed9..6ec8181 100644 --- a/interweb/packages/manifests/src/index.ts +++ b/packages/manifests/src/index.ts @@ -3,7 +3,7 @@ import * as fs from 'fs'; import * as path from 'path'; import { createRequire } from 'module'; import { OPERATOR_OBJECTS, OperatorObjectModule, OPERATOR_VERSIONS, OPERATOR_MAP, OPERATOR_IDS } from './generated'; -import { KubernetesResource } from '@interweb/interwebjs'; +import { KubernetesResource } from '@kubernetesjs/ops'; // Optional metadata for UIs: display name, description, docs, and (optionally) canonical namespaces export interface OperatorCatalogEntry { diff --git a/interweb/packages/manifests/tsconfig.esm.json b/packages/manifests/tsconfig.esm.json similarity index 100% rename from interweb/packages/manifests/tsconfig.esm.json rename to packages/manifests/tsconfig.esm.json diff --git a/interweb/packages/manifests/tsconfig.json b/packages/manifests/tsconfig.json similarity index 100% rename from interweb/packages/manifests/tsconfig.json rename to packages/manifests/tsconfig.json diff --git a/interweb/packages/cli/README.md b/packages/ops-cli/README.md similarity index 100% rename from interweb/packages/cli/README.md rename to packages/ops-cli/README.md diff --git a/interweb/packages/cli/__fixtures__/config/deploy.config.yaml b/packages/ops-cli/__fixtures__/config/deploy.config.yaml similarity index 100% rename from interweb/packages/cli/__fixtures__/config/deploy.config.yaml rename to packages/ops-cli/__fixtures__/config/deploy.config.yaml diff --git a/interweb/packages/cli/__fixtures__/config/setup.config.yaml b/packages/ops-cli/__fixtures__/config/setup.config.yaml similarity index 100% rename from interweb/packages/cli/__fixtures__/config/setup.config.yaml rename to packages/ops-cli/__fixtures__/config/setup.config.yaml diff --git a/interweb/packages/cli/__tests__/k8s-utils.test.ts b/packages/ops-cli/__tests__/k8s-utils.test.ts similarity index 100% rename from interweb/packages/cli/__tests__/k8s-utils.test.ts rename to packages/ops-cli/__tests__/k8s-utils.test.ts diff --git a/interweb/packages/cli/__tests__/setup.test.ts b/packages/ops-cli/__tests__/setup.test.ts similarity index 99% rename from interweb/packages/cli/__tests__/setup.test.ts rename to packages/ops-cli/__tests__/setup.test.ts index caa5ffd..c890609 100644 --- a/interweb/packages/cli/__tests__/setup.test.ts +++ b/packages/ops-cli/__tests__/setup.test.ts @@ -2,7 +2,7 @@ import { Command } from 'commander'; import * as path from 'path'; // Mock dependencies first -jest.mock('@interweb/client'); +jest.mock('@kubernetesjs/client'); jest.mock('inquirer', () => ({ prompt: jest.fn() })); @@ -16,7 +16,7 @@ jest.mock('chalk', () => ({ bold: jest.fn((text) => text) })); -import { Client, ConfigLoader } from '@interweb/client'; +import { Client, ConfigLoader } from '@kubernetesjs/client'; import chalk from 'chalk'; import inquirer from 'inquirer'; import { createSetupCommand } from '../src/commands/setup'; diff --git a/interweb/packages/cli/__tests__/teardown.test.ts b/packages/ops-cli/__tests__/teardown.test.ts similarity index 99% rename from interweb/packages/cli/__tests__/teardown.test.ts rename to packages/ops-cli/__tests__/teardown.test.ts index e5ed9e0..4111be0 100644 --- a/interweb/packages/cli/__tests__/teardown.test.ts +++ b/packages/ops-cli/__tests__/teardown.test.ts @@ -1,5 +1,5 @@ // Mock dependencies first -jest.mock('@interweb/client'); +jest.mock('@kubernetesjs/client'); jest.mock('inquirer', () => ({ prompt: jest.fn() })); @@ -16,7 +16,7 @@ jest.mock('chalk', () => ({ import { Command } from 'commander'; -import { Client, ConfigLoader } from '@interweb/client'; +import { Client, ConfigLoader } from '@kubernetesjs/client'; import chalk from 'chalk'; import inquirer from 'inquirer'; import { createTeardownCommand } from '../src/commands/teardown'; diff --git a/interweb/packages/cli/interweb.setup.yaml b/packages/ops-cli/interweb.setup.yaml similarity index 100% rename from interweb/packages/cli/interweb.setup.yaml rename to packages/ops-cli/interweb.setup.yaml diff --git a/interweb/packages/cli/jest.config.js b/packages/ops-cli/jest.config.js similarity index 100% rename from interweb/packages/cli/jest.config.js rename to packages/ops-cli/jest.config.js diff --git a/interweb/packages/cli/package.json b/packages/ops-cli/package.json similarity index 77% rename from interweb/packages/cli/package.json rename to packages/ops-cli/package.json index 87ce216..c3fb3ab 100644 --- a/interweb/packages/cli/package.json +++ b/packages/ops-cli/package.json @@ -1,7 +1,7 @@ { - "name": "@interweb/cli", + "name": "@kubernetesjs/ops-cli", "version": "0.0.1", - "description": "CLI for interweb", + "description": "KubernetesJS Ops CLI", "main": "./index.js", "types": "./index.d.ts", "module": "./esm/index.js", @@ -18,8 +18,8 @@ "test:watch": "jest --watch" }, "dependencies": { - "@interweb/client": "workspace:^", - "@interweb/interwebjs": "workspace:^", + "@kubernetesjs/client": "workspace:^", + "@kubernetesjs/ops": "workspace:^", "chalk": "^4.1.0", "commander": "^11.0.0", "inquirer": "^9.2.0" @@ -28,6 +28,6 @@ "@types/inquirer": "^9.0.3" }, "bin": { - "interweb": "./index.js" + "kjs": "./index.js" } -} \ No newline at end of file +} diff --git a/interweb/packages/cli/src/commands/delete.ts b/packages/ops-cli/src/commands/delete.ts similarity index 93% rename from interweb/packages/cli/src/commands/delete.ts rename to packages/ops-cli/src/commands/delete.ts index b0249a7..59d672e 100644 --- a/interweb/packages/cli/src/commands/delete.ts +++ b/packages/ops-cli/src/commands/delete.ts @@ -1,5 +1,5 @@ import { Command } from 'commander'; -import { Client, ConfigLoader } from '@interweb/client'; +import { Client, ConfigLoader } from '@kubernetesjs/client'; import chalk from 'chalk'; import inquirer from 'inquirer'; import { getApiEndpoint } from '../utils/k8s-utils'; @@ -35,14 +35,14 @@ async function deleteResources(options: any): Promise { if (!configPath) { // Try to auto-detect config file - if (ConfigLoader.configExists('interweb.setup.yaml')) { - configPath = 'interweb.setup.yaml'; + if (ConfigLoader.configExists('kjs.setup.yaml')) { + configPath = 'kjs.setup.yaml'; configType = 'cluster'; - } else if (ConfigLoader.configExists('interweb.deploy.yaml')) { - configPath = 'interweb.deploy.yaml'; + } else if (ConfigLoader.configExists('kjs.deploy.yaml')) { + configPath = 'kjs.deploy.yaml'; configType = 'application'; } else { - throw new Error('No configuration file found. Please specify -c or ensure interweb.setup.yaml or interweb.deploy.yaml exists.'); + throw new Error('No configuration file found. Please specify -c or ensure kjs.setup.yaml or kjs.deploy.yaml exists.'); } } @@ -172,9 +172,9 @@ async function deleteResources(options: any): Promise { if (configType === 'cluster') { console.log(chalk.blue('\nThe cluster setup has been completely removed.')); - console.log(chalk.blue('You can set up a new cluster using: interweb setup -c ' + configPath)); + console.log(chalk.blue('You can set up a new cluster using: kjs setup -c ' + configPath)); } else { console.log(chalk.blue('\nThe application has been completely removed.')); - console.log(chalk.blue('You can redeploy the application using: interweb deploy -c ' + configPath)); + console.log(chalk.blue('You can redeploy the application using: kjs deploy -c ' + configPath)); } } diff --git a/interweb/packages/cli/src/commands/deploy.ts b/packages/ops-cli/src/commands/deploy.ts similarity index 97% rename from interweb/packages/cli/src/commands/deploy.ts rename to packages/ops-cli/src/commands/deploy.ts index defc511..1c562e0 100644 --- a/interweb/packages/cli/src/commands/deploy.ts +++ b/packages/ops-cli/src/commands/deploy.ts @@ -1,5 +1,5 @@ import { Command } from 'commander'; -import { Client, ConfigLoader } from '@interweb/client'; +import { Client, ConfigLoader } from '@kubernetesjs/client'; import chalk from 'chalk'; import inquirer from 'inquirer'; import { getApiEndpoint } from '../utils/k8s-utils'; @@ -257,10 +257,10 @@ async function generateAppConfig(options: any): Promise { }; } - const outputPath = options.config || 'interweb.deploy.yaml'; + const outputPath = options.config || 'kjs.deploy.yaml'; ConfigLoader.saveConfig(config, outputPath); console.log(chalk.green(`✓ Configuration saved to ${outputPath}`)); console.log(chalk.blue('\nTo deploy the application, run:')); - console.log(` interweb deploy -c ${outputPath}`); + console.log(` kjs deploy -c ${outputPath}`); } diff --git a/interweb/packages/cli/src/commands/index.ts b/packages/ops-cli/src/commands/index.ts similarity index 100% rename from interweb/packages/cli/src/commands/index.ts rename to packages/ops-cli/src/commands/index.ts diff --git a/interweb/packages/cli/src/commands/setup.ts b/packages/ops-cli/src/commands/setup.ts similarity index 98% rename from interweb/packages/cli/src/commands/setup.ts rename to packages/ops-cli/src/commands/setup.ts index 58eba2d..c8e9e79 100644 --- a/interweb/packages/cli/src/commands/setup.ts +++ b/packages/ops-cli/src/commands/setup.ts @@ -1,5 +1,5 @@ import { Command } from 'commander'; -import { Client, ConfigLoader } from '@interweb/client'; +import { Client, ConfigLoader } from '@kubernetesjs/client'; import chalk from 'chalk'; import inquirer from 'inquirer'; import * as path from 'path'; @@ -127,7 +127,7 @@ async function setupCluster(options: any): Promise { } }; - const outputPath = options.config || 'interweb.setup.yaml'; + const outputPath = options.config || 'kjs.setup.yaml'; ConfigLoader.saveConfig(generatedConfig as any, outputPath); options.config = outputPath; configPath = outputPath; @@ -210,7 +210,7 @@ async function generateConfig(options: any): Promise { const fixturePath = path.resolve(__dirname, '../../__fixtures__/config/setup.config.yaml'); let outputPath = options.config; if (!outputPath || path.resolve(outputPath) === fixturePath || outputPath === '__fixtures__/config/setup.config.yaml') { - outputPath = path.resolve(process.cwd(), 'config/interweb.setup.yaml'); + outputPath = path.resolve(process.cwd(), 'config/kjs.setup.yaml'); } const dir = path.dirname(outputPath); if (!fs.existsSync(dir)) { @@ -313,7 +313,7 @@ async function generateConfig(options: any): Promise { } }; - const outputPath = options.config || path.resolve(process.cwd(), 'config/interweb.setup.yaml'); + const outputPath = options.config || path.resolve(process.cwd(), 'config/kjs.setup.yaml'); const outDir = path.dirname(outputPath); if (!fs.existsSync(outDir)) { fs.mkdirSync(outDir, { recursive: true }); diff --git a/interweb/packages/cli/src/commands/status.ts b/packages/ops-cli/src/commands/status.ts similarity index 97% rename from interweb/packages/cli/src/commands/status.ts rename to packages/ops-cli/src/commands/status.ts index cdc7474..1fcac05 100644 --- a/interweb/packages/cli/src/commands/status.ts +++ b/packages/ops-cli/src/commands/status.ts @@ -1,5 +1,5 @@ import { Command } from 'commander'; -import { Client, ConfigLoader } from '@interweb/client'; +import { Client, ConfigLoader } from '@kubernetesjs/client'; import chalk from 'chalk'; import { getApiEndpoint } from '../utils/k8s-utils'; @@ -41,7 +41,7 @@ async function checkStatus(options: any): Promise { configPath = '__fixtures__/config/deploy.config.yaml'; configType = 'application'; } else { - throw new Error('No configuration file found. Please specify -c or ensure __fixtures__/config/setup.config.yaml or interweb.setup.yaml exists.'); + throw new Error('No configuration file found. Please specify -c or ensure __fixtures__/config/setup.config.yaml or kjs.setup.yaml exists.'); } } @@ -138,7 +138,7 @@ async function checkStatus(options: any): Promise { console.log(chalk.blue('Tip: Use --watch to monitor progress in real-time')); } else if (status.phase === 'pending') { console.log(chalk.gray('\n⭕ Cluster operators are not installed')); - console.log(chalk.blue('Run: interweb setup -c to install operators')); + console.log(chalk.blue('Run: kjs setup -c to install operators')); } else if (status.phase === 'failed') { console.log(chalk.red('\n❌ Cluster setup has failed')); console.log(chalk.blue('Check the conditions above for more details')); diff --git a/interweb/packages/cli/src/commands/teardown.ts b/packages/ops-cli/src/commands/teardown.ts similarity index 96% rename from interweb/packages/cli/src/commands/teardown.ts rename to packages/ops-cli/src/commands/teardown.ts index 12fcd2d..23556f5 100644 --- a/interweb/packages/cli/src/commands/teardown.ts +++ b/packages/ops-cli/src/commands/teardown.ts @@ -1,5 +1,5 @@ import { Command } from 'commander'; -import { Client, ConfigLoader } from '@interweb/client'; +import { Client, ConfigLoader } from '@kubernetesjs/client'; import chalk from 'chalk'; import inquirer from 'inquirer'; @@ -95,8 +95,8 @@ async function teardownOperators(options: any): Promise { console.log(chalk.green('\n✅ Operators teardown completed!')); console.log(chalk.blue('\nNext steps:')); - console.log(' 1. Reinstall operators if needed: interweb setup -c ' + options.config); - console.log(' 2. Check cluster status: interweb status -c ' + options.config); + console.log(' 1. Reinstall operators if needed: kjs setup -c ' + options.config); + console.log(' 2. Check cluster status: kjs status -c ' + options.config); } async function waitForNamespaceDeletion(config: any): Promise { @@ -163,4 +163,4 @@ async function waitForNamespaceDeletion(config: any): Promise { console.log(chalk.yellow(`You may need to manually clean up namespace ${namespace} before running setup again.`)); } } -} \ No newline at end of file +} diff --git a/interweb/packages/cli/src/index.ts b/packages/ops-cli/src/index.ts similarity index 80% rename from interweb/packages/cli/src/index.ts rename to packages/ops-cli/src/index.ts index 5e14a71..501417b 100644 --- a/interweb/packages/cli/src/index.ts +++ b/packages/ops-cli/src/index.ts @@ -10,8 +10,8 @@ const program = new Command(); const version = '0.0.1'; program - .name('interweb') - .description('Interweb CLI - Kubernetes cluster management and application deployment') + .name('kjs') + .description('KubernetesJS Ops CLI - Kubernetes cluster management and application deployment') .version(version, '-v, --version', 'Display version number'); // Add commands @@ -75,19 +75,19 @@ program.exitOverride((err: any) => { program.on('--help', () => { console.log(''); console.log(chalk.blue('Examples:')); - console.log(' $ interweb setup # Set up cluster with interweb.setup.yaml'); - console.log(' $ interweb setup --generate-config # Generate sample cluster config'); - console.log(' $ interweb deploy -c app.yaml # Deploy application'); - console.log(' $ interweb status # Check cluster status'); - console.log(' $ interweb status -t application # Check application status'); - console.log(' $ interweb delete -c app.yaml # Delete application'); + console.log(' $ kjs setup # Set up cluster with kjs.setup.yaml'); + console.log(' $ kjs setup --generate-config # Generate sample cluster config'); + console.log(' $ kjs deploy -c app.yaml # Deploy application'); + console.log(' $ kjs status # Check cluster status'); + console.log(' $ kjs status -t application # Check application status'); + console.log(' $ kjs delete -c app.yaml # Delete application'); console.log(''); console.log(chalk.blue('Configuration Files:')); - console.log(' interweb.setup.yaml - Cluster setup configuration'); - console.log(' interweb.deploy.yaml - Application deployment configuration'); + console.log(' kjs.setup.yaml - Cluster setup configuration'); + console.log(' kjs.deploy.yaml - Application deployment configuration'); console.log(''); console.log(chalk.blue('Documentation:')); - console.log(' https://docs.interweb.dev'); + console.log(' https://docs.kubernetesjs.dev'); }); // Show help if no command is provided diff --git a/interweb/packages/cli/src/utils/k8s-utils.ts b/packages/ops-cli/src/utils/k8s-utils.ts similarity index 100% rename from interweb/packages/cli/src/utils/k8s-utils.ts rename to packages/ops-cli/src/utils/k8s-utils.ts diff --git a/interweb/packages/client/tsconfig.esm.json b/packages/ops-cli/tsconfig.esm.json similarity index 100% rename from interweb/packages/client/tsconfig.esm.json rename to packages/ops-cli/tsconfig.esm.json diff --git a/interweb/packages/cli/tsconfig.json b/packages/ops-cli/tsconfig.json similarity index 100% rename from interweb/packages/cli/tsconfig.json rename to packages/ops-cli/tsconfig.json diff --git a/interweb/packages/interwebjs/README.md b/packages/ops/README.md similarity index 100% rename from interweb/packages/interwebjs/README.md rename to packages/ops/README.md diff --git a/interweb/packages/interwebjs/__tests__/test.ts b/packages/ops/__tests__/test.ts similarity index 100% rename from interweb/packages/interwebjs/__tests__/test.ts rename to packages/ops/__tests__/test.ts diff --git a/interweb/packages/interwebjs/jest.config.js b/packages/ops/jest.config.js similarity index 100% rename from interweb/packages/interwebjs/jest.config.js rename to packages/ops/jest.config.js diff --git a/interweb/packages/interwebjs/package.json b/packages/ops/package.json similarity index 89% rename from interweb/packages/interwebjs/package.json rename to packages/ops/package.json index 22bb362..b3bf5bd 100644 --- a/interweb/packages/interwebjs/package.json +++ b/packages/ops/package.json @@ -1,7 +1,7 @@ { - "name": "@interweb/interwebjs", + "name": "@kubernetesjs/ops", "version": "0.0.1", - "description": "InterwebJS", + "description": "KubernetesJS Ops library", "main": "./index.js", "types": "./index.d.ts", "module": "./esm/index.js", @@ -22,4 +22,4 @@ "devDependencies": { "schema-sdk": "^0.15.0" } -} \ No newline at end of file +} diff --git a/interweb/packages/interwebjs/scripts/codegen.ts b/packages/ops/scripts/codegen.ts similarity index 100% rename from interweb/packages/interwebjs/scripts/codegen.ts rename to packages/ops/scripts/codegen.ts diff --git a/interweb/packages/interwebjs/scripts/fetch-swagger.ts b/packages/ops/scripts/fetch-swagger.ts similarity index 100% rename from interweb/packages/interwebjs/scripts/fetch-swagger.ts rename to packages/ops/scripts/fetch-swagger.ts diff --git a/interweb/packages/interwebjs/scripts/swagger.json b/packages/ops/scripts/swagger.json similarity index 100% rename from interweb/packages/interwebjs/scripts/swagger.json rename to packages/ops/scripts/swagger.json diff --git a/interweb/packages/interwebjs/src/client.ts b/packages/ops/src/client.ts similarity index 100% rename from interweb/packages/interwebjs/src/client.ts rename to packages/ops/src/client.ts diff --git a/interweb/packages/interwebjs/src/index.ts b/packages/ops/src/index.ts similarity index 100% rename from interweb/packages/interwebjs/src/index.ts rename to packages/ops/src/index.ts diff --git a/interweb/packages/interwebjs/tsconfig.esm.json b/packages/ops/tsconfig.esm.json similarity index 100% rename from interweb/packages/interwebjs/tsconfig.esm.json rename to packages/ops/tsconfig.esm.json diff --git a/interweb/packages/interwebjs/tsconfig.json b/packages/ops/tsconfig.json similarity index 100% rename from interweb/packages/interwebjs/tsconfig.json rename to packages/ops/tsconfig.json diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 66330e2..4e708bd 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,3 +1,3 @@ packages: - 'packages/*' - + - 'apps/*' From 343deb8f752996e9d7fc0afd3d06490cc03496f0 Mon Sep 17 00:00:00 2001 From: Anmol1696 Date: Sat, 8 Nov 2025 10:05:46 +0400 Subject: [PATCH 03/11] fix packages copy command --- packages/client/package.json | 2 +- packages/manifests/package.json | 2 +- packages/ops-cli/package.json | 2 +- packages/ops/package.json | 2 +- pnpm-lock.yaml | 8241 +++++++++++++++++++++++++++++-- 5 files changed, 7899 insertions(+), 350 deletions(-) diff --git a/packages/client/package.json b/packages/client/package.json index 7e73d12..21621ef 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -10,7 +10,7 @@ "directory": "dist" }, "scripts": { - "copy": "cpy ../../LICENSE README.md package.json dist --flat", + "copy": "copyfiles -f ../../LICENSE README.md package.json dist", "clean": "rimraf dist", "prepare": "pnpm run build", "build": "pnpm run clean && tsc && tsc -p tsconfig.esm.json && pnpm run copy", diff --git a/packages/manifests/package.json b/packages/manifests/package.json index 124debd..579ddbf 100644 --- a/packages/manifests/package.json +++ b/packages/manifests/package.json @@ -10,7 +10,7 @@ "directory": "dist" }, "scripts": { - "copy": "cpy ../../LICENSE README.md package.json dist --flat", + "copy": "copyfiles -f ../../LICENSE README.md package.json dist", "clean": "rimraf dist", "prepare": "pnpm run build", "build": "pnpm run clean && tsc && tsc -p tsconfig.esm.json && pnpm run copy", diff --git a/packages/ops-cli/package.json b/packages/ops-cli/package.json index c3fb3ab..fc4fc8d 100644 --- a/packages/ops-cli/package.json +++ b/packages/ops-cli/package.json @@ -10,7 +10,7 @@ "directory": "dist" }, "scripts": { - "copy": "cpy ../../LICENSE README.md package.json dist --flat", + "copy": "copyfiles -f ../../LICENSE README.md package.json dist", "clean": "rimraf dist", "prepare": "pnpm run build", "build": "pnpm run clean && tsc && tsc -p tsconfig.esm.json && pnpm run copy", diff --git a/packages/ops/package.json b/packages/ops/package.json index b3bf5bd..f6c4e0c 100644 --- a/packages/ops/package.json +++ b/packages/ops/package.json @@ -10,7 +10,7 @@ "directory": "dist" }, "scripts": { - "copy": "cpy ../../LICENSE README.md package.json dist --flat", + "copy": "copyfiles -f ../../LICENSE README.md package.json dist", "clean": "rimraf dist", "prepare": "pnpm run build", "build": "pnpm run clean && tsc && tsc -p tsconfig.esm.json && pnpm run copy", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8911bbf..78f4038 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -37,10 +37,10 @@ importers: version: 4.3.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1) jest: specifier: ^29.6.2 - version: 29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3)) + version: 29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@swc/core@1.15.0(@swc/helpers@0.5.17))(@swc/wasm@1.15.0)(@types/node@20.19.24)(typescript@5.9.3)) lerna: specifier: ^8.2.3 - version: 8.2.4(@types/node@20.19.24)(encoding@0.1.13) + version: 8.2.4(@swc/core@1.15.0(@swc/helpers@0.5.17))(@types/node@20.19.24)(encoding@0.1.13) prettier: specifier: ^3.0.2 version: 3.6.2 @@ -52,14 +52,267 @@ importers: version: 6.0.1 ts-jest: specifier: ^29.1.1 - version: 29.4.5(@babel/core@7.28.5)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.5))(jest-util@29.7.0)(jest@29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3)))(typescript@5.9.3) + version: 29.4.5(@babel/core@7.28.5)(@jest/transform@29.7.0)(@jest/types@30.2.0)(babel-jest@29.7.0(@babel/core@7.28.5))(jest-util@30.2.0)(jest@29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@swc/core@1.15.0(@swc/helpers@0.5.17))(@swc/wasm@1.15.0)(@types/node@20.19.24)(typescript@5.9.3)))(typescript@5.9.3) ts-node: specifier: ^10.9.2 - version: 10.9.2(@types/node@20.19.24)(typescript@5.9.3) + version: 10.9.2(@swc/core@1.15.0(@swc/helpers@0.5.17))(@swc/wasm@1.15.0)(@types/node@20.19.24)(typescript@5.9.3) typescript: specifier: ^5.1.6 version: 5.9.3 + apps/ops-dashboard: + dependencies: + '@agentic-kit/ollama': + specifier: ^0.1.2 + version: 0.1.2(encoding@0.1.13) + '@ark-ui/react': + specifier: ^5.0.1 + version: 5.27.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@kubernetesjs/client': + specifier: workspace:* + version: link:../../packages/client/dist + '@kubernetesjs/manifests': + specifier: workspace:* + version: link:../../packages/manifests/dist + '@kubernetesjs/ops': + specifier: workspace:* + version: link:../../packages/ops/dist + '@radix-ui/react-accordion': + specifier: ^1.2.3 + version: 1.2.12(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-alert-dialog': + specifier: ^1.1.6 + version: 1.1.15(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-avatar': + specifier: ^1.1.3 + version: 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-checkbox': + specifier: ^1.3.2 + version: 1.3.3(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-context-menu': + specifier: ^2.2.6 + version: 2.2.16(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-dialog': + specifier: ^1.1.6 + version: 1.1.15(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-dropdown-menu': + specifier: ^2.1.6 + version: 2.1.16(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-label': + specifier: ^2.1.2 + version: 2.1.8(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-popover': + specifier: ^1.1.6 + version: 1.1.15(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-radio-group': + specifier: ^1.2.3 + version: 1.3.8(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-scroll-area': + specifier: ^1.2.3 + version: 1.2.10(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-select': + specifier: ^2.2.5 + version: 2.2.6(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': + specifier: ^1.1.2 + version: 1.2.4(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-switch': + specifier: ^1.2.6 + version: 1.2.6(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-tabs': + specifier: ^1.1.3 + version: 1.1.13(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-toast': + specifier: ^1.2.6 + version: 1.2.15(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-tooltip': + specifier: ^1.1.8 + version: 1.2.8(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@swc/wasm': + specifier: ^1.11.8 + version: 1.15.0 + '@swc/wasm-web': + specifier: ^1.11.8 + version: 1.15.0 + '@tanstack/react-query': + specifier: ^5.29.0 + version: 5.79.2(react@18.3.1) + agentic-kit: + specifier: ^0.1.2 + version: 0.1.2(encoding@0.1.13) + buffer: + specifier: ^6.0.3 + version: 6.0.3 + class-variance-authority: + specifier: ^0.7.1 + version: 0.7.1 + clsx: + specifier: ^2.1.1 + version: 2.1.1 + cross-fetch: + specifier: ^4.1.0 + version: 4.1.0(encoding@0.1.13) + dayjs: + specifier: ^1.11.13 + version: 1.11.19 + embla-carousel-react: + specifier: ^8.5.2 + version: 8.6.0(react@18.3.1) + gray-matter: + specifier: ^4.0.3 + version: 4.0.3 + js-yaml: + specifier: ^4.1.0 + version: 4.1.0 + kubernetesjs: + specifier: ^0.6.1 + version: 0.6.2 + lodash-es: + specifier: ^4.17.21 + version: 4.17.21 + lucide-react: + specifier: ^0.454.0 + version: 0.454.0(react@18.3.1) + match-sorter: + specifier: ^8.0.0 + version: 8.1.0 + next: + specifier: ^15.2.2 + version: 15.5.6(@babel/core@7.28.5)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next-seo: + specifier: ^6.6.0 + version: 6.8.0(next@15.5.6(@babel/core@7.28.5)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next-themes: + specifier: ^0.3.0 + version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + nuqs: + specifier: ^2.4.1 + version: 2.7.3(next@15.5.6(@babel/core@7.28.5)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + react: + specifier: ^18.3.1 + version: 18.3.1 + react-dom: + specifier: ^18.3.1 + version: 18.3.1(react@18.3.1) + react-hook-form: + specifier: ^7.54.2 + version: 7.66.0(react@18.3.1) + react-markdown: + specifier: ^9.1.0 + version: 9.1.0(@types/react@18.3.26)(react@18.3.1) + react-syntax-highlighter: + specifier: ^15.6.1 + version: 15.6.6(react@18.3.1) + remark: + specifier: ^15.0.1 + version: 15.0.1 + remark-gfm: + specifier: ^4.0.0 + version: 4.0.1 + tailwind-merge: + specifier: ^2.6.0 + version: 2.6.0 + tailwindcss-animate: + specifier: ^1.0.7 + version: 1.0.7(tailwindcss@3.4.18(yaml@2.8.1)) + undici: + specifier: ^7.16.0 + version: 7.16.0 + unist-util-visit: + specifier: ^5.0.0 + version: 5.0.0 + use-debounce: + specifier: ^10.0.4 + version: 10.0.6(react@18.3.1) + uuid: + specifier: ^11.1.0 + version: 11.1.0 + devDependencies: + '@babel/plugin-transform-modules-commonjs': + specifier: ^7.27.1 + version: 7.27.1(@babel/core@7.28.5) + '@babel/preset-typescript': + specifier: ^7.27.1 + version: 7.28.5(@babel/core@7.28.5) + '@playwright/test': + specifier: ^1.56.1 + version: 1.56.1 + '@swc/core': + specifier: ^1.13.19 + version: 1.15.0(@swc/helpers@0.5.17) + '@testing-library/jest-dom': + specifier: ^6.9.1 + version: 6.9.1 + '@testing-library/react': + specifier: ^16.3.0 + version: 16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@testing-library/react-hooks': + specifier: ^8.0.1 + version: 8.0.1(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@testing-library/user-event': + specifier: ^14.6.1 + version: 14.6.1(@testing-library/dom@10.4.1) + '@types/js-yaml': + specifier: ^4.0.9 + version: 4.0.9 + '@types/node': + specifier: ^20.11.5 + version: 20.19.24 + '@types/react': + specifier: ^18.2.77 + version: 18.3.26 + '@types/react-dom': + specifier: ^18.2.18 + version: 18.3.7(@types/react@18.3.26) + '@types/react-syntax-highlighter': + specifier: ^15.5.11 + version: 15.5.13 + autoprefixer: + specifier: ^10.4.17 + version: 10.4.21(postcss@8.5.6) + eslint: + specifier: ^8.56.0 + version: 8.57.1 + eslint-config-next: + specifier: 14.1.0 + version: 14.1.0(eslint@8.57.1)(typescript@5.9.3) + jest: + specifier: ^29.7.0 + version: 29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@swc/core@1.15.0(@swc/helpers@0.5.17))(@swc/wasm@1.15.0)(@types/node@20.19.24)(typescript@5.9.3)) + jest-environment-jsdom: + specifier: ^30.2.0 + version: 30.2.0 + jest-fixed-jsdom: + specifier: ^0.0.10 + version: 0.0.10(jest-environment-jsdom@30.2.0) + msw: + specifier: 2.11.5 + version: 2.11.5(@types/node@20.19.24)(typescript@5.9.3) + node-fetch: + specifier: ^3.3.2 + version: 3.3.2 + postcss: + specifier: ^8.4.33 + version: 8.5.6 + pretty-format: + specifier: ^30.2.0 + version: 30.2.0 + schema-sdk: + specifier: ^0.11.3 + version: 0.11.3(encoding@0.1.13) + tailwindcss: + specifier: ^3.4.1 + version: 3.4.18(yaml@2.8.1) + ts-node: + specifier: ^10.9.2 + version: 10.9.2(@swc/core@1.15.0(@swc/helpers@0.5.17))(@swc/wasm@1.15.0)(@types/node@20.19.24)(typescript@5.9.3) + typescript: + specifier: ^5.3.3 + version: 5.9.3 + whatwg-fetch: + specifier: ^3.6.20 + version: 3.6.20 + packages/cli: dependencies: chalk: @@ -86,6 +339,38 @@ importers: version: 4.0.9 publishDirectory: dist + packages/client: + dependencies: + '@kubernetesjs/manifests': + specifier: workspace:^ + version: link:../manifests/dist + '@kubernetesjs/ops': + specifier: workspace:^ + version: link:../ops/dist + axios: + specifier: ^1.7.2 + version: 1.13.2 + chalk: + specifier: ^4.1.0 + version: 4.1.2 + js-yaml: + specifier: ^4.1.0 + version: 4.1.0 + pg: + specifier: ^8.16.3 + version: 8.16.3 + devDependencies: + '@types/js-yaml': + specifier: ^4.0.5 + version: 4.0.9 + '@types/pg': + specifier: ^8.11.10 + version: 8.15.6 + ts-node: + specifier: ^10.9.2 + version: 10.9.2(@swc/core@1.15.0(@swc/helpers@0.5.17))(@swc/wasm@1.15.0)(@types/node@20.19.24)(typescript@5.9.3) + publishDirectory: dist + packages/kubernetesjs: devDependencies: schema-sdk: @@ -93,6 +378,59 @@ importers: version: 0.12.0(encoding@0.1.13) publishDirectory: dist + packages/manifests: + dependencies: + '@kubernetesjs/ops': + specifier: workspace:* + version: link:../ops/dist + js-yaml: + specifier: ^4.1.0 + version: 4.1.0 + devDependencies: + '@babel/generator': + specifier: ^7.25.0 + version: 7.28.5 + '@babel/types': + specifier: ^7.25.0 + version: 7.28.5 + '@types/babel__generator': + specifier: ^7.6.8 + version: 7.27.0 + '@types/js-yaml': + specifier: ^4.0.5 + version: 4.0.9 + publishDirectory: dist + + packages/ops: + devDependencies: + schema-sdk: + specifier: ^0.15.0 + version: 0.15.0(encoding@0.1.13) + publishDirectory: dist + + packages/ops-cli: + dependencies: + '@kubernetesjs/client': + specifier: workspace:^ + version: link:../client/dist + '@kubernetesjs/ops': + specifier: workspace:^ + version: link:../ops/dist + chalk: + specifier: ^4.1.0 + version: 4.1.2 + commander: + specifier: ^11.0.0 + version: 11.1.0 + inquirer: + specifier: ^9.2.0 + version: 9.3.8(@types/node@20.19.24) + devDependencies: + '@types/inquirer': + specifier: ^9.0.3 + version: 9.0.9 + publishDirectory: dist + packages/react: dependencies: '@tanstack/react-query': @@ -115,6 +453,28 @@ importers: packages: + '@adobe/css-tools@4.4.4': + resolution: {integrity: sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==} + + '@agentic-kit/bradie@0.1.2': + resolution: {integrity: sha512-t9HkaRPd9T5m537YNctjhGIqRjM+IfSb1kuv5BOp5UEKQjcnbJrX/WNQhI5n6dbgyFqJDWL8AjEOXtAHRPWBGw==} + + '@agentic-kit/ollama@0.1.2': + resolution: {integrity: sha512-eegaTzgjDRf4aq0ogGN85xTxBXSjhwdMZYFvdpWOuCNve2dUu79onQIeNjiT36Za4eMNBrz6GzgxzttTi5d+qw==} + + '@alloc/quick-lru@5.2.0': + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} + + '@ark-ui/react@5.27.1': + resolution: {integrity: sha512-Rg5UPIXMtD0h2JLKS1meQ5qbx5TLLsDoiCpzhbcPCnFyH/c78nqm8ee1RHOjeCnxohNYStSwi49KLzpxttE+Rw==} + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + + '@asamuzakjp/css-color@3.2.0': + resolution: {integrity: sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==} + '@babel/code-frame@7.27.1': resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} @@ -131,14 +491,28 @@ packages: resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==} engines: {node: '>=6.9.0'} + '@babel/helper-annotate-as-pure@7.27.3': + resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} + engines: {node: '>=6.9.0'} + '@babel/helper-compilation-targets@7.27.2': resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} engines: {node: '>=6.9.0'} + '@babel/helper-create-class-features-plugin@7.28.5': + resolution: {integrity: sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@babel/helper-globals@7.28.0': resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} engines: {node: '>=6.9.0'} + '@babel/helper-member-expression-to-functions@7.28.5': + resolution: {integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==} + engines: {node: '>=6.9.0'} + '@babel/helper-module-imports@7.27.1': resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} engines: {node: '>=6.9.0'} @@ -149,10 +523,24 @@ packages: peerDependencies: '@babel/core': ^7.0.0 + '@babel/helper-optimise-call-expression@7.27.1': + resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} + engines: {node: '>=6.9.0'} + '@babel/helper-plugin-utils@7.27.1': resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} engines: {node: '>=6.9.0'} + '@babel/helper-replace-supers@7.27.1': + resolution: {integrity: sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} + engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.27.1': resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} @@ -265,6 +653,28 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-modules-commonjs@7.27.1': + resolution: {integrity: sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typescript@7.28.5': + resolution: {integrity: sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-typescript@7.28.5': + resolution: {integrity: sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/runtime@7.28.4': + resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} + engines: {node: '>=6.9.0'} + '@babel/template@7.27.2': resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} engines: {node: '>=6.9.0'} @@ -284,6 +694,34 @@ packages: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} + '@csstools/color-helpers@5.1.0': + resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==} + engines: {node: '>=18'} + + '@csstools/css-calc@2.1.4': + resolution: {integrity: sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-color-parser@3.1.0': + resolution: {integrity: sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-parser-algorithms@3.0.5': + resolution: {integrity: sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-tokenizer@3.0.4': + resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} + engines: {node: '>=18'} + '@emnapi/core@1.7.0': resolution: {integrity: sha512-pJdKGq/1iquWYtv1RRSljZklxHCOCAJFJrImO5ZLKPJVJlVUcs8yFwNQlqS0Lo8xT1VAXXTCZocF9n26FWEKsw==} @@ -311,6 +749,21 @@ packages: resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@floating-ui/core@1.7.3': + resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==} + + '@floating-ui/dom@1.7.4': + resolution: {integrity: sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==} + + '@floating-ui/react-dom@2.1.6': + resolution: {integrity: sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/utils@0.2.10': + resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} + '@humanwhocodes/config-array@0.13.0': resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} engines: {node: '>=10.10.0'} @@ -328,6 +781,165 @@ packages: resolution: {integrity: sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==} engines: {node: '>=6.9.0'} + '@img/colour@1.0.0': + resolution: {integrity: sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==} + engines: {node: '>=18'} + + '@img/sharp-darwin-arm64@0.34.5': + resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.34.5': + resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.2.4': + resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.2.4': + resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.2.4': + resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linux-arm@1.2.4': + resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} + cpu: [arm] + os: [linux] + + '@img/sharp-libvips-linux-ppc64@1.2.4': + resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} + cpu: [ppc64] + os: [linux] + + '@img/sharp-libvips-linux-riscv64@1.2.4': + resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} + cpu: [riscv64] + os: [linux] + + '@img/sharp-libvips-linux-s390x@1.2.4': + resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} + cpu: [s390x] + os: [linux] + + '@img/sharp-libvips-linux-x64@1.2.4': + resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} + cpu: [x64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} + cpu: [x64] + os: [linux] + + '@img/sharp-linux-arm64@0.34.5': + resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linux-arm@0.34.5': + resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + + '@img/sharp-linux-ppc64@0.34.5': + resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ppc64] + os: [linux] + + '@img/sharp-linux-riscv64@0.34.5': + resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [riscv64] + os: [linux] + + '@img/sharp-linux-s390x@0.34.5': + resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + + '@img/sharp-linux-x64@0.34.5': + resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-linuxmusl-arm64@0.34.5': + resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linuxmusl-x64@0.34.5': + resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-wasm32@0.34.5': + resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-arm64@0.34.5': + resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.34.5': + resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.34.5': + resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + + '@inquirer/ansi@1.0.1': + resolution: {integrity: sha512-yqq0aJW/5XPhi5xOAL1xRCpe1eh8UFVgYFpFsjEqmIR8rKLyP+HINvFXwUaxYICflJrVlxnp7lLN6As735kVpw==} + engines: {node: '>=18'} + + '@inquirer/confirm@5.1.19': + resolution: {integrity: sha512-wQNz9cfcxrtEnUyG5PndC8g3gZ7lGDBzmWiXZkX8ot3vfZ+/BLjR8EvyGX4YzQLeVqtAlY/YScZpW7CW8qMoDQ==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/core@10.3.0': + resolution: {integrity: sha512-Uv2aPPPSK5jeCplQmQ9xadnFx2Zhj9b5Dj7bU6ZeCdDNNY11nhYy4btcSdtDguHqCT2h5oNeQTcUNSGGLA7NTA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/external-editor@1.0.2': resolution: {integrity: sha512-yy9cOoBnx58TlsPrIxauKIFQTiyH+0MK4e97y4sV9ERbI+zDxw7i2hxHLCIEGIE/8PPvDxGhgzIOTSOWcs6/MQ==} engines: {node: '>=18'} @@ -337,6 +949,25 @@ packages: '@types/node': optional: true + '@inquirer/figures@1.0.14': + resolution: {integrity: sha512-DbFgdt+9/OZYFM+19dbpXOSeAstPy884FPy1KjDu4anWwymZeOYhMY1mdFri172htv6mvc/uvIAAi7b7tvjJBQ==} + engines: {node: '>=18'} + + '@inquirer/type@3.0.9': + resolution: {integrity: sha512-QPaNt/nmE2bLGQa9b7wwyRJoLZ7pN6rcyXvzU0YCmivmJyq1BVo94G98tStRWkoD1RgDX5C+dPlhhHzNdu/W/w==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@internationalized/date@3.10.0': + resolution: {integrity: sha512-oxDR/NTEJ1k+UFVQElaNIk65E/Z83HK1z1WI3lQyhTtnNg4R5oVXaPzK3jcpKG8UHKDVuDQHzn+wsxSz8RP3aw==} + + '@internationalized/number@3.6.5': + resolution: {integrity: sha512-6hY4Kl4HPBvtfS62asS/R22JzNNy8vi/Ssev7x6EobfCp+9QIB2hKvI2EtbdJ0VSQacxVNtqhE/NmF/NZ0gm6g==} + '@interweb-utils/casing@0.2.0': resolution: {integrity: sha512-ORQySrHzMYmtVRkYvtE1HGa8QnoqYPhu5UWQyv9302D/ZZe0Ae6cpk4NH1xEXgHeFq/CraiOcnLhmc3h7wdNHg==} @@ -374,10 +1005,24 @@ packages: node-notifier: optional: true + '@jest/environment-jsdom-abstract@30.2.0': + resolution: {integrity: sha512-kazxw2L9IPuZpQ0mEt9lu9Z98SqR74xcagANmMBU16X0lS23yPc0+S6hGLUz8kVRlomZEs/5S/Zlpqwf5yu6OQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + peerDependencies: + canvas: ^3.0.0 + jsdom: '*' + peerDependenciesMeta: + canvas: + optional: true + '@jest/environment@29.7.0': resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/environment@30.2.0': + resolution: {integrity: sha512-/QPTL7OBJQ5ac09UDRa3EQes4gt1FTEG/8jZ/4v5IVzx+Cv7dLxlVIvfvSVRiiX2drWyXeBjkMSR8hvOWSog5g==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/expect-utils@29.7.0': resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -390,10 +1035,18 @@ packages: resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/fake-timers@30.2.0': + resolution: {integrity: sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/globals@29.7.0': resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/pattern@30.0.1': + resolution: {integrity: sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/reporters@29.7.0': resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -407,6 +1060,10 @@ packages: resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/schemas@30.0.5': + resolution: {integrity: sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/source-map@29.6.3': resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -427,6 +1084,10 @@ packages: resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/types@30.2.0': + resolution: {integrity: sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -450,29 +1111,94 @@ packages: resolution: {integrity: sha512-A8AlzetnS2WIuhijdAzKUyFpR5YbLLfV3luQ4lzBgIBgRfuoBDZeF+RSZPhra+7A6/zTUlrbhKZIOi/MNhqgvQ==} engines: {node: '>=18.0.0'} + '@mswjs/interceptors@0.39.8': + resolution: {integrity: sha512-2+BzZbjRO7Ct61k8fMNHEtoKjeWI9pIlHFTqBwZ5icHpqszIgEZbjb1MW5Z0+bITTCTl3gk4PDBxs9tA/csXvA==} + engines: {node: '>=18'} + + '@napi-rs/wasm-runtime@0.2.12': + resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} + '@napi-rs/wasm-runtime@0.2.4': resolution: {integrity: sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==} - '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} + '@next/env@15.5.6': + resolution: {integrity: sha512-3qBGRW+sCGzgbpc5TS1a0p7eNxnOarGVQhZxfvTdnV0gFI61lX7QNtQ4V1TSREctXzYn5NetbUsLvyqwLFJM6Q==} - '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} + '@next/eslint-plugin-next@14.1.0': + resolution: {integrity: sha512-x4FavbNEeXx/baD/zC/SdrvkjSby8nBn8KcCREqk6UuwvwoAPZmaV8TFCAuo/cpovBRTIY67mHhe86MQQm/68Q==} - '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} + '@next/swc-darwin-arm64@15.5.6': + resolution: {integrity: sha512-ES3nRz7N+L5Umz4KoGfZ4XX6gwHplwPhioVRc25+QNsDa7RtUF/z8wJcbuQ2Tffm5RZwuN2A063eapoJ1u4nPg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] - '@npmcli/agent@2.2.2': - resolution: {integrity: sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og==} - engines: {node: ^16.14.0 || >=18.0.0} + '@next/swc-darwin-x64@15.5.6': + resolution: {integrity: sha512-JIGcytAyk9LQp2/nuVZPAtj8uaJ/zZhsKOASTjxDug0SPU9LAM3wy6nPU735M1OqacR4U20LHVF5v5Wnl9ptTA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] - '@npmcli/arborist@7.5.4': - resolution: {integrity: sha512-nWtIc6QwwoUORCRNzKx4ypHqCk3drI+5aeYdMTQQiRCcn4lOOgfQh7WyZobGYTxXPSq1VwV53lkpN/BRlRk08g==} - engines: {node: ^16.14.0 || >=18.0.0} - hasBin: true + '@next/swc-linux-arm64-gnu@15.5.6': + resolution: {integrity: sha512-qvz4SVKQ0P3/Im9zcS2RmfFL/UCQnsJKJwQSkissbngnB/12c6bZTCB0gHTexz1s6d/mD0+egPKXAIRFVS7hQg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-arm64-musl@15.5.6': + resolution: {integrity: sha512-FsbGVw3SJz1hZlvnWD+T6GFgV9/NYDeLTNQB2MXoPN5u9VA9OEDy6fJEfePfsUKAhJufFbZLgp0cPxMuV6SV0w==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-x64-gnu@15.5.6': + resolution: {integrity: sha512-3QnHGFWlnvAgyxFxt2Ny8PTpXtQD7kVEeaFat5oPAHHI192WKYB+VIKZijtHLGdBBvc16tiAkPTDmQNOQ0dyrA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-linux-x64-musl@15.5.6': + resolution: {integrity: sha512-OsGX148sL+TqMK9YFaPFPoIaJKbFJJxFzkXZljIgA9hjMjdruKht6xDCEv1HLtlLNfkx3c5w2GLKhj7veBQizQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-win32-arm64-msvc@15.5.6': + resolution: {integrity: sha512-ONOMrqWxdzXDJNh2n60H6gGyKed42Ieu6UTVPZteXpuKbLZTH4G4eBMsr5qWgOBA+s7F+uB4OJbZnrkEDnZ5Fg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@next/swc-win32-x64-msvc@15.5.6': + resolution: {integrity: sha512-pxK4VIjFRx1MY92UycLOOw7dTdvccWsNETQ0kDHkBlcFH1GrTLUjSiHU1ohrznnux6TqRHgv5oflhfIWZwVROQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@nolyfill/is-core-module@1.0.39': + resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} + engines: {node: '>=12.4.0'} + + '@npmcli/agent@2.2.2': + resolution: {integrity: sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@npmcli/arborist@7.5.4': + resolution: {integrity: sha512-nWtIc6QwwoUORCRNzKx4ypHqCk3drI+5aeYdMTQQiRCcn4lOOgfQh7WyZobGYTxXPSq1VwV53lkpN/BRlRk08g==} + engines: {node: ^16.14.0 || >=18.0.0} + hasBin: true '@npmcli/fs@3.1.1': resolution: {integrity: sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==} @@ -643,185 +1369,978 @@ packages: '@octokit/types@13.10.0': resolution: {integrity: sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==} - '@pkgjs/parseargs@0.11.0': - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} - - '@sigstore/bundle@2.3.2': - resolution: {integrity: sha512-wueKWDk70QixNLB363yHc2D2ItTgYiMTdPwK8D9dKQMR3ZQ0c35IxP5xnwQ8cNLoCgCRcHf14kE+CLIvNX1zmA==} - engines: {node: ^16.14.0 || >=18.0.0} - - '@sigstore/core@1.1.0': - resolution: {integrity: sha512-JzBqdVIyqm2FRQCulY6nbQzMpJJpSiJ8XXWMhtOX9eKgaXXpfNOF53lzQEjIydlStnd/eFtuC1dW4VYdD93oRg==} - engines: {node: ^16.14.0 || >=18.0.0} - - '@sigstore/protobuf-specs@0.3.3': - resolution: {integrity: sha512-RpacQhBlwpBWd7KEJsRKcBQalbV28fvkxwTOJIqhIuDysMMaJW47V4OqW30iJB9uRpqOSxxEAQFdr8tTattReQ==} - engines: {node: ^18.17.0 || >=20.5.0} - - '@sigstore/sign@2.3.2': - resolution: {integrity: sha512-5Vz5dPVuunIIvC5vBb0APwo7qKA4G9yM48kPWJT+OEERs40md5GoUR1yedwpekWZ4m0Hhw44m6zU+ObsON+iDA==} - engines: {node: ^16.14.0 || >=18.0.0} + '@open-draft/deferred-promise@2.2.0': + resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} - '@sigstore/tuf@2.3.4': - resolution: {integrity: sha512-44vtsveTPUpqhm9NCrbU8CWLe3Vck2HO1PNLw7RIajbB7xhtn5RBPm1VNSCMwqGYHhDsBJG8gDF0q4lgydsJvw==} - engines: {node: ^16.14.0 || >=18.0.0} + '@open-draft/logger@0.3.0': + resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==} - '@sigstore/verify@1.2.1': - resolution: {integrity: sha512-8iKx79/F73DKbGfRf7+t4dqrc0bRr0thdPrxAtCKWRm/F0tG71i6O1rvlnScncJLLBZHn3h8M3c1BSUAb9yu8g==} - engines: {node: ^16.14.0 || >=18.0.0} + '@open-draft/until@2.1.0': + resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} - '@sinclair/typebox@0.27.8': - resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} - '@sinonjs/commons@3.0.1': - resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} + '@playwright/test@1.56.1': + resolution: {integrity: sha512-vSMYtL/zOcFpvJCW71Q/OEGQb7KYBPAdKh35WNSkaZA75JlAO8ED8UN6GUNTm3drWomcbcqRPFqQbLae8yBTdg==} + engines: {node: '>=18'} + hasBin: true - '@sinonjs/fake-timers@10.3.0': - resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + '@radix-ui/number@1.1.1': + resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==} - '@tanstack/query-core@5.79.2': - resolution: {integrity: sha512-kr+KQrBuqd6495eP9S41BoftFI1H50XA9O+6FmbnTx/Te6bjiq1mj8rt9rJjW3YZSO2aaUNUres0TWesJW1j1g==} + '@radix-ui/primitive@1.1.3': + resolution: {integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==} - '@tanstack/react-query@5.79.2': - resolution: {integrity: sha512-kadeprsH6bWuhHCpqukXHRykJkxcLBxAaF0cQ05yawPmLZ/KiCpR1DyQenonF7A/70rnRUxhJD0RJejqk9wImQ==} + '@radix-ui/react-accordion@1.2.12': + resolution: {integrity: sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==} peerDependencies: - react: ^18 || ^19 - - '@tsconfig/node10@1.0.11': - resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} - - '@tsconfig/node12@1.0.11': - resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} - - '@tsconfig/node14@1.0.3': - resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} - - '@tsconfig/node16@1.0.4': - resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} - - '@tufjs/canonical-json@2.0.0': - resolution: {integrity: sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==} - engines: {node: ^16.14.0 || >=18.0.0} - - '@tufjs/models@2.0.1': - resolution: {integrity: sha512-92F7/SFyufn4DXsha9+QfKnN03JGqtMFMXgSHbZOo8JG59WkTni7UzAouNQDf7AuP9OAMxVOPQcqG3sB7w+kkg==} - engines: {node: ^16.14.0 || >=18.0.0} - - '@tybys/wasm-util@0.9.0': - resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} - - '@types/babel__core@7.20.5': - resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} - - '@types/babel__generator@7.27.0': - resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} - - '@types/babel__template@7.4.4': - resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} - - '@types/babel__traverse@7.28.0': - resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} - - '@types/graceful-fs@4.1.9': - resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} - - '@types/istanbul-lib-coverage@2.0.6': - resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} - - '@types/istanbul-lib-report@3.0.3': - resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} - - '@types/istanbul-reports@3.0.4': - resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@types/jest@29.5.14': - resolution: {integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==} + '@radix-ui/react-alert-dialog@1.1.15': + resolution: {integrity: sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@types/js-yaml@4.0.9': - resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} + '@radix-ui/react-arrow@1.1.7': + resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@types/minimatch@3.0.5': - resolution: {integrity: sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==} + '@radix-ui/react-avatar@1.1.11': + resolution: {integrity: sha512-0Qk603AHGV28BOBO34p7IgD5m+V5Sg/YovfayABkoDDBM5d3NCx0Mp4gGrjzLGes1jV5eNOE1r3itqOR33VC6Q==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@types/minimist@1.2.5': - resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} + '@radix-ui/react-checkbox@1.3.3': + resolution: {integrity: sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@types/node@20.19.24': - resolution: {integrity: sha512-FE5u0ezmi6y9OZEzlJfg37mqqf6ZDSF2V/NLjUyGrR9uTZ7Sb9F7bLNZ03S4XVUNRWGA7Ck4c1kK+YnuWjl+DA==} + '@radix-ui/react-collapsible@1.1.12': + resolution: {integrity: sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@types/normalize-package-data@2.4.4': - resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + '@radix-ui/react-collection@1.1.7': + resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@types/prop-types@15.7.15': - resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} + '@radix-ui/react-compose-refs@1.1.2': + resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@types/react@18.3.26': - resolution: {integrity: sha512-RFA/bURkcKzx/X9oumPG9Vp3D3JUgus/d0b67KB0t5S/raciymilkOa66olh78MUI92QLbEJevO7rvqU/kjwKA==} + '@radix-ui/react-context-menu@2.2.16': + resolution: {integrity: sha512-O8morBEW+HsVG28gYDZPTrT9UUovQUlJue5YO836tiTJhuIWBm/zQHc7j388sHWtdH/xUZurK9olD2+pcqx5ww==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@types/stack-utils@2.0.3': - resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + '@radix-ui/react-context@1.1.2': + resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@types/yargs-parser@21.0.3': - resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + '@radix-ui/react-context@1.1.3': + resolution: {integrity: sha512-ieIFACdMpYfMEjF0rEf5KLvfVyIkOz6PDGyNnP+u+4xQ6jny3VCgA4OgXOwNx2aUkxn8zx9fiVcM8CfFYv9Lxw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@types/yargs@17.0.34': - resolution: {integrity: sha512-KExbHVa92aJpw9WDQvzBaGVE2/Pz+pLZQloT2hjL8IqsZnV62rlPOYvNnLmf/L2dyllfVUOVBj64M0z/46eR2A==} + '@radix-ui/react-dialog@1.1.15': + resolution: {integrity: sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@typescript-eslint/eslint-plugin@7.18.0': - resolution: {integrity: sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==} - engines: {node: ^18.18.0 || >=20.0.0} + '@radix-ui/react-direction@1.1.1': + resolution: {integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==} peerDependencies: - '@typescript-eslint/parser': ^7.0.0 - eslint: ^8.56.0 - typescript: '*' + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: - typescript: + '@types/react': optional: true - '@typescript-eslint/parser@7.18.0': - resolution: {integrity: sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==} - engines: {node: ^18.18.0 || >=20.0.0} + '@radix-ui/react-dismissable-layer@1.1.11': + resolution: {integrity: sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==} peerDependencies: - eslint: ^8.56.0 - typescript: '*' + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: - typescript: + '@types/react': + optional: true + '@types/react-dom': optional: true - '@typescript-eslint/scope-manager@7.18.0': - resolution: {integrity: sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==} - engines: {node: ^18.18.0 || >=20.0.0} + '@radix-ui/react-dropdown-menu@2.1.16': + resolution: {integrity: sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@typescript-eslint/type-utils@7.18.0': - resolution: {integrity: sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==} - engines: {node: ^18.18.0 || >=20.0.0} + '@radix-ui/react-focus-guards@1.1.3': + resolution: {integrity: sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==} peerDependencies: - eslint: ^8.56.0 - typescript: '*' + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: - typescript: + '@types/react': optional: true - '@typescript-eslint/types@7.18.0': - resolution: {integrity: sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==} - engines: {node: ^18.18.0 || >=20.0.0} + '@radix-ui/react-focus-scope@1.1.7': + resolution: {integrity: sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@typescript-eslint/typescript-estree@7.18.0': - resolution: {integrity: sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==} - engines: {node: ^18.18.0 || >=20.0.0} + '@radix-ui/react-id@1.1.1': + resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==} peerDependencies: - typescript: '*' + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: - typescript: + '@types/react': optional: true - '@typescript-eslint/utils@7.18.0': - resolution: {integrity: sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==} - engines: {node: ^18.18.0 || >=20.0.0} + '@radix-ui/react-label@2.1.8': + resolution: {integrity: sha512-FmXs37I6hSBVDlO4y764TNz1rLgKwjJMQ0EGte6F3Cb3f4bIuHB/iLa/8I9VKkmOy+gNHq8rql3j686ACVV21A==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-menu@2.1.16': + resolution: {integrity: sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-popover@1.1.15': + resolution: {integrity: sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-popper@1.2.8': + resolution: {integrity: sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-portal@1.1.9': + resolution: {integrity: sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-presence@1.1.5': + resolution: {integrity: sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-primitive@2.1.3': + resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-primitive@2.1.4': + resolution: {integrity: sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-radio-group@1.3.8': + resolution: {integrity: sha512-VBKYIYImA5zsxACdisNQ3BjCBfmbGH3kQlnFVqlWU4tXwjy7cGX8ta80BcrO+WJXIn5iBylEH3K6ZTlee//lgQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-roving-focus@1.1.11': + resolution: {integrity: sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-scroll-area@1.2.10': + resolution: {integrity: sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-select@2.2.6': + resolution: {integrity: sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-slot@1.2.3': + resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-slot@1.2.4': + resolution: {integrity: sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-switch@1.2.6': + resolution: {integrity: sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-tabs@1.1.13': + resolution: {integrity: sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-toast@1.2.15': + resolution: {integrity: sha512-3OSz3TacUWy4WtOXV38DggwxoqJK4+eDkNMl5Z/MJZaoUPaP4/9lf81xXMe1I2ReTAptverZUpbPY4wWwWyL5g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-tooltip@1.2.8': + resolution: {integrity: sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-use-callback-ref@1.1.1': + resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-controllable-state@1.2.2': + resolution: {integrity: sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-effect-event@0.0.2': + resolution: {integrity: sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-escape-keydown@1.1.1': + resolution: {integrity: sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-is-hydrated@0.1.0': + resolution: {integrity: sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-layout-effect@1.1.1': + resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-previous@1.1.1': + resolution: {integrity: sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-rect@1.1.1': + resolution: {integrity: sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-size@1.1.1': + resolution: {integrity: sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-visually-hidden@1.2.3': + resolution: {integrity: sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/rect@1.1.1': + resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} + + '@rtsao/scc@1.1.0': + resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + + '@rushstack/eslint-patch@1.14.1': + resolution: {integrity: sha512-jGTk8UD/RdjsNZW8qq10r0RBvxL8OWtoT+kImlzPDFilmozzM+9QmIJsmze9UiSBrFU45ZxhTYBypn9q9z/VfQ==} + + '@sigstore/bundle@2.3.2': + resolution: {integrity: sha512-wueKWDk70QixNLB363yHc2D2ItTgYiMTdPwK8D9dKQMR3ZQ0c35IxP5xnwQ8cNLoCgCRcHf14kE+CLIvNX1zmA==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@sigstore/core@1.1.0': + resolution: {integrity: sha512-JzBqdVIyqm2FRQCulY6nbQzMpJJpSiJ8XXWMhtOX9eKgaXXpfNOF53lzQEjIydlStnd/eFtuC1dW4VYdD93oRg==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@sigstore/protobuf-specs@0.3.3': + resolution: {integrity: sha512-RpacQhBlwpBWd7KEJsRKcBQalbV28fvkxwTOJIqhIuDysMMaJW47V4OqW30iJB9uRpqOSxxEAQFdr8tTattReQ==} + engines: {node: ^18.17.0 || >=20.5.0} + + '@sigstore/sign@2.3.2': + resolution: {integrity: sha512-5Vz5dPVuunIIvC5vBb0APwo7qKA4G9yM48kPWJT+OEERs40md5GoUR1yedwpekWZ4m0Hhw44m6zU+ObsON+iDA==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@sigstore/tuf@2.3.4': + resolution: {integrity: sha512-44vtsveTPUpqhm9NCrbU8CWLe3Vck2HO1PNLw7RIajbB7xhtn5RBPm1VNSCMwqGYHhDsBJG8gDF0q4lgydsJvw==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@sigstore/verify@1.2.1': + resolution: {integrity: sha512-8iKx79/F73DKbGfRf7+t4dqrc0bRr0thdPrxAtCKWRm/F0tG71i6O1rvlnScncJLLBZHn3h8M3c1BSUAb9yu8g==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@sinclair/typebox@0.27.8': + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + + '@sinclair/typebox@0.34.41': + resolution: {integrity: sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==} + + '@sinonjs/commons@3.0.1': + resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} + + '@sinonjs/fake-timers@10.3.0': + resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + + '@sinonjs/fake-timers@13.0.5': + resolution: {integrity: sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==} + + '@standard-schema/spec@1.0.0': + resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} + + '@swc/core-darwin-arm64@1.15.0': + resolution: {integrity: sha512-TBKWkbnShnEjlIbO4/gfsrIgAqHBVqgPWLbWmPdZ80bF393yJcLgkrb7bZEnJs6FCbSSuGwZv2rx1jDR2zo6YA==} + engines: {node: '>=10'} + cpu: [arm64] + os: [darwin] + + '@swc/core-darwin-x64@1.15.0': + resolution: {integrity: sha512-f5JKL1v1H56CIZc1pVn4RGPOfnWqPwmuHdpf4wesvXunF1Bx85YgcspW5YxwqG5J9g3nPU610UFuExJXVUzOiQ==} + engines: {node: '>=10'} + cpu: [x64] + os: [darwin] + + '@swc/core-linux-arm-gnueabihf@1.15.0': + resolution: {integrity: sha512-duK6nG+WyuunnfsfiTUQdzC9Fk8cyDLqT9zyXvY2i2YgDu5+BH5W6wM5O4mDNCU5MocyB/SuF5YDF7XySnowiQ==} + engines: {node: '>=10'} + cpu: [arm] + os: [linux] + + '@swc/core-linux-arm64-gnu@1.15.0': + resolution: {integrity: sha512-ITe9iDtTRXM98B91rvyPP6qDVbhUBnmA/j4UxrHlMQ0RlwpqTjfZYZkD0uclOxSZ6qIrOj/X5CaoJlDUuQ0+Cw==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-arm64-musl@1.15.0': + resolution: {integrity: sha512-Q5ldc2bzriuzYEoAuqJ9Vr3FyZhakk5hiwDbniZ8tlEXpbjBhbOleGf9/gkhLaouDnkNUEazFW9mtqwUTRdh7Q==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-x64-gnu@1.15.0': + resolution: {integrity: sha512-pY4is+jEpOxlYCSnI+7N8Oxbap9TmTz5YT84tUvRTlOlTBwFAUlWFCX0FRwWJlsfP0TxbqhIe8dNNzlsEmJbXQ==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-linux-x64-musl@1.15.0': + resolution: {integrity: sha512-zYEt5eT8y8RUpoe7t5pjpoOdGu+/gSTExj8PV86efhj6ugB3bPlj3Y85ogdW3WMVXr4NvwqvzdaYGCZfXzSyVg==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-win32-arm64-msvc@1.15.0': + resolution: {integrity: sha512-zC1rmOgFH5v2BCbByOazEqs0aRNpTdLRchDExfcCfgKgeaD+IdpUOqp7i3VG1YzkcnbuZjMlXfM0ugpt+CddoA==} + engines: {node: '>=10'} + cpu: [arm64] + os: [win32] + + '@swc/core-win32-ia32-msvc@1.15.0': + resolution: {integrity: sha512-7t9U9KwMwQblkdJIH+zX1V4q1o3o41i0HNO+VlnAHT5o+5qHJ963PHKJ/pX3P2UlZnBCY465orJuflAN4rAP9A==} + engines: {node: '>=10'} + cpu: [ia32] + os: [win32] + + '@swc/core-win32-x64-msvc@1.15.0': + resolution: {integrity: sha512-VE0Zod5vcs8iMLT64m5QS1DlTMXJFI/qSgtMDRx8rtZrnjt6/9NW8XUaiPJuRu8GluEO1hmHoyf1qlbY19gGSQ==} + engines: {node: '>=10'} + cpu: [x64] + os: [win32] + + '@swc/core@1.15.0': + resolution: {integrity: sha512-8SnJV+JV0rYbfSiEiUvYOmf62E7QwsEG+aZueqSlKoxFt0pw333+bgZSQXGUV6etXU88nxur0afVMaINujBMSw==} + engines: {node: '>=10'} + peerDependencies: + '@swc/helpers': '>=0.5.17' + peerDependenciesMeta: + '@swc/helpers': + optional: true + + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + + '@swc/helpers@0.5.15': + resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + + '@swc/helpers@0.5.17': + resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} + + '@swc/types@0.1.25': + resolution: {integrity: sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==} + + '@swc/wasm-web@1.15.0': + resolution: {integrity: sha512-9XU+wN8Rq0Jo78RDbskhniNKdcu05EyY/6Y9MsqPMGLkbvhOCEDwnVdgrpVXL/Sry6xe6JqNdau5UOHvassu8Q==} + + '@swc/wasm@1.15.0': + resolution: {integrity: sha512-bIxXPOFQXlYKXPhiaYWpY/83qXgTDSLaaB+0AtSh7UtW7ZZttr3Vp0/mzOB8ovCAurC8Eac3Ppn8oj6/IYnjGA==} + + '@tanstack/query-core@5.79.2': + resolution: {integrity: sha512-kr+KQrBuqd6495eP9S41BoftFI1H50XA9O+6FmbnTx/Te6bjiq1mj8rt9rJjW3YZSO2aaUNUres0TWesJW1j1g==} + + '@tanstack/react-query@5.79.2': + resolution: {integrity: sha512-kadeprsH6bWuhHCpqukXHRykJkxcLBxAaF0cQ05yawPmLZ/KiCpR1DyQenonF7A/70rnRUxhJD0RJejqk9wImQ==} + peerDependencies: + react: ^18 || ^19 + + '@testing-library/dom@10.4.1': + resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} + engines: {node: '>=18'} + + '@testing-library/jest-dom@6.9.1': + resolution: {integrity: sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==} + engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + + '@testing-library/react-hooks@8.0.1': + resolution: {integrity: sha512-Aqhl2IVmLt8IovEVarNDFuJDVWVvhnr9/GCU6UUnrYXwgDFF9h2L2o2P9KBni1AST5sT6riAyoukFLyjQUgD/g==} + engines: {node: '>=12'} + peerDependencies: + '@types/react': ^16.9.0 || ^17.0.0 + react: ^16.9.0 || ^17.0.0 + react-dom: ^16.9.0 || ^17.0.0 + react-test-renderer: ^16.9.0 || ^17.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + react-dom: + optional: true + react-test-renderer: + optional: true + + '@testing-library/react@16.3.0': + resolution: {integrity: sha512-kFSyxiEDwv1WLl2fgsq6pPBbw5aWKrsY2/noi1Id0TK0UParSF62oFQFGHXIyaG4pp2tEub/Zlel+fjjZILDsw==} + engines: {node: '>=18'} + peerDependencies: + '@testing-library/dom': ^10.0.0 + '@types/react': ^18.0.0 || ^19.0.0 + '@types/react-dom': ^18.0.0 || ^19.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@testing-library/user-event@14.6.1': + resolution: {integrity: sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==} + engines: {node: '>=12', npm: '>=6'} + peerDependencies: + '@testing-library/dom': '>=7.21.4' + + '@tsconfig/node10@1.0.11': + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + + '@tufjs/canonical-json@2.0.0': + resolution: {integrity: sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@tufjs/models@2.0.1': + resolution: {integrity: sha512-92F7/SFyufn4DXsha9+QfKnN03JGqtMFMXgSHbZOo8JG59WkTni7UzAouNQDf7AuP9OAMxVOPQcqG3sB7w+kkg==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@tybys/wasm-util@0.10.1': + resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + + '@tybys/wasm-util@0.9.0': + resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} + + '@types/aria-query@5.0.4': + resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.28.0': + resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + + '@types/debug@4.1.12': + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + + '@types/estree-jsx@1.0.5': + resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/graceful-fs@4.1.9': + resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} + + '@types/hast@2.3.10': + resolution: {integrity: sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==} + + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + + '@types/inquirer@9.0.9': + resolution: {integrity: sha512-/mWx5136gts2Z2e5izdoRCo46lPp5TMs9R15GTSsgg/XnZyxDWVqoVU3R9lWnccKpqwsJLvRoxbCjoJtZB7DSw==} + + '@types/istanbul-lib-coverage@2.0.6': + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + + '@types/istanbul-lib-report@3.0.3': + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + + '@types/istanbul-reports@3.0.4': + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + + '@types/jest@29.5.14': + resolution: {integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==} + + '@types/js-yaml@4.0.9': + resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} + + '@types/jsdom@21.1.7': + resolution: {integrity: sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA==} + + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/minimatch@3.0.5': + resolution: {integrity: sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==} + + '@types/minimist@1.2.5': + resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/node@20.19.24': + resolution: {integrity: sha512-FE5u0ezmi6y9OZEzlJfg37mqqf6ZDSF2V/NLjUyGrR9uTZ7Sb9F7bLNZ03S4XVUNRWGA7Ck4c1kK+YnuWjl+DA==} + + '@types/normalize-package-data@2.4.4': + resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + + '@types/pg@8.15.6': + resolution: {integrity: sha512-NoaMtzhxOrubeL/7UZuNTrejB4MPAJ0RpxZqXQf2qXuVlTPuG6Y8p4u9dKRaue4yjmC7ZhzVO2/Yyyn25znrPQ==} + + '@types/prop-types@15.7.15': + resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} + + '@types/react-dom@18.3.7': + resolution: {integrity: sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==} + peerDependencies: + '@types/react': ^18.0.0 + + '@types/react-syntax-highlighter@15.5.13': + resolution: {integrity: sha512-uLGJ87j6Sz8UaBAooU0T6lWJ0dBmjZgN1PZTrj05TNql2/XpC6+4HhMT5syIdFUUt+FASfCeLLv4kBygNU+8qA==} + + '@types/react@18.3.26': + resolution: {integrity: sha512-RFA/bURkcKzx/X9oumPG9Vp3D3JUgus/d0b67KB0t5S/raciymilkOa66olh78MUI92QLbEJevO7rvqU/kjwKA==} + + '@types/stack-utils@2.0.3': + resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + + '@types/statuses@2.0.6': + resolution: {integrity: sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==} + + '@types/through@0.0.33': + resolution: {integrity: sha512-HsJ+z3QuETzP3cswwtzt2vEIiHBk/dCcHGhbmG5X3ecnwFD/lPrMpliGXxSCg03L9AhrdwA4Oz/qfspkDW+xGQ==} + + '@types/tough-cookie@4.0.5': + resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} + + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@types/yargs-parser@21.0.3': + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + + '@types/yargs@17.0.34': + resolution: {integrity: sha512-KExbHVa92aJpw9WDQvzBaGVE2/Pz+pLZQloT2hjL8IqsZnV62rlPOYvNnLmf/L2dyllfVUOVBj64M0z/46eR2A==} + + '@typescript-eslint/eslint-plugin@7.18.0': + resolution: {integrity: sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + '@typescript-eslint/parser': ^7.0.0 + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/parser@6.21.0': + resolution: {integrity: sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/parser@7.18.0': + resolution: {integrity: sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/scope-manager@6.21.0': + resolution: {integrity: sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==} + engines: {node: ^16.0.0 || >=18.0.0} + + '@typescript-eslint/scope-manager@7.18.0': + resolution: {integrity: sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==} + engines: {node: ^18.18.0 || >=20.0.0} + + '@typescript-eslint/type-utils@7.18.0': + resolution: {integrity: sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/types@6.21.0': + resolution: {integrity: sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==} + engines: {node: ^16.0.0 || >=18.0.0} + + '@typescript-eslint/types@7.18.0': + resolution: {integrity: sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==} + engines: {node: ^18.18.0 || >=20.0.0} + + '@typescript-eslint/typescript-estree@6.21.0': + resolution: {integrity: sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/typescript-estree@7.18.0': + resolution: {integrity: sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/utils@7.18.0': + resolution: {integrity: sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==} + engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 + '@typescript-eslint/visitor-keys@6.21.0': + resolution: {integrity: sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==} + engines: {node: ^16.0.0 || >=18.0.0} + '@typescript-eslint/visitor-keys@7.18.0': resolution: {integrity: sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==} engines: {node: ^18.18.0 || >=20.0.0} @@ -829,6 +2348,101 @@ packages: '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + '@unrs/resolver-binding-android-arm-eabi@1.11.1': + resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} + cpu: [arm] + os: [android] + + '@unrs/resolver-binding-android-arm64@1.11.1': + resolution: {integrity: sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==} + cpu: [arm64] + os: [android] + + '@unrs/resolver-binding-darwin-arm64@1.11.1': + resolution: {integrity: sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==} + cpu: [arm64] + os: [darwin] + + '@unrs/resolver-binding-darwin-x64@1.11.1': + resolution: {integrity: sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==} + cpu: [x64] + os: [darwin] + + '@unrs/resolver-binding-freebsd-x64@1.11.1': + resolution: {integrity: sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==} + cpu: [x64] + os: [freebsd] + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + resolution: {integrity: sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + resolution: {integrity: sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} + cpu: [ppc64] + os: [linux] + + '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} + cpu: [riscv64] + os: [linux] + + '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} + cpu: [riscv64] + os: [linux] + + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} + cpu: [s390x] + os: [linux] + + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-linux-x64-musl@1.11.1': + resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-wasm32-wasi@1.11.1': + resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + resolution: {integrity: sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==} + cpu: [arm64] + os: [win32] + + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + resolution: {integrity: sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==} + cpu: [ia32] + os: [win32] + + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + resolution: {integrity: sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==} + cpu: [x64] + os: [win32] + '@yarnpkg/lockfile@1.1.0': resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==} @@ -836,6 +2450,226 @@ packages: resolution: {integrity: sha512-/HcYgtUSiJiot/XWGLOlGxPYUG65+/31V8oqk17vZLW1xlCoR4PampyePljOxY2n8/3jz9+tIFzICsyGujJZoA==} engines: {node: '>=18.12.0'} + '@zag-js/accordion@1.27.0': + resolution: {integrity: sha512-fRPNZaORLd+pa3dfVMUOhHemf98gq33p0NdwdHwPkl2E2nWsQJkFCbqhAR9DJR/Td5b37rEsmPUtOXMHoKc5dw==} + + '@zag-js/anatomy@1.27.0': + resolution: {integrity: sha512-fzd+sv0Xn+LbculHDHUMdJUuODwqtr/sVrOl5fcfLhwX1qXV91ZNgN6wWsAdvevG9eoMhP3tGxoei57ys7YlWQ==} + + '@zag-js/angle-slider@1.27.0': + resolution: {integrity: sha512-xDLMmHkX3AXpN0eLccvmbaq/zSzYi8G84ucsI5hjeyofdCIq+ZzXulxFesk1eBKXqut40Umc9UjrFWf2NwL/AA==} + + '@zag-js/aria-hidden@1.27.0': + resolution: {integrity: sha512-kDUl0eey7wBCNFAdrAxvse4Rbto0OpMaa0wf0rm5w+oB2kp7IqK5Tuq6rF4T72HDZHxs4FMhR4puWpmle+2IqA==} + + '@zag-js/async-list@1.27.0': + resolution: {integrity: sha512-ts7zxVnt1NHU4VQdBNO3LIkig6Ub2rqWlbJkW3vIhV/2MJsbMya8ZECa2Od7TAYr8Mu4KF0z7qt7JPsnOodImQ==} + + '@zag-js/auto-resize@1.27.0': + resolution: {integrity: sha512-E4hBld3CTtKz5mtTZDXX+URzHvKRn/C0fvYnP9BopPZfG4GUCLhnBGEGZxAWV/hLZ1/Rq0I0X+g/iU5hRxKngA==} + + '@zag-js/avatar@1.27.0': + resolution: {integrity: sha512-O3o3UQRyltbOysbkHQKRvfeGfG23iuOvXSIsRWbT5Q8rsAoocz3utlV1uoH00bGTvBPimdoYb4vrnLejJDFKfw==} + + '@zag-js/bottom-sheet@1.27.0': + resolution: {integrity: sha512-nswX/7qzF7nGBkMhEQ6UgP//CISUSwzcZIuFJ3RceTNJ1XUarskX/KiC6lf7WTJ2YUPdceRds6Y6EootHGcRHQ==} + + '@zag-js/carousel@1.27.0': + resolution: {integrity: sha512-hjRZnV+5swzKHW9MloViQZpAMHN4e7WKMteiZoH5WeTKcq66RetezmlOiyvBBt3k59PZwk0Y8WFxNA0L94Amzw==} + + '@zag-js/checkbox@1.27.0': + resolution: {integrity: sha512-nJjGIvGzSOj6t3A/jjDULcSIHIp45Rp+FE100Yad71MDJEfQhXpeHALBGSKJrzn3Bk4QDsmkDrlTXEmXbWtDJg==} + + '@zag-js/clipboard@1.27.0': + resolution: {integrity: sha512-ndEr6zyKj57eHKiTEpNgGNTSRAUFkHKVs5/C1ysgQzDnvSwd+yaSsm4JGYDlmOg5rCCZVY3Cyw4qcsFEQKDiAg==} + + '@zag-js/collapsible@1.27.0': + resolution: {integrity: sha512-IQ88gl+PAEFs4qVrepum8PksykVf2mAKmw+ZSViHnzRYnHGtNEtvgVeJKO9eFEdtMJVtyTKIlExkoQyWdfc9OA==} + + '@zag-js/collection@1.27.0': + resolution: {integrity: sha512-O/2CdEdYbEC8H86CvHRcC31+6+cYPDLWIeGDvylFmwU3qvOLXgWjptDwp/4d60/ni02gPfq7W2qOL2nfMhUH1g==} + + '@zag-js/color-picker@1.27.0': + resolution: {integrity: sha512-zSM6ZzFlmTcemMH7pNzEsGtwVFmNZc3Nwqno4Fd/1sJSGrkvXAwymYeoRk3PEi0dTcpYwHCn9sCH4M4ZiZJGkw==} + + '@zag-js/color-utils@1.27.0': + resolution: {integrity: sha512-ejqLTKM1sE07ZGkaNG1eRCs56hNjHPMgmnZl8GhwOLO7Ku8wnYTNdocdlwYLeV7shV3PFmzl5cVEOH1Dnsifzw==} + + '@zag-js/combobox@1.27.0': + resolution: {integrity: sha512-PuucoFx6LyHPqdr2PaCgbOrlaDTBgeQa8skVIeKSepS6IMEqJztx9HNLbeCgqcticGB/JxTFv0cfdnm+8F97Uw==} + + '@zag-js/core@1.27.0': + resolution: {integrity: sha512-wM5M4DQE1iCnowivXtDrauzM0cwVFWukxrcNFXB2eX0MPMjMjrb3uGdk5Mm9JxKGKLtAlhloOzijjS7JHwW+SQ==} + + '@zag-js/date-picker@1.27.0': + resolution: {integrity: sha512-EpLkY2BnK8GovEOlG31OoqK7iFqt+lRUKmB/AsECdstAwppr1EoklfeCFPX6FKAejuwrSj0+o4Ds6//9poHjag==} + peerDependencies: + '@internationalized/date': '>=3.0.0' + + '@zag-js/date-utils@1.27.0': + resolution: {integrity: sha512-0f669Pjg0bzV8oE7sxZQlnR0sBQAFv8/UEciP5OYRqIvtILpnxoMKuZIzs1ZHt9w24WScB0k6lIqVKXta4lHjA==} + peerDependencies: + '@internationalized/date': '>=3.0.0' + + '@zag-js/dialog@1.27.0': + resolution: {integrity: sha512-YnVApCZ9s1AnmwcPExolFoct6llG2lofkjyFrVxPJkQhxk6/qlqFZdeCZArIW1sNiURmyZZBq7AEfbs7jYXKpQ==} + + '@zag-js/dismissable@1.27.0': + resolution: {integrity: sha512-ttwJb+C/epldAV9nzENJ0a2lExusq9KHSr6hqFC2WM96xDFyCE7pnDw27PFHwNgSUJWBjMgjx0TRJvWSvzwfCg==} + + '@zag-js/dom-query@1.27.0': + resolution: {integrity: sha512-URe81xXzbwzZd4EIv/bJrrWuQAS9pZbkL789rsHj/nfcumtTipi5TW7O2EccGvI7edgVCPlih+HS75E7exyUOQ==} + + '@zag-js/editable@1.27.0': + resolution: {integrity: sha512-WNQ3pAouF4i1Qp7CdQm1atv9K3XYWR9ILUzOn3K0P8mkv6fqvszt0KMszXxY0Uqf/GvD5lnDI3ZJ0keNUWNMrQ==} + + '@zag-js/file-upload@1.27.0': + resolution: {integrity: sha512-AbJQVHeZI083xWusdZwhLP5bGYqAmYsLk5Wu2N8GRX8cghyLI+9IwKoLGjuM7LBpTTul1tBw/fBr8+4LOodGbw==} + + '@zag-js/file-utils@1.27.0': + resolution: {integrity: sha512-jJUR8Q2amS84PuMzEBlTmIrWZmSq2UwPXIF6phAvIA/E9/0S7M4nPu6aWM+b1B4/uxb0yW2Idjq21ybGhbK+sg==} + + '@zag-js/floating-panel@1.27.0': + resolution: {integrity: sha512-/w0eAeHK53zJ07U3z00RjHX9DJz3YZ5UcBnMleR61ymANVd2ICnyxGG/kr29cmnDdizaUE0PcD4p0dwQpJLLEg==} + + '@zag-js/focus-trap@1.27.0': + resolution: {integrity: sha512-UzOQ+MkHeRAHnLxMYHZifDDXXZAa7S7pRGt1rFTKw0J7OnrrybwyDYQaBNmQxjrOTShw90pSp7RBMUz9yuUjPA==} + + '@zag-js/focus-visible@1.27.0': + resolution: {integrity: sha512-zE53T401uXfdqy1FxfinkqBZ8spE1iXTZ5M+0j2+S62QPwh5UFwbrqO5PSSn2fTkj3KlK6eBYmv6rhvIcFGJCQ==} + + '@zag-js/highlight-word@1.27.0': + resolution: {integrity: sha512-0akVl+GX6VIFOmTuKykkkvkswNJKP8nC9tvjlj1/MeMNKu3rR4UTweVdnPlMeiQtp/oh2ArEoN+lCIzz4iPHBg==} + + '@zag-js/hover-card@1.27.0': + resolution: {integrity: sha512-wiBDePKVlVnPqJOGYzXTjza05qmzeDDl0TFz0RPkjc44UZPUWBc/ghgUEW4UP879sI0ip9f2EOFvZJR4jj7N/g==} + + '@zag-js/i18n-utils@1.27.0': + resolution: {integrity: sha512-rWFUTGE+0LkPOOWTmii2M9nNWt+46b7gsEsStrBen+IhRGWKKS+RLr/aJiAC0K4+BZJP0OaEFEMzYZ8IXynSyA==} + + '@zag-js/interact-outside@1.27.0': + resolution: {integrity: sha512-FhOABcaDq0vQwHSEeI9S/9dcNeghLE5t/TwPzquGUmbDxloczVKMOzkZAZJViQkvtHbMjaCDJnURcyP1KDPUOw==} + + '@zag-js/json-tree-utils@1.27.0': + resolution: {integrity: sha512-x8xUgXlF2xNjnUAAeOqSBCC4Lw5oiR/k++EZ3KG5uqgkPBOlpveb9lmTBVGMxGI4v1gG7wqdFF5CeWSR5sLaOw==} + + '@zag-js/listbox@1.27.0': + resolution: {integrity: sha512-awND6os+sICTSUxVzckl712TzMrl4bQEhfrMtpYGNgEj9cg33OQd6ljKGllZajqT+zUu+HAuByI9ygm0q9aEJg==} + + '@zag-js/live-region@1.27.0': + resolution: {integrity: sha512-zsu534ILXiaoxf0lviJiBoEPkPLY1uy0N/a2hjfdcz2oCIYDcY8WAh7aubRy7gQRrvkAg84PtxkGA0ymTne3jw==} + + '@zag-js/marquee@1.27.0': + resolution: {integrity: sha512-1RtFx8+k4/UfrhVo94dAtFg/GyOyd1QTjOQ4DWmx5hijOtACbi6/QjRWUlep8foyzP4zTwAYszD/ApvZ/OMUTA==} + + '@zag-js/menu@1.27.0': + resolution: {integrity: sha512-R1pCj+zxXLmXHAgtkA/QkBSxBU4/2FG+5PNrUhEkBxdoPQdB4oeYdcqxZRyFKWnganQVPy/bcJi3fF1NXjj+HA==} + + '@zag-js/number-input@1.27.0': + resolution: {integrity: sha512-0FMKxjJLjecX4bB2anDXxPvLuHn3SDyDaZgIqFwSJzr63vSL6X5KRV0G2Y8Rfnu6/HKWNwXmA2jxN/OOPwAYww==} + + '@zag-js/pagination@1.27.0': + resolution: {integrity: sha512-rYIf5aY14vNPcK05gL/fsuImgQxZ8YDmfSGZAdosrbgXGzV7oW6HMMq1CtEsruOhJgfd7vp8C1a2KJnmQjjb7Q==} + + '@zag-js/password-input@1.27.0': + resolution: {integrity: sha512-MJxiysWKYZU9tD6HwnLuMdriSH0SsS1AtfOD215Gl/rtWTNm2CDujX6BJAX2Gisxki3PqVYLI4VjWo80tucpqw==} + + '@zag-js/pin-input@1.27.0': + resolution: {integrity: sha512-PrOUz/covtfRiwW0l6jDO4ZzFvQkGlxuo+0JgUVbwykUXwT3NWjs+ANdvxETXi6LBQ1r1j2awq6t6lQhAeHkRQ==} + + '@zag-js/popover@1.27.0': + resolution: {integrity: sha512-uRFuZcJfSitv02OPpmEsDmIKJQF9JprXgrsgnNvbDRMw2njfMIXvoDqQS+duqYrnz78QKJL7TSgDy6xXbaEOig==} + + '@zag-js/popper@1.27.0': + resolution: {integrity: sha512-1eEEdhmIjZ7d9ymCB4QH8iCnPw3SHPNMaIccux3hz1cFZxwkgQprkiMl59BRwXMzM1wBHHQ5B8muznaUVvOMFQ==} + + '@zag-js/presence@1.27.0': + resolution: {integrity: sha512-u4YCQteURyDHbf6gy6ko9EScqU1qDUdl7xkuMe2Jl+bKRvpOPShA3/yVwLXaEcwQCIURJSg39huWRuuWYYWYjQ==} + + '@zag-js/progress@1.27.0': + resolution: {integrity: sha512-63cZO153qOrt8c/JWbiQ/x1zk3CJb7fhA7ZCNuGsloPgTEUHBtp0X6V01jSR/Y9SEK7ftUHhWUidTdnP56+5AQ==} + + '@zag-js/qr-code@1.27.0': + resolution: {integrity: sha512-jaSklNbr+GXwecAn/Ack2tu7YhIsaCtML7YHEEHa23cutVn3JVWH3xaZGkTXlNpfxRbuPUFcX5YRax8hwUkiGg==} + + '@zag-js/radio-group@1.27.0': + resolution: {integrity: sha512-VF1d/UlrpdnNN2iL4IzZLu2KBiMopw8qCFvfjSZVthIhEKpPrnc/VgHgZPhYmPveF3+pI22hZ8KUzoacDfd/rA==} + + '@zag-js/rating-group@1.27.0': + resolution: {integrity: sha512-7Mgfgr1UNh9ZF0A7UY5PpT18niMMV6RzrcUFIbBXAIKslfVvjTrT7FPnuT3JJN6BknL6BEYXTvpgf7IEtMyxTg==} + + '@zag-js/react@1.27.0': + resolution: {integrity: sha512-NyO+wd0CN5DmdvbDqOUHMsSnfl3SMFHszB+FqUlIPK5/fkpw/d/z2VCs4qHZ5t12w4goKcb2UKXdzbrqhA4jOQ==} + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + + '@zag-js/rect-utils@1.27.0': + resolution: {integrity: sha512-a6WKKURCVxv+c+vSC8K3/c7sHdbGtPNNU26/WRUGDdy9yz6C4cqPMy+43m/0vWF7/+hWLoLLClNQlE76M/PS0Q==} + + '@zag-js/remove-scroll@1.27.0': + resolution: {integrity: sha512-4MtYINKEhY0bz84Ot75+FKtRFXCmz8qyhN9zMfcU12lwvdYY07yDAlzaG10kFCGGmf1RDPOwxmtd+Dl1JcRWXQ==} + + '@zag-js/scroll-area@1.27.0': + resolution: {integrity: sha512-QF5y2Myturf4mnZKWuN6x8A3u79QaYN7EYfzhOEoAvtOg2ak5dBYgLR0vuxSPsJIh5vYIt160pPohls886lNgQ==} + + '@zag-js/scroll-snap@1.27.0': + resolution: {integrity: sha512-GYhzIkjwl8Oi0LAatKG/0yuPKeY8NzsX1Dvipw1ES8vD3k+bjESf2RY+lc8mQRC3NbOE+UHVA6EfULnxDriBBw==} + + '@zag-js/select@1.27.0': + resolution: {integrity: sha512-5IOGaS04vHnMA/3CCTdScoszZGtCsWAUta6qLcC1FGQehwvcoJPPhT2jY6RLE80YdsvUOEdL3hkYPlhH9VsJ5g==} + + '@zag-js/signature-pad@1.27.0': + resolution: {integrity: sha512-rJ1OPkE2D+WmSpwHitwXw73nNXtrxsc0pEyO07DuY1Ua0M7L5OV18JqDc4mWvEI13itSmXF5rkFtCUxI+fIzbg==} + + '@zag-js/slider@1.27.0': + resolution: {integrity: sha512-XRccFvA5Grflp0HRLCo+Ru2zUGr9Sk7/RNI2O+RSLKbdifFVQnLFK9WTyHHw1ns0qxMZbU1/lNGk4NFg5hh3UQ==} + + '@zag-js/splitter@1.27.0': + resolution: {integrity: sha512-uZmKai+3vW9nwsoST//6HtGWdLVuQWgNYQTHy0v69borNR30ng5RrQvy4t6P6orXwWmTEfF8t2paJkvWHYy5/Q==} + + '@zag-js/steps@1.27.0': + resolution: {integrity: sha512-vaiZBPtgQpPNwDPEXRH7KL/UMc/uvPCal5pbVUZYJlA/QbXSIkfWWaaXY1dQHMN92IbNRYWpfvBPEbMHOvwXwQ==} + + '@zag-js/store@1.27.0': + resolution: {integrity: sha512-LDK02t58I5YerVpW0t4Q3Jvu/NLv6fufeVo2WuGvYw5T6VJ/aGaPoRV8ENRyoSXuW4DSkVVDrm1jQNXuahK8Jg==} + + '@zag-js/switch@1.27.0': + resolution: {integrity: sha512-OYLG/Aer2l8yJDV/7xXCjpGDn+ODnIODXDHJ8QxWoXYqiJggZeX+lLsEODN9Wfj/Ssb9F0h/zdaMXRgp6IWGEg==} + + '@zag-js/tabs@1.27.0': + resolution: {integrity: sha512-+PwOMJGjGdcOIpXFyA/zJQaE0d7mboqgAE7GZXkAYZG80pBpQhoEio0RpMg66UvMFEqbjbi6Xb3E4U6Lvt+DtA==} + + '@zag-js/tags-input@1.27.0': + resolution: {integrity: sha512-xa9/M+5bPr5L4KQjl5X2w7I5NTSspbVcWpFjLw6w2bczo23PeayfOrNDhcFkOenn10OREA7vluVLlLkKJeq48Q==} + + '@zag-js/timer@1.27.0': + resolution: {integrity: sha512-7jwRMUsSn+FqXAebFLvgcMLU5G9D6j/zD0GfWhW0SEjUATfnMXf/pfqy/qPkEjxw/A+BntzHJ/wvsmemjbchsw==} + + '@zag-js/toast@1.27.0': + resolution: {integrity: sha512-Ng6DTh1dNdsTl6xqNJi6QxXxmf2wfA73YQVdLv8AOPG9ppLH/JORrM7XPJl4FQajox7r9mOnAKnHdcPywKZT2A==} + + '@zag-js/toggle-group@1.27.0': + resolution: {integrity: sha512-6yw50UiQryDH6M14dr6x6WQpUjocmaQcGASc0JRh69MbjD9fs0EzpjZBEWhTSjB0GrC6+AIrO/5ToAOTMO8RAw==} + + '@zag-js/toggle@1.27.0': + resolution: {integrity: sha512-NzRp02KUlTPI+R7TnNCWxj483jGAIdBRd3GDHTh/kzGzxpPtGP6S8DkpMs9/0bqgm31kkvYPLb2EjMZD2nP1pg==} + + '@zag-js/tooltip@1.27.0': + resolution: {integrity: sha512-6rLC39vAnC196xzw00GNeWephveKrj4goCXw+MEIkJTiKSYM78BcZkAndi929isiyda7XJ2Fb5vJ2oUg1vJgEQ==} + + '@zag-js/tour@1.27.0': + resolution: {integrity: sha512-tKsDcYLJJP5LY66hAlGP2lwelW1AjUxg3k4LxxEOdmWP//VlVxw6a7auaSPMeJ5kM3g4bn58CYsTTqlSqNZRmQ==} + + '@zag-js/tree-view@1.27.0': + resolution: {integrity: sha512-Y3syrU7ht9gQXM7JNwXeBYos1/dpzyS1Of4uWsmV9mlz08VN0d+zTDwPUH4e2xczaEIFW5LMhttf/AGSGT+3Yw==} + + '@zag-js/types@1.27.0': + resolution: {integrity: sha512-gd9G4C4Nszgs8VYE33aDM76olSExGqJi1J0gkH2Z6X9/isG/7AC3sF2R4ucJtfvnliCEX0I0soGFQiLd53S9HA==} + + '@zag-js/utils@1.27.0': + resolution: {integrity: sha512-kKaqcQDogeUa3Q9+z1YICBAbBVTPC1RdFdDJ8HJ+RxpbwhsfRmgcYFdtiQu4+nruG82BgoIUtdt9KzQAbM4rHQ==} + '@zkochan/js-yaml@0.0.7': resolution: {integrity: sha512-nrUSn7hzt7J6JWgWGz78ZYI8wj+gdIJdk0Ynjpp8l+trkn58Uqsf6RYrYkEK+3X18EX+TNdtJI0WxAtc+L84SQ==} hasBin: true @@ -869,6 +2703,9 @@ packages: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} + agentic-kit@0.1.2: + resolution: {integrity: sha512-VnGdH2zmP6j+XC7z2bxm04+IZl72XT14AC8BqTWYAV02vrfomFEhv6bSvhPQcMEa60qUFaQsUAQyGVS6XWNe3w==} + aggregate-error@3.1.0: resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} engines: {node: '>=8'} @@ -904,6 +2741,9 @@ packages: resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} engines: {node: '>=12'} + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} @@ -914,12 +2754,30 @@ packages: arg@4.1.3: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + aria-hidden@1.2.6: + resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} + engines: {node: '>=10'} + + aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + + array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} + engines: {node: '>= 0.4'} + array-differ@3.0.0: resolution: {integrity: sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==} engines: {node: '>=8'} @@ -927,10 +2785,38 @@ packages: array-ify@1.0.0: resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} + array-includes@3.1.9: + resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==} + engines: {node: '>= 0.4'} + array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} + array.prototype.findlast@1.2.5: + resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlastindex@1.2.6: + resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==} + engines: {node: '>= 0.4'} + + array.prototype.flat@1.3.3: + resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} + engines: {node: '>= 0.4'} + + array.prototype.flatmap@1.3.3: + resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} + engines: {node: '>= 0.4'} + + array.prototype.tosorted@1.1.4: + resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} + engines: {node: '>= 0.4'} + arrify@1.0.1: resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} engines: {node: '>=0.10.0'} @@ -939,15 +2825,41 @@ packages: resolution: {integrity: sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==} engines: {node: '>=8'} + ast-types-flow@0.0.8: + resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} + + async-function@1.0.0: + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} + engines: {node: '>= 0.4'} + async@3.2.6: resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + autoprefixer@10.4.21: + resolution: {integrity: sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + axe-core@4.11.0: + resolution: {integrity: sha512-ilYanEU8vxxBexpJd8cWM4ElSQq4QctCLKih0TSfjIfCQTeyH/6zVrmIJfLPrKTKJRbiG+cfnZbQIjAlJmF1jQ==} + engines: {node: '>=4'} + axios@1.13.2: resolution: {integrity: sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==} + axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} + engines: {node: '>= 0.4'} + babel-jest@29.7.0: resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -973,6 +2885,9 @@ packages: peerDependencies: '@babel/core': ^7.0.0 + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -990,6 +2905,10 @@ packages: resolution: {integrity: sha512-cMtq4W5ZsEwcutJrVId+a/tjt8GSbS+h0oNkdl6+6rBuEv8Ot33Bevj5KPm40t309zuhVic8NjpuL42QCiJWWA==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} @@ -1021,6 +2940,9 @@ packages: buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + byte-size@8.1.1: resolution: {integrity: sha512-tUkzZWK0M/qdoLEqikxBWe4kumyuwjl3HO6zHTr4yEI23EojPtLYXdG1+AQY7MN0cGyNDvEaJ8wiYQm6P2bPxg==} engines: {node: '>=12.17'} @@ -1033,10 +2955,22 @@ packages: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} + camelcase-css@2.0.1: + resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} + engines: {node: '>= 6'} + camelcase-keys@6.2.2: resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==} engines: {node: '>=8'} @@ -1052,6 +2986,9 @@ packages: caniuse-lite@1.0.30001754: resolution: {integrity: sha512-x6OeBXueoAceOmotzx3PO4Zpt4rzpeIFsSr6AAePTZxSkXiYDUmpypEl7e2+8NCd9bD7bXjqyef8CJYPC1jfxg==} + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + chalk@4.1.0: resolution: {integrity: sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==} engines: {node: '>=10'} @@ -1064,9 +3001,34 @@ packages: resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} engines: {node: '>=10'} + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@1.1.4: + resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + character-entities@1.2.4: + resolution: {integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + character-reference-invalid@1.1.4: + resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==} + + character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + chardet@2.1.1: resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + chownr@2.0.0: resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} engines: {node: '>=10'} @@ -1082,6 +3044,9 @@ packages: cjs-module-lexer@1.4.3: resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} + class-variance-authority@0.7.1: + resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} + clean-stack@2.2.0: resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} engines: {node: '>=6'} @@ -1102,6 +3067,13 @@ packages: resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} engines: {node: '>= 10'} + cli-width@4.1.0: + resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} + engines: {node: '>= 12'} + + client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + cliui@7.0.4: resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} @@ -1117,6 +3089,10 @@ packages: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + cmd-shim@6.0.3: resolution: {integrity: sha512-FMabTRlc5t5zjdenF6mS0MBeFZm0XqHqeOkcskKFb/LYCcRQ5fVgLOHVc4Lq9CqABd9zhjwPjMBCJvMCziSVtA==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} @@ -1147,6 +3123,20 @@ packages: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} + comma-separated-tokens@1.0.8: + resolution: {integrity: sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==} + + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + + commander@11.1.0: + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} + engines: {node: '>=16'} + + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + common-ancestor-path@1.0.1: resolution: {integrity: sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==} @@ -1197,6 +3187,10 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cookie@1.0.2: + resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} + engines: {node: '>=18'} + copyfiles@2.4.1: resolution: {integrity: sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg==} hasBin: true @@ -1221,25 +3215,69 @@ packages: create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + cross-fetch@4.1.0: + resolution: {integrity: sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==} + cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + css.escape@1.5.1: + resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} + cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} hasBin: true + cssstyle@4.6.0: + resolution: {integrity: sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==} + engines: {node: '>=18'} + csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + damerau-levenshtein@1.0.8: + resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} + dargs@7.0.0: resolution: {integrity: sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==} engines: {node: '>=8'} + data-uri-to-buffer@4.0.1: + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + engines: {node: '>= 12'} + + data-urls@5.0.0: + resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} + engines: {node: '>=18'} + + data-view-buffer@1.0.2: + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.2: + resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.1: + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} + engines: {node: '>= 0.4'} + dateformat@3.0.3: resolution: {integrity: sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==} + dayjs@1.11.19: + resolution: {integrity: sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==} + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} @@ -1257,6 +3295,12 @@ packages: resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} engines: {node: '>=0.10.0'} + decimal.js@10.6.0: + resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + + decode-named-character-reference@1.2.0: + resolution: {integrity: sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==} + dedent@1.5.3: resolution: {integrity: sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==} peerDependencies: @@ -1283,10 +3327,18 @@ packages: defaults@1.0.4: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + define-lazy-prop@2.0.0: resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} engines: {node: '>=8'} + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} @@ -1294,14 +3346,31 @@ packages: deprecation@2.3.1: resolution: {integrity: sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==} + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + detect-indent@5.0.0: resolution: {integrity: sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g==} engines: {node: '>=4'} + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + detect-newline@3.1.0: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} engines: {node: '>=8'} + detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + didyoumean@1.2.2: + resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + diff-sequences@29.6.3: resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -1314,10 +3383,23 @@ packages: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} + dlv@1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + + doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + doctrine@3.0.0: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} + dom-accessibility-api@0.5.16: + resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + + dom-accessibility-api@0.6.3: + resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} + dot-prop@5.3.0: resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} engines: {node: '>=8'} @@ -1345,6 +3427,19 @@ packages: electron-to-chromium@1.5.249: resolution: {integrity: sha512-5vcfL3BBe++qZ5kuFhD/p8WOM1N9m3nwvJPULJx+4xf2usSlZFJ0qoNYO2fOX4hi3ocuDcmDobtA+5SFr4OmBg==} + embla-carousel-react@8.6.0: + resolution: {integrity: sha512-0/PjqU7geVmo6F734pmPqpyHqiM99olvyecY7zdweCw+6tKEXnrE90pBiBbMMU8s5tICemzpQ3hi5EpxzGW+JA==} + peerDependencies: + react: ^16.8.0 || ^17.0.1 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + + embla-carousel-reactive-utils@8.6.0: + resolution: {integrity: sha512-fMVUDUEx0/uIEDM0Mz3dHznDhfX+znCCDCeIophYb1QGVM7YThSWX+wz11zlYwWFOr74b4QLGg0hrGPJeG2s4A==} + peerDependencies: + embla-carousel: 8.6.0 + + embla-carousel@8.6.0: + resolution: {integrity: sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==} + emittery@0.13.1: resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} engines: {node: '>=12'} @@ -1365,6 +3460,10 @@ packages: resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} engines: {node: '>=8.6'} + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} + env-paths@2.2.1: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} @@ -1380,6 +3479,10 @@ packages: error-ex@1.3.4: resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} + es-abstract@1.24.0: + resolution: {integrity: sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==} + engines: {node: '>= 0.4'} + es-define-property@1.0.1: resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} engines: {node: '>= 0.4'} @@ -1388,6 +3491,10 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} + es-iterator-helpers@1.2.1: + resolution: {integrity: sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==} + engines: {node: '>= 0.4'} + es-object-atoms@1.1.1: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} engines: {node: '>= 0.4'} @@ -1396,6 +3503,14 @@ packages: resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} engines: {node: '>= 0.4'} + es-shim-unscopables@1.1.0: + resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} + engines: {node: '>= 0.4'} + + es-to-primitive@1.3.0: + resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} + engines: {node: '>= 0.4'} + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -1412,12 +3527,90 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + + eslint-config-next@14.1.0: + resolution: {integrity: sha512-SBX2ed7DoRFXC6CQSLc/SbLY9Ut6HxNB2wPTcoIWjUMd7aF7O/SIE7111L8FdZ9TXsNV4pulUDnfthpyPtbFUg==} + peerDependencies: + eslint: ^7.23.0 || ^8.0.0 + typescript: '>=3.3.1' + peerDependenciesMeta: + typescript: + optional: true + eslint-config-prettier@9.1.2: resolution: {integrity: sha512-iI1f+D2ViGn+uvv5HuHVUamg8ll4tN+JRHGc6IJi4TP9Kl976C57fzPXgseXNs8v0iA8aSJpHsTWjDb9QJamGQ==} hasBin: true peerDependencies: eslint: '>=7.0.0' + eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + + eslint-import-resolver-typescript@3.10.1: + resolution: {integrity: sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + eslint-plugin-import-x: '*' + peerDependenciesMeta: + eslint-plugin-import: + optional: true + eslint-plugin-import-x: + optional: true + + eslint-module-utils@2.12.1: + resolution: {integrity: sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + + eslint-plugin-import@2.32.0: + resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + + eslint-plugin-jsx-a11y@6.10.2: + resolution: {integrity: sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==} + engines: {node: '>=4.0'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 + + eslint-plugin-react-hooks@5.0.0-canary-7118f5dd7-20230705: + resolution: {integrity: sha512-AZYbMo/NW9chdL7vk6HQzQhT+PvTAEVqWk9ziruUoW2kAOcN5qNyelv70e0F1VNQAbvutOC9oc+xfWycI9FxDw==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 + + eslint-plugin-react@7.37.5: + resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 + eslint-plugin-simple-import-sort@12.1.1: resolution: {integrity: sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA==} peerDependencies: @@ -1467,6 +3660,9 @@ packages: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} + estree-util-is-identifier-name@3.0.0: + resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} @@ -1493,6 +3689,13 @@ packages: exponential-backoff@3.1.3: resolution: {integrity: sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==} + extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -1512,6 +3715,9 @@ packages: fastq@1.19.1: resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + fault@1.0.4: + resolution: {integrity: sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==} + fb-watchman@2.0.2: resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} @@ -1524,6 +3730,10 @@ packages: picomatch: optional: true + fetch-blob@3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + figures@3.2.0: resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} engines: {node: '>=8'} @@ -1571,6 +3781,10 @@ packages: debug: optional: true + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + foreground-child@3.3.1: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} @@ -1579,6 +3793,17 @@ packages: resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} engines: {node: '>= 6'} + format@0.2.2: + resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} + engines: {node: '>=0.4.x'} + + formdata-polyfill@4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + + fraction.js@4.3.7: + resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + front-matter@4.0.2: resolution: {integrity: sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==} @@ -1600,6 +3825,11 @@ packages: fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -1608,6 +3838,17 @@ packages: function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + function.prototype.name@1.1.8: + resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + generator-function@2.0.1: + resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} + engines: {node: '>= 0.4'} + gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} @@ -1620,6 +3861,10 @@ packages: resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} engines: {node: '>= 0.4'} + get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + get-package-type@0.1.0: resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} engines: {node: '>=8.0.0'} @@ -1645,6 +3890,13 @@ packages: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} + get-symbol-description@1.1.0: + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} + engines: {node: '>= 0.4'} + + get-tsconfig@4.13.0: + resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} + git-raw-commits@3.0.0: resolution: {integrity: sha512-b5OHmZ3vAgGrDn/X0kS+9qCfNKWe4K/jFnhwzVWWg0/k5eLa3060tZShrRg8Dja5kPc+YjS0Gc6y7cRr44Lpjw==} engines: {node: '>=14'} @@ -1676,6 +3928,11 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} + glob@10.3.10: + resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + glob@10.4.5: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} hasBin: true @@ -1692,6 +3949,10 @@ packages: resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} engines: {node: '>=8'} + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + globby@11.1.0: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} @@ -1706,6 +3967,14 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + graphql@16.12.0: + resolution: {integrity: sha512-DKKrynuQRne0PNpEbzuEdHlYOMksHSUI8Zc9Unei5gTsMNA2/vMpoMz/yKba50pejK56qj98qM0SjYxAKi13gQ==} + engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} + + gray-matter@4.0.3: + resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} + engines: {node: '>=6.0'} + handlebars@4.7.8: resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} engines: {node: '>=0.4.7'} @@ -1715,10 +3984,21 @@ packages: resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==} engines: {node: '>=6'} + has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} + engines: {node: '>= 0.4'} + has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.2.0: + resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} + engines: {node: '>= 0.4'} + has-symbols@1.1.0: resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} engines: {node: '>= 0.4'} @@ -1734,6 +4014,27 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} + hast-util-parse-selector@2.2.5: + resolution: {integrity: sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==} + + hast-util-to-jsx-runtime@2.3.6: + resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + hastscript@6.0.0: + resolution: {integrity: sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==} + + headers-polyfill@4.0.3: + resolution: {integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==} + + highlight.js@10.7.3: + resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} + + highlightjs-vue@1.0.0: + resolution: {integrity: sha512-PDEfEF102G23vHmPhLyPboFCD+BkMGu+GuJe2d9/eH4FsCwvgBpnc9n0pGE+ffKdph38s6foEZiEjdgHdzp+IA==} + hosted-git-info@2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} @@ -1745,9 +4046,16 @@ packages: resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} engines: {node: ^16.14.0 || >=18.0.0} + html-encoding-sniffer@4.0.0: + resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==} + engines: {node: '>=18'} + html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + html-url-attributes@3.0.1: + resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==} + http-cache-semantics@4.2.0: resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} @@ -1822,20 +4130,70 @@ packages: resolution: {integrity: sha512-Zfeb5ol+H+eqJWHTaGca9BovufyGeIfr4zaaBorPmJBMrJ+KBnN+kQx2ZtXdsotUTgldHmHQV44xvUWOUA7E2w==} engines: {node: ^16.14.0 || >=18.0.0} + inline-style-parser@0.2.6: + resolution: {integrity: sha512-gtGXVaBdl5mAes3rPcMedEBm12ibjt1kDMFfheul1wUAOVEJW60voNdMVzVkfLN06O7ZaD/rxhfKgtlgtTbMjg==} + inquirer@8.2.7: resolution: {integrity: sha512-UjOaSel/iddGZJ5xP/Eixh6dY1XghiBw4XK13rCCIJcJfyhhoul/7KhLLUGtebEj6GDYM6Vnx/mVsjx2L/mFIA==} engines: {node: '>=12.0.0'} + inquirer@9.3.8: + resolution: {integrity: sha512-pFGGdaHrmRKMh4WoDDSowddgjT1Vkl90atobmTeSmcPGdYiwikch/m/Ef5wRaiamHejtw0cUUMMerzDUXCci2w==} + engines: {node: '>=18'} + inquirerer@2.0.8: resolution: {integrity: sha512-/LfmACfRG/pCg0C/Ll1matjeFWUQoyiHNJTgZqxpqw20mDg/9bdzcRQ/6PFRANKaC+BUf9J/bXvsQ6FEXJV3Xw==} + internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} + engines: {node: '>= 0.4'} + ip-address@10.0.1: resolution: {integrity: sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==} engines: {node: '>= 12'} + is-alphabetical@1.0.4: + resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==} + + is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + + is-alphanumerical@1.0.4: + resolution: {integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==} + + is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + + is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} + engines: {node: '>= 0.4'} + is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + is-async-function@2.1.1: + resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} + engines: {node: '>= 0.4'} + + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-boolean-object@1.2.2: + resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} + engines: {node: '>= 0.4'} + + is-bun-module@2.0.0: + resolution: {integrity: sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + is-ci@3.0.1: resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} hasBin: true @@ -1844,15 +4202,37 @@ packages: resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} engines: {node: '>= 0.4'} + is-data-view@1.0.2: + resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} + engines: {node: '>= 0.4'} + + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + + is-decimal@1.0.4: + resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==} + + is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + is-docker@2.2.1: resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} engines: {node: '>=8'} hasBin: true + is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} + is-finalizationregistry@1.1.1: + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} + engines: {node: '>= 0.4'} + is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} @@ -1861,10 +4241,20 @@ packages: resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} engines: {node: '>=6'} + is-generator-function@1.1.2: + resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} + engines: {node: '>= 0.4'} + is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} + is-hexadecimal@1.0.4: + resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==} + + is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + is-interactive@1.0.0: resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} engines: {node: '>=8'} @@ -1872,6 +4262,21 @@ packages: is-lambda@1.0.1: resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + + is-node-process@1.2.0: + resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==} + + is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} + engines: {node: '>= 0.4'} + is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -1888,10 +4293,29 @@ packages: resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} engines: {node: '>=0.10.0'} + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + is-plain-object@2.0.4: resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} engines: {node: '>=0.10.0'} + is-potential-custom-element-name@1.0.1: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} + engines: {node: '>= 0.4'} + is-ssh@1.4.1: resolution: {integrity: sha512-JNeu1wQsHjyHgn9NcWTaXq6zWSR6hqE0++zhfZlkFBbScNkyvxCdeV8sRkSBaeLKxmbpR21brail63ACNxJ0Tg==} @@ -1903,14 +4327,38 @@ packages: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} + is-string@1.1.1: + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} + engines: {node: '>= 0.4'} + + is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} + engines: {node: '>= 0.4'} + is-text-path@1.0.1: resolution: {integrity: sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==} engines: {node: '>=0.10.0'} + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + is-unicode-supported@0.1.0: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakref@1.1.1: + resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} + engines: {node: '>= 0.4'} + + is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} + engines: {node: '>= 0.4'} + is-wsl@2.2.0: resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} engines: {node: '>=8'} @@ -1921,6 +4369,9 @@ packages: isarray@1.0.0: resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} @@ -1959,6 +4410,14 @@ packages: resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} engines: {node: '>=8'} + iterator.prototype@1.1.5: + resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} + engines: {node: '>= 0.4'} + + jackspeak@2.3.6: + resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} + engines: {node: '>=14'} + jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} @@ -2009,10 +4468,25 @@ packages: resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-environment-jsdom@30.2.0: + resolution: {integrity: sha512-zbBTiqr2Vl78pKp/laGBREYzbZx9ZtqPjOK4++lL4BNDhxRnahg51HtoDrk9/VjIy9IthNEWdKVd7H5bqBhiWQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + peerDependencies: + canvas: ^3.0.0 + peerDependenciesMeta: + canvas: + optional: true + jest-environment-node@29.7.0: resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-fixed-jsdom@0.0.10: + resolution: {integrity: sha512-WaEVX+FripJh+Hn/7dysIgqP66h0KT1NNC22NGmNYANExtCoYNk1q2yjwwcdSboBMkkhn0NtmvKad/cmisnCLg==} + engines: {node: '>=18.0.0'} + peerDependencies: + jest-environment-jsdom: '>=28.0.0' + jest-get-type@29.6.3: resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -2033,10 +4507,18 @@ packages: resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-message-util@30.2.0: + resolution: {integrity: sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-mock@29.7.0: resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-mock@30.2.0: + resolution: {integrity: sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-pnp-resolver@1.2.3: resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} engines: {node: '>=6'} @@ -2050,6 +4532,10 @@ packages: resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-regex-util@30.0.1: + resolution: {integrity: sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-resolve-dependencies@29.7.0: resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -2074,6 +4560,10 @@ packages: resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-util@30.2.0: + resolution: {integrity: sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-validate@29.7.0: resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -2096,6 +4586,10 @@ packages: node-notifier: optional: true + jiti@1.21.7: + resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} + hasBin: true + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -2107,6 +4601,15 @@ packages: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true + jsdom@26.1.0: + resolution: {integrity: sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==} + engines: {node: '>=18'} + peerDependencies: + canvas: ^3.0.0 + peerDependenciesMeta: + canvas: + optional: true + jsesc@3.1.0: resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} engines: {node: '>=6'} @@ -2137,6 +4640,10 @@ packages: json-stringify-safe@5.0.1: resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} @@ -2152,6 +4659,10 @@ packages: resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} engines: {'0': node >= 0.2.0} + jsx-ast-utils@3.3.5: + resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} + engines: {node: '>=4.0'} + just-diff-apply@5.5.0: resolution: {integrity: sha512-OYTthRfSh55WOItVqwpefPtNt2VdKsq5AnAK6apdtR6yCH8pr0CmSr710J0Mf+WdQy7K/OzMy7K2MgAfdQURDw==} @@ -2169,6 +4680,16 @@ packages: resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} engines: {node: '>=6'} + kubernetesjs@0.6.2: + resolution: {integrity: sha512-pGo1uaVnAg4M6T18Y32xkIZ2KBgt7GfWHMi2yBXSlkijCIRDuv6kOpPC6JamtC8B7wCnbNmm/f6JK8WLFS+UPg==} + + language-subtag-registry@0.3.23: + resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} + + language-tags@1.0.9: + resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} + engines: {node: '>=0.10'} + lerna@8.2.4: resolution: {integrity: sha512-0gaVWDIVT7fLfprfwpYcQajb7dBJv3EGavjG7zvJ+TmGx3/wovl5GklnSwM2/WeE0Z2wrIz7ndWhBcDUHVjOcQ==} engines: {node: '>=18.0.0'} @@ -2190,6 +4711,10 @@ packages: resolution: {integrity: sha512-26zzwoBNAvX9AWOPiqqF6FG4HrSCPsHFkQm7nT+xU1ggAujL/eae81RnCv4CJ2In9q9fh10B88sYSzKCUh/Ghg==} engines: {node: ^16.14.0 || >=18.0.0} + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} @@ -2217,6 +4742,9 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} + lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + lodash.ismatch@4.4.0: resolution: {integrity: sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==} @@ -2233,10 +4761,16 @@ packages: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true + lowlight@1.20.0: + resolution: {integrity: sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==} + lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} @@ -2247,6 +4781,15 @@ packages: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} + lucide-react@0.454.0: + resolution: {integrity: sha512-hw7zMDwykCLnEzgncEEjHeA6+45aeEzRYuKHuyRSOPkhko+J3ySGjGIzu+mmMfDFG1vazHepMaYFYHbTFAZAAQ==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc + + lz-string@1.5.0: + resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + hasBin: true + make-dir@2.1.0: resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} engines: {node: '>=6'} @@ -2273,20 +4816,155 @@ packages: resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==} engines: {node: '>=8'} + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + + match-sorter@8.1.0: + resolution: {integrity: sha512-0HX3BHPixkbECX+Vt7nS1vJ6P2twPgGTU3PMXjWrl1eyVCL24tFHeyYN1FN5RKLzve0TyzNI9qntqQGbebnfPQ==} + math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} + mdast-util-find-and-replace@3.0.2: + resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} + + mdast-util-from-markdown@2.0.2: + resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==} + + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} + + mdast-util-gfm-footnote@2.1.0: + resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} + + mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + + mdast-util-gfm@3.1.0: + resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + + mdast-util-mdx-expression@2.0.1: + resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} + + mdast-util-mdx-jsx@3.2.0: + resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} + + mdast-util-mdxjs-esm@2.0.1: + resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} + + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + + mdast-util-to-hast@13.2.0: + resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==} + + mdast-util-to-markdown@2.1.2: + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + meow@8.1.2: resolution: {integrity: sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==} engines: {node: '>=10'} - merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + + micromark-extension-gfm-strikethrough@2.1.0: + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} + + micromark-extension-gfm-table@2.1.1: + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} + + micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + + micromark-extension-gfm-task-list-item@2.1.0: + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} + + micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} - merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} @@ -2389,6 +5067,16 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + msw@2.11.5: + resolution: {integrity: sha512-atFI4GjKSJComxcigz273honh8h4j5zzpk5kwG4tGm0TPcYne6bqmVrufeRll6auBeouIkXqZYXxVbWSWxM3RA==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + typescript: '>= 4.8.x' + peerDependenciesMeta: + typescript: + optional: true + multimatch@5.0.0: resolution: {integrity: sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==} engines: {node: '>=10'} @@ -2400,6 +5088,23 @@ packages: resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + mute-stream@2.0.0: + resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} + engines: {node: ^18.17.0 || >=20.5.0} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + napi-postinstall@0.3.4: + resolution: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + hasBin: true + natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -2410,6 +5115,45 @@ packages: neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + next-seo@6.8.0: + resolution: {integrity: sha512-zcxaV67PFXCSf8e6SXxbxPaOTgc8St/esxfsYXfQXMM24UESUVSXFm7f2A9HMkAwa0Gqn4s64HxYZAGfdF4Vhg==} + peerDependencies: + next: ^8.1.1-canary.54 || >=9.0.0 + react: '>=16.0.0' + react-dom: '>=16.0.0' + + next-themes@0.3.0: + resolution: {integrity: sha512-/QHIrsYpd6Kfk7xakK4svpDI5mmXP0gfvCoJdGpZQ2TOrQZmsW0QxjaiLn8wbIKjtm4BTSqLoix4lxYYOnLJ/w==} + peerDependencies: + react: ^16.8 || ^17 || ^18 + react-dom: ^16.8 || ^17 || ^18 + + next@15.5.6: + resolution: {integrity: sha512-zTxsnI3LQo3c9HSdSf91O1jMNsEzIXDShXd4wVdg9y5shwLqBXi4ZtUUJyB86KGVSJLZx0PFONvO54aheGX8QQ==} + engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.51.1 + babel-plugin-react-compiler: '*' + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + + node-domexception@1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + deprecated: Use your platform's native DOMException instead + node-fetch@2.6.7: resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} engines: {node: 4.x || >=6.0.0} @@ -2428,6 +5172,10 @@ packages: encoding: optional: true + node-fetch@3.3.2: + resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + node-gyp@10.3.1: resolution: {integrity: sha512-Pp3nFHBThHzVtNY7U6JfPjvT/DTE8+o/4xKsLQtBoU+j2HLsGlhcfzflAoUreaJbNmYnX+LlLi0qjV8kpyO6xQ==} engines: {node: ^16.14.0 || >=18.0.0} @@ -2465,6 +5213,10 @@ packages: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} + normalize-range@0.1.2: + resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} + engines: {node: '>=0.10.0'} + npm-bundled@3.0.1: resolution: {integrity: sha512-+AvaheE/ww1JEwRHOrn4WHNzOxGtVp+adrg2AeZS/7KuxGUYFuBta98wYpfHBbJp6Tg6j1NKSEVHNcfZzJHQwQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} @@ -2497,6 +5249,30 @@ packages: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} + nuqs@2.7.3: + resolution: {integrity: sha512-lQzSYLsXUYftc0cerww64yevjMeYOX8thkcqI25XtyyTEJFTk3LE+i2hcY2h0Jwvp1+owCb+KJ0GMaKQwfmq3g==} + peerDependencies: + '@remix-run/react': '>=2' + '@tanstack/react-router': ^1 + next: '>=14.2.0' + react: '>=18.2.0 || ^19.0.0-0' + react-router: ^6 || ^7 + react-router-dom: ^6 || ^7 + peerDependenciesMeta: + '@remix-run/react': + optional: true + '@tanstack/react-router': + optional: true + next: + optional: true + react-router: + optional: true + react-router-dom: + optional: true + + nwsapi@2.2.22: + resolution: {integrity: sha512-ujSMe1OWVn55euT1ihwCI1ZcAaAU3nxUiDwfDQldc51ZXaB9m2AyOn6/jh1BLe2t/G8xd6uKG1UBF2aZJeg2SQ==} + nx@20.8.2: resolution: {integrity: sha512-mDKpbH3vEpUFDx0rrLh+tTqLq1PYU8KiD/R7OVZGd1FxQxghx2HOl32MiqNsfPcw6AvKlXhslbwIESV+N55FLQ==} hasBin: true @@ -2509,6 +5285,42 @@ packages: '@swc/core': optional: true + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-hash@3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + + object.entries@1.1.9: + resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==} + engines: {node: '>= 0.4'} + + object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + + object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + + object.values@1.2.1: + resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} + engines: {node: '>= 0.4'} + once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} @@ -2532,6 +5344,13 @@ packages: resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} engines: {node: '>=10'} + outvariant@1.4.3: + resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} + + own-keys@1.0.1: + resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + engines: {node: '>= 0.4'} + p-finally@1.0.0: resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} engines: {node: '>=4'} @@ -2612,6 +5431,12 @@ packages: resolution: {integrity: sha512-01TvEktc68vwbJOtWZluyWeVGWjP+bZwXtPDMQVbBKzbJ/vZBif0L69KH1+cHv1SZ6e0FKLvjyHe8mqsIqYOmw==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + parse-entities@2.0.0: + resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==} + + parse-entities@4.0.2: + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + parse-json@4.0.0: resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} engines: {node: '>=4'} @@ -2626,6 +5451,9 @@ packages: parse-url@8.1.0: resolution: {integrity: sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w==} + parse5@7.3.0: + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + path-exists@3.0.0: resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} engines: {node: '>=4'} @@ -2649,6 +5477,9 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} + path-to-regexp@6.3.0: + resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} + path-type@3.0.0: resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} engines: {node: '>=4'} @@ -2657,6 +5488,43 @@ packages: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} + perfect-freehand@1.2.2: + resolution: {integrity: sha512-eh31l019WICQ03pkF3FSzHxB8n07ItqIQ++G5UV8JX0zVOXzgTGCqnRR0jJ2h9U8/2uW4W4mtGJELt9kEV0CFQ==} + + pg-cloudflare@1.2.7: + resolution: {integrity: sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==} + + pg-connection-string@2.9.1: + resolution: {integrity: sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w==} + + pg-int8@1.0.1: + resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} + engines: {node: '>=4.0.0'} + + pg-pool@3.10.1: + resolution: {integrity: sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg==} + peerDependencies: + pg: '>=8.0' + + pg-protocol@1.10.3: + resolution: {integrity: sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==} + + pg-types@2.2.0: + resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} + engines: {node: '>=4'} + + pg@8.16.3: + resolution: {integrity: sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==} + engines: {node: '>= 16.0.0'} + peerDependencies: + pg-native: '>=3.0.1' + peerDependenciesMeta: + pg-native: + optional: true + + pgpass@1.0.5: + resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -2692,10 +5560,87 @@ packages: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} + playwright-core@1.56.1: + resolution: {integrity: sha512-hutraynyn31F+Bifme+Ps9Vq59hKuUCz7H1kDOcBs+2oGguKkWTU50bBWrtz34OUWmIwpBTWDxaRPXrIXkgvmQ==} + engines: {node: '>=18'} + hasBin: true + + playwright@1.56.1: + resolution: {integrity: sha512-aFi5B0WovBHTEvpM3DzXTUaeN6eN0qWnTkKx4NQaH4Wvcmc153PdaY2UBdSYKaGYw+UyWXSVyxDUg5DoPEttjw==} + engines: {node: '>=18'} + hasBin: true + + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + + postcss-import@15.1.0: + resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} + engines: {node: '>=14.0.0'} + peerDependencies: + postcss: ^8.0.0 + + postcss-js@4.1.0: + resolution: {integrity: sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==} + engines: {node: ^12 || ^14 || >= 16} + peerDependencies: + postcss: ^8.4.21 + + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} + peerDependencies: + jiti: '>=1.21.0' + postcss: '>=8.0.9' + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + + postcss-nested@6.2.0: + resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + postcss-selector-parser@6.1.2: resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} engines: {node: '>=4'} + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss@8.4.31: + resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} + engines: {node: ^10 || ^12 || >=14} + + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + engines: {node: ^10 || ^12 || >=14} + + postgres-array@2.0.0: + resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} + engines: {node: '>=4'} + + postgres-bytea@1.0.0: + resolution: {integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==} + engines: {node: '>=0.10.0'} + + postgres-date@1.0.7: + resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} + engines: {node: '>=0.10.0'} + + postgres-interval@1.2.0: + resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} + engines: {node: '>=0.10.0'} + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -2705,10 +5650,26 @@ packages: engines: {node: '>=14'} hasBin: true + pretty-format@27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + pretty-format@29.7.0: resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + pretty-format@30.2.0: + resolution: {integrity: sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + prismjs@1.27.0: + resolution: {integrity: sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==} + engines: {node: '>=6'} + + prismjs@1.30.0: + resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} + engines: {node: '>=6'} + proc-log@4.2.0: resolution: {integrity: sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} @@ -2746,12 +5707,27 @@ packages: resolution: {integrity: sha512-2FPputGL+mP3jJ3UZg/Dl9YOkovB7DX0oOr+ck5QbZ5MtORtds8k/BZdn+02peDLI8/YWbmzx34k5fA+fHvCVQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + + property-information@5.6.0: + resolution: {integrity: sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==} + + property-information@7.1.0: + resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + protocols@2.0.2: resolution: {integrity: sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ==} + proxy-compare@3.0.1: + resolution: {integrity: sha512-V9plBAt3qjMlS1+nC8771KNf6oJ12gExvaxnNzN/9yVRLdTv/lc+oJlnSzrdYDAvBfTStPCoiaCOTmTs0adv7Q==} + proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + proxy-memoize@3.0.1: + resolution: {integrity: sha512-VDdG/VYtOgdGkWJx7y0o7p+zArSf2383Isci8C+BP3YXgMYDoPd3cCBjw0JdWb6YBb9sFiOPbAADDVTPJnh+9g==} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -2766,13 +5742,80 @@ packages: resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} engines: {node: '>=8'} + react-dom@18.3.1: + resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + peerDependencies: + react: ^18.3.1 + + react-error-boundary@3.1.4: + resolution: {integrity: sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==} + engines: {node: '>=10', npm: '>=6'} + peerDependencies: + react: '>=16.13.1' + + react-hook-form@7.66.0: + resolution: {integrity: sha512-xXBqsWGKrY46ZqaHDo+ZUYiMUgi8suYu5kdrS20EG8KiL7VRQitEbNjm+UcrDYrNi1YLyfpmAeGjCZYXLT9YBw==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^16.8.0 || ^17 || ^18 || ^19 + + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + react-is@18.3.1: resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + react-markdown@9.1.0: + resolution: {integrity: sha512-xaijuJB0kzGiUdG7nc2MOMDUDBWPyGAjZtUrow9XxUeua8IqeP+VlIfAZ3bphpcLTnSZXz6z9jcVC/TCwbfgdw==} + peerDependencies: + '@types/react': '>=18' + react: '>=18' + + react-remove-scroll-bar@2.3.8: + resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + react-remove-scroll@2.7.1: + resolution: {integrity: sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + react-style-singleton@2.2.3: + resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + react-syntax-highlighter@15.6.6: + resolution: {integrity: sha512-DgXrc+AZF47+HvAPEmn7Ua/1p10jNoVZVI/LoPiYdtY+OM+/nG5yefLHKJwdKqY1adMuHFbeyBaG9j64ML7vTw==} + peerDependencies: + react: '>= 0.14.0' + react@18.3.1: resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} engines: {node: '>=0.10.0'} + read-cache@1.0.0: + resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + read-cmd-shim@4.0.0: resolution: {integrity: sha512-yILWifhaSEEytfXI76kB9xEEiG1AiozaCJZ83A87ytjRiN+jVibXjedjCRNjoZviinhG+4UkalO3mWTd8u5O0Q==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} @@ -2811,10 +5854,43 @@ packages: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + redent@3.0.0: resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} engines: {node: '>=8'} + reflect.getprototypeof@1.0.10: + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} + engines: {node: '>= 0.4'} + + refractor@3.6.0: + resolution: {integrity: sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==} + + regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} + engines: {node: '>= 0.4'} + + remark-gfm@4.0.1: + resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + + remark-rehype@11.1.2: + resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==} + + remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + + remark@15.0.1: + resolution: {integrity: sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A==} + + remove-accents@0.5.0: + resolution: {integrity: sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==} + require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -2831,6 +5907,9 @@ packages: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + resolve.exports@2.0.3: resolution: {integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==} engines: {node: '>=10'} @@ -2840,6 +5919,10 @@ packages: engines: {node: '>= 0.4'} hasBin: true + resolve@2.0.0-next.5: + resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} + hasBin: true + restore-cursor@3.1.0: resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} engines: {node: '>=8'} @@ -2848,6 +5931,9 @@ packages: resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} engines: {node: '>= 4'} + rettime@0.7.0: + resolution: {integrity: sha512-LPRKoHnLKd/r3dVxcwO7vhCW+orkOGj9ViueosEBK6ie89CijnfRlhaDhHq/3Hxu4CkWQtxwlBG0mzTQY6uQjw==} + reusify@1.1.0: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -2862,31 +5948,67 @@ packages: engines: {node: '>=14'} hasBin: true + rrweb-cssom@0.8.0: + resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==} + run-async@2.4.1: resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} engines: {node: '>=0.12.0'} + run-async@3.0.0: + resolution: {integrity: sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==} + engines: {node: '>=0.12.0'} + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} rxjs@7.8.2: resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} + safe-array-concat@1.1.3: + resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} + engines: {node: '>=0.4'} + safe-buffer@5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + safe-push-apply@1.0.0: + resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} + engines: {node: '>= 0.4'} + + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + saxes@6.0.0: + resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} + engines: {node: '>=v12.22.7'} + + scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + + schema-sdk@0.11.3: + resolution: {integrity: sha512-clsw2kq2jkXAEhVw7qc1vV1xVBNUSbDc9OqhxU69XlKtiZaOfjz1viPB1FAFW4vFBM98YTzKNDDPA/jEh5Rr8A==} + schema-sdk@0.12.0: resolution: {integrity: sha512-Za2kaXpanSioGqkK4cRe/epndQkJc6a037EcJ6ZrvhoFs6N9IW9IRT/IVEv7J0bpyR4WGloB2yk4w+/eSUkMdg==} + schema-sdk@0.15.0: + resolution: {integrity: sha512-O7FFduWsrdjUew42oQ1cj66ckW5ElYB0iX+khV8f1W5Q7pC3cCCcPK7meH7EypEQEOHENTrW/kWziCX/dR9Mbg==} + schema-typescript@0.12.1: resolution: {integrity: sha512-dgfQrLjqsXEAC7vZ3fJDBsIPpUDJ2SrzuQFvXslrEjVjOSQyVykBua2tNmM4uFn4uIL7K3Ux64pXbaUnngkhhw==} + section-matter@1.0.0: + resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} + engines: {node: '>=4'} + semver@5.7.2: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true @@ -2903,10 +6025,26 @@ packages: set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + set-proto@1.0.0: + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} + engines: {node: '>= 0.4'} + shallow-clone@3.0.1: resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} engines: {node: '>=8'} + sharp@0.34.5: + resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -2915,6 +6053,22 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} @@ -2949,6 +6103,10 @@ packages: resolution: {integrity: sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg==} engines: {node: '>=4'} + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + source-map-support@0.5.13: resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} @@ -2956,6 +6114,12 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} + space-separated-tokens@1.1.5: + resolution: {integrity: sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==} + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + spdx-correct@3.2.0: resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} @@ -2971,6 +6135,10 @@ packages: split2@3.2.2: resolution: {integrity: sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==} + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + split@1.0.1: resolution: {integrity: sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==} @@ -2981,10 +6149,24 @@ packages: resolution: {integrity: sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + stable-hash@0.0.5: + resolution: {integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==} + stack-utils@2.0.6: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + + stop-iteration-iterator@1.1.0: + resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} + engines: {node: '>= 0.4'} + + strict-event-emitter@0.5.1: + resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} + string-length@4.0.2: resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} engines: {node: '>=10'} @@ -2997,6 +6179,29 @@ packages: resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} engines: {node: '>=12'} + string.prototype.includes@2.0.1: + resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==} + engines: {node: '>= 0.4'} + + string.prototype.matchall@4.0.12: + resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} + engines: {node: '>= 0.4'} + + string.prototype.repeat@1.0.0: + resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} + + string.prototype.trim@1.2.10: + resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.9: + resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} + engines: {node: '>= 0.4'} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + string_decoder@0.10.31: resolution: {integrity: sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==} @@ -3006,6 +6211,9 @@ packages: string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -3014,6 +6222,10 @@ packages: resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} engines: {node: '>=12'} + strip-bom-string@1.0.0: + resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} + engines: {node: '>=0.10.0'} + strip-bom@3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} @@ -3034,6 +6246,30 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} + style-to-js@1.1.19: + resolution: {integrity: sha512-Ev+SgeqiNGT1ufsXyVC5RrJRXdrkRJ1Gol9Qw7Pb72YCKJXrBvP0ckZhBeVSrw2m06DJpei2528uIpjMb4TsoQ==} + + style-to-object@1.0.12: + resolution: {integrity: sha512-ddJqYnoT4t97QvN2C95bCgt+m7AAgXjVnkk/jxAfmp7EAB8nnqqZYEbMd3em7/vEomDb2LAQKAy1RFfv41mdNw==} + + styled-jsx@5.1.6: + resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true + + sucrase@3.35.0: + resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -3046,6 +6282,22 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + symbol-tree@3.2.4: + resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + + tailwind-merge@2.6.0: + resolution: {integrity: sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==} + + tailwindcss-animate@1.0.7: + resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==} + peerDependencies: + tailwindcss: '>=3.0.0 || insiders' + + tailwindcss@3.4.18: + resolution: {integrity: sha512-6A2rnmW5xZMdw11LYjhcI5846rt9pbLSabY5XPxo+XWdxwZaFEn47Go4NzFiHu9sNNmr/kXivP1vStfvMaK1GQ==} + engines: {node: '>=14.0.0'} + hasBin: true + tar-stream@2.2.0: resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} engines: {node: '>=6'} @@ -3069,6 +6321,13 @@ packages: text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + through2@2.0.5: resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} @@ -3079,6 +6338,24 @@ packages: resolution: {integrity: sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==} engines: {node: '>=12.0.0'} + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + + tldts-core@6.1.86: + resolution: {integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==} + + tldts-core@7.0.17: + resolution: {integrity: sha512-DieYoGrP78PWKsrXr8MZwtQ7GLCUeLxihtjC1jZsW1DnvSMdKPitJSe8OSYDM2u5H6g3kWJZpePqkp43TfLh0g==} + + tldts@6.1.86: + resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} + hasBin: true + + tldts@7.0.17: + resolution: {integrity: sha512-Y1KQBgDd/NUc+LfOtKS6mNsC9CCaH+m2P1RoIZy7RAPo3C3/t8X45+zgut31cRZtZ3xKPjfn3TkGTrctC2TQIQ==} + hasBin: true + tmp@0.2.5: resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} engines: {node: '>=14.14'} @@ -3090,23 +6367,44 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + tough-cookie@5.1.2: + resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==} + engines: {node: '>=16'} + + tough-cookie@6.0.0: + resolution: {integrity: sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==} + engines: {node: '>=16'} + tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + tr46@5.1.1: + resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==} + engines: {node: '>=18'} + treeverse@3.0.0: resolution: {integrity: sha512-gcANaAnd2QDZFmHFEOF4k7uc1J/6a6z3DJMd/QwEyxLoKGiptJRwid582r7QIsFlFMIZ3SnxfS52S4hm2DHkuQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + trim-newlines@3.0.1: resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} engines: {node: '>=8'} + trough@2.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + ts-api-utils@1.4.3: resolution: {integrity: sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==} engines: {node: '>=16'} peerDependencies: typescript: '>=4.2.0' + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + ts-jest@29.4.5: resolution: {integrity: sha512-HO3GyiWn2qvTQA4kTgjDcXiMwYQt68a1Y8+JuLRVpdIzm+UOLSHgl/XqR4c6nzJkq5rOkjc02O2I7P7l/Yof0Q==} engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} @@ -3148,6 +6446,9 @@ packages: '@swc/wasm': optional: true + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + tsconfig-paths@4.2.0: resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} engines: {node: '>=6'} @@ -3195,6 +6496,22 @@ packages: resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} engines: {node: '>=16'} + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.3: + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.4: + resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.7: + resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} + engines: {node: '>= 0.4'} + typedarray@0.0.6: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} @@ -3208,9 +6525,20 @@ packages: engines: {node: '>=0.8.0'} hasBin: true + unbox-primitive@1.1.0: + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} + engines: {node: '>= 0.4'} + undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + undici@7.16.0: + resolution: {integrity: sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g==} + engines: {node: '>=20.18.1'} + + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + unique-filename@3.0.0: resolution: {integrity: sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} @@ -3219,6 +6547,21 @@ packages: resolution: {integrity: sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + unist-util-is@6.0.1: + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@6.0.2: + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + + unist-util-visit@5.0.0: + resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + universal-user-agent@6.0.1: resolution: {integrity: sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==} @@ -3226,6 +6569,12 @@ packages: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} + unrs-resolver@1.11.1: + resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} + + until-async@3.0.2: + resolution: {integrity: sha512-IiSk4HlzAMqTUseHHe3VhIGyuFmN90zMTpD3Z3y8jeQbzLIq500MVM7Jq2vUAnTKAFPJrqwkzr6PoTcPhGcOiw==} + untildify@4.0.0: resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} engines: {node: '>=8'} @@ -3240,9 +6589,43 @@ packages: peerDependencies: browserslist: '>= 4.21.0' + uqr@0.1.2: + resolution: {integrity: sha512-MJu7ypHq6QasgF5YRTjqscSzQp/W11zoUk6kvmlH+fmWEs63Y0Eib13hYFwAzagRJcVY8WVnlV+eBDUGMJ5IbA==} + uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + use-callback-ref@1.3.3: + resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + use-debounce@10.0.6: + resolution: {integrity: sha512-C5OtPyhAZgVoteO9heXMTdW7v/IbFI+8bSVKYCJrSmiWWCLsbUxiBSp4t9v0hNBTGY97bT72ydDIDyGSFWfwXg==} + engines: {node: '>= 16.0.0'} + peerDependencies: + react: '*' + + use-sidecar@1.1.3: + resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + use-sync-external-store@1.6.0: + resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} @@ -3250,6 +6633,10 @@ packages: resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} hasBin: true + uuid@11.1.0: + resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} + hasBin: true + v8-compile-cache-lib@3.0.1: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} @@ -3264,6 +6651,16 @@ packages: resolution: {integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + + w3c-xmlserializer@5.0.0: + resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} + engines: {node: '>=18'} + walk-up-path@3.0.1: resolution: {integrity: sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==} @@ -3273,15 +6670,51 @@ packages: wcwidth@1.0.1: resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + web-streams-polyfill@3.3.3: + resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} + engines: {node: '>= 8'} + webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + webidl-conversions@7.0.0: + resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} + engines: {node: '>=12'} + + whatwg-encoding@3.1.1: + resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} + engines: {node: '>=18'} + whatwg-fetch@3.6.20: resolution: {integrity: sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==} + whatwg-mimetype@4.0.0: + resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} + engines: {node: '>=18'} + + whatwg-url@14.2.0: + resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==} + engines: {node: '>=18'} + whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} + engines: {node: '>= 0.4'} + + which-builtin-type@1.2.1: + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + + which-typed-array@1.1.19: + resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} + engines: {node: '>= 0.4'} + which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -3336,6 +6769,25 @@ packages: resolution: {integrity: sha512-v2UQ+50TNf2rNHJ8NyWttfm/EJUBWMJcx6ZTYZr6Qp52uuegWw/lBkCtCbnYZEmPRNL61m+u67dAmGxo+HTULA==} engines: {node: '>=8'} + ws@8.18.3: + resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xml-name-validator@5.0.0: + resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} + engines: {node: '>=18'} + + xmlchars@2.2.0: + resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} @@ -3379,8 +6831,106 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + yoctocolors-cjs@2.1.3: + resolution: {integrity: sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==} + engines: {node: '>=18'} + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + snapshots: + '@adobe/css-tools@4.4.4': {} + + '@agentic-kit/bradie@0.1.2(encoding@0.1.13)': + dependencies: + cross-fetch: 4.1.0(encoding@0.1.13) + transitivePeerDependencies: + - encoding + + '@agentic-kit/ollama@0.1.2(encoding@0.1.13)': + dependencies: + cross-fetch: 4.1.0(encoding@0.1.13) + transitivePeerDependencies: + - encoding + + '@alloc/quick-lru@5.2.0': {} + + '@ark-ui/react@5.27.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@internationalized/date': 3.10.0 + '@zag-js/accordion': 1.27.0 + '@zag-js/anatomy': 1.27.0 + '@zag-js/angle-slider': 1.27.0 + '@zag-js/async-list': 1.27.0 + '@zag-js/auto-resize': 1.27.0 + '@zag-js/avatar': 1.27.0 + '@zag-js/bottom-sheet': 1.27.0 + '@zag-js/carousel': 1.27.0 + '@zag-js/checkbox': 1.27.0 + '@zag-js/clipboard': 1.27.0 + '@zag-js/collapsible': 1.27.0 + '@zag-js/collection': 1.27.0 + '@zag-js/color-picker': 1.27.0 + '@zag-js/color-utils': 1.27.0 + '@zag-js/combobox': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/date-picker': 1.27.0(@internationalized/date@3.10.0) + '@zag-js/date-utils': 1.27.0(@internationalized/date@3.10.0) + '@zag-js/dialog': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/editable': 1.27.0 + '@zag-js/file-upload': 1.27.0 + '@zag-js/file-utils': 1.27.0 + '@zag-js/floating-panel': 1.27.0 + '@zag-js/focus-trap': 1.27.0 + '@zag-js/highlight-word': 1.27.0 + '@zag-js/hover-card': 1.27.0 + '@zag-js/i18n-utils': 1.27.0 + '@zag-js/json-tree-utils': 1.27.0 + '@zag-js/listbox': 1.27.0 + '@zag-js/marquee': 1.27.0 + '@zag-js/menu': 1.27.0 + '@zag-js/number-input': 1.27.0 + '@zag-js/pagination': 1.27.0 + '@zag-js/password-input': 1.27.0 + '@zag-js/pin-input': 1.27.0 + '@zag-js/popover': 1.27.0 + '@zag-js/presence': 1.27.0 + '@zag-js/progress': 1.27.0 + '@zag-js/qr-code': 1.27.0 + '@zag-js/radio-group': 1.27.0 + '@zag-js/rating-group': 1.27.0 + '@zag-js/react': 1.27.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@zag-js/scroll-area': 1.27.0 + '@zag-js/select': 1.27.0 + '@zag-js/signature-pad': 1.27.0 + '@zag-js/slider': 1.27.0 + '@zag-js/splitter': 1.27.0 + '@zag-js/steps': 1.27.0 + '@zag-js/switch': 1.27.0 + '@zag-js/tabs': 1.27.0 + '@zag-js/tags-input': 1.27.0 + '@zag-js/timer': 1.27.0 + '@zag-js/toast': 1.27.0 + '@zag-js/toggle': 1.27.0 + '@zag-js/toggle-group': 1.27.0 + '@zag-js/tooltip': 1.27.0 + '@zag-js/tour': 1.27.0 + '@zag-js/tree-view': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@asamuzakjp/css-color@3.2.0': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + lru-cache: 10.4.3 + '@babel/code-frame@7.27.1': dependencies: '@babel/helper-validator-identifier': 7.28.5 @@ -3417,6 +6967,10 @@ snapshots: '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 + '@babel/helper-annotate-as-pure@7.27.3': + dependencies: + '@babel/types': 7.28.5 + '@babel/helper-compilation-targets@7.27.2': dependencies: '@babel/compat-data': 7.28.5 @@ -3425,8 +6979,28 @@ snapshots: lru-cache: 5.1.1 semver: 6.3.1 + '@babel/helper-create-class-features-plugin@7.28.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.5) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/traverse': 7.28.5 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + '@babel/helper-globals@7.28.0': {} + '@babel/helper-member-expression-to-functions@7.28.5': + dependencies: + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + transitivePeerDependencies: + - supports-color + '@babel/helper-module-imports@7.27.1': dependencies: '@babel/traverse': 7.28.5 @@ -3443,8 +7017,28 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-optimise-call-expression@7.27.1': + dependencies: + '@babel/types': 7.28.5 + '@babel/helper-plugin-utils@7.27.1': {} + '@babel/helper-replace-supers@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + dependencies: + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + transitivePeerDependencies: + - supports-color + '@babel/helper-string-parser@7.27.1': {} '@babel/helper-validator-identifier@7.28.5': {} @@ -3545,6 +7139,38 @@ snapshots: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-typescript@7.28.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.5) + transitivePeerDependencies: + - supports-color + + '@babel/preset-typescript@7.28.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-typescript': 7.28.5(@babel/core@7.28.5) + transitivePeerDependencies: + - supports-color + + '@babel/runtime@7.28.4': {} + '@babel/template@7.27.2': dependencies: '@babel/code-frame': 7.27.1 @@ -3574,55 +7200,211 @@ snapshots: dependencies: '@jridgewell/trace-mapping': 0.3.9 + '@csstools/color-helpers@5.1.0': {} + + '@csstools/css-calc@2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-color-parser@3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/color-helpers': 5.1.0 + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-tokenizer@3.0.4': {} + '@emnapi/core@1.7.0': dependencies: '@emnapi/wasi-threads': 1.1.0 tslib: 2.8.1 - '@emnapi/runtime@1.7.0': - dependencies: - tslib: 2.8.1 + '@emnapi/runtime@1.7.0': + dependencies: + tslib: 2.8.1 + + '@emnapi/wasi-threads@1.1.0': + dependencies: + tslib: 2.8.1 + + '@eslint-community/eslint-utils@4.9.0(eslint@8.57.1)': + dependencies: + eslint: 8.57.1 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/eslintrc@2.1.4': + dependencies: + ajv: 6.12.6 + debug: 4.4.3 + espree: 9.6.1 + globals: 13.24.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@8.57.1': {} + + '@floating-ui/core@1.7.3': + dependencies: + '@floating-ui/utils': 0.2.10 + + '@floating-ui/dom@1.7.4': + dependencies: + '@floating-ui/core': 1.7.3 + '@floating-ui/utils': 0.2.10 + + '@floating-ui/react-dom@2.1.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@floating-ui/dom': 1.7.4 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@floating-ui/utils@0.2.10': {} + + '@humanwhocodes/config-array@0.13.0': + dependencies: + '@humanwhocodes/object-schema': 2.0.3 + debug: 4.4.3 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/object-schema@2.0.3': {} + + '@hutson/parse-repository-url@3.0.2': {} + + '@img/colour@1.0.0': + optional: true + + '@img/sharp-darwin-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.2.4 + optional: true + + '@img/sharp-darwin-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.2.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.2.4': + optional: true + + '@img/sharp-libvips-linux-ppc64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-riscv64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-s390x@1.2.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + optional: true + + '@img/sharp-linux-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.2.4 + optional: true + + '@img/sharp-linux-arm@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.2.4 + optional: true + + '@img/sharp-linux-ppc64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-ppc64': 1.2.4 + optional: true + + '@img/sharp-linux-riscv64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-riscv64': 1.2.4 + optional: true + + '@img/sharp-linux-s390x@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.2.4 + optional: true - '@emnapi/wasi-threads@1.1.0': - dependencies: - tslib: 2.8.1 + '@img/sharp-linux-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.2.4 + optional: true - '@eslint-community/eslint-utils@4.9.0(eslint@8.57.1)': - dependencies: - eslint: 8.57.1 - eslint-visitor-keys: 3.4.3 + '@img/sharp-linuxmusl-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + optional: true - '@eslint-community/regexpp@4.12.2': {} + '@img/sharp-linuxmusl-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + optional: true - '@eslint/eslintrc@2.1.4': + '@img/sharp-wasm32@0.34.5': dependencies: - ajv: 6.12.6 - debug: 4.4.3 - espree: 9.6.1 - globals: 13.24.0 - ignore: 5.3.2 - import-fresh: 3.3.1 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color + '@emnapi/runtime': 1.7.0 + optional: true - '@eslint/js@8.57.1': {} + '@img/sharp-win32-arm64@0.34.5': + optional: true - '@humanwhocodes/config-array@0.13.0': - dependencies: - '@humanwhocodes/object-schema': 2.0.3 - debug: 4.4.3 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color + '@img/sharp-win32-ia32@0.34.5': + optional: true - '@humanwhocodes/module-importer@1.0.1': {} + '@img/sharp-win32-x64@0.34.5': + optional: true - '@humanwhocodes/object-schema@2.0.3': {} + '@inquirer/ansi@1.0.1': {} - '@hutson/parse-repository-url@3.0.2': {} + '@inquirer/confirm@5.1.19(@types/node@20.19.24)': + dependencies: + '@inquirer/core': 10.3.0(@types/node@20.19.24) + '@inquirer/type': 3.0.9(@types/node@20.19.24) + optionalDependencies: + '@types/node': 20.19.24 + + '@inquirer/core@10.3.0(@types/node@20.19.24)': + dependencies: + '@inquirer/ansi': 1.0.1 + '@inquirer/figures': 1.0.14 + '@inquirer/type': 3.0.9(@types/node@20.19.24) + cli-width: 4.1.0 + mute-stream: 2.0.0 + signal-exit: 4.1.0 + wrap-ansi: 6.2.0 + yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 20.19.24 '@inquirer/external-editor@1.0.2(@types/node@20.19.24)': dependencies: @@ -3631,6 +7413,20 @@ snapshots: optionalDependencies: '@types/node': 20.19.24 + '@inquirer/figures@1.0.14': {} + + '@inquirer/type@3.0.9(@types/node@20.19.24)': + optionalDependencies: + '@types/node': 20.19.24 + + '@internationalized/date@3.10.0': + dependencies: + '@swc/helpers': 0.5.17 + + '@internationalized/number@3.6.5': + dependencies: + '@swc/helpers': 0.5.17 + '@interweb-utils/casing@0.2.0': {} '@interweb/fetch-api-client@0.6.1(encoding@0.1.13)': @@ -3672,7 +7468,7 @@ snapshots: jest-util: 29.7.0 slash: 3.0.0 - '@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3))': + '@jest/core@29.7.0(ts-node@10.9.2(@swc/core@1.15.0(@swc/helpers@0.5.17))(@swc/wasm@1.15.0)(@types/node@20.19.24)(typescript@5.9.3))': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0 @@ -3686,7 +7482,7 @@ snapshots: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3)) + jest-config: 29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@swc/core@1.15.0(@swc/helpers@0.5.17))(@swc/wasm@1.15.0)(@types/node@20.19.24)(typescript@5.9.3)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -3707,6 +7503,17 @@ snapshots: - supports-color - ts-node + '@jest/environment-jsdom-abstract@30.2.0(jsdom@26.1.0)': + dependencies: + '@jest/environment': 30.2.0 + '@jest/fake-timers': 30.2.0 + '@jest/types': 30.2.0 + '@types/jsdom': 21.1.7 + '@types/node': 20.19.24 + jest-mock: 30.2.0 + jest-util: 30.2.0 + jsdom: 26.1.0 + '@jest/environment@29.7.0': dependencies: '@jest/fake-timers': 29.7.0 @@ -3714,6 +7521,13 @@ snapshots: '@types/node': 20.19.24 jest-mock: 29.7.0 + '@jest/environment@30.2.0': + dependencies: + '@jest/fake-timers': 30.2.0 + '@jest/types': 30.2.0 + '@types/node': 20.19.24 + jest-mock: 30.2.0 + '@jest/expect-utils@29.7.0': dependencies: jest-get-type: 29.6.3 @@ -3734,6 +7548,15 @@ snapshots: jest-mock: 29.7.0 jest-util: 29.7.0 + '@jest/fake-timers@30.2.0': + dependencies: + '@jest/types': 30.2.0 + '@sinonjs/fake-timers': 13.0.5 + '@types/node': 20.19.24 + jest-message-util: 30.2.0 + jest-mock: 30.2.0 + jest-util: 30.2.0 + '@jest/globals@29.7.0': dependencies: '@jest/environment': 29.7.0 @@ -3743,6 +7566,11 @@ snapshots: transitivePeerDependencies: - supports-color + '@jest/pattern@30.0.1': + dependencies: + '@types/node': 20.19.24 + jest-regex-util: 30.0.1 + '@jest/reporters@29.7.0': dependencies: '@bcoe/v8-coverage': 0.2.3 @@ -3776,6 +7604,10 @@ snapshots: dependencies: '@sinclair/typebox': 0.27.8 + '@jest/schemas@30.0.5': + dependencies: + '@sinclair/typebox': 0.34.41 + '@jest/source-map@29.6.3': dependencies: '@jridgewell/trace-mapping': 0.3.31 @@ -3825,6 +7657,16 @@ snapshots: '@types/yargs': 17.0.34 chalk: 4.1.2 + '@jest/types@30.2.0': + dependencies: + '@jest/pattern': 30.0.1 + '@jest/schemas': 30.0.5 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 20.19.24 + '@types/yargs': 17.0.34 + chalk: 4.1.2 + '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -3849,12 +7691,12 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - '@lerna/create@8.2.4(@types/node@20.19.24)(encoding@0.1.13)(typescript@5.9.3)': + '@lerna/create@8.2.4(@swc/core@1.15.0(@swc/helpers@0.5.17))(@types/node@20.19.24)(encoding@0.1.13)(typescript@5.9.3)': dependencies: '@npmcli/arborist': 7.5.4 '@npmcli/package-json': 5.2.0 '@npmcli/run-script': 8.1.0 - '@nx/devkit': 20.8.2(nx@20.8.2) + '@nx/devkit': 20.8.2(nx@20.8.2(@swc/core@1.15.0(@swc/helpers@0.5.17))) '@octokit/plugin-enterprise-rest': 6.0.1 '@octokit/rest': 20.1.2 aproba: 2.0.0 @@ -3891,7 +7733,7 @@ snapshots: npm-package-arg: 11.0.2 npm-packlist: 8.0.2 npm-registry-fetch: 17.1.0 - nx: 20.8.2 + nx: 20.8.2(@swc/core@1.15.0(@swc/helpers@0.5.17)) p-map: 4.0.0 p-map-series: 2.1.0 p-queue: 6.6.2 @@ -3931,12 +7773,58 @@ snapshots: - supports-color - typescript + '@mswjs/interceptors@0.39.8': + dependencies: + '@open-draft/deferred-promise': 2.2.0 + '@open-draft/logger': 0.3.0 + '@open-draft/until': 2.1.0 + is-node-process: 1.2.0 + outvariant: 1.4.3 + strict-event-emitter: 0.5.1 + + '@napi-rs/wasm-runtime@0.2.12': + dependencies: + '@emnapi/core': 1.7.0 + '@emnapi/runtime': 1.7.0 + '@tybys/wasm-util': 0.10.1 + optional: true + '@napi-rs/wasm-runtime@0.2.4': dependencies: '@emnapi/core': 1.7.0 '@emnapi/runtime': 1.7.0 '@tybys/wasm-util': 0.9.0 + '@next/env@15.5.6': {} + + '@next/eslint-plugin-next@14.1.0': + dependencies: + glob: 10.3.10 + + '@next/swc-darwin-arm64@15.5.6': + optional: true + + '@next/swc-darwin-x64@15.5.6': + optional: true + + '@next/swc-linux-arm64-gnu@15.5.6': + optional: true + + '@next/swc-linux-arm64-musl@15.5.6': + optional: true + + '@next/swc-linux-x64-gnu@15.5.6': + optional: true + + '@next/swc-linux-x64-musl@15.5.6': + optional: true + + '@next/swc-win32-arm64-msvc@15.5.6': + optional: true + + '@next/swc-win32-x64-msvc@15.5.6': + optional: true + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -3949,6 +7837,8 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.1 + '@nolyfill/is-core-module@1.0.39': {} + '@npmcli/agent@2.2.2': dependencies: agent-base: 7.1.4 @@ -4079,115 +7969,697 @@ snapshots: - bluebird - supports-color - '@nx/devkit@20.8.2(nx@20.8.2)': + '@nx/devkit@20.8.2(nx@20.8.2(@swc/core@1.15.0(@swc/helpers@0.5.17)))': dependencies: ejs: 3.1.10 enquirer: 2.3.6 ignore: 5.3.2 minimatch: 9.0.3 - nx: 20.8.2 + nx: 20.8.2(@swc/core@1.15.0(@swc/helpers@0.5.17)) semver: 7.7.3 tmp: 0.2.5 tslib: 2.8.1 yargs-parser: 21.1.1 - '@nx/nx-darwin-arm64@20.8.2': - optional: true + '@nx/nx-darwin-arm64@20.8.2': + optional: true + + '@nx/nx-darwin-x64@20.8.2': + optional: true + + '@nx/nx-freebsd-x64@20.8.2': + optional: true + + '@nx/nx-linux-arm-gnueabihf@20.8.2': + optional: true + + '@nx/nx-linux-arm64-gnu@20.8.2': + optional: true + + '@nx/nx-linux-arm64-musl@20.8.2': + optional: true + + '@nx/nx-linux-x64-gnu@20.8.2': + optional: true + + '@nx/nx-linux-x64-musl@20.8.2': + optional: true + + '@nx/nx-win32-arm64-msvc@20.8.2': + optional: true + + '@nx/nx-win32-x64-msvc@20.8.2': + optional: true + + '@octokit/auth-token@4.0.0': {} + + '@octokit/core@5.2.2': + dependencies: + '@octokit/auth-token': 4.0.0 + '@octokit/graphql': 7.1.1 + '@octokit/request': 8.4.1 + '@octokit/request-error': 5.1.1 + '@octokit/types': 13.10.0 + before-after-hook: 2.2.3 + universal-user-agent: 6.0.1 + + '@octokit/endpoint@9.0.6': + dependencies: + '@octokit/types': 13.10.0 + universal-user-agent: 6.0.1 + + '@octokit/graphql@7.1.1': + dependencies: + '@octokit/request': 8.4.1 + '@octokit/types': 13.10.0 + universal-user-agent: 6.0.1 + + '@octokit/openapi-types@24.2.0': {} + + '@octokit/plugin-enterprise-rest@6.0.1': {} + + '@octokit/plugin-paginate-rest@11.4.4-cjs.2(@octokit/core@5.2.2)': + dependencies: + '@octokit/core': 5.2.2 + '@octokit/types': 13.10.0 + + '@octokit/plugin-request-log@4.0.1(@octokit/core@5.2.2)': + dependencies: + '@octokit/core': 5.2.2 + + '@octokit/plugin-rest-endpoint-methods@13.3.2-cjs.1(@octokit/core@5.2.2)': + dependencies: + '@octokit/core': 5.2.2 + '@octokit/types': 13.10.0 + + '@octokit/request-error@5.1.1': + dependencies: + '@octokit/types': 13.10.0 + deprecation: 2.3.1 + once: 1.4.0 + + '@octokit/request@8.4.1': + dependencies: + '@octokit/endpoint': 9.0.6 + '@octokit/request-error': 5.1.1 + '@octokit/types': 13.10.0 + universal-user-agent: 6.0.1 + + '@octokit/rest@20.1.2': + dependencies: + '@octokit/core': 5.2.2 + '@octokit/plugin-paginate-rest': 11.4.4-cjs.2(@octokit/core@5.2.2) + '@octokit/plugin-request-log': 4.0.1(@octokit/core@5.2.2) + '@octokit/plugin-rest-endpoint-methods': 13.3.2-cjs.1(@octokit/core@5.2.2) + + '@octokit/types@13.10.0': + dependencies: + '@octokit/openapi-types': 24.2.0 + + '@open-draft/deferred-promise@2.2.0': {} + + '@open-draft/logger@0.3.0': + dependencies: + is-node-process: 1.2.0 + outvariant: 1.4.3 + + '@open-draft/until@2.1.0': {} + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@playwright/test@1.56.1': + dependencies: + playwright: 1.56.1 + + '@radix-ui/number@1.1.1': {} + + '@radix-ui/primitive@1.1.3': {} + + '@radix-ui/react-accordion@1.2.12(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.26)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.26 + '@types/react-dom': 18.3.7(@types/react@18.3.26) + + '@radix-ui/react-alert-dialog@1.1.15(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-dialog': 1.1.15(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@18.3.26)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.26 + '@types/react-dom': 18.3.7(@types/react@18.3.26) + + '@radix-ui/react-arrow@1.1.7(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.26 + '@types/react-dom': 18.3.7(@types/react@18.3.26) + + '@radix-ui/react-avatar@1.1.11(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-context': 1.1.3(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.4(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.26)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.26 + '@types/react-dom': 18.3.7(@types/react@18.3.26) + + '@radix-ui/react-checkbox@1.3.3(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@18.3.26)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.26 + '@types/react-dom': 18.3.7(@types/react@18.3.26) + + '@radix-ui/react-collapsible@1.1.12(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.26)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.26 + '@types/react-dom': 18.3.7(@types/react@18.3.26) + + '@radix-ui/react-collection@1.1.7(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@18.3.26)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.26 + '@types/react-dom': 18.3.7(@types/react@18.3.26) + + '@radix-ui/react-compose-refs@1.1.2(@types/react@18.3.26)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.26 + + '@radix-ui/react-context-menu@2.2.16(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-context': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-menu': 2.1.16(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.26)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.26 + '@types/react-dom': 18.3.7(@types/react@18.3.26) + + '@radix-ui/react-context@1.1.2(@types/react@18.3.26)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.26 + + '@radix-ui/react-context@1.1.3(@types/react@18.3.26)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.26 + + '@radix-ui/react-dialog@1.1.15(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.26)(react@18.3.1) + aria-hidden: 1.2.6 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.7.1(@types/react@18.3.26)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.26 + '@types/react-dom': 18.3.7(@types/react@18.3.26) + + '@radix-ui/react-direction@1.1.1(@types/react@18.3.26)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.26 - '@nx/nx-darwin-x64@20.8.2': - optional: true + '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@18.3.26)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.26 + '@types/react-dom': 18.3.7(@types/react@18.3.26) + + '@radix-ui/react-dropdown-menu@2.1.16(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-menu': 2.1.16(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.26)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.26 + '@types/react-dom': 18.3.7(@types/react@18.3.26) - '@nx/nx-freebsd-x64@20.8.2': - optional: true + '@radix-ui/react-focus-guards@1.1.3(@types/react@18.3.26)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.26 - '@nx/nx-linux-arm-gnueabihf@20.8.2': - optional: true + '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.26)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.26 + '@types/react-dom': 18.3.7(@types/react@18.3.26) - '@nx/nx-linux-arm64-gnu@20.8.2': - optional: true + '@radix-ui/react-id@1.1.1(@types/react@18.3.26)(react@18.3.1)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.26)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.26 - '@nx/nx-linux-arm64-musl@20.8.2': - optional: true + '@radix-ui/react-label@2.1.8(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-primitive': 2.1.4(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.26 + '@types/react-dom': 18.3.7(@types/react@18.3.26) + + '@radix-ui/react-menu@2.1.16(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.26)(react@18.3.1) + aria-hidden: 1.2.6 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.7.1(@types/react@18.3.26)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.26 + '@types/react-dom': 18.3.7(@types/react@18.3.26) + + '@radix-ui/react-popover@1.1.15(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.26)(react@18.3.1) + aria-hidden: 1.2.6 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.7.1(@types/react@18.3.26)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.26 + '@types/react-dom': 18.3.7(@types/react@18.3.26) + + '@radix-ui/react-popper@1.2.8(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@floating-ui/react-dom': 2.1.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-arrow': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-use-rect': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/rect': 1.1.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.26 + '@types/react-dom': 18.3.7(@types/react@18.3.26) - '@nx/nx-linux-x64-gnu@20.8.2': - optional: true + '@radix-ui/react-portal@1.1.9(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.26)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.26 + '@types/react-dom': 18.3.7(@types/react@18.3.26) - '@nx/nx-linux-x64-musl@20.8.2': - optional: true + '@radix-ui/react-presence@1.1.5(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.26)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.26 + '@types/react-dom': 18.3.7(@types/react@18.3.26) - '@nx/nx-win32-arm64-msvc@20.8.2': - optional: true + '@radix-ui/react-primitive@2.1.3(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-slot': 1.2.3(@types/react@18.3.26)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.26 + '@types/react-dom': 18.3.7(@types/react@18.3.26) - '@nx/nx-win32-x64-msvc@20.8.2': - optional: true + '@radix-ui/react-primitive@2.1.4(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-slot': 1.2.4(@types/react@18.3.26)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.26 + '@types/react-dom': 18.3.7(@types/react@18.3.26) + + '@radix-ui/react-radio-group@1.3.8(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@18.3.26)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.26 + '@types/react-dom': 18.3.7(@types/react@18.3.26) + + '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.26)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.26 + '@types/react-dom': 18.3.7(@types/react@18.3.26) + + '@radix-ui/react-scroll-area@1.2.10(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/number': 1.1.1 + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.26)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.26 + '@types/react-dom': 18.3.7(@types/react@18.3.26) + + '@radix-ui/react-select@2.2.6(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/number': 1.1.1 + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + aria-hidden: 1.2.6 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.7.1(@types/react@18.3.26)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.26 + '@types/react-dom': 18.3.7(@types/react@18.3.26) - '@octokit/auth-token@4.0.0': {} + '@radix-ui/react-slot@1.2.3(@types/react@18.3.26)(react@18.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.26)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.26 - '@octokit/core@5.2.2': + '@radix-ui/react-slot@1.2.4(@types/react@18.3.26)(react@18.3.1)': dependencies: - '@octokit/auth-token': 4.0.0 - '@octokit/graphql': 7.1.1 - '@octokit/request': 8.4.1 - '@octokit/request-error': 5.1.1 - '@octokit/types': 13.10.0 - before-after-hook: 2.2.3 - universal-user-agent: 6.0.1 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.26)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.26 - '@octokit/endpoint@9.0.6': + '@radix-ui/react-switch@1.2.6(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@octokit/types': 13.10.0 - universal-user-agent: 6.0.1 + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@18.3.26)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.26 + '@types/react-dom': 18.3.7(@types/react@18.3.26) + + '@radix-ui/react-tabs@1.1.13(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-context': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.26)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.26 + '@types/react-dom': 18.3.7(@types/react@18.3.26) + + '@radix-ui/react-toast@1.2.15(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.26 + '@types/react-dom': 18.3.7(@types/react@18.3.26) + + '@radix-ui/react-tooltip@1.2.8(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.26 + '@types/react-dom': 18.3.7(@types/react@18.3.26) - '@octokit/graphql@7.1.1': + '@radix-ui/react-use-callback-ref@1.1.1(@types/react@18.3.26)(react@18.3.1)': dependencies: - '@octokit/request': 8.4.1 - '@octokit/types': 13.10.0 - universal-user-agent: 6.0.1 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.26 - '@octokit/openapi-types@24.2.0': {} + '@radix-ui/react-use-controllable-state@1.2.2(@types/react@18.3.26)(react@18.3.1)': + dependencies: + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@18.3.26)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.26)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.26 - '@octokit/plugin-enterprise-rest@6.0.1': {} + '@radix-ui/react-use-effect-event@0.0.2(@types/react@18.3.26)(react@18.3.1)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.26)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.26 - '@octokit/plugin-paginate-rest@11.4.4-cjs.2(@octokit/core@5.2.2)': + '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@18.3.26)(react@18.3.1)': dependencies: - '@octokit/core': 5.2.2 - '@octokit/types': 13.10.0 + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.26)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.26 - '@octokit/plugin-request-log@4.0.1(@octokit/core@5.2.2)': + '@radix-ui/react-use-is-hydrated@0.1.0(@types/react@18.3.26)(react@18.3.1)': dependencies: - '@octokit/core': 5.2.2 + react: 18.3.1 + use-sync-external-store: 1.6.0(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.26 - '@octokit/plugin-rest-endpoint-methods@13.3.2-cjs.1(@octokit/core@5.2.2)': + '@radix-ui/react-use-layout-effect@1.1.1(@types/react@18.3.26)(react@18.3.1)': dependencies: - '@octokit/core': 5.2.2 - '@octokit/types': 13.10.0 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.26 - '@octokit/request-error@5.1.1': + '@radix-ui/react-use-previous@1.1.1(@types/react@18.3.26)(react@18.3.1)': dependencies: - '@octokit/types': 13.10.0 - deprecation: 2.3.1 - once: 1.4.0 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.26 - '@octokit/request@8.4.1': + '@radix-ui/react-use-rect@1.1.1(@types/react@18.3.26)(react@18.3.1)': dependencies: - '@octokit/endpoint': 9.0.6 - '@octokit/request-error': 5.1.1 - '@octokit/types': 13.10.0 - universal-user-agent: 6.0.1 + '@radix-ui/rect': 1.1.1 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.26 - '@octokit/rest@20.1.2': + '@radix-ui/react-use-size@1.1.1(@types/react@18.3.26)(react@18.3.1)': dependencies: - '@octokit/core': 5.2.2 - '@octokit/plugin-paginate-rest': 11.4.4-cjs.2(@octokit/core@5.2.2) - '@octokit/plugin-request-log': 4.0.1(@octokit/core@5.2.2) - '@octokit/plugin-rest-endpoint-methods': 13.3.2-cjs.1(@octokit/core@5.2.2) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.26)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.26 - '@octokit/types@13.10.0': + '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@octokit/openapi-types': 24.2.0 + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.26 + '@types/react-dom': 18.3.7(@types/react@18.3.26) - '@pkgjs/parseargs@0.11.0': - optional: true + '@radix-ui/rect@1.1.1': {} + + '@rtsao/scc@1.1.0': {} + + '@rushstack/eslint-patch@1.14.1': {} '@sigstore/bundle@2.3.2': dependencies: @@ -4223,6 +8695,8 @@ snapshots: '@sinclair/typebox@0.27.8': {} + '@sinclair/typebox@0.34.41': {} + '@sinonjs/commons@3.0.1': dependencies: type-detect: 4.0.8 @@ -4231,6 +8705,77 @@ snapshots: dependencies: '@sinonjs/commons': 3.0.1 + '@sinonjs/fake-timers@13.0.5': + dependencies: + '@sinonjs/commons': 3.0.1 + + '@standard-schema/spec@1.0.0': {} + + '@swc/core-darwin-arm64@1.15.0': + optional: true + + '@swc/core-darwin-x64@1.15.0': + optional: true + + '@swc/core-linux-arm-gnueabihf@1.15.0': + optional: true + + '@swc/core-linux-arm64-gnu@1.15.0': + optional: true + + '@swc/core-linux-arm64-musl@1.15.0': + optional: true + + '@swc/core-linux-x64-gnu@1.15.0': + optional: true + + '@swc/core-linux-x64-musl@1.15.0': + optional: true + + '@swc/core-win32-arm64-msvc@1.15.0': + optional: true + + '@swc/core-win32-ia32-msvc@1.15.0': + optional: true + + '@swc/core-win32-x64-msvc@1.15.0': + optional: true + + '@swc/core@1.15.0(@swc/helpers@0.5.17)': + dependencies: + '@swc/counter': 0.1.3 + '@swc/types': 0.1.25 + optionalDependencies: + '@swc/core-darwin-arm64': 1.15.0 + '@swc/core-darwin-x64': 1.15.0 + '@swc/core-linux-arm-gnueabihf': 1.15.0 + '@swc/core-linux-arm64-gnu': 1.15.0 + '@swc/core-linux-arm64-musl': 1.15.0 + '@swc/core-linux-x64-gnu': 1.15.0 + '@swc/core-linux-x64-musl': 1.15.0 + '@swc/core-win32-arm64-msvc': 1.15.0 + '@swc/core-win32-ia32-msvc': 1.15.0 + '@swc/core-win32-x64-msvc': 1.15.0 + '@swc/helpers': 0.5.17 + + '@swc/counter@0.1.3': {} + + '@swc/helpers@0.5.15': + dependencies: + tslib: 2.8.1 + + '@swc/helpers@0.5.17': + dependencies: + tslib: 2.8.1 + + '@swc/types@0.1.25': + dependencies: + '@swc/counter': 0.1.3 + + '@swc/wasm-web@1.15.0': {} + + '@swc/wasm@1.15.0': {} + '@tanstack/query-core@5.79.2': {} '@tanstack/react-query@5.79.2(react@18.3.1)': @@ -4238,6 +8783,49 @@ snapshots: '@tanstack/query-core': 5.79.2 react: 18.3.1 + '@testing-library/dom@10.4.1': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/runtime': 7.28.4 + '@types/aria-query': 5.0.4 + aria-query: 5.3.0 + dom-accessibility-api: 0.5.16 + lz-string: 1.5.0 + picocolors: 1.1.1 + pretty-format: 27.5.1 + + '@testing-library/jest-dom@6.9.1': + dependencies: + '@adobe/css-tools': 4.4.4 + aria-query: 5.3.2 + css.escape: 1.5.1 + dom-accessibility-api: 0.6.3 + picocolors: 1.1.1 + redent: 3.0.0 + + '@testing-library/react-hooks@8.0.1(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.28.4 + react: 18.3.1 + react-error-boundary: 3.1.4(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.26 + react-dom: 18.3.1(react@18.3.1) + + '@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.28.4 + '@testing-library/dom': 10.4.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.26 + '@types/react-dom': 18.3.7(@types/react@18.3.26) + + '@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1)': + dependencies: + '@testing-library/dom': 10.4.1 + '@tsconfig/node10@1.0.11': {} '@tsconfig/node12@1.0.11': {} @@ -4253,10 +8841,17 @@ snapshots: '@tufjs/canonical-json': 2.0.0 minimatch: 9.0.5 + '@tybys/wasm-util@0.10.1': + dependencies: + tslib: 2.8.1 + optional: true + '@tybys/wasm-util@0.9.0': dependencies: tslib: 2.8.1 + '@types/aria-query@5.0.4': {} + '@types/babel__core@7.20.5': dependencies: '@babel/parser': 7.28.5 @@ -4278,10 +8873,33 @@ snapshots: dependencies: '@babel/types': 7.28.5 + '@types/debug@4.1.12': + dependencies: + '@types/ms': 2.1.0 + + '@types/estree-jsx@1.0.5': + dependencies: + '@types/estree': 1.0.8 + + '@types/estree@1.0.8': {} + '@types/graceful-fs@4.1.9': dependencies: '@types/node': 20.19.24 + '@types/hast@2.3.10': + dependencies: + '@types/unist': 2.0.11 + + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/inquirer@9.0.9': + dependencies: + '@types/through': 0.0.33 + rxjs: 7.8.2 + '@types/istanbul-lib-coverage@2.0.6': {} '@types/istanbul-lib-report@3.0.3': @@ -4299,18 +8917,46 @@ snapshots: '@types/js-yaml@4.0.9': {} + '@types/jsdom@21.1.7': + dependencies: + '@types/node': 20.19.24 + '@types/tough-cookie': 4.0.5 + parse5: 7.3.0 + + '@types/json5@0.0.29': {} + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + '@types/minimatch@3.0.5': {} '@types/minimist@1.2.5': {} + '@types/ms@2.1.0': {} + '@types/node@20.19.24': dependencies: undici-types: 6.21.0 '@types/normalize-package-data@2.4.4': {} + '@types/pg@8.15.6': + dependencies: + '@types/node': 20.19.24 + pg-protocol: 1.10.3 + pg-types: 2.2.0 + '@types/prop-types@15.7.15': {} + '@types/react-dom@18.3.7(@types/react@18.3.26)': + dependencies: + '@types/react': 18.3.26 + + '@types/react-syntax-highlighter@15.5.13': + dependencies: + '@types/react': 18.3.26 + '@types/react@18.3.26': dependencies: '@types/prop-types': 15.7.15 @@ -4318,6 +8964,18 @@ snapshots: '@types/stack-utils@2.0.3': {} + '@types/statuses@2.0.6': {} + + '@types/through@0.0.33': + dependencies: + '@types/node': 20.19.24 + + '@types/tough-cookie@4.0.5': {} + + '@types/unist@2.0.11': {} + + '@types/unist@3.0.3': {} + '@types/yargs-parser@21.0.3': {} '@types/yargs@17.0.34': @@ -4333,10 +8991,23 @@ snapshots: '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.9.3) '@typescript-eslint/visitor-keys': 7.18.0 eslint: 8.57.1 - graphemer: 1.4.0 - ignore: 5.3.2 - natural-compare: 1.4.0 - ts-api-utils: 1.4.3(typescript@5.9.3) + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare: 1.4.0 + ts-api-utils: 1.4.3(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 6.21.0 + debug: 4.4.3 + eslint: 8.57.1 optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: @@ -4355,6 +9026,11 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/scope-manager@6.21.0': + dependencies: + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/visitor-keys': 6.21.0 + '@typescript-eslint/scope-manager@7.18.0': dependencies: '@typescript-eslint/types': 7.18.0 @@ -4372,8 +9048,25 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/types@6.21.0': {} + '@typescript-eslint/types@7.18.0': {} + '@typescript-eslint/typescript-estree@6.21.0(typescript@5.9.3)': + dependencies: + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/visitor-keys': 6.21.0 + debug: 4.4.3 + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.3 + semver: 7.7.3 + ts-api-utils: 1.4.3(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/typescript-estree@7.18.0(typescript@5.9.3)': dependencies: '@typescript-eslint/types': 7.18.0 @@ -4400,6 +9093,11 @@ snapshots: - supports-color - typescript + '@typescript-eslint/visitor-keys@6.21.0': + dependencies: + '@typescript-eslint/types': 6.21.0 + eslint-visitor-keys: 3.4.3 + '@typescript-eslint/visitor-keys@7.18.0': dependencies: '@typescript-eslint/types': 7.18.0 @@ -4407,6 +9105,65 @@ snapshots: '@ungap/structured-clone@1.3.0': {} + '@unrs/resolver-binding-android-arm-eabi@1.11.1': + optional: true + + '@unrs/resolver-binding-android-arm64@1.11.1': + optional: true + + '@unrs/resolver-binding-darwin-arm64@1.11.1': + optional: true + + '@unrs/resolver-binding-darwin-x64@1.11.1': + optional: true + + '@unrs/resolver-binding-freebsd-x64@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-x64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-wasm32-wasi@1.11.1': + dependencies: + '@napi-rs/wasm-runtime': 0.2.12 + optional: true + + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + optional: true + + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + optional: true + + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + optional: true + '@yarnpkg/lockfile@1.1.0': {} '@yarnpkg/parsers@3.0.2': @@ -4414,6 +9171,529 @@ snapshots: js-yaml: 3.14.1 tslib: 2.8.1 + '@zag-js/accordion@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/anatomy@1.27.0': {} + + '@zag-js/angle-slider@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/rect-utils': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/aria-hidden@1.27.0': + dependencies: + '@zag-js/dom-query': 1.27.0 + + '@zag-js/async-list@1.27.0': + dependencies: + '@zag-js/core': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/auto-resize@1.27.0': + dependencies: + '@zag-js/dom-query': 1.27.0 + + '@zag-js/avatar@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/bottom-sheet@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/aria-hidden': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dismissable': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/focus-trap': 1.27.0 + '@zag-js/remove-scroll': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/carousel@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/scroll-snap': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/checkbox@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/focus-visible': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/clipboard@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/collapsible@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/collection@1.27.0': + dependencies: + '@zag-js/utils': 1.27.0 + + '@zag-js/color-picker@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/color-utils': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dismissable': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/popper': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/color-utils@1.27.0': + dependencies: + '@zag-js/utils': 1.27.0 + + '@zag-js/combobox@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/aria-hidden': 1.27.0 + '@zag-js/collection': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dismissable': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/popper': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/core@1.27.0': + dependencies: + '@zag-js/dom-query': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/date-picker@1.27.0(@internationalized/date@3.10.0)': + dependencies: + '@internationalized/date': 3.10.0 + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/date-utils': 1.27.0(@internationalized/date@3.10.0) + '@zag-js/dismissable': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/live-region': 1.27.0 + '@zag-js/popper': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/date-utils@1.27.0(@internationalized/date@3.10.0)': + dependencies: + '@internationalized/date': 3.10.0 + + '@zag-js/dialog@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/aria-hidden': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dismissable': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/focus-trap': 1.27.0 + '@zag-js/remove-scroll': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/dismissable@1.27.0': + dependencies: + '@zag-js/dom-query': 1.27.0 + '@zag-js/interact-outside': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/dom-query@1.27.0': + dependencies: + '@zag-js/types': 1.27.0 + + '@zag-js/editable@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/interact-outside': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/file-upload@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/file-utils': 1.27.0 + '@zag-js/i18n-utils': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/file-utils@1.27.0': + dependencies: + '@zag-js/i18n-utils': 1.27.0 + + '@zag-js/floating-panel@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/popper': 1.27.0 + '@zag-js/rect-utils': 1.27.0 + '@zag-js/store': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/focus-trap@1.27.0': + dependencies: + '@zag-js/dom-query': 1.27.0 + + '@zag-js/focus-visible@1.27.0': + dependencies: + '@zag-js/dom-query': 1.27.0 + + '@zag-js/highlight-word@1.27.0': {} + + '@zag-js/hover-card@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dismissable': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/popper': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/i18n-utils@1.27.0': + dependencies: + '@zag-js/dom-query': 1.27.0 + + '@zag-js/interact-outside@1.27.0': + dependencies: + '@zag-js/dom-query': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/json-tree-utils@1.27.0': {} + + '@zag-js/listbox@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/collection': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/focus-visible': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/live-region@1.27.0': {} + + '@zag-js/marquee@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/menu@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dismissable': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/popper': 1.27.0 + '@zag-js/rect-utils': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/number-input@1.27.0': + dependencies: + '@internationalized/number': 3.6.5 + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/pagination@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/password-input@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/pin-input@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/popover@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/aria-hidden': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dismissable': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/focus-trap': 1.27.0 + '@zag-js/popper': 1.27.0 + '@zag-js/remove-scroll': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/popper@1.27.0': + dependencies: + '@floating-ui/dom': 1.7.4 + '@zag-js/dom-query': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/presence@1.27.0': + dependencies: + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/types': 1.27.0 + + '@zag-js/progress@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/qr-code@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + proxy-memoize: 3.0.1 + uqr: 0.1.2 + + '@zag-js/radio-group@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/focus-visible': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/rating-group@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/react@1.27.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@zag-js/core': 1.27.0 + '@zag-js/store': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@zag-js/rect-utils@1.27.0': {} + + '@zag-js/remove-scroll@1.27.0': + dependencies: + '@zag-js/dom-query': 1.27.0 + + '@zag-js/scroll-area@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/scroll-snap@1.27.0': + dependencies: + '@zag-js/dom-query': 1.27.0 + + '@zag-js/select@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/collection': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dismissable': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/popper': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/signature-pad@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + perfect-freehand: 1.2.2 + + '@zag-js/slider@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/splitter@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/steps@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/store@1.27.0': + dependencies: + proxy-compare: 3.0.1 + + '@zag-js/switch@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/focus-visible': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/tabs@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/tags-input@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/auto-resize': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/interact-outside': 1.27.0 + '@zag-js/live-region': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/timer@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/toast@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dismissable': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/toggle-group@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/toggle@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/tooltip@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/focus-visible': 1.27.0 + '@zag-js/popper': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/tour@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dismissable': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/focus-trap': 1.27.0 + '@zag-js/interact-outside': 1.27.0 + '@zag-js/popper': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/tree-view@1.27.0': + dependencies: + '@zag-js/anatomy': 1.27.0 + '@zag-js/collection': 1.27.0 + '@zag-js/core': 1.27.0 + '@zag-js/dom-query': 1.27.0 + '@zag-js/types': 1.27.0 + '@zag-js/utils': 1.27.0 + + '@zag-js/types@1.27.0': + dependencies: + csstype: 3.1.3 + + '@zag-js/utils@1.27.0': {} + '@zkochan/js-yaml@0.0.7': dependencies: argparse: 2.0.1 @@ -4439,6 +9719,13 @@ snapshots: agent-base@7.1.4: {} + agentic-kit@0.1.2(encoding@0.1.13): + dependencies: + '@agentic-kit/bradie': 0.1.2(encoding@0.1.13) + '@agentic-kit/ollama': 0.1.2(encoding@0.1.13) + transitivePeerDependencies: + - encoding + aggregate-error@3.1.0: dependencies: clean-stack: 2.2.0 @@ -4469,6 +9756,8 @@ snapshots: ansi-styles@6.2.3: {} + any-promise@1.3.0: {} + anymatch@3.1.3: dependencies: normalize-path: 3.0.0 @@ -4478,26 +9767,125 @@ snapshots: arg@4.1.3: {} + arg@5.0.2: {} + argparse@1.0.10: dependencies: sprintf-js: 1.0.3 argparse@2.0.1: {} + aria-hidden@1.2.6: + dependencies: + tslib: 2.8.1 + + aria-query@5.3.0: + dependencies: + dequal: 2.0.3 + + aria-query@5.3.2: {} + + array-buffer-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + is-array-buffer: 3.0.5 + array-differ@3.0.0: {} array-ify@1.0.0: {} + array-includes@3.1.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + is-string: 1.1.1 + math-intrinsics: 1.1.0 + array-union@2.1.0: {} + array.prototype.findlast@1.2.5: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 + + array.prototype.findlastindex@1.2.6: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 + + array.prototype.flat@1.3.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-shim-unscopables: 1.1.0 + + array.prototype.flatmap@1.3.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-shim-unscopables: 1.1.0 + + array.prototype.tosorted@1.1.4: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-errors: 1.3.0 + es-shim-unscopables: 1.1.0 + + arraybuffer.prototype.slice@1.0.4: + dependencies: + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + is-array-buffer: 3.0.5 + arrify@1.0.1: {} arrify@2.0.1: {} + ast-types-flow@0.0.8: {} + + async-function@1.0.0: {} + async@3.2.6: {} asynckit@0.4.0: {} + autoprefixer@10.4.21(postcss@8.5.6): + dependencies: + browserslist: 4.27.0 + caniuse-lite: 1.0.30001754 + fraction.js: 4.3.7 + normalize-range: 0.1.2 + picocolors: 1.1.1 + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.1.0 + + axe-core@4.11.0: {} + axios@1.13.2: dependencies: follow-redirects: 1.15.11 @@ -4506,6 +9894,8 @@ snapshots: transitivePeerDependencies: - debug + axobject-query@4.1.0: {} + babel-jest@29.7.0(@babel/core@7.28.5): dependencies: '@babel/core': 7.28.5 @@ -4561,6 +9951,8 @@ snapshots: babel-plugin-jest-hoist: 29.6.3 babel-preset-current-node-syntax: 1.2.0(@babel/core@7.28.5) + bail@2.0.2: {} + balanced-match@1.0.2: {} base64-js@1.5.1: {} @@ -4576,6 +9968,8 @@ snapshots: read-cmd-shim: 4.0.0 write-file-atomic: 5.0.1 + binary-extensions@2.3.0: {} + bl@4.1.0: dependencies: buffer: 5.7.1 @@ -4618,6 +10012,11 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + byte-size@8.1.1: {} cacache@18.0.4: @@ -4640,8 +10039,22 @@ snapshots: es-errors: 1.3.0 function-bind: 1.1.2 + call-bind@1.0.8: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + callsites@3.1.0: {} + camelcase-css@2.0.1: {} + camelcase-keys@6.2.2: dependencies: camelcase: 5.3.1 @@ -4654,6 +10067,8 @@ snapshots: caniuse-lite@1.0.30001754: {} + ccount@2.0.1: {} + chalk@4.1.0: dependencies: ansi-styles: 4.3.0 @@ -4666,8 +10081,34 @@ snapshots: char-regex@1.0.2: {} + character-entities-html4@2.1.0: {} + + character-entities-legacy@1.1.4: {} + + character-entities-legacy@3.0.0: {} + + character-entities@1.2.4: {} + + character-entities@2.0.2: {} + + character-reference-invalid@1.1.4: {} + + character-reference-invalid@2.0.1: {} + chardet@2.1.1: {} + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + chownr@2.0.0: {} ci-info@3.9.0: {} @@ -4676,6 +10117,10 @@ snapshots: cjs-module-lexer@1.4.3: {} + class-variance-authority@0.7.1: + dependencies: + clsx: 2.1.1 + clean-stack@2.2.0: {} cli-cursor@3.1.0: @@ -4688,6 +10133,10 @@ snapshots: cli-width@3.0.0: {} + cli-width@4.1.0: {} + + client-only@0.0.1: {} + cliui@7.0.4: dependencies: string-width: 4.2.3 @@ -4708,6 +10157,8 @@ snapshots: clone@1.0.4: {} + clsx@2.1.1: {} + cmd-shim@6.0.3: {} co@4.6.0: {} @@ -4731,6 +10182,14 @@ snapshots: dependencies: delayed-stream: 1.0.0 + comma-separated-tokens@1.0.8: {} + + comma-separated-tokens@2.0.3: {} + + commander@11.1.0: {} + + commander@4.1.1: {} + common-ancestor-path@1.0.1: {} compare-func@2.0.0: @@ -4803,6 +10262,8 @@ snapshots: convert-source-map@2.0.0: {} + cookie@1.0.2: {} + copyfiles@2.4.1: dependencies: glob: 7.2.3 @@ -4824,13 +10285,13 @@ snapshots: optionalDependencies: typescript: 5.9.3 - create-jest@29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3)): + create-jest@29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@swc/core@1.15.0(@swc/helpers@0.5.17))(@swc/wasm@1.15.0)(@types/node@20.19.24)(typescript@5.9.3)): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3)) + jest-config: 29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@swc/core@1.15.0(@swc/helpers@0.5.17))(@swc/wasm@1.15.0)(@types/node@20.19.24)(typescript@5.9.3)) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -4841,20 +10302,66 @@ snapshots: create-require@1.1.1: {} + cross-fetch@4.1.0(encoding@0.1.13): + dependencies: + node-fetch: 2.7.0(encoding@0.1.13) + transitivePeerDependencies: + - encoding + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 shebang-command: 2.0.0 which: 2.0.2 + css.escape@1.5.1: {} + cssesc@3.0.0: {} + cssstyle@4.6.0: + dependencies: + '@asamuzakjp/css-color': 3.2.0 + rrweb-cssom: 0.8.0 + csstype@3.1.3: {} + damerau-levenshtein@1.0.8: {} + dargs@7.0.0: {} + data-uri-to-buffer@4.0.1: {} + + data-urls@5.0.0: + dependencies: + whatwg-mimetype: 4.0.0 + whatwg-url: 14.2.0 + + data-view-buffer@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-offset@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + dateformat@3.0.3: {} + dayjs@1.11.19: {} + + debug@3.2.7: + dependencies: + ms: 2.1.3 + debug@4.4.3: dependencies: ms: 2.1.3 @@ -4866,6 +10373,12 @@ snapshots: decamelize@1.2.0: {} + decimal.js@10.6.0: {} + + decode-named-character-reference@1.2.0: + dependencies: + character-entities: 2.0.2 + dedent@1.5.3: {} dedent@1.7.0: {} @@ -4878,16 +10391,41 @@ snapshots: dependencies: clone: 1.0.4 + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + define-lazy-prop@2.0.0: {} + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + delayed-stream@1.0.0: {} deprecation@2.3.1: {} + dequal@2.0.3: {} + detect-indent@5.0.0: {} + detect-libc@2.1.2: + optional: true + detect-newline@3.1.0: {} + detect-node-es@1.1.0: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + didyoumean@1.2.2: {} + diff-sequences@29.6.3: {} diff@4.0.2: {} @@ -4896,10 +10434,20 @@ snapshots: dependencies: path-type: 4.0.0 + dlv@1.1.3: {} + + doctrine@2.1.0: + dependencies: + esutils: 2.0.3 + doctrine@3.0.0: dependencies: esutils: 2.0.3 + dom-accessibility-api@0.5.16: {} + + dom-accessibility-api@0.6.3: {} + dot-prop@5.3.0: dependencies: is-obj: 2.0.0 @@ -4924,6 +10472,18 @@ snapshots: electron-to-chromium@1.5.249: {} + embla-carousel-react@8.6.0(react@18.3.1): + dependencies: + embla-carousel: 8.6.0 + embla-carousel-reactive-utils: 8.6.0(embla-carousel@8.6.0) + react: 18.3.1 + + embla-carousel-reactive-utils@8.6.0(embla-carousel@8.6.0): + dependencies: + embla-carousel: 8.6.0 + + embla-carousel@8.6.0: {} + emittery@0.13.1: {} emoji-regex@8.0.0: {} @@ -4943,6 +10503,8 @@ snapshots: dependencies: ansi-colors: 4.1.3 + entities@6.0.1: {} + env-paths@2.2.1: {} envinfo@7.13.0: {} @@ -4953,10 +10515,86 @@ snapshots: dependencies: is-arrayish: 0.2.1 + es-abstract@1.24.0: + dependencies: + array-buffer-byte-length: 1.0.2 + arraybuffer.prototype.slice: 1.0.4 + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + data-view-buffer: 1.0.2 + data-view-byte-length: 1.0.2 + data-view-byte-offset: 1.0.1 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-set-tostringtag: 2.1.0 + es-to-primitive: 1.3.0 + function.prototype.name: 1.1.8 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + get-symbol-description: 1.1.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + internal-slot: 1.1.0 + is-array-buffer: 3.0.5 + is-callable: 1.2.7 + is-data-view: 1.0.2 + is-negative-zero: 2.0.3 + is-regex: 1.2.1 + is-set: 2.0.3 + is-shared-array-buffer: 1.0.4 + is-string: 1.1.1 + is-typed-array: 1.1.15 + is-weakref: 1.1.1 + math-intrinsics: 1.1.0 + object-inspect: 1.13.4 + object-keys: 1.1.1 + object.assign: 4.1.7 + own-keys: 1.0.1 + regexp.prototype.flags: 1.5.4 + safe-array-concat: 1.1.3 + safe-push-apply: 1.0.0 + safe-regex-test: 1.1.0 + set-proto: 1.0.0 + stop-iteration-iterator: 1.1.0 + string.prototype.trim: 1.2.10 + string.prototype.trimend: 1.0.9 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.3 + typed-array-byte-length: 1.0.3 + typed-array-byte-offset: 1.0.4 + typed-array-length: 1.0.7 + unbox-primitive: 1.1.0 + which-typed-array: 1.1.19 + es-define-property@1.0.1: {} es-errors@1.3.0: {} + es-iterator-helpers@1.2.1: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-errors: 1.3.0 + es-set-tostringtag: 2.1.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + iterator.prototype: 1.1.5 + safe-array-concat: 1.1.3 + es-object-atoms@1.1.1: dependencies: es-errors: 1.3.0 @@ -4968,6 +10606,16 @@ snapshots: has-tostringtag: 1.0.2 hasown: 2.0.2 + es-shim-unscopables@1.1.0: + dependencies: + hasown: 2.0.2 + + es-to-primitive@1.3.0: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.1.0 + is-symbol: 1.1.1 + escalade@3.2.0: {} escape-string-regexp@1.0.5: {} @@ -4976,10 +10624,139 @@ snapshots: escape-string-regexp@4.0.0: {} + escape-string-regexp@5.0.0: {} + + eslint-config-next@14.1.0(eslint@8.57.1)(typescript@5.9.3): + dependencies: + '@next/eslint-plugin-next': 14.1.0 + '@rushstack/eslint-patch': 1.14.1 + '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.9.3) + eslint: 8.57.1 + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) + eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1) + eslint-plugin-react: 7.37.5(eslint@8.57.1) + eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.57.1) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - eslint-import-resolver-webpack + - eslint-plugin-import-x + - supports-color + eslint-config-prettier@9.1.2(eslint@8.57.1): dependencies: eslint: 8.57.1 + eslint-import-resolver-node@0.3.9: + dependencies: + debug: 3.2.7 + is-core-module: 2.16.1 + resolve: 1.22.11 + transitivePeerDependencies: + - supports-color + + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1): + dependencies: + '@nolyfill/is-core-module': 1.0.39 + debug: 4.4.3 + eslint: 8.57.1 + get-tsconfig: 4.13.0 + is-bun-module: 2.0.0 + stable-hash: 0.0.5 + tinyglobby: 0.2.15 + unrs-resolver: 1.11.1 + optionalDependencies: + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.9.3) + eslint: 8.57.1 + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1) + transitivePeerDependencies: + - supports-color + + eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1): + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: 3.1.9 + array.prototype.findlastindex: 1.2.6 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.57.1 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + hasown: 2.0.2 + is-core-module: 2.16.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.9 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.9.3) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.1): + dependencies: + aria-query: 5.3.2 + array-includes: 3.1.9 + array.prototype.flatmap: 1.3.3 + ast-types-flow: 0.0.8 + axe-core: 4.11.0 + axobject-query: 4.1.0 + damerau-levenshtein: 1.0.8 + emoji-regex: 9.2.2 + eslint: 8.57.1 + hasown: 2.0.2 + jsx-ast-utils: 3.3.5 + language-tags: 1.0.9 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + safe-regex-test: 1.1.0 + string.prototype.includes: 2.0.1 + + eslint-plugin-react-hooks@5.0.0-canary-7118f5dd7-20230705(eslint@8.57.1): + dependencies: + eslint: 8.57.1 + + eslint-plugin-react@7.37.5(eslint@8.57.1): + dependencies: + array-includes: 3.1.9 + array.prototype.findlast: 1.2.5 + array.prototype.flatmap: 1.3.3 + array.prototype.tosorted: 1.1.4 + doctrine: 2.1.0 + es-iterator-helpers: 1.2.1 + eslint: 8.57.1 + estraverse: 5.3.0 + hasown: 2.0.2 + jsx-ast-utils: 3.3.5 + minimatch: 3.1.2 + object.entries: 1.1.9 + object.fromentries: 2.0.8 + object.values: 1.2.1 + prop-types: 15.8.1 + resolve: 2.0.0-next.5 + semver: 6.3.1 + string.prototype.matchall: 4.0.12 + string.prototype.repeat: 1.0.0 + eslint-plugin-simple-import-sort@12.1.1(eslint@8.57.1): dependencies: eslint: 8.57.1 @@ -5058,6 +10835,8 @@ snapshots: estraverse@5.3.0: {} + estree-util-is-identifier-name@3.0.0: {} + esutils@2.0.3: {} eventemitter3@4.0.7: {} @@ -5098,6 +10877,12 @@ snapshots: exponential-backoff@3.1.3: {} + extend-shallow@2.0.1: + dependencies: + is-extendable: 0.1.1 + + extend@3.0.2: {} + fast-deep-equal@3.1.3: {} fast-glob@3.3.3: @@ -5118,6 +10903,10 @@ snapshots: dependencies: reusify: 1.1.0 + fault@1.0.4: + dependencies: + format: 0.2.2 + fb-watchman@2.0.2: dependencies: bser: 2.1.1 @@ -5126,6 +10915,11 @@ snapshots: optionalDependencies: picomatch: 4.0.3 + fetch-blob@3.2.0: + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.3.3 + figures@3.2.0: dependencies: escape-string-regexp: 1.0.5 @@ -5168,6 +10962,10 @@ snapshots: follow-redirects@1.15.11: {} + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + foreground-child@3.3.1: dependencies: cross-spawn: 7.0.6 @@ -5181,6 +10979,14 @@ snapshots: hasown: 2.0.2 mime-types: 2.1.35 + format@0.2.2: {} + + formdata-polyfill@4.0.10: + dependencies: + fetch-blob: 3.2.0 + + fraction.js@4.3.7: {} + front-matter@4.0.2: dependencies: js-yaml: 3.14.1 @@ -5203,11 +11009,27 @@ snapshots: fs.realpath@1.0.0: {} + fsevents@2.3.2: + optional: true + fsevents@2.3.3: optional: true function-bind@1.1.2: {} + function.prototype.name@1.1.8: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + functions-have-names: 1.2.3 + hasown: 2.0.2 + is-callable: 1.2.7 + + functions-have-names@1.2.3: {} + + generator-function@2.0.1: {} + gensync@1.0.0-beta.2: {} get-caller-file@2.0.5: {} @@ -5225,6 +11047,8 @@ snapshots: hasown: 2.0.2 math-intrinsics: 1.1.0 + get-nonce@1.0.1: {} + get-package-type@0.1.0: {} get-pkg-repo@4.2.1: @@ -5245,6 +11069,16 @@ snapshots: get-stream@6.0.1: {} + get-symbol-description@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + + get-tsconfig@4.13.0: + dependencies: + resolve-pkg-maps: 1.0.0 + git-raw-commits@3.0.0: dependencies: dargs: 7.0.0 @@ -5282,6 +11116,14 @@ snapshots: dependencies: is-glob: 4.0.3 + glob@10.3.10: + dependencies: + foreground-child: 3.3.1 + jackspeak: 2.3.6 + minimatch: 9.0.5 + minipass: 7.1.2 + path-scurry: 1.11.1 + glob@10.4.5: dependencies: foreground-child: 3.3.1 @@ -5311,6 +11153,11 @@ snapshots: dependencies: type-fest: 0.20.2 + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.2.0 + globby@11.1.0: dependencies: array-union: 2.1.0 @@ -5326,6 +11173,15 @@ snapshots: graphemer@1.4.0: {} + graphql@16.12.0: {} + + gray-matter@4.0.3: + dependencies: + js-yaml: 3.14.1 + kind-of: 6.0.3 + section-matter: 1.0.0 + strip-bom-string: 1.0.0 + handlebars@4.7.8: dependencies: minimist: 1.2.8 @@ -5337,8 +11193,18 @@ snapshots: hard-rejection@2.1.0: {} + has-bigints@1.1.0: {} + has-flag@4.0.0: {} + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-proto@1.2.0: + dependencies: + dunder-proto: 1.0.1 + has-symbols@1.1.0: {} has-tostringtag@1.0.2: @@ -5351,6 +11217,46 @@ snapshots: dependencies: function-bind: 1.1.2 + hast-util-parse-selector@2.2.5: {} + + hast-util-to-jsx-runtime@2.3.6: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.19 + unist-util-position: 5.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hastscript@6.0.0: + dependencies: + '@types/hast': 2.3.10 + comma-separated-tokens: 1.0.8 + hast-util-parse-selector: 2.2.5 + property-information: 5.6.0 + space-separated-tokens: 1.1.5 + + headers-polyfill@4.0.3: {} + + highlight.js@10.7.3: {} + + highlightjs-vue@1.0.0: {} + hosted-git-info@2.8.9: {} hosted-git-info@4.1.0: @@ -5361,8 +11267,14 @@ snapshots: dependencies: lru-cache: 10.4.3 + html-encoding-sniffer@4.0.0: + dependencies: + whatwg-encoding: 3.1.1 + html-escaper@2.0.2: {} + html-url-attributes@3.0.1: {} + http-cache-semantics@4.2.0: {} http-proxy-agent@7.0.2: @@ -5384,7 +11296,6 @@ snapshots: iconv-lite@0.6.3: dependencies: safer-buffer: 2.1.2 - optional: true iconv-lite@0.7.0: dependencies: @@ -5440,6 +11351,8 @@ snapshots: transitivePeerDependencies: - bluebird + inline-style-parser@0.2.6: {} + inquirer@8.2.7(@types/node@20.19.24): dependencies: '@inquirer/external-editor': 1.0.2(@types/node@20.19.24) @@ -5460,16 +11373,86 @@ snapshots: transitivePeerDependencies: - '@types/node' + inquirer@9.3.8(@types/node@20.19.24): + dependencies: + '@inquirer/external-editor': 1.0.2(@types/node@20.19.24) + '@inquirer/figures': 1.0.14 + ansi-escapes: 4.3.2 + cli-width: 4.1.0 + mute-stream: 1.0.0 + ora: 5.4.1 + run-async: 3.0.0 + rxjs: 7.8.2 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + yoctocolors-cjs: 2.1.3 + transitivePeerDependencies: + - '@types/node' + inquirerer@2.0.8: dependencies: - chalk: 4.1.2 - deepmerge: 4.3.1 - js-yaml: 4.1.0 - minimist: 1.2.8 + chalk: 4.1.2 + deepmerge: 4.3.1 + js-yaml: 4.1.0 + minimist: 1.2.8 + + internal-slot@1.1.0: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.1.0 + + ip-address@10.0.1: {} + + is-alphabetical@1.0.4: {} + + is-alphabetical@2.0.1: {} + + is-alphanumerical@1.0.4: + dependencies: + is-alphabetical: 1.0.4 + is-decimal: 1.0.4 + + is-alphanumerical@2.0.1: + dependencies: + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 + + is-array-buffer@3.0.5: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + is-arrayish@0.2.1: {} + + is-async-function@2.1.1: + dependencies: + async-function: 1.0.0 + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-bigint@1.1.0: + dependencies: + has-bigints: 1.1.0 + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-boolean-object@1.2.2: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 - ip-address@10.0.1: {} + is-bun-module@2.0.0: + dependencies: + semver: 7.7.3 - is-arrayish@0.2.1: {} + is-callable@1.2.7: {} is-ci@3.0.1: dependencies: @@ -5479,22 +11462,66 @@ snapshots: dependencies: hasown: 2.0.2 + is-data-view@1.0.2: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + is-typed-array: 1.1.15 + + is-date-object@1.1.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-decimal@1.0.4: {} + + is-decimal@2.0.1: {} + is-docker@2.2.1: {} + is-extendable@0.1.1: {} + is-extglob@2.1.1: {} + is-finalizationregistry@1.1.1: + dependencies: + call-bound: 1.0.4 + is-fullwidth-code-point@3.0.0: {} is-generator-fn@2.1.0: {} + is-generator-function@1.1.2: + dependencies: + call-bound: 1.0.4 + generator-function: 2.0.1 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + is-glob@4.0.3: dependencies: is-extglob: 2.1.1 + is-hexadecimal@1.0.4: {} + + is-hexadecimal@2.0.1: {} + is-interactive@1.0.0: {} is-lambda@1.0.1: {} + is-map@2.0.3: {} + + is-negative-zero@2.0.3: {} + + is-node-process@1.2.0: {} + + is-number-object@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + is-number@7.0.0: {} is-obj@2.0.0: {} @@ -5503,10 +11530,27 @@ snapshots: is-plain-obj@1.1.0: {} + is-plain-obj@4.1.0: {} + is-plain-object@2.0.4: dependencies: isobject: 3.0.1 + is-potential-custom-element-name@1.0.1: {} + + is-regex@1.2.1: + dependencies: + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + is-set@2.0.3: {} + + is-shared-array-buffer@1.0.4: + dependencies: + call-bound: 1.0.4 + is-ssh@1.4.1: dependencies: protocols: 2.0.2 @@ -5515,12 +11559,38 @@ snapshots: is-stream@2.0.1: {} + is-string@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-symbol@1.1.1: + dependencies: + call-bound: 1.0.4 + has-symbols: 1.1.0 + safe-regex-test: 1.1.0 + is-text-path@1.0.1: dependencies: text-extensions: 1.9.0 + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.19 + is-unicode-supported@0.1.0: {} + is-weakmap@2.0.2: {} + + is-weakref@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-weakset@2.0.4: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + is-wsl@2.2.0: dependencies: is-docker: 2.2.1 @@ -5529,6 +11599,8 @@ snapshots: isarray@1.0.0: {} + isarray@2.0.5: {} + isexe@2.0.0: {} isexe@3.1.1: {} @@ -5583,6 +11655,21 @@ snapshots: html-escaper: 2.0.2 istanbul-lib-report: 3.0.1 + iterator.prototype@1.1.5: + dependencies: + define-data-property: 1.1.4 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + has-symbols: 1.1.0 + set-function-name: 2.0.2 + + jackspeak@2.3.6: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + jackspeak@3.4.3: dependencies: '@isaacs/cliui': 8.0.2 @@ -5627,16 +11714,16 @@ snapshots: - babel-plugin-macros - supports-color - jest-cli@29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3)): + jest-cli@29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@swc/core@1.15.0(@swc/helpers@0.5.17))(@swc/wasm@1.15.0)(@types/node@20.19.24)(typescript@5.9.3)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3)) + '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.15.0(@swc/helpers@0.5.17))(@swc/wasm@1.15.0)(@types/node@20.19.24)(typescript@5.9.3)) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3)) + create-jest: 29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@swc/core@1.15.0(@swc/helpers@0.5.17))(@swc/wasm@1.15.0)(@types/node@20.19.24)(typescript@5.9.3)) exit: 0.1.2 import-local: 3.2.0 - jest-config: 29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3)) + jest-config: 29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@swc/core@1.15.0(@swc/helpers@0.5.17))(@swc/wasm@1.15.0)(@types/node@20.19.24)(typescript@5.9.3)) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -5646,7 +11733,7 @@ snapshots: - supports-color - ts-node - jest-config@29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3)): + jest-config@29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@swc/core@1.15.0(@swc/helpers@0.5.17))(@swc/wasm@1.15.0)(@types/node@20.19.24)(typescript@5.9.3)): dependencies: '@babel/core': 7.28.5 '@jest/test-sequencer': 29.7.0 @@ -5672,14 +11759,14 @@ snapshots: strip-json-comments: 3.1.1 optionalDependencies: '@types/node': 20.19.24 - ts-node: 10.9.2(@types/node@20.19.24)(typescript@5.9.3) + ts-node: 10.9.2(@swc/core@1.15.0(@swc/helpers@0.5.17))(@swc/wasm@1.15.0)(@types/node@20.19.24)(typescript@5.9.3) transitivePeerDependencies: - babel-plugin-macros - supports-color jest-diff@29.7.0: dependencies: - chalk: 4.1.0 + chalk: 4.1.2 diff-sequences: 29.6.3 jest-get-type: 29.6.3 pretty-format: 29.7.0 @@ -5696,6 +11783,18 @@ snapshots: jest-util: 29.7.0 pretty-format: 29.7.0 + jest-environment-jsdom@30.2.0: + dependencies: + '@jest/environment': 30.2.0 + '@jest/environment-jsdom-abstract': 30.2.0(jsdom@26.1.0) + '@types/jsdom': 21.1.7 + '@types/node': 20.19.24 + jsdom: 26.1.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + jest-environment-node@29.7.0: dependencies: '@jest/environment': 29.7.0 @@ -5705,6 +11804,10 @@ snapshots: jest-mock: 29.7.0 jest-util: 29.7.0 + jest-fixed-jsdom@0.0.10(jest-environment-jsdom@30.2.0): + dependencies: + jest-environment-jsdom: 30.2.0 + jest-get-type@29.6.3: {} jest-haste-map@29.7.0: @@ -5747,18 +11850,38 @@ snapshots: slash: 3.0.0 stack-utils: 2.0.6 + jest-message-util@30.2.0: + dependencies: + '@babel/code-frame': 7.27.1 + '@jest/types': 30.2.0 + '@types/stack-utils': 2.0.3 + chalk: 4.1.2 + graceful-fs: 4.2.11 + micromatch: 4.0.8 + pretty-format: 30.2.0 + slash: 3.0.0 + stack-utils: 2.0.6 + jest-mock@29.7.0: dependencies: '@jest/types': 29.6.3 '@types/node': 20.19.24 jest-util: 29.7.0 + jest-mock@30.2.0: + dependencies: + '@jest/types': 30.2.0 + '@types/node': 20.19.24 + jest-util: 30.2.0 + jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): optionalDependencies: jest-resolve: 29.7.0 jest-regex-util@29.6.3: {} + jest-regex-util@30.0.1: {} + jest-resolve-dependencies@29.7.0: dependencies: jest-regex-util: 29.6.3 @@ -5865,6 +11988,15 @@ snapshots: graceful-fs: 4.2.11 picomatch: 2.3.1 + jest-util@30.2.0: + dependencies: + '@jest/types': 30.2.0 + '@types/node': 20.19.24 + chalk: 4.1.2 + ci-info: 4.3.1 + graceful-fs: 4.2.11 + picomatch: 4.0.3 + jest-validate@29.7.0: dependencies: '@jest/types': 29.6.3 @@ -5892,18 +12024,20 @@ snapshots: merge-stream: 2.0.0 supports-color: 8.1.1 - jest@29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3)): + jest@29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@swc/core@1.15.0(@swc/helpers@0.5.17))(@swc/wasm@1.15.0)(@types/node@20.19.24)(typescript@5.9.3)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3)) + '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.15.0(@swc/helpers@0.5.17))(@swc/wasm@1.15.0)(@types/node@20.19.24)(typescript@5.9.3)) '@jest/types': 29.6.3 import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3)) + jest-cli: 29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@swc/core@1.15.0(@swc/helpers@0.5.17))(@swc/wasm@1.15.0)(@types/node@20.19.24)(typescript@5.9.3)) transitivePeerDependencies: - '@types/node' - babel-plugin-macros - supports-color - ts-node + jiti@1.21.7: {} + js-tokens@4.0.0: {} js-yaml@3.14.1: @@ -5915,6 +12049,33 @@ snapshots: dependencies: argparse: 2.0.1 + jsdom@26.1.0: + dependencies: + cssstyle: 4.6.0 + data-urls: 5.0.0 + decimal.js: 10.6.0 + html-encoding-sniffer: 4.0.0 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + is-potential-custom-element-name: 1.0.1 + nwsapi: 2.2.22 + parse5: 7.3.0 + rrweb-cssom: 0.8.0 + saxes: 6.0.0 + symbol-tree: 3.2.4 + tough-cookie: 5.1.2 + w3c-xmlserializer: 5.0.0 + webidl-conversions: 7.0.0 + whatwg-encoding: 3.1.1 + whatwg-mimetype: 4.0.0 + whatwg-url: 14.2.0 + ws: 8.18.3 + xml-name-validator: 5.0.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + jsesc@3.1.0: {} json-buffer@3.0.1: {} @@ -5933,6 +12094,10 @@ snapshots: json-stringify-safe@5.0.1: {} + json5@1.0.2: + dependencies: + minimist: 1.2.8 + json5@2.2.3: {} jsonc-parser@3.2.0: {} @@ -5945,6 +12110,13 @@ snapshots: jsonparse@1.3.1: {} + jsx-ast-utils@3.3.5: + dependencies: + array-includes: 3.1.9 + array.prototype.flat: 1.3.3 + object.assign: 4.1.7 + object.values: 1.2.1 + just-diff-apply@5.5.0: {} just-diff@6.0.2: {} @@ -5957,13 +12129,21 @@ snapshots: kleur@3.0.3: {} - lerna@8.2.4(@types/node@20.19.24)(encoding@0.1.13): + kubernetesjs@0.6.2: {} + + language-subtag-registry@0.3.23: {} + + language-tags@1.0.9: + dependencies: + language-subtag-registry: 0.3.23 + + lerna@8.2.4(@swc/core@1.15.0(@swc/helpers@0.5.17))(@types/node@20.19.24)(encoding@0.1.13): dependencies: - '@lerna/create': 8.2.4(@types/node@20.19.24)(encoding@0.1.13)(typescript@5.9.3) + '@lerna/create': 8.2.4(@swc/core@1.15.0(@swc/helpers@0.5.17))(@types/node@20.19.24)(encoding@0.1.13)(typescript@5.9.3) '@npmcli/arborist': 7.5.4 '@npmcli/package-json': 5.2.0 '@npmcli/run-script': 8.1.0 - '@nx/devkit': 20.8.2(nx@20.8.2) + '@nx/devkit': 20.8.2(nx@20.8.2(@swc/core@1.15.0(@swc/helpers@0.5.17))) '@octokit/plugin-enterprise-rest': 6.0.1 '@octokit/rest': 20.1.2 aproba: 2.0.0 @@ -6006,7 +12186,7 @@ snapshots: npm-package-arg: 11.0.2 npm-packlist: 8.0.2 npm-registry-fetch: 17.1.0 - nx: 20.8.2 + nx: 20.8.2(@swc/core@1.15.0(@swc/helpers@0.5.17)) p-map: 4.0.0 p-map-series: 2.1.0 p-pipe: 3.1.0 @@ -6075,6 +12255,8 @@ snapshots: transitivePeerDependencies: - supports-color + lilconfig@3.1.3: {} + lines-and-columns@1.2.4: {} lines-and-columns@2.0.3: {} @@ -6106,6 +12288,8 @@ snapshots: dependencies: p-locate: 5.0.0 + lodash-es@4.17.21: {} + lodash.ismatch@4.4.0: {} lodash.memoize@4.1.2: {} @@ -6116,13 +12300,20 @@ snapshots: log-symbols@4.1.0: dependencies: - chalk: 4.1.0 + chalk: 4.1.2 is-unicode-supported: 0.1.0 + longest-streak@3.1.0: {} + loose-envify@1.4.0: dependencies: js-tokens: 4.0.0 + lowlight@1.20.0: + dependencies: + fault: 1.0.4 + highlight.js: 10.7.3 + lru-cache@10.4.3: {} lru-cache@5.1.1: @@ -6133,61 +12324,418 @@ snapshots: dependencies: yallist: 4.0.0 - make-dir@2.1.0: + lucide-react@0.454.0(react@18.3.1): + dependencies: + react: 18.3.1 + + lz-string@1.5.0: {} + + make-dir@2.1.0: + dependencies: + pify: 4.0.1 + semver: 5.7.2 + + make-dir@4.0.0: + dependencies: + semver: 7.7.3 + + make-error@1.3.6: {} + + make-fetch-happen@13.0.1: + dependencies: + '@npmcli/agent': 2.2.2 + cacache: 18.0.4 + http-cache-semantics: 4.2.0 + is-lambda: 1.0.1 + minipass: 7.1.2 + minipass-fetch: 3.0.5 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + negotiator: 0.6.4 + proc-log: 4.2.0 + promise-retry: 2.0.1 + ssri: 10.0.6 + transitivePeerDependencies: + - supports-color + + makeerror@1.0.12: + dependencies: + tmpl: 1.0.5 + + map-obj@1.0.1: {} + + map-obj@4.3.0: {} + + markdown-table@3.0.4: {} + + match-sorter@8.1.0: + dependencies: + '@babel/runtime': 7.28.4 + remove-accents: 0.5.0 + + math-intrinsics@1.1.0: {} + + mdast-util-find-and-replace@3.0.2: + dependencies: + '@types/mdast': 4.0.4 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + mdast-util-from-markdown@2.0.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.2.0 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.2 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-autolink-literal@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.2 + micromark-util-character: 2.1.1 + + mdast-util-gfm-footnote@2.1.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + micromark-util-normalize-identifier: 2.0.1 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-strikethrough@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-table@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + markdown-table: 3.0.4 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-task-list-item@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm@3.1.0: + dependencies: + mdast-util-from-markdown: 2.0.2 + mdast-util-gfm-autolink-literal: 2.0.1 + mdast-util-gfm-footnote: 2.1.0 + mdast-util-gfm-strikethrough: 2.0.0 + mdast-util-gfm-table: 2.0.0 + mdast-util-gfm-task-list-item: 2.0.0 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-expression@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-jsx@3.2.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + mdast-util-mdxjs-esm@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.4 + unist-util-is: 6.0.1 + + mdast-util-to-hast@13.2.0: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + + mdast-util-to-markdown@2.1.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 + unist-util-visit: 5.0.0 + zwitch: 2.0.4 + + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + + meow@8.1.2: + dependencies: + '@types/minimist': 1.2.5 + camelcase-keys: 6.2.2 + decamelize-keys: 1.1.1 + hard-rejection: 2.1.0 + minimist-options: 4.1.0 + normalize-package-data: 3.0.3 + read-pkg-up: 7.0.1 + redent: 3.0.0 + trim-newlines: 3.0.1 + type-fest: 0.18.1 + yargs-parser: 20.2.9 + + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.2.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-strikethrough@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-table@2.1.1: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-tagfilter@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-gfm-task-list-item@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm@3.0.0: + dependencies: + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.1 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.1.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 + + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-chunked@2.0.1: dependencies: - pify: 4.0.1 - semver: 5.7.2 + micromark-util-symbol: 2.0.1 - make-dir@4.0.0: + micromark-util-classify-character@2.0.1: dependencies: - semver: 7.7.3 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 - make-error@1.3.6: {} + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 - make-fetch-happen@13.0.1: + micromark-util-decode-numeric-character-reference@2.0.2: dependencies: - '@npmcli/agent': 2.2.2 - cacache: 18.0.4 - http-cache-semantics: 4.2.0 - is-lambda: 1.0.1 - minipass: 7.1.2 - minipass-fetch: 3.0.5 - minipass-flush: 1.0.5 - minipass-pipeline: 1.2.4 - negotiator: 0.6.4 - proc-log: 4.2.0 - promise-retry: 2.0.1 - ssri: 10.0.6 - transitivePeerDependencies: - - supports-color + micromark-util-symbol: 2.0.1 - makeerror@1.0.12: + micromark-util-decode-string@2.0.1: dependencies: - tmpl: 1.0.5 + decode-named-character-reference: 1.2.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 - map-obj@1.0.1: {} + micromark-util-encode@2.0.1: {} - map-obj@4.3.0: {} + micromark-util-html-tag-name@2.0.1: {} - math-intrinsics@1.1.0: {} + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 - meow@8.1.2: + micromark-util-resolve-all@2.0.1: dependencies: - '@types/minimist': 1.2.5 - camelcase-keys: 6.2.2 - decamelize-keys: 1.1.1 - hard-rejection: 2.1.0 - minimist-options: 4.1.0 - normalize-package-data: 3.0.3 - read-pkg-up: 7.0.1 - redent: 3.0.0 - trim-newlines: 3.0.1 - type-fest: 0.18.1 - yargs-parser: 20.2.9 + micromark-util-types: 2.0.2 - merge-stream@2.0.0: {} + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 - merge2@1.4.1: {} + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.2: {} + + micromark@4.0.2: + dependencies: + '@types/debug': 4.1.12 + debug: 4.4.3 + decode-named-character-reference: 1.2.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color micromatch@4.0.8: dependencies: @@ -6281,6 +12829,31 @@ snapshots: ms@2.1.3: {} + msw@2.11.5(@types/node@20.19.24)(typescript@5.9.3): + dependencies: + '@inquirer/confirm': 5.1.19(@types/node@20.19.24) + '@mswjs/interceptors': 0.39.8 + '@open-draft/deferred-promise': 2.2.0 + '@types/statuses': 2.0.6 + cookie: 1.0.2 + graphql: 16.12.0 + headers-polyfill: 4.0.3 + is-node-process: 1.2.0 + outvariant: 1.4.3 + path-to-regexp: 6.3.0 + picocolors: 1.1.1 + rettime: 0.7.0 + statuses: 2.0.2 + strict-event-emitter: 0.5.1 + tough-cookie: 6.0.0 + type-fest: 4.41.0 + until-async: 3.0.2 + yargs: 17.7.2 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - '@types/node' + multimatch@5.0.0: dependencies: '@types/minimatch': 3.0.5 @@ -6293,12 +12866,61 @@ snapshots: mute-stream@1.0.0: {} + mute-stream@2.0.0: {} + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + nanoid@3.3.11: {} + + napi-postinstall@0.3.4: {} + natural-compare@1.4.0: {} negotiator@0.6.4: {} neo-async@2.6.2: {} + next-seo@6.8.0(next@15.5.6(@babel/core@7.28.5)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + next: 15.5.6(@babel/core@7.28.5)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + next-themes@0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + next@15.5.6(@babel/core@7.28.5)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@next/env': 15.5.6 + '@swc/helpers': 0.5.15 + caniuse-lite: 1.0.30001754 + postcss: 8.4.31 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + styled-jsx: 5.1.6(@babel/core@7.28.5)(react@18.3.1) + optionalDependencies: + '@next/swc-darwin-arm64': 15.5.6 + '@next/swc-darwin-x64': 15.5.6 + '@next/swc-linux-arm64-gnu': 15.5.6 + '@next/swc-linux-arm64-musl': 15.5.6 + '@next/swc-linux-x64-gnu': 15.5.6 + '@next/swc-linux-x64-musl': 15.5.6 + '@next/swc-win32-arm64-msvc': 15.5.6 + '@next/swc-win32-x64-msvc': 15.5.6 + '@playwright/test': 1.56.1 + sharp: 0.34.5 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + + node-domexception@1.0.0: {} + node-fetch@2.6.7(encoding@0.1.13): dependencies: whatwg-url: 5.0.0 @@ -6311,6 +12933,12 @@ snapshots: optionalDependencies: encoding: 0.1.13 + node-fetch@3.3.2: + dependencies: + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + node-gyp@10.3.1: dependencies: env-paths: 2.2.1 @@ -6363,6 +12991,8 @@ snapshots: normalize-path@3.0.0: {} + normalize-range@0.1.2: {} + npm-bundled@3.0.1: dependencies: npm-normalize-package-bin: 3.0.1 @@ -6408,14 +13038,23 @@ snapshots: dependencies: path-key: 3.1.1 - nx@20.8.2: + nuqs@2.7.3(next@15.5.6(@babel/core@7.28.5)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1): + dependencies: + '@standard-schema/spec': 1.0.0 + react: 18.3.1 + optionalDependencies: + next: 15.5.6(@babel/core@7.28.5)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + + nwsapi@2.2.22: {} + + nx@20.8.2(@swc/core@1.15.0(@swc/helpers@0.5.17)): dependencies: '@napi-rs/wasm-runtime': 0.2.4 '@yarnpkg/lockfile': 1.1.0 '@yarnpkg/parsers': 3.0.2 '@zkochan/js-yaml': 0.0.7 axios: 1.13.2 - chalk: 4.1.0 + chalk: 4.1.2 cli-cursor: 3.1.0 cli-spinners: 2.6.1 cliui: 8.0.1 @@ -6455,9 +13094,54 @@ snapshots: '@nx/nx-linux-x64-musl': 20.8.2 '@nx/nx-win32-arm64-msvc': 20.8.2 '@nx/nx-win32-x64-msvc': 20.8.2 + '@swc/core': 1.15.0(@swc/helpers@0.5.17) transitivePeerDependencies: - debug + object-assign@4.1.1: {} + + object-hash@3.0.0: {} + + object-inspect@1.13.4: {} + + object-keys@1.1.1: {} + + object.assign@4.1.7: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + has-symbols: 1.1.0 + object-keys: 1.1.1 + + object.entries@1.1.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + object.fromentries@2.0.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-object-atoms: 1.1.1 + + object.groupby@1.0.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + + object.values@1.2.1: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + once@1.4.0: dependencies: wrappy: 1.0.2 @@ -6484,7 +13168,7 @@ snapshots: ora@5.3.0: dependencies: bl: 4.1.0 - chalk: 4.1.0 + chalk: 4.1.2 cli-cursor: 3.1.0 cli-spinners: 2.6.1 is-interactive: 1.0.0 @@ -6504,6 +13188,14 @@ snapshots: strip-ansi: 6.0.1 wcwidth: 1.0.1 + outvariant@1.4.3: {} + + own-keys@1.0.1: + dependencies: + get-intrinsic: 1.3.0 + object-keys: 1.1.1 + safe-push-apply: 1.0.0 + p-finally@1.0.0: {} p-limit@1.3.0: @@ -6592,6 +13284,25 @@ snapshots: just-diff: 6.0.2 just-diff-apply: 5.5.0 + parse-entities@2.0.0: + dependencies: + character-entities: 1.2.4 + character-entities-legacy: 1.1.4 + character-reference-invalid: 1.1.4 + is-alphanumerical: 1.0.4 + is-decimal: 1.0.4 + is-hexadecimal: 1.0.4 + + parse-entities@4.0.2: + dependencies: + '@types/unist': 2.0.11 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.2.0 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + parse-json@4.0.0: dependencies: error-ex: 1.3.4 @@ -6612,6 +13323,10 @@ snapshots: dependencies: parse-path: 7.1.0 + parse5@7.3.0: + dependencies: + entities: 6.0.1 + path-exists@3.0.0: {} path-exists@4.0.0: {} @@ -6627,12 +13342,51 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.2 + path-to-regexp@6.3.0: {} + path-type@3.0.0: dependencies: pify: 3.0.0 path-type@4.0.0: {} + perfect-freehand@1.2.2: {} + + pg-cloudflare@1.2.7: + optional: true + + pg-connection-string@2.9.1: {} + + pg-int8@1.0.1: {} + + pg-pool@3.10.1(pg@8.16.3): + dependencies: + pg: 8.16.3 + + pg-protocol@1.10.3: {} + + pg-types@2.2.0: + dependencies: + pg-int8: 1.0.1 + postgres-array: 2.0.0 + postgres-bytea: 1.0.0 + postgres-date: 1.0.7 + postgres-interval: 1.2.0 + + pg@8.16.3: + dependencies: + pg-connection-string: 2.9.1 + pg-pool: 3.10.1(pg@8.16.3) + pg-protocol: 1.10.3 + pg-types: 2.2.0 + pgpass: 1.0.5 + optionalDependencies: + pg-cloudflare: 1.2.7 + + pgpass@1.0.5: + dependencies: + split2: 4.2.0 + picocolors@1.1.1: {} picomatch@2.3.1: {} @@ -6653,21 +13407,96 @@ snapshots: dependencies: find-up: 4.1.0 + playwright-core@1.56.1: {} + + playwright@1.56.1: + dependencies: + playwright-core: 1.56.1 + optionalDependencies: + fsevents: 2.3.2 + + possible-typed-array-names@1.1.0: {} + + postcss-import@15.1.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.11 + + postcss-js@4.1.0(postcss@8.5.6): + dependencies: + camelcase-css: 2.0.1 + postcss: 8.5.6 + + postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.6)(yaml@2.8.1): + dependencies: + lilconfig: 3.1.3 + optionalDependencies: + jiti: 1.21.7 + postcss: 8.5.6 + yaml: 2.8.1 + + postcss-nested@6.2.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 6.1.2 + postcss-selector-parser@6.1.2: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 + postcss-value-parser@4.2.0: {} + + postcss@8.4.31: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + postcss@8.5.6: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + postgres-array@2.0.0: {} + + postgres-bytea@1.0.0: {} + + postgres-date@1.0.7: {} + + postgres-interval@1.2.0: + dependencies: + xtend: 4.0.2 + prelude-ls@1.2.1: {} prettier@3.6.2: {} + pretty-format@27.5.1: + dependencies: + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 17.0.2 + pretty-format@29.7.0: dependencies: '@jest/schemas': 29.6.3 ansi-styles: 5.2.0 react-is: 18.3.1 + pretty-format@30.2.0: + dependencies: + '@jest/schemas': 30.0.5 + ansi-styles: 5.2.0 + react-is: 18.3.1 + + prismjs@1.27.0: {} + + prismjs@1.30.0: {} + proc-log@4.2.0: {} process-nextick-args@2.0.1: {} @@ -6694,10 +13523,28 @@ snapshots: dependencies: read: 3.0.1 + prop-types@15.8.1: + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + + property-information@5.6.0: + dependencies: + xtend: 4.0.2 + + property-information@7.1.0: {} + protocols@2.0.2: {} + proxy-compare@3.0.1: {} + proxy-from-env@1.1.0: {} + proxy-memoize@3.0.1: + dependencies: + proxy-compare: 3.0.1 + punycode@2.3.1: {} pure-rand@6.1.0: {} @@ -6706,12 +13553,90 @@ snapshots: quick-lru@4.0.1: {} + react-dom@18.3.1(react@18.3.1): + dependencies: + loose-envify: 1.4.0 + react: 18.3.1 + scheduler: 0.23.2 + + react-error-boundary@3.1.4(react@18.3.1): + dependencies: + '@babel/runtime': 7.28.4 + react: 18.3.1 + + react-hook-form@7.66.0(react@18.3.1): + dependencies: + react: 18.3.1 + + react-is@16.13.1: {} + + react-is@17.0.2: {} + react-is@18.3.1: {} + react-markdown@9.1.0(@types/react@18.3.26)(react@18.3.1): + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@types/react': 18.3.26 + devlop: 1.1.0 + hast-util-to-jsx-runtime: 2.3.6 + html-url-attributes: 3.0.1 + mdast-util-to-hast: 13.2.0 + react: 18.3.1 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + unified: 11.0.5 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + react-remove-scroll-bar@2.3.8(@types/react@18.3.26)(react@18.3.1): + dependencies: + react: 18.3.1 + react-style-singleton: 2.2.3(@types/react@18.3.26)(react@18.3.1) + tslib: 2.8.1 + optionalDependencies: + '@types/react': 18.3.26 + + react-remove-scroll@2.7.1(@types/react@18.3.26)(react@18.3.1): + dependencies: + react: 18.3.1 + react-remove-scroll-bar: 2.3.8(@types/react@18.3.26)(react@18.3.1) + react-style-singleton: 2.2.3(@types/react@18.3.26)(react@18.3.1) + tslib: 2.8.1 + use-callback-ref: 1.3.3(@types/react@18.3.26)(react@18.3.1) + use-sidecar: 1.1.3(@types/react@18.3.26)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.26 + + react-style-singleton@2.2.3(@types/react@18.3.26)(react@18.3.1): + dependencies: + get-nonce: 1.0.1 + react: 18.3.1 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 18.3.26 + + react-syntax-highlighter@15.6.6(react@18.3.1): + dependencies: + '@babel/runtime': 7.28.4 + highlight.js: 10.7.3 + highlightjs-vue: 1.0.0 + lowlight: 1.20.0 + prismjs: 1.30.0 + react: 18.3.1 + refractor: 3.6.0 + react@18.3.1: dependencies: loose-envify: 1.4.0 + read-cache@1.0.0: + dependencies: + pify: 2.3.0 + read-cmd-shim@4.0.0: {} read-package-json-fast@3.0.2: @@ -6770,10 +13695,85 @@ snapshots: string_decoder: 1.3.0 util-deprecate: 1.0.2 + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + redent@3.0.0: dependencies: - indent-string: 4.0.0 - strip-indent: 3.0.0 + indent-string: 4.0.0 + strip-indent: 3.0.0 + + reflect.getprototypeof@1.0.10: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + which-builtin-type: 1.2.1 + + refractor@3.6.0: + dependencies: + hastscript: 6.0.0 + parse-entities: 2.0.0 + prismjs: 1.27.0 + + regexp.prototype.flags@1.5.4: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-errors: 1.3.0 + get-proto: 1.0.1 + gopd: 1.2.0 + set-function-name: 2.0.2 + + remark-gfm@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-gfm: 3.1.0 + micromark-extension-gfm: 3.0.0 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-parse@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.2 + micromark-util-types: 2.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-rehype@11.1.2: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + mdast-util-to-hast: 13.2.0 + unified: 11.0.5 + vfile: 6.0.3 + + remark-stringify@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-to-markdown: 2.1.2 + unified: 11.0.5 + + remark@15.0.1: + dependencies: + '@types/mdast': 4.0.4 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remove-accents@0.5.0: {} require-directory@2.1.1: {} @@ -6785,6 +13785,8 @@ snapshots: resolve-from@5.0.0: {} + resolve-pkg-maps@1.0.0: {} + resolve.exports@2.0.3: {} resolve@1.22.11: @@ -6793,6 +13795,12 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + resolve@2.0.0-next.5: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + restore-cursor@3.1.0: dependencies: onetime: 5.1.2 @@ -6800,6 +13808,8 @@ snapshots: retry@0.12.0: {} + rettime@0.7.0: {} + reusify@1.1.0: {} rimraf@3.0.2: @@ -6810,8 +13820,12 @@ snapshots: dependencies: glob: 9.3.5 + rrweb-cssom@0.8.0: {} + run-async@2.4.1: {} + run-async@3.0.0: {} + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 @@ -6820,12 +13834,50 @@ snapshots: dependencies: tslib: 2.8.1 + safe-array-concat@1.1.3: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + has-symbols: 1.1.0 + isarray: 2.0.5 + safe-buffer@5.1.2: {} safe-buffer@5.2.1: {} + safe-push-apply@1.0.0: + dependencies: + es-errors: 1.3.0 + isarray: 2.0.5 + + safe-regex-test@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-regex: 1.2.1 + safer-buffer@2.1.2: {} + saxes@6.0.0: + dependencies: + xmlchars: 2.2.0 + + scheduler@0.23.2: + dependencies: + loose-envify: 1.4.0 + + schema-sdk@0.11.3(encoding@0.1.13): + dependencies: + '@babel/generator': 7.28.5 + '@babel/types': 7.28.5 + '@interweb-utils/casing': 0.2.0 + '@interweb/fetch-api-client': 0.6.1(encoding@0.1.13) + deepmerge: 4.3.1 + schema-typescript: 0.12.1 + transitivePeerDependencies: + - encoding + schema-sdk@0.12.0(encoding@0.1.13): dependencies: '@babel/generator': 7.28.5 @@ -6838,6 +13890,18 @@ snapshots: transitivePeerDependencies: - encoding + schema-sdk@0.15.0(encoding@0.1.13): + dependencies: + '@babel/generator': 7.28.5 + '@babel/types': 7.28.5 + '@interweb-utils/casing': 0.2.0 + '@interweb/fetch-api-client': 0.6.1(encoding@0.1.13) + deepmerge: 4.3.1 + fast-json-patch: 3.1.1 + schema-typescript: 0.12.1 + transitivePeerDependencies: + - encoding + schema-typescript@0.12.1: dependencies: '@babel/generator': 7.28.5 @@ -6846,6 +13910,11 @@ snapshots: deepmerge: 4.3.1 minimatch: 9.0.5 + section-matter@1.0.0: + dependencies: + extend-shallow: 2.0.1 + kind-of: 6.0.3 + semver@5.7.2: {} semver@6.3.1: {} @@ -6854,16 +13923,98 @@ snapshots: set-blocking@2.0.0: {} + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + set-proto@1.0.0: + dependencies: + dunder-proto: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + shallow-clone@3.0.1: dependencies: kind-of: 6.0.3 + sharp@0.34.5: + dependencies: + '@img/colour': 1.0.0 + detect-libc: 2.1.2 + semver: 7.7.3 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.34.5 + '@img/sharp-darwin-x64': 0.34.5 + '@img/sharp-libvips-darwin-arm64': 1.2.4 + '@img/sharp-libvips-darwin-x64': 1.2.4 + '@img/sharp-libvips-linux-arm': 1.2.4 + '@img/sharp-libvips-linux-arm64': 1.2.4 + '@img/sharp-libvips-linux-ppc64': 1.2.4 + '@img/sharp-libvips-linux-riscv64': 1.2.4 + '@img/sharp-libvips-linux-s390x': 1.2.4 + '@img/sharp-libvips-linux-x64': 1.2.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + '@img/sharp-linux-arm': 0.34.5 + '@img/sharp-linux-arm64': 0.34.5 + '@img/sharp-linux-ppc64': 0.34.5 + '@img/sharp-linux-riscv64': 0.34.5 + '@img/sharp-linux-s390x': 0.34.5 + '@img/sharp-linux-x64': 0.34.5 + '@img/sharp-linuxmusl-arm64': 0.34.5 + '@img/sharp-linuxmusl-x64': 0.34.5 + '@img/sharp-wasm32': 0.34.5 + '@img/sharp-win32-arm64': 0.34.5 + '@img/sharp-win32-ia32': 0.34.5 + '@img/sharp-win32-x64': 0.34.5 + optional: true + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 shebang-regex@3.0.0: {} + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + signal-exit@3.0.7: {} signal-exit@4.1.0: {} @@ -6902,6 +14053,8 @@ snapshots: dependencies: is-plain-obj: 1.1.0 + source-map-js@1.2.1: {} + source-map-support@0.5.13: dependencies: buffer-from: 1.1.2 @@ -6909,6 +14062,10 @@ snapshots: source-map@0.6.1: {} + space-separated-tokens@1.1.5: {} + + space-separated-tokens@2.0.2: {} + spdx-correct@3.2.0: dependencies: spdx-expression-parse: 3.0.1 @@ -6927,6 +14084,8 @@ snapshots: dependencies: readable-stream: 3.6.2 + split2@4.2.0: {} + split@1.0.1: dependencies: through: 2.3.8 @@ -6937,10 +14096,21 @@ snapshots: dependencies: minipass: 7.1.2 + stable-hash@0.0.5: {} + stack-utils@2.0.6: dependencies: escape-string-regexp: 2.0.0 + statuses@2.0.2: {} + + stop-iteration-iterator@1.1.0: + dependencies: + es-errors: 1.3.0 + internal-slot: 1.1.0 + + strict-event-emitter@0.5.1: {} + string-length@4.0.2: dependencies: char-regex: 1.0.2 @@ -6958,6 +14128,56 @@ snapshots: emoji-regex: 9.2.2 strip-ansi: 7.1.2 + string.prototype.includes@2.0.1: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + + string.prototype.matchall@4.0.12: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + regexp.prototype.flags: 1.5.4 + set-function-name: 2.0.2 + side-channel: 1.1.0 + + string.prototype.repeat@1.0.0: + dependencies: + define-properties: 1.2.1 + es-abstract: 1.24.0 + + string.prototype.trim@1.2.10: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-data-property: 1.1.4 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-object-atoms: 1.1.1 + has-property-descriptors: 1.0.2 + + string.prototype.trimend@1.0.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + string_decoder@0.10.31: {} string_decoder@1.1.1: @@ -6968,6 +14188,11 @@ snapshots: dependencies: safe-buffer: 5.2.1 + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 @@ -6976,6 +14201,8 @@ snapshots: dependencies: ansi-regex: 6.2.2 + strip-bom-string@1.0.0: {} + strip-bom@3.0.0: {} strip-bom@4.0.0: {} @@ -6988,6 +14215,31 @@ snapshots: strip-json-comments@3.1.1: {} + style-to-js@1.1.19: + dependencies: + style-to-object: 1.0.12 + + style-to-object@1.0.12: + dependencies: + inline-style-parser: 0.2.6 + + styled-jsx@5.1.6(@babel/core@7.28.5)(react@18.3.1): + dependencies: + client-only: 0.0.1 + react: 18.3.1 + optionalDependencies: + '@babel/core': 7.28.5 + + sucrase@3.35.0: + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + commander: 4.1.1 + glob: 10.4.5 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.7 + ts-interface-checker: 0.1.13 + supports-color@7.2.0: dependencies: has-flag: 4.0.0 @@ -6998,6 +14250,42 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} + symbol-tree@3.2.4: {} + + tailwind-merge@2.6.0: {} + + tailwindcss-animate@1.0.7(tailwindcss@3.4.18(yaml@2.8.1)): + dependencies: + tailwindcss: 3.4.18(yaml@2.8.1) + + tailwindcss@3.4.18(yaml@2.8.1): + dependencies: + '@alloc/quick-lru': 5.2.0 + arg: 5.0.2 + chokidar: 3.6.0 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.3.3 + glob-parent: 6.0.2 + is-glob: 4.0.3 + jiti: 1.21.7 + lilconfig: 3.1.3 + micromatch: 4.0.8 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.1.1 + postcss: 8.5.6 + postcss-import: 15.1.0(postcss@8.5.6) + postcss-js: 4.1.0(postcss@8.5.6) + postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.6)(yaml@2.8.1) + postcss-nested: 6.2.0(postcss@8.5.6) + postcss-selector-parser: 6.1.2 + resolve: 1.22.11 + sucrase: 3.35.0 + transitivePeerDependencies: + - tsx + - yaml + tar-stream@2.2.0: dependencies: bl: 4.1.0 @@ -7027,6 +14315,14 @@ snapshots: text-table@0.2.0: {} + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + through2@2.0.5: dependencies: readable-stream: 2.3.8 @@ -7039,6 +14335,23 @@ snapshots: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + + tldts-core@6.1.86: {} + + tldts-core@7.0.17: {} + + tldts@6.1.86: + dependencies: + tldts-core: 6.1.86 + + tldts@7.0.17: + dependencies: + tldts-core: 7.0.17 + tmp@0.2.5: {} tmpl@1.0.5: {} @@ -7047,22 +14360,40 @@ snapshots: dependencies: is-number: 7.0.0 + tough-cookie@5.1.2: + dependencies: + tldts: 6.1.86 + + tough-cookie@6.0.0: + dependencies: + tldts: 7.0.17 + tr46@0.0.3: {} + tr46@5.1.1: + dependencies: + punycode: 2.3.1 + treeverse@3.0.0: {} + trim-lines@3.0.1: {} + trim-newlines@3.0.1: {} + trough@2.2.0: {} + ts-api-utils@1.4.3(typescript@5.9.3): dependencies: typescript: 5.9.3 - ts-jest@29.4.5(@babel/core@7.28.5)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.5))(jest-util@29.7.0)(jest@29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3)))(typescript@5.9.3): + ts-interface-checker@0.1.13: {} + + ts-jest@29.4.5(@babel/core@7.28.5)(@jest/transform@29.7.0)(@jest/types@30.2.0)(babel-jest@29.7.0(@babel/core@7.28.5))(jest-util@30.2.0)(jest@29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@swc/core@1.15.0(@swc/helpers@0.5.17))(@swc/wasm@1.15.0)(@types/node@20.19.24)(typescript@5.9.3)))(typescript@5.9.3): dependencies: bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 handlebars: 4.7.8 - jest: 29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3)) + jest: 29.7.0(@types/node@20.19.24)(ts-node@10.9.2(@swc/core@1.15.0(@swc/helpers@0.5.17))(@swc/wasm@1.15.0)(@types/node@20.19.24)(typescript@5.9.3)) json5: 2.2.3 lodash.memoize: 4.1.2 make-error: 1.3.6 @@ -7073,11 +14404,11 @@ snapshots: optionalDependencies: '@babel/core': 7.28.5 '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 + '@jest/types': 30.2.0 babel-jest: 29.7.0(@babel/core@7.28.5) - jest-util: 29.7.0 + jest-util: 30.2.0 - ts-node@10.9.2(@types/node@20.19.24)(typescript@5.9.3): + ts-node@10.9.2(@swc/core@1.15.0(@swc/helpers@0.5.17))(@swc/wasm@1.15.0)(@types/node@20.19.24)(typescript@5.9.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 @@ -7094,6 +14425,16 @@ snapshots: typescript: 5.9.3 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 + optionalDependencies: + '@swc/core': 1.15.0(@swc/helpers@0.5.17) + '@swc/wasm': 1.15.0 + + tsconfig-paths@3.15.0: + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 tsconfig-paths@4.2.0: dependencies: @@ -7131,6 +14472,39 @@ snapshots: type-fest@4.41.0: {} + typed-array-buffer@1.0.3: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-typed-array: 1.1.15 + + typed-array-byte-length@1.0.3: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + + typed-array-byte-offset@1.0.4: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + reflect.getprototypeof: 1.0.10 + + typed-array-length@1.0.7: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + is-typed-array: 1.1.15 + possible-typed-array-names: 1.1.0 + reflect.getprototypeof: 1.0.10 + typedarray@0.0.6: {} typescript@5.9.3: {} @@ -7138,8 +14512,27 @@ snapshots: uglify-js@3.19.3: optional: true + unbox-primitive@1.1.0: + dependencies: + call-bound: 1.0.4 + has-bigints: 1.1.0 + has-symbols: 1.1.0 + which-boxed-primitive: 1.1.1 + undici-types@6.21.0: {} + undici@7.16.0: {} + + unified@11.0.5: + dependencies: + '@types/unist': 3.0.3 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 6.0.3 + unique-filename@3.0.0: dependencies: unique-slug: 4.0.0 @@ -7148,10 +14541,59 @@ snapshots: dependencies: imurmurhash: 0.1.4 + unist-util-is@6.0.1: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-visit@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + universal-user-agent@6.0.1: {} universalify@2.0.1: {} + unrs-resolver@1.11.1: + dependencies: + napi-postinstall: 0.3.4 + optionalDependencies: + '@unrs/resolver-binding-android-arm-eabi': 1.11.1 + '@unrs/resolver-binding-android-arm64': 1.11.1 + '@unrs/resolver-binding-darwin-arm64': 1.11.1 + '@unrs/resolver-binding-darwin-x64': 1.11.1 + '@unrs/resolver-binding-freebsd-x64': 1.11.1 + '@unrs/resolver-binding-linux-arm-gnueabihf': 1.11.1 + '@unrs/resolver-binding-linux-arm-musleabihf': 1.11.1 + '@unrs/resolver-binding-linux-arm64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-arm64-musl': 1.11.1 + '@unrs/resolver-binding-linux-ppc64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-riscv64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-riscv64-musl': 1.11.1 + '@unrs/resolver-binding-linux-s390x-gnu': 1.11.1 + '@unrs/resolver-binding-linux-x64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-x64-musl': 1.11.1 + '@unrs/resolver-binding-wasm32-wasi': 1.11.1 + '@unrs/resolver-binding-win32-arm64-msvc': 1.11.1 + '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 + '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 + + until-async@3.0.2: {} + untildify@4.0.0: {} upath@2.0.1: {} @@ -7162,14 +14604,41 @@ snapshots: escalade: 3.2.0 picocolors: 1.1.1 + uqr@0.1.2: {} + uri-js@4.4.1: dependencies: punycode: 2.3.1 + use-callback-ref@1.3.3(@types/react@18.3.26)(react@18.3.1): + dependencies: + react: 18.3.1 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 18.3.26 + + use-debounce@10.0.6(react@18.3.1): + dependencies: + react: 18.3.1 + + use-sidecar@1.1.3(@types/react@18.3.26)(react@18.3.1): + dependencies: + detect-node-es: 1.1.0 + react: 18.3.1 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 18.3.26 + + use-sync-external-store@1.6.0(react@18.3.1): + dependencies: + react: 18.3.1 + util-deprecate@1.0.2: {} uuid@10.0.0: {} + uuid@11.1.0: {} + v8-compile-cache-lib@3.0.1: {} v8-to-istanbul@9.3.0: @@ -7185,6 +14654,20 @@ snapshots: validate-npm-package-name@5.0.1: {} + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + + w3c-xmlserializer@5.0.0: + dependencies: + xml-name-validator: 5.0.0 + walk-up-path@3.0.1: {} walker@1.0.8: @@ -7195,15 +14678,71 @@ snapshots: dependencies: defaults: 1.0.4 + web-streams-polyfill@3.3.3: {} + webidl-conversions@3.0.1: {} + webidl-conversions@7.0.0: {} + + whatwg-encoding@3.1.1: + dependencies: + iconv-lite: 0.6.3 + whatwg-fetch@3.6.20: {} + whatwg-mimetype@4.0.0: {} + + whatwg-url@14.2.0: + dependencies: + tr46: 5.1.1 + webidl-conversions: 7.0.0 + whatwg-url@5.0.0: dependencies: tr46: 0.0.3 webidl-conversions: 3.0.1 + which-boxed-primitive@1.1.1: + dependencies: + is-bigint: 1.1.0 + is-boolean-object: 1.2.2 + is-number-object: 1.1.1 + is-string: 1.1.1 + is-symbol: 1.1.1 + + which-builtin-type@1.2.1: + dependencies: + call-bound: 1.0.4 + function.prototype.name: 1.1.8 + has-tostringtag: 1.0.2 + is-async-function: 2.1.1 + is-date-object: 1.1.0 + is-finalizationregistry: 1.1.1 + is-generator-function: 1.1.2 + is-regex: 1.2.1 + is-weakref: 1.1.1 + isarray: 2.0.5 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.19 + + which-collection@1.0.2: + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.4 + + which-typed-array@1.1.19: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + which@2.0.2: dependencies: isexe: 2.0.0 @@ -7271,6 +14810,12 @@ snapshots: type-fest: 0.4.1 write-json-file: 3.2.0 + ws@8.18.3: {} + + xml-name-validator@5.0.0: {} + + xmlchars@2.2.0: {} + xtend@4.0.2: {} y18n@5.0.8: {} @@ -7308,3 +14853,7 @@ snapshots: yn@3.1.1: {} yocto-queue@0.1.0: {} + + yoctocolors-cjs@2.1.3: {} + + zwitch@2.0.4: {} From 63b9bd1d45b04c92516bf4bc05f131b484baba58 Mon Sep 17 00:00:00 2001 From: Anmol1696 Date: Sat, 8 Nov 2025 10:07:11 +0400 Subject: [PATCH 04/11] remove running unit tests for dashboard --- .github/workflows/test-unit-dashboard.yml | 194 ---------------------- 1 file changed, 194 deletions(-) delete mode 100644 .github/workflows/test-unit-dashboard.yml diff --git a/.github/workflows/test-unit-dashboard.yml b/.github/workflows/test-unit-dashboard.yml deleted file mode 100644 index 18af68d..0000000 --- a/.github/workflows/test-unit-dashboard.yml +++ /dev/null @@ -1,194 +0,0 @@ -name: Dashboard Unit Tests - -on: - push: - branches: [main] - paths: - - "apps/ops-dashboard/**/__tests__/**" - - "apps/ops-dashboard/**/src/**" - - "apps/ops-dashboard/**/components/**" - - "apps/ops-dashboard/**/hooks/**" - - "apps/ops-dashboard/**/lib/**" - - "apps/ops-dashboard/**/app/**" - - "apps/ops-dashboard/**/jest.config.js" - - "apps/ops-dashboard/**/package.json" - - ".github/workflows/test-unit-dashboard.yml" - pull_request: - branches: [main] - paths: - - "apps/ops-dashboard/**/__tests__/**" - - "apps/ops-dashboard/**/src/**" - - "apps/ops-dashboard/**/components/**" - - "apps/ops-dashboard/**/hooks/**" - - "apps/ops-dashboard/**/lib/**" - - "apps/ops-dashboard/**/app/**" - - "apps/ops-dashboard/**/jest.config.js" - - "apps/ops-dashboard/**/package.json" - - ".github/workflows/test-unit-dashboard.yml" - workflow_dispatch: - inputs: - test_package: - description: 'Package to test (or "all")' - required: true - default: 'dashboard' - type: choice - options: - - dashboard - - all - -jobs: - unit-tests-dashboard: - runs-on: ubuntu-latest - timeout-minutes: 15 - if: ${{ github.event.inputs.test_package == 'all' || github.event.inputs.test_package == 'dashboard' || github.event.inputs.test_package == '' }} - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup pnpm - uses: pnpm/action-setup@v2 - with: - version: 10.12.2 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: "20.x" - cache: "pnpm" - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Build packages - run: pnpm build - - - name: Run dashboard unit tests - run: | - cd apps/ops-dashboard - pnpm test --coverage --watchAll=false - env: - CI: true - - - name: Upload coverage reports - uses: codecov/codecov-action@v4 - with: - file: apps/ops-dashboard/coverage/lcov.info - flags: dashboard - name: dashboard-coverage - fail_ci_if_error: false - - - name: Upload test results - if: always() - uses: actions/upload-artifact@v4 - with: - name: dashboard-unit-test-results - path: apps/ops-dashboard/coverage/ - retention-days: 7 - - # Other packages unit tests (only when "all" is selected) - unit-tests-other-packages: - runs-on: ubuntu-latest - timeout-minutes: 20 - if: ${{ github.event.inputs.test_package == 'all' }} - - strategy: - fail-fast: false - matrix: - package: - - client - - manifests - - ops - - cli - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup pnpm - uses: pnpm/action-setup@v2 - with: - version: 10.12.2 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: "20.x" - cache: "pnpm" - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Build packages - run: pnpm build - - - name: Run unit tests for ${{ matrix.package }} - run: | - cd packages/${{ matrix.package }} - if [ "${{ matrix.package }}" = "client" ]; then - pnpm tests:unit --coverage --watchAll=false --passWithNoTests - else - pnpm test --coverage --watchAll=false --passWithNoTests - fi - env: - CI: true - - - name: Upload coverage for ${{ matrix.package }} - uses: codecov/codecov-action@v4 - with: - file: packages/${{ matrix.package }}/coverage/lcov.info - flags: ${{ matrix.package }}-unit - name: ${{ matrix.package }}-unit-coverage - fail_ci_if_error: false - - - name: Upload test results for ${{ matrix.package }} - if: always() - uses: actions/upload-artifact@v4 - with: - name: ${{ matrix.package }}-unit-test-results - path: packages/${{ matrix.package }}/coverage/ - retention-days: 7 - - test-summary: - runs-on: ubuntu-latest - needs: [unit-tests-dashboard, unit-tests-other-packages] - if: always() - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Download all test results - uses: actions/download-artifact@v4 - with: - path: test-results - - - name: Generate test summary - run: | - echo "# Dashboard Unit Test Results Summary" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - - # Check dashboard results - if [ -d "test-results/dashboard-unit-test-results" ]; then - echo "✅ **Dashboard unit tests completed**" >> $GITHUB_STEP_SUMMARY - else - echo "❌ **Dashboard unit tests failed or skipped**" >> $GITHUB_STEP_SUMMARY - fi - - # Check other packages results (only if "all" was selected) - if [ "${{ github.event.inputs.test_package }}" = "all" ]; then - echo "" >> $GITHUB_STEP_SUMMARY - echo "## Other Packages" >> $GITHUB_STEP_SUMMARY - - for package in client manifests interwebjs cli; do - if [ -d "test-results/$package-unit-test-results" ]; then - echo "✅ $package unit tests completed" >> $GITHUB_STEP_SUMMARY - else - echo "❌ $package unit tests failed or skipped" >> $GITHUB_STEP_SUMMARY - fi - done - fi - - echo "" >> $GITHUB_STEP_SUMMARY - echo "## Coverage Reports" >> $GITHUB_STEP_SUMMARY - echo "Coverage reports have been uploaded to Codecov for detailed analysis." >> $GITHUB_STEP_SUMMARY From b29cd8ab704e87469f3759daa918f838cf798e95 Mon Sep 17 00:00:00 2001 From: Anmol1696 Date: Sat, 8 Nov 2025 10:10:37 +0400 Subject: [PATCH 05/11] remove interweb dir fully --- interweb/.gitignore | 147 - interweb/.prettiierrc.json | 7 - interweb/.vscode/launch.json | 70 - interweb/LICENSE | 4 - interweb/PUBLISH.md | 41 - interweb/README.md | 68 - interweb/eslint.config.js | 45 - interweb/lerna.json | 11 - interweb/package.json | 51 - interweb/pnpm-lock.yaml | 14974 --------------------------------- interweb/pnpm-workspace.yaml | 2 - interweb/tsconfig.json | 15 - 12 files changed, 15435 deletions(-) delete mode 100644 interweb/.gitignore delete mode 100644 interweb/.prettiierrc.json delete mode 100644 interweb/.vscode/launch.json delete mode 100644 interweb/LICENSE delete mode 100644 interweb/PUBLISH.md delete mode 100644 interweb/README.md delete mode 100644 interweb/eslint.config.js delete mode 100644 interweb/lerna.json delete mode 100644 interweb/package.json delete mode 100644 interweb/pnpm-lock.yaml delete mode 100644 interweb/pnpm-workspace.yaml delete mode 100644 interweb/tsconfig.json diff --git a/interweb/.gitignore b/interweb/.gitignore deleted file mode 100644 index 64e84b6..0000000 --- a/interweb/.gitignore +++ /dev/null @@ -1,147 +0,0 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage -*.lcov - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# Snowpack dependency directory (https://snowpack.dev/) -web_modules/ - -# TypeScript cache -*.tsbuildinfo - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Optional stylelint cache -.stylelintcache - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variable files -.env -.env.* -!.env.example - -# parcel-bundler cache (https://parceljs.org/) -.cache -.parcel-cache - -# Next.js build output -.next -out - -# Nuxt.js build / generate output -.nuxt -dist - -# Gatsby files -.cache/ -# Comment in the public line in if your project uses Gatsby and not Next.js -# https://nextjs.org/blog/next-9-1#public-directory-support -# public - -# vuepress build output -.vuepress/dist - -# vuepress v2.x temp and cache directory -.temp -.cache - -# Sveltekit cache directory -.svelte-kit/ - -# vitepress build output -**/.vitepress/dist - -# vitepress cache directory -**/.vitepress/cache - -# Docusaurus cache and generated files -.docusaurus - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# Firebase cache directory -.firebase/ - -# TernJS port file -.tern-port - -# Stores VSCode versions used for testing VSCode extensions -.vscode-test - -# yarn v3 -.pnp.* -.yarn/* -!.yarn/patches -!.yarn/plugins -!.yarn/releases -!.yarn/sdks -!.yarn/versions - -# Vite logs files -vite.config.js.timestamp-* -vite.config.ts.timestamp-* - - -# Playwright -playwright-report/ -test-results/ -screenshots/ -videos/ -traces/ \ No newline at end of file diff --git a/interweb/.prettiierrc.json b/interweb/.prettiierrc.json deleted file mode 100644 index 1b591cf..0000000 --- a/interweb/.prettiierrc.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "trailingComma": "es5", - "tabWidth": 2, - "semi": true, - "useTabs": false, - "singleQuote": false -} diff --git a/interweb/.vscode/launch.json b/interweb/.vscode/launch.json deleted file mode 100644 index 75dcf2d..0000000 --- a/interweb/.vscode/launch.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - "type": "node", - "request": "launch", - "name": "Jest: (client)", - "cwd": "${workspaceFolder}/packages/client", - "runtimeExecutable": "node", - "program": "${workspaceFolder}/node_modules/jest/bin/jest.js", - "args": [ - "--runInBand", - "--config", - "${workspaceFolder}/packages/client/jest.config.js", - "${file}" - ], - "console": "integratedTerminal", - "internalConsoleOptions": "neverOpen", - "env": { - "K8S_API": "http://127.0.0.1:8001" - } - }, - { - "type": "node", - "request": "launch", - "name": "Jest: (manifests - current file)", - "cwd": "${workspaceFolder}/packages/manifests", - "runtimeExecutable": "node", - "program": "${workspaceFolder}/node_modules/jest/bin/jest.js", - "args": [ - "--runInBand", - "--config", - "${workspaceFolder}/packages/manifests/jest.config.js", - "${file}" - ], - "console": "integratedTerminal", - "internalConsoleOptions": "neverOpen" - }, - { - "type": "node", - "request": "launch", - "name": "Jest: (manifests - all)", - "cwd": "${workspaceFolder}/packages/manifests", - "runtimeExecutable": "node", - "program": "${workspaceFolder}/node_modules/jest/bin/jest.js", - "args": [ - "--runInBand", - "--config", - "${workspaceFolder}/packages/manifests/jest.config.js", - "--watch" - ], - "console": "integratedTerminal", - "internalConsoleOptions": "neverOpen" - }, - { - "type": "node", - "request": "attach", - "name": "Attach: Node 9229", - "port": 9229 - } - ], - "inputs": [ - { - "id": "testName", - "type": "promptString", - "description": "Enter Jest test name pattern", - "default": "parity" - } - ] -} diff --git a/interweb/LICENSE b/interweb/LICENSE deleted file mode 100644 index 85c86b5..0000000 --- a/interweb/LICENSE +++ /dev/null @@ -1,4 +0,0 @@ -Copyright (c) 2025 Interweb, Inc. All rights reserved. - -Unauthorized copying, modification, redistribution, or use of this software, via any medium, -is strictly prohibited without the prior written consent of Interweb, Inc. \ No newline at end of file diff --git a/interweb/PUBLISH.md b/interweb/PUBLISH.md deleted file mode 100644 index c35c341..0000000 --- a/interweb/PUBLISH.md +++ /dev/null @@ -1,41 +0,0 @@ -# Publishing Guide - -## Quick Publishing Workflow - -### 1. Prepare -```bash -pnpm install -pnpm -r build -pnpm -r test -``` - -### 2. Version -```bash -# Independent versioning (recommended) -pnpm lerna version - -# Or fixed versioning -pnpm lerna version --conventional-commits -``` - -### 3. Publish - -use `from-package` option - -```bash -pnpm lerna publish from-package -``` - -## Dry Run Commands -```bash -# Test versioning (no git operations) -pnpm lerna version --no-git-tag-version --no-push - -# Test publishing -pnpm lerna publish from-package --dry-run -``` - -## One-liner for Full Workflow -```bash -pnpm install && pnpm -r build && pnpm -r test && lerna version && lerna publish from-package -``` \ No newline at end of file diff --git a/interweb/README.md b/interweb/README.md deleted file mode 100644 index a3be57f..0000000 --- a/interweb/README.md +++ /dev/null @@ -1,68 +0,0 @@ -# Interweb - -

- Build - Integration Tests - E2E Tests -

- -Interweb is a TypeScript toolkit for programmatic Kubernetes operations. It ships a curated set of operator manifests, a generated Kubernetes API client, and a high‑level client that applies manifests with kube‑native semantics (create/replace), CRD awareness, and sensible ordering. - -Use Interweb to install core platform operators (ingress-nginx, cert-manager, Knative Serving, CloudNativePG, kube‑prometheus‑stack) and to manage app resources without shelling out to kubectl/helm. - -## Packages -- @interweb/interwebjs: Generated, fetch‑based Kubernetes REST client (CJS + ESM) -- @interweb/client: High‑level SetupClient with CRD‑aware apply/delete, status helpers -- @interweb/manifests: Versioned YAML bundles for supported operators (with CRDs) -- @interweb/cli: Thin CLI wrapper around the client (optional) - -## Quick Start (dev) -- Prereqs: Node 20+, pnpm, a Kubernetes cluster (Kind/Docker Desktop), kubectl -- Install: `pnpm install` -- Build all: `pnpm -r build` -- Start API proxy (in another shell): `kubectl proxy --port=8001 --accept-hosts='^.*$' --address='0.0.0.0'` - -Apply an operator in code (example): - -```ts -import { InterwebClient as K8s } from '@interweb/interwebjs'; -import { SetupClient } from '@interweb/client/src/setup'; -import { ManifestLoader } from '@interweb/manifests'; - -const api = new K8s({ restEndpoint: 'http://127.0.0.1:8001' } as any); -const setup = new SetupClient(api); - -const manifests = ManifestLoader.loadOperatorManifests('ingress-nginx'); -await setup.applyManifests(manifests); -``` - -## Testing -- Unit tests: `pnpm -r test` -- E2E (per‑operator, requires cluster + proxy): - - `cd packages/client` - - `OPERATOR=ingress-nginx K8S_API=http://127.0.0.1:8001 pnpm test -- __tests__/e2e.setup.operator.test.ts` - -CI runs two workflows: -- Test Client Package: small smoke tests + targeted applies -- Client E2E (Per Operator): matrix job, one operator per Kind cluster - -## Manifests Maintenance -- Update all bundles: `pnpm -w @interweb/manifests run pull:all` -- Notes: - - Helm charts are rendered with `--include-crds` and a large buffer; a Namespace doc is auto‑prepended if a chart doesn’t ship one. - - URL‑sourced bundles (e.g., Knative Serving) are combined without reformatting and de‑duplicated by (apiVersion, kind, name, namespace) to avoid duplicate CRDs. - -## Apply Engine Highlights -- Create/replace semantics (idempotent) -- Phased ordering: CRDs → Namespaces → built‑in kinds → webhooks ready → custom kinds -- Waits for CRDs to be Established and for webhook Services to have endpoints -- Tolerates 409 conflicts on CRDs (install‑only behavior) - -## Local Tips -- Verify proxy: `curl http://127.0.0.1:8001/api` -- Inspect a bundle: `less packages/manifests/operators/ingress-nginx.yaml` -- Apply just Namespaces/CRDs first if debugging timing on new clusters - -## Credits - -🛠 Built by [Interweb](https://interweb.co) — if you like our tools, please checkout and contribute [https://interweb.co](https://interweb.co) diff --git a/interweb/eslint.config.js b/interweb/eslint.config.js deleted file mode 100644 index b85f41a..0000000 --- a/interweb/eslint.config.js +++ /dev/null @@ -1,45 +0,0 @@ -const js = require("@eslint/js"); -const tsPlugin = require("@typescript-eslint/eslint-plugin"); -const tsParser = require("@typescript-eslint/parser"); -const prettier = require("eslint-config-prettier"); -const simpleImportSort = require("eslint-plugin-simple-import-sort"); -const unusedImports = require("eslint-plugin-unused-imports"); -const jestPlugin = require("eslint-plugin-jest"); - -module.exports = [ - { ignores: ["**/dist/**", "**/node_modules/**", "**/.next/**", "**/playwright-report/**", "**/jest.config.js","**/jest.polyfills.js","**/jest.setup.js"] }, - js.configs.recommended, - { - languageOptions: { - parser: tsParser, - ecmaVersion: "latest", - sourceType: "module" - }, - plugins: { - "@typescript-eslint": tsPlugin, - "simple-import-sort": simpleImportSort, - "unused-imports": unusedImports, - "jest": jestPlugin - }, - rules: { - ...tsPlugin.configs.recommended.rules, - "simple-import-sort/imports": "warn", - "simple-import-sort/exports": "warn", - "unused-imports/no-unused-imports": "warn" - } - }, - { - files: ["**/*.config.js", "eslint.config.js", "jest.config.js", "**/jest.config.js"], - languageOptions: { - globals: { - module: "readonly", - require: "readonly" - } - }, - rules: { - "@typescript-eslint/no-require-imports": "off", - "no-undef": "off" - } - }, - prettier -]; diff --git a/interweb/lerna.json b/interweb/lerna.json deleted file mode 100644 index 5ec017c..0000000 --- a/interweb/lerna.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "$schema": "node_modules/lerna/schemas/lerna-schema.json", - "version": "independent", - "npmClient": "pnpm", - "command": { - "publish": { - "conventionalCommits": true, - "message": "chore(release): publish" - } - } -} diff --git a/interweb/package.json b/interweb/package.json deleted file mode 100644 index 43ff231..0000000 --- a/interweb/package.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "interweb", - "version": "0.0.1", - "author": "Anmol1696 ", - "repository": { - "type": "git", - "url": "https://github.com/hyperweb-io/interweb" - }, - "license": "MIT", - "publishConfig": { - "access": "restricted" - }, - "packageManager": "pnpm@10.12.2", - "workspaces": [ - "packages/*" - ], - "scripts": { - "clean": "pnpm -r clean", - "build": "pnpm -r build", - "format": "pnpm eslint --fix .", - "lint": "pnpm eslint ." - }, - "devDependencies": { - "@eslint/js": "^9.34.0", - "@types/jest": "^29.5.11", - "@types/node": "^22.10.4", - "@typescript-eslint/eslint-plugin": "^8.0.0", - "@typescript-eslint/parser": "^8.0.0", - "cpy-cli": "^6.0.0", - "eslint": "^8.56.0", - "eslint-plugin-jest": "^29.0.1", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-simple-import-sort": "^12.1.0", - "eslint-plugin-unused-imports": "^4.0.0", - "jest": "^29.6.2", - "lerna": "^8.2.3", - "prettier": "^3.0.2", - "rimraf": "4.4.1", - "ts-jest": "^29.1.1", - "ts-node": "^10.9.2", - "typescript": "^5.1.6" - }, - "dependencies": { - "kubernetesjs": "^0.7.2" - }, - "pnpm": { - "overrides": { - "@tanstack/react-query": "^5.29.0" - } - } -} \ No newline at end of file diff --git a/interweb/pnpm-lock.yaml b/interweb/pnpm-lock.yaml deleted file mode 100644 index f368075..0000000 --- a/interweb/pnpm-lock.yaml +++ /dev/null @@ -1,14974 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -overrides: - '@tanstack/react-query': ^5.29.0 - -importers: - - .: - dependencies: - kubernetesjs: - specifier: ^0.7.2 - version: 0.7.2 - devDependencies: - '@eslint/js': - specifier: ^9.34.0 - version: 9.36.0 - '@types/jest': - specifier: ^29.5.11 - version: 29.5.14 - '@types/node': - specifier: ^22.10.4 - version: 22.18.6 - '@typescript-eslint/eslint-plugin': - specifier: ^8.0.0 - version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2) - '@typescript-eslint/parser': - specifier: ^8.0.0 - version: 8.44.1(eslint@8.57.1)(typescript@5.9.2) - cpy-cli: - specifier: ^6.0.0 - version: 6.0.0 - eslint: - specifier: ^8.56.0 - version: 8.57.1 - eslint-config-prettier: - specifier: ^9.1.0 - version: 9.1.2(eslint@8.57.1) - eslint-plugin-jest: - specifier: ^29.0.1 - version: 29.0.1(@typescript-eslint/eslint-plugin@8.44.1(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(jest@29.7.0(@types/node@22.18.6)(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@22.18.6)(typescript@5.9.2)))(typescript@5.9.2) - eslint-plugin-simple-import-sort: - specifier: ^12.1.0 - version: 12.1.1(eslint@8.57.1) - eslint-plugin-unused-imports: - specifier: ^4.0.0 - version: 4.2.0(@typescript-eslint/eslint-plugin@8.44.1(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1) - jest: - specifier: ^29.6.2 - version: 29.7.0(@types/node@22.18.6)(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@22.18.6)(typescript@5.9.2)) - lerna: - specifier: ^8.2.3 - version: 8.2.4(@swc/core@1.13.19(@swc/helpers@0.5.17))(@types/node@22.18.6)(encoding@0.1.13) - prettier: - specifier: ^3.0.2 - version: 3.6.2 - rimraf: - specifier: 4.4.1 - version: 4.4.1 - ts-jest: - specifier: ^29.1.1 - version: 29.4.4(@babel/core@7.28.4)(@jest/transform@29.7.0)(@jest/types@30.2.0)(babel-jest@29.7.0(@babel/core@7.28.4))(jest-util@30.2.0)(jest@29.7.0(@types/node@22.18.6)(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@22.18.6)(typescript@5.9.2)))(typescript@5.9.2) - ts-node: - specifier: ^10.9.2 - version: 10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@22.18.6)(typescript@5.9.2) - typescript: - specifier: ^5.1.6 - version: 5.9.2 - - packages/cli: - dependencies: - '@interweb/client': - specifier: workspace:^ - version: link:../client/dist - '@interweb/interwebjs': - specifier: workspace:^ - version: link:../interwebjs/dist - chalk: - specifier: ^4.1.0 - version: 4.1.2 - commander: - specifier: ^11.0.0 - version: 11.1.0 - inquirer: - specifier: ^9.2.0 - version: 9.3.8(@types/node@22.18.6) - devDependencies: - '@types/inquirer': - specifier: ^9.0.3 - version: 9.0.9 - publishDirectory: dist - - packages/client: - dependencies: - '@interweb/interwebjs': - specifier: workspace:^ - version: link:../interwebjs/dist - '@interweb/manifests': - specifier: workspace:^ - version: link:../manifests/dist - axios: - specifier: ^1.7.2 - version: 1.12.2 - chalk: - specifier: ^4.1.0 - version: 4.1.2 - js-yaml: - specifier: ^4.1.0 - version: 4.1.0 - pg: - specifier: ^8.16.3 - version: 8.16.3 - devDependencies: - '@types/js-yaml': - specifier: ^4.0.5 - version: 4.0.9 - '@types/pg': - specifier: ^8.11.10 - version: 8.15.5 - ts-node: - specifier: ^10.9.2 - version: 10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@22.18.6)(typescript@5.9.2) - publishDirectory: dist - - packages/dashboard: - dependencies: - '@agentic-kit/ollama': - specifier: ^0.1.2 - version: 0.1.2(encoding@0.1.13) - '@ark-ui/react': - specifier: ^5.0.1 - version: 5.25.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@interweb/client': - specifier: workspace:* - version: link:../client/dist - '@interweb/interwebjs': - specifier: workspace:* - version: link:../interwebjs/dist - '@interweb/manifests': - specifier: workspace:* - version: link:../manifests/dist - '@radix-ui/react-accordion': - specifier: ^1.2.3 - version: 1.2.12(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-alert-dialog': - specifier: ^1.1.6 - version: 1.1.15(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-avatar': - specifier: ^1.1.3 - version: 1.1.10(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-checkbox': - specifier: ^1.3.2 - version: 1.3.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-context-menu': - specifier: ^2.2.6 - version: 2.2.16(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-dialog': - specifier: ^1.1.6 - version: 1.1.15(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-dropdown-menu': - specifier: ^2.1.6 - version: 2.1.16(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-label': - specifier: ^2.1.2 - version: 2.1.7(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-popover': - specifier: ^1.1.6 - version: 1.1.15(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-radio-group': - specifier: ^1.2.3 - version: 1.3.8(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-scroll-area': - specifier: ^1.2.3 - version: 1.2.10(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-select': - specifier: ^2.2.5 - version: 2.2.6(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': - specifier: ^1.1.2 - version: 1.2.3(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-switch': - specifier: ^1.2.6 - version: 1.2.6(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-tabs': - specifier: ^1.1.3 - version: 1.1.13(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-toast': - specifier: ^1.2.6 - version: 1.2.15(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-tooltip': - specifier: ^1.1.8 - version: 1.2.8(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@swc/wasm': - specifier: ^1.11.8 - version: 1.13.19 - '@swc/wasm-web': - specifier: ^1.11.8 - version: 1.13.19 - '@tanstack/react-query': - specifier: ^5.29.0 - version: 5.90.2(react@18.3.1) - agentic-kit: - specifier: ^0.1.2 - version: 0.1.2(encoding@0.1.13) - buffer: - specifier: ^6.0.3 - version: 6.0.3 - class-variance-authority: - specifier: ^0.7.1 - version: 0.7.1 - clsx: - specifier: ^2.1.1 - version: 2.1.1 - cross-fetch: - specifier: ^4.1.0 - version: 4.1.0(encoding@0.1.13) - dayjs: - specifier: ^1.11.13 - version: 1.11.18 - embla-carousel-react: - specifier: ^8.5.2 - version: 8.6.0(react@18.3.1) - gray-matter: - specifier: ^4.0.3 - version: 4.0.3 - js-yaml: - specifier: ^4.1.0 - version: 4.1.0 - kubernetesjs: - specifier: ^0.6.1 - version: 0.6.2 - lodash-es: - specifier: ^4.17.21 - version: 4.17.21 - lucide-react: - specifier: ^0.454.0 - version: 0.454.0(react@18.3.1) - match-sorter: - specifier: ^8.0.0 - version: 8.1.0 - next: - specifier: ^15.2.2 - version: 15.5.4(@babel/core@7.28.4)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - next-seo: - specifier: ^6.6.0 - version: 6.8.0(next@15.5.4(@babel/core@7.28.4)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - next-themes: - specifier: ^0.3.0 - version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - nuqs: - specifier: ^2.4.1 - version: 2.6.0(next@15.5.4(@babel/core@7.28.4)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) - react: - specifier: ^18.3.1 - version: 18.3.1 - react-dom: - specifier: ^18.3.1 - version: 18.3.1(react@18.3.1) - react-hook-form: - specifier: ^7.54.2 - version: 7.63.0(react@18.3.1) - react-markdown: - specifier: ^9.1.0 - version: 9.1.0(@types/react@18.3.24)(react@18.3.1) - react-syntax-highlighter: - specifier: ^15.6.1 - version: 15.6.6(react@18.3.1) - remark: - specifier: ^15.0.1 - version: 15.0.1 - remark-gfm: - specifier: ^4.0.0 - version: 4.0.1 - tailwind-merge: - specifier: ^2.6.0 - version: 2.6.0 - tailwindcss-animate: - specifier: ^1.0.7 - version: 1.0.7(tailwindcss@3.4.17(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@20.19.17)(typescript@5.9.2))) - undici: - specifier: ^7.16.0 - version: 7.16.0 - unist-util-visit: - specifier: ^5.0.0 - version: 5.0.0 - use-debounce: - specifier: ^10.0.4 - version: 10.0.6(react@18.3.1) - uuid: - specifier: ^11.1.0 - version: 11.1.0 - devDependencies: - '@babel/plugin-transform-modules-commonjs': - specifier: ^7.27.1 - version: 7.27.1(@babel/core@7.28.4) - '@babel/preset-typescript': - specifier: ^7.27.1 - version: 7.27.1(@babel/core@7.28.4) - '@playwright/test': - specifier: ^1.56.1 - version: 1.56.1 - '@swc/core': - specifier: ^1.13.19 - version: 1.13.19(@swc/helpers@0.5.17) - '@testing-library/jest-dom': - specifier: ^6.9.1 - version: 6.9.1 - '@testing-library/react': - specifier: ^16.3.0 - version: 16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@testing-library/react-hooks': - specifier: ^8.0.1 - version: 8.0.1(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@testing-library/user-event': - specifier: ^14.6.1 - version: 14.6.1(@testing-library/dom@10.4.1) - '@types/js-yaml': - specifier: ^4.0.9 - version: 4.0.9 - '@types/node': - specifier: ^20.11.5 - version: 20.19.17 - '@types/react': - specifier: ^18.2.77 - version: 18.3.24 - '@types/react-dom': - specifier: ^18.2.18 - version: 18.3.7(@types/react@18.3.24) - '@types/react-syntax-highlighter': - specifier: ^15.5.11 - version: 15.5.13 - autoprefixer: - specifier: ^10.4.17 - version: 10.4.21(postcss@8.5.6) - eslint: - specifier: ^8.56.0 - version: 8.57.1 - eslint-config-next: - specifier: 14.1.0 - version: 14.1.0(eslint@8.57.1)(typescript@5.9.2) - jest: - specifier: ^29.7.0 - version: 29.7.0(@types/node@20.19.17)(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@20.19.17)(typescript@5.9.2)) - jest-environment-jsdom: - specifier: ^30.2.0 - version: 30.2.0 - jest-fixed-jsdom: - specifier: ^0.0.10 - version: 0.0.10(jest-environment-jsdom@30.2.0) - msw: - specifier: 2.11.5 - version: 2.11.5(@types/node@20.19.17)(typescript@5.9.2) - node-fetch: - specifier: ^3.3.2 - version: 3.3.2 - postcss: - specifier: ^8.4.33 - version: 8.5.6 - pretty-format: - specifier: ^30.2.0 - version: 30.2.0 - schema-sdk: - specifier: ^0.11.3 - version: 0.11.3(encoding@0.1.13) - tailwindcss: - specifier: ^3.4.1 - version: 3.4.17(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@20.19.17)(typescript@5.9.2)) - ts-node: - specifier: ^10.9.2 - version: 10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@20.19.17)(typescript@5.9.2) - typescript: - specifier: ^5.3.3 - version: 5.9.2 - whatwg-fetch: - specifier: ^3.6.20 - version: 3.6.20 - - packages/interwebjs: - devDependencies: - schema-sdk: - specifier: ^0.15.0 - version: 0.15.0(encoding@0.1.13) - publishDirectory: dist - - packages/manifests: - dependencies: - '@interweb/interwebjs': - specifier: workspace:* - version: link:../interwebjs/dist - js-yaml: - specifier: ^4.1.0 - version: 4.1.0 - devDependencies: - '@babel/generator': - specifier: ^7.25.0 - version: 7.28.3 - '@babel/types': - specifier: ^7.25.0 - version: 7.28.4 - '@types/babel__generator': - specifier: ^7.6.8 - version: 7.27.0 - '@types/js-yaml': - specifier: ^4.0.5 - version: 4.0.9 - publishDirectory: dist - -packages: - - '@adobe/css-tools@4.4.4': - resolution: {integrity: sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==} - - '@agentic-kit/bradie@0.1.2': - resolution: {integrity: sha512-t9HkaRPd9T5m537YNctjhGIqRjM+IfSb1kuv5BOp5UEKQjcnbJrX/WNQhI5n6dbgyFqJDWL8AjEOXtAHRPWBGw==} - - '@agentic-kit/ollama@0.1.2': - resolution: {integrity: sha512-eegaTzgjDRf4aq0ogGN85xTxBXSjhwdMZYFvdpWOuCNve2dUu79onQIeNjiT36Za4eMNBrz6GzgxzttTi5d+qw==} - - '@alloc/quick-lru@5.2.0': - resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} - engines: {node: '>=10'} - - '@ark-ui/react@5.25.0': - resolution: {integrity: sha512-+r91hfLQNmGbM37rvwu6Ppy7Xaa1Dww80spn49xHhiS8ZCYQbZyPNzgOEVoSjURiroLkLdQdh869OscfczkAyA==} - peerDependencies: - react: '>=18.0.0' - react-dom: '>=18.0.0' - - '@asamuzakjp/css-color@3.2.0': - resolution: {integrity: sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==} - - '@babel/code-frame@7.27.1': - resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} - engines: {node: '>=6.9.0'} - - '@babel/compat-data@7.28.4': - resolution: {integrity: sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==} - engines: {node: '>=6.9.0'} - - '@babel/core@7.28.4': - resolution: {integrity: sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==} - engines: {node: '>=6.9.0'} - - '@babel/generator@7.28.3': - resolution: {integrity: sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-annotate-as-pure@7.27.3': - resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} - engines: {node: '>=6.9.0'} - - '@babel/helper-compilation-targets@7.27.2': - resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} - engines: {node: '>=6.9.0'} - - '@babel/helper-create-class-features-plugin@7.28.3': - resolution: {integrity: sha512-V9f6ZFIYSLNEbuGA/92uOvYsGCJNsuA8ESZ4ldc09bWk/j8H8TKiPw8Mk1eG6olpnO0ALHJmYfZvF4MEE4gajg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/helper-globals@7.28.0': - resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-member-expression-to-functions@7.27.1': - resolution: {integrity: sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-imports@7.27.1': - resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-transforms@7.28.3': - resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/helper-optimise-call-expression@7.27.1': - resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-plugin-utils@7.27.1': - resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-replace-supers@7.27.1': - resolution: {integrity: sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/helper-skip-transparent-expression-wrappers@7.27.1': - resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} - engines: {node: '>=6.9.0'} - - '@babel/helper-string-parser@7.27.1': - resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-identifier@7.27.1': - resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-option@7.27.1': - resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} - engines: {node: '>=6.9.0'} - - '@babel/helpers@7.28.4': - resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.28.4': - resolution: {integrity: sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==} - engines: {node: '>=6.0.0'} - hasBin: true - - '@babel/plugin-syntax-async-generators@7.8.4': - resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-bigint@7.8.3': - resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-class-properties@7.12.13': - resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-class-static-block@7.14.5': - resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-import-attributes@7.27.1': - resolution: {integrity: sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-import-meta@7.10.4': - resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-json-strings@7.8.3': - resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-jsx@7.27.1': - resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-logical-assignment-operators@7.10.4': - resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3': - resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-numeric-separator@7.10.4': - resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-object-rest-spread@7.8.3': - resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-optional-catch-binding@7.8.3': - resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-optional-chaining@7.8.3': - resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-private-property-in-object@7.14.5': - resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-top-level-await@7.14.5': - resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-typescript@7.27.1': - resolution: {integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-modules-commonjs@7.27.1': - resolution: {integrity: sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-typescript@7.28.0': - resolution: {integrity: sha512-4AEiDEBPIZvLQaWlc9liCavE0xRM0dNca41WtBeM3jgFptfUOSG9z0uteLhq6+3rq+WB6jIvUwKDTpXEHPJ2Vg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/preset-typescript@7.27.1': - resolution: {integrity: sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/runtime@7.28.4': - resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} - engines: {node: '>=6.9.0'} - - '@babel/template@7.27.2': - resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} - engines: {node: '>=6.9.0'} - - '@babel/traverse@7.28.4': - resolution: {integrity: sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==} - engines: {node: '>=6.9.0'} - - '@babel/types@7.28.4': - resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==} - engines: {node: '>=6.9.0'} - - '@bcoe/v8-coverage@0.2.3': - resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} - - '@cspotcode/source-map-support@0.8.1': - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} - - '@csstools/color-helpers@5.1.0': - resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==} - engines: {node: '>=18'} - - '@csstools/css-calc@2.1.4': - resolution: {integrity: sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==} - engines: {node: '>=18'} - peerDependencies: - '@csstools/css-parser-algorithms': ^3.0.5 - '@csstools/css-tokenizer': ^3.0.4 - - '@csstools/css-color-parser@3.1.0': - resolution: {integrity: sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==} - engines: {node: '>=18'} - peerDependencies: - '@csstools/css-parser-algorithms': ^3.0.5 - '@csstools/css-tokenizer': ^3.0.4 - - '@csstools/css-parser-algorithms@3.0.5': - resolution: {integrity: sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==} - engines: {node: '>=18'} - peerDependencies: - '@csstools/css-tokenizer': ^3.0.4 - - '@csstools/css-tokenizer@3.0.4': - resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} - engines: {node: '>=18'} - - '@emnapi/core@1.5.0': - resolution: {integrity: sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg==} - - '@emnapi/runtime@1.5.0': - resolution: {integrity: sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==} - - '@emnapi/wasi-threads@1.1.0': - resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} - - '@eslint-community/eslint-utils@4.9.0': - resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - - '@eslint-community/regexpp@4.12.1': - resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - - '@eslint/eslintrc@2.1.4': - resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - '@eslint/js@8.57.1': - resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - '@eslint/js@9.36.0': - resolution: {integrity: sha512-uhCbYtYynH30iZErszX78U+nR3pJU3RHGQ57NXy5QupD4SBVwDeU8TNBy+MjMngc1UyIW9noKqsRqfjQTBU2dw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@floating-ui/core@1.7.3': - resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==} - - '@floating-ui/dom@1.7.4': - resolution: {integrity: sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==} - - '@floating-ui/react-dom@2.1.6': - resolution: {integrity: sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==} - peerDependencies: - react: '>=16.8.0' - react-dom: '>=16.8.0' - - '@floating-ui/utils@0.2.10': - resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} - - '@humanwhocodes/config-array@0.13.0': - resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} - engines: {node: '>=10.10.0'} - deprecated: Use @eslint/config-array instead - - '@humanwhocodes/module-importer@1.0.1': - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - - '@humanwhocodes/object-schema@2.0.3': - resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} - deprecated: Use @eslint/object-schema instead - - '@hutson/parse-repository-url@3.0.2': - resolution: {integrity: sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==} - engines: {node: '>=6.9.0'} - - '@img/colour@1.0.0': - resolution: {integrity: sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==} - engines: {node: '>=18'} - - '@img/sharp-darwin-arm64@0.34.4': - resolution: {integrity: sha512-sitdlPzDVyvmINUdJle3TNHl+AG9QcwiAMsXmccqsCOMZNIdW2/7S26w0LyU8euiLVzFBL3dXPwVCq/ODnf2vA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [darwin] - - '@img/sharp-darwin-x64@0.34.4': - resolution: {integrity: sha512-rZheupWIoa3+SOdF/IcUe1ah4ZDpKBGWcsPX6MT0lYniH9micvIU7HQkYTfrx5Xi8u+YqwLtxC/3vl8TQN6rMg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [darwin] - - '@img/sharp-libvips-darwin-arm64@1.2.3': - resolution: {integrity: sha512-QzWAKo7kpHxbuHqUC28DZ9pIKpSi2ts2OJnoIGI26+HMgq92ZZ4vk8iJd4XsxN+tYfNJxzH6W62X5eTcsBymHw==} - cpu: [arm64] - os: [darwin] - - '@img/sharp-libvips-darwin-x64@1.2.3': - resolution: {integrity: sha512-Ju+g2xn1E2AKO6YBhxjj+ACcsPQRHT0bhpglxcEf+3uyPY+/gL8veniKoo96335ZaPo03bdDXMv0t+BBFAbmRA==} - cpu: [x64] - os: [darwin] - - '@img/sharp-libvips-linux-arm64@1.2.3': - resolution: {integrity: sha512-I4RxkXU90cpufazhGPyVujYwfIm9Nk1QDEmiIsaPwdnm013F7RIceaCc87kAH+oUB1ezqEvC6ga4m7MSlqsJvQ==} - cpu: [arm64] - os: [linux] - - '@img/sharp-libvips-linux-arm@1.2.3': - resolution: {integrity: sha512-x1uE93lyP6wEwGvgAIV0gP6zmaL/a0tGzJs/BIDDG0zeBhMnuUPm7ptxGhUbcGs4okDJrk4nxgrmxpib9g6HpA==} - cpu: [arm] - os: [linux] - - '@img/sharp-libvips-linux-ppc64@1.2.3': - resolution: {integrity: sha512-Y2T7IsQvJLMCBM+pmPbM3bKT/yYJvVtLJGfCs4Sp95SjvnFIjynbjzsa7dY1fRJX45FTSfDksbTp6AGWudiyCg==} - cpu: [ppc64] - os: [linux] - - '@img/sharp-libvips-linux-s390x@1.2.3': - resolution: {integrity: sha512-RgWrs/gVU7f+K7P+KeHFaBAJlNkD1nIZuVXdQv6S+fNA6syCcoboNjsV2Pou7zNlVdNQoQUpQTk8SWDHUA3y/w==} - cpu: [s390x] - os: [linux] - - '@img/sharp-libvips-linux-x64@1.2.3': - resolution: {integrity: sha512-3JU7LmR85K6bBiRzSUc/Ff9JBVIFVvq6bomKE0e63UXGeRw2HPVEjoJke1Yx+iU4rL7/7kUjES4dZ/81Qjhyxg==} - cpu: [x64] - os: [linux] - - '@img/sharp-libvips-linuxmusl-arm64@1.2.3': - resolution: {integrity: sha512-F9q83RZ8yaCwENw1GieztSfj5msz7GGykG/BA+MOUefvER69K/ubgFHNeSyUu64amHIYKGDs4sRCMzXVj8sEyw==} - cpu: [arm64] - os: [linux] - - '@img/sharp-libvips-linuxmusl-x64@1.2.3': - resolution: {integrity: sha512-U5PUY5jbc45ANM6tSJpsgqmBF/VsL6LnxJmIf11kB7J5DctHgqm0SkuXzVWtIY90GnJxKnC/JT251TDnk1fu/g==} - cpu: [x64] - os: [linux] - - '@img/sharp-linux-arm64@0.34.4': - resolution: {integrity: sha512-YXU1F/mN/Wu786tl72CyJjP/Ngl8mGHN1hST4BGl+hiW5jhCnV2uRVTNOcaYPs73NeT/H8Upm3y9582JVuZHrQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [linux] - - '@img/sharp-linux-arm@0.34.4': - resolution: {integrity: sha512-Xyam4mlqM0KkTHYVSuc6wXRmM7LGN0P12li03jAnZ3EJWZqj83+hi8Y9UxZUbxsgsK1qOEwg7O0Bc0LjqQVtxA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm] - os: [linux] - - '@img/sharp-linux-ppc64@0.34.4': - resolution: {integrity: sha512-F4PDtF4Cy8L8hXA2p3TO6s4aDt93v+LKmpcYFLAVdkkD3hSxZzee0rh6/+94FpAynsuMpLX5h+LRsSG3rIciUQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [ppc64] - os: [linux] - - '@img/sharp-linux-s390x@0.34.4': - resolution: {integrity: sha512-qVrZKE9Bsnzy+myf7lFKvng6bQzhNUAYcVORq2P7bDlvmF6u2sCmK2KyEQEBdYk+u3T01pVsPrkj943T1aJAsw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [s390x] - os: [linux] - - '@img/sharp-linux-x64@0.34.4': - resolution: {integrity: sha512-ZfGtcp2xS51iG79c6Vhw9CWqQC8l2Ot8dygxoDoIQPTat/Ov3qAa8qpxSrtAEAJW+UjTXc4yxCjNfxm4h6Xm2A==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [linux] - - '@img/sharp-linuxmusl-arm64@0.34.4': - resolution: {integrity: sha512-8hDVvW9eu4yHWnjaOOR8kHVrew1iIX+MUgwxSuH2XyYeNRtLUe4VNioSqbNkB7ZYQJj9rUTT4PyRscyk2PXFKA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [linux] - - '@img/sharp-linuxmusl-x64@0.34.4': - resolution: {integrity: sha512-lU0aA5L8QTlfKjpDCEFOZsTYGn3AEiO6db8W5aQDxj0nQkVrZWmN3ZP9sYKWJdtq3PWPhUNlqehWyXpYDcI9Sg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [linux] - - '@img/sharp-wasm32@0.34.4': - resolution: {integrity: sha512-33QL6ZO/qpRyG7woB/HUALz28WnTMI2W1jgX3Nu2bypqLIKx/QKMILLJzJjI+SIbvXdG9fUnmrxR7vbi1sTBeA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [wasm32] - - '@img/sharp-win32-arm64@0.34.4': - resolution: {integrity: sha512-2Q250do/5WXTwxW3zjsEuMSv5sUU4Tq9VThWKlU2EYLm4MB7ZeMwF+SFJutldYODXF6jzc6YEOC+VfX0SZQPqA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [win32] - - '@img/sharp-win32-ia32@0.34.4': - resolution: {integrity: sha512-3ZeLue5V82dT92CNL6rsal6I2weKw1cYu+rGKm8fOCCtJTR2gYeUfY3FqUnIJsMUPIH68oS5jmZ0NiJ508YpEw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [ia32] - os: [win32] - - '@img/sharp-win32-x64@0.34.4': - resolution: {integrity: sha512-xIyj4wpYs8J18sVN3mSQjwrw7fKUqRw+Z5rnHNCy5fYTxigBz81u5mOMPmFumwjcn8+ld1ppptMBCLic1nz6ig==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [win32] - - '@inquirer/ansi@1.0.0': - resolution: {integrity: sha512-JWaTfCxI1eTmJ1BIv86vUfjVatOdxwD0DAVKYevY8SazeUUZtW+tNbsdejVO1GYE0GXJW1N1ahmiC3TFd+7wZA==} - engines: {node: '>=18'} - - '@inquirer/confirm@5.1.18': - resolution: {integrity: sha512-MilmWOzHa3Ks11tzvuAmFoAd/wRuaP3SwlT1IZhyMke31FKLxPiuDWcGXhU+PKveNOpAc4axzAgrgxuIJJRmLw==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/core@10.2.2': - resolution: {integrity: sha512-yXq/4QUnk4sHMtmbd7irwiepjB8jXU0kkFRL4nr/aDBA2mDz13cMakEWdDwX3eSCTkk03kwcndD1zfRAIlELxA==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/external-editor@1.0.2': - resolution: {integrity: sha512-yy9cOoBnx58TlsPrIxauKIFQTiyH+0MK4e97y4sV9ERbI+zDxw7i2hxHLCIEGIE/8PPvDxGhgzIOTSOWcs6/MQ==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/figures@1.0.13': - resolution: {integrity: sha512-lGPVU3yO9ZNqA7vTYz26jny41lE7yoQansmqdMLBEfqaGsmdg7V3W9mK9Pvb5IL4EVZ9GnSDGMO/cJXud5dMaw==} - engines: {node: '>=18'} - - '@inquirer/type@3.0.8': - resolution: {integrity: sha512-lg9Whz8onIHRthWaN1Q9EGLa/0LFJjyM8mEUbL1eTi6yMGvBf8gvyDLtxSXztQsxMvhxxNpJYrwa1YHdq+w4Jw==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@internationalized/date@3.9.0': - resolution: {integrity: sha512-yaN3brAnHRD+4KyyOsJyk49XUvj2wtbNACSqg0bz3u8t2VuzhC8Q5dfRnrSxjnnbDb+ienBnkn1TzQfE154vyg==} - - '@internationalized/number@3.6.5': - resolution: {integrity: sha512-6hY4Kl4HPBvtfS62asS/R22JzNNy8vi/Ssev7x6EobfCp+9QIB2hKvI2EtbdJ0VSQacxVNtqhE/NmF/NZ0gm6g==} - - '@interweb-utils/casing@0.2.0': - resolution: {integrity: sha512-ORQySrHzMYmtVRkYvtE1HGa8QnoqYPhu5UWQyv9302D/ZZe0Ae6cpk4NH1xEXgHeFq/CraiOcnLhmc3h7wdNHg==} - - '@interweb/fetch-api-client@0.6.1': - resolution: {integrity: sha512-+QfJrK8c+uGhnIkGaoLeyuL7NuLbNgH8AeZwVkGqtOr9/hkrYMJQN+Jnw06TJeeuM12R8QZgM/0M8bpdG8KnlQ==} - - '@interweb/http-errors@0.1.1': - resolution: {integrity: sha512-JEwL0a8ixMT1WQwx4YNEHLiFrB/7QKxMU2j/HxycdS1BIfZxWVLggdmONHENdmsVPOuaxUJduGmhzFVidOL0IA==} - - '@isaacs/cliui@8.0.2': - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} - - '@isaacs/string-locale-compare@1.1.0': - resolution: {integrity: sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ==} - - '@istanbuljs/load-nyc-config@1.1.0': - resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} - engines: {node: '>=8'} - - '@istanbuljs/schema@0.1.3': - resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} - engines: {node: '>=8'} - - '@jest/console@29.7.0': - resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/core@29.7.0': - resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - - '@jest/environment-jsdom-abstract@30.2.0': - resolution: {integrity: sha512-kazxw2L9IPuZpQ0mEt9lu9Z98SqR74xcagANmMBU16X0lS23yPc0+S6hGLUz8kVRlomZEs/5S/Zlpqwf5yu6OQ==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - peerDependencies: - canvas: ^3.0.0 - jsdom: '*' - peerDependenciesMeta: - canvas: - optional: true - - '@jest/environment@29.7.0': - resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/environment@30.2.0': - resolution: {integrity: sha512-/QPTL7OBJQ5ac09UDRa3EQes4gt1FTEG/8jZ/4v5IVzx+Cv7dLxlVIvfvSVRiiX2drWyXeBjkMSR8hvOWSog5g==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - '@jest/expect-utils@29.7.0': - resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/expect@29.7.0': - resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/fake-timers@29.7.0': - resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/fake-timers@30.2.0': - resolution: {integrity: sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - '@jest/globals@29.7.0': - resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/pattern@30.0.1': - resolution: {integrity: sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - '@jest/reporters@29.7.0': - resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - - '@jest/schemas@29.6.3': - resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/schemas@30.0.5': - resolution: {integrity: sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - '@jest/source-map@29.6.3': - resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/test-result@29.7.0': - resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/test-sequencer@29.7.0': - resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/transform@29.7.0': - resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/types@29.6.3': - resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/types@30.2.0': - resolution: {integrity: sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - '@jridgewell/gen-mapping@0.3.13': - resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} - - '@jridgewell/remapping@2.3.5': - resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - - '@jridgewell/trace-mapping@0.3.31': - resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - - '@jridgewell/trace-mapping@0.3.9': - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - - '@lerna/create@8.2.4': - resolution: {integrity: sha512-A8AlzetnS2WIuhijdAzKUyFpR5YbLLfV3luQ4lzBgIBgRfuoBDZeF+RSZPhra+7A6/zTUlrbhKZIOi/MNhqgvQ==} - engines: {node: '>=18.0.0'} - - '@mswjs/interceptors@0.39.7': - resolution: {integrity: sha512-sURvQbbKsq5f8INV54YJgJEdk8oxBanqkTiXXd33rKmofFCwZLhLRszPduMZ9TA9b8/1CHc/IJmOlBHJk2Q5AQ==} - engines: {node: '>=18'} - - '@napi-rs/wasm-runtime@0.2.12': - resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} - - '@napi-rs/wasm-runtime@0.2.4': - resolution: {integrity: sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==} - - '@next/env@15.5.4': - resolution: {integrity: sha512-27SQhYp5QryzIT5uO8hq99C69eLQ7qkzkDPsk3N+GuS2XgOgoYEeOav7Pf8Tn4drECOVDsDg8oj+/DVy8qQL2A==} - - '@next/eslint-plugin-next@14.1.0': - resolution: {integrity: sha512-x4FavbNEeXx/baD/zC/SdrvkjSby8nBn8KcCREqk6UuwvwoAPZmaV8TFCAuo/cpovBRTIY67mHhe86MQQm/68Q==} - - '@next/swc-darwin-arm64@15.5.4': - resolution: {integrity: sha512-nopqz+Ov6uvorej8ndRX6HlxCYWCO3AHLfKK2TYvxoSB2scETOcfm/HSS3piPqc3A+MUgyHoqE6je4wnkjfrOA==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [darwin] - - '@next/swc-darwin-x64@15.5.4': - resolution: {integrity: sha512-QOTCFq8b09ghfjRJKfb68kU9k2K+2wsC4A67psOiMn849K9ZXgCSRQr0oVHfmKnoqCbEmQWG1f2h1T2vtJJ9mA==} - engines: {node: '>= 10'} - cpu: [x64] - os: [darwin] - - '@next/swc-linux-arm64-gnu@15.5.4': - resolution: {integrity: sha512-eRD5zkts6jS3VfE/J0Kt1VxdFqTnMc3QgO5lFE5GKN3KDI/uUpSyK3CjQHmfEkYR4wCOl0R0XrsjpxfWEA++XA==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@next/swc-linux-arm64-musl@15.5.4': - resolution: {integrity: sha512-TOK7iTxmXFc45UrtKqWdZ1shfxuL4tnVAOuuJK4S88rX3oyVV4ZkLjtMT85wQkfBrOOvU55aLty+MV8xmcJR8A==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@next/swc-linux-x64-gnu@15.5.4': - resolution: {integrity: sha512-7HKolaj+481FSW/5lL0BcTkA4Ueam9SPYWyN/ib/WGAFZf0DGAN8frNpNZYFHtM4ZstrHZS3LY3vrwlIQfsiMA==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@next/swc-linux-x64-musl@15.5.4': - resolution: {integrity: sha512-nlQQ6nfgN0nCO/KuyEUwwOdwQIGjOs4WNMjEUtpIQJPR2NUfmGpW2wkJln1d4nJ7oUzd1g4GivH5GoEPBgfsdw==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@next/swc-win32-arm64-msvc@15.5.4': - resolution: {integrity: sha512-PcR2bN7FlM32XM6eumklmyWLLbu2vs+D7nJX8OAIoWy69Kef8mfiN4e8TUv2KohprwifdpFKPzIP1njuCjD0YA==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [win32] - - '@next/swc-win32-x64-msvc@15.5.4': - resolution: {integrity: sha512-1ur2tSHZj8Px/KMAthmuI9FMp/YFusMMGoRNJaRZMOlSkgvLjzosSdQI0cJAKogdHl3qXUQKL9MGaYvKwA7DXg==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - - '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} - - '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - - '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} - - '@nolyfill/is-core-module@1.0.39': - resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} - engines: {node: '>=12.4.0'} - - '@npmcli/agent@2.2.2': - resolution: {integrity: sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og==} - engines: {node: ^16.14.0 || >=18.0.0} - - '@npmcli/arborist@7.5.4': - resolution: {integrity: sha512-nWtIc6QwwoUORCRNzKx4ypHqCk3drI+5aeYdMTQQiRCcn4lOOgfQh7WyZobGYTxXPSq1VwV53lkpN/BRlRk08g==} - engines: {node: ^16.14.0 || >=18.0.0} - hasBin: true - - '@npmcli/fs@3.1.1': - resolution: {integrity: sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - '@npmcli/git@5.0.8': - resolution: {integrity: sha512-liASfw5cqhjNW9UFd+ruwwdEf/lbOAQjLL2XY2dFW/bkJheXDYZgOyul/4gVvEV4BWkTXjYGmDqMw9uegdbJNQ==} - engines: {node: ^16.14.0 || >=18.0.0} - - '@npmcli/installed-package-contents@2.1.0': - resolution: {integrity: sha512-c8UuGLeZpm69BryRykLuKRyKFZYJsZSCT4aVY5ds4omyZqJ172ApzgfKJ5eV/r3HgLdUYgFVe54KSFVjKoe27w==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - hasBin: true - - '@npmcli/map-workspaces@3.0.6': - resolution: {integrity: sha512-tkYs0OYnzQm6iIRdfy+LcLBjcKuQCeE5YLb8KnrIlutJfheNaPvPpgoFEyEFgbjzl5PLZ3IA/BWAwRU0eHuQDA==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - '@npmcli/metavuln-calculator@7.1.1': - resolution: {integrity: sha512-Nkxf96V0lAx3HCpVda7Vw4P23RILgdi/5K1fmj2tZkWIYLpXAN8k2UVVOsW16TsS5F8Ws2I7Cm+PU1/rsVF47g==} - engines: {node: ^16.14.0 || >=18.0.0} - - '@npmcli/name-from-folder@2.0.0': - resolution: {integrity: sha512-pwK+BfEBZJbKdNYpHHRTNBwBoqrN/iIMO0AiGvYsp3Hoaq0WbgGSWQR6SCldZovoDpY3yje5lkFUe6gsDgJ2vg==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - '@npmcli/node-gyp@3.0.0': - resolution: {integrity: sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - '@npmcli/package-json@5.2.0': - resolution: {integrity: sha512-qe/kiqqkW0AGtvBjL8TJKZk/eBBSpnJkUWvHdQ9jM2lKHXRYYJuyNpJPlJw3c8QjC2ow6NZYiLExhUaeJelbxQ==} - engines: {node: ^16.14.0 || >=18.0.0} - - '@npmcli/promise-spawn@7.0.2': - resolution: {integrity: sha512-xhfYPXoV5Dy4UkY0D+v2KkwvnDfiA/8Mt3sWCGI/hM03NsYIH8ZaG6QzS9x7pje5vHZBZJ2v6VRFVTWACnqcmQ==} - engines: {node: ^16.14.0 || >=18.0.0} - - '@npmcli/query@3.1.0': - resolution: {integrity: sha512-C/iR0tk7KSKGldibYIB9x8GtO/0Bd0I2mhOaDb8ucQL/bQVTmGoeREaFj64Z5+iCBRf3dQfed0CjJL7I8iTkiQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - '@npmcli/redact@2.0.1': - resolution: {integrity: sha512-YgsR5jCQZhVmTJvjduTOIHph0L73pK8xwMVaDY0PatySqVM9AZj93jpoXYSJqfHFxFkN9dmqTw6OiqExsS3LPw==} - engines: {node: ^16.14.0 || >=18.0.0} - - '@npmcli/run-script@8.1.0': - resolution: {integrity: sha512-y7efHHwghQfk28G2z3tlZ67pLG0XdfYbcVG26r7YIXALRsrVQcTq4/tdenSmdOrEsNahIYA/eh8aEVROWGFUDg==} - engines: {node: ^16.14.0 || >=18.0.0} - - '@nx/devkit@20.8.2': - resolution: {integrity: sha512-rr9p2/tZDQivIpuBUpZaFBK6bZ+b5SAjZk75V4tbCUqGW3+5OPuVvBPm+X+7PYwUF6rwSpewxkjWNeGskfCe+Q==} - peerDependencies: - nx: '>= 19 <= 21' - - '@nx/nx-darwin-arm64@20.8.2': - resolution: {integrity: sha512-t+bmCn6sRPNGU6hnSyWNvbQYA/KgsxGZKYlaCLRwkNhI2akModcBUqtktJzCKd1XHDqs6EkEFBWjFr8/kBEkSg==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [darwin] - - '@nx/nx-darwin-x64@20.8.2': - resolution: {integrity: sha512-pt/wmDLM31Es8/EzazlyT5U+ou2l60rfMNFGCLqleHEQ0JUTc0KWnOciBLbHIQFiPsCQZJFEKyfV5V/ncePmmw==} - engines: {node: '>= 10'} - cpu: [x64] - os: [darwin] - - '@nx/nx-freebsd-x64@20.8.2': - resolution: {integrity: sha512-joZxFbgJfkHkB9uMIJr73Gpnm9pnpvr0XKGbWC409/d2x7q1qK77tKdyhGm+A3+kaZFwstNVPmCUtUwJYyU6LA==} - engines: {node: '>= 10'} - cpu: [x64] - os: [freebsd] - - '@nx/nx-linux-arm-gnueabihf@20.8.2': - resolution: {integrity: sha512-98O/qsxn4vIMPY/FyzvmVrl7C5yFhCUVk0/4PF+PA2SvtQ051L1eMRY6bq/lb69qfN6szJPZ41PG5mPx0NeLZw==} - engines: {node: '>= 10'} - cpu: [arm] - os: [linux] - - '@nx/nx-linux-arm64-gnu@20.8.2': - resolution: {integrity: sha512-h6a+HxwfSpxsi4KpxGgPh9GDBmD2E+XqGCdfYpobabxqEBvlnIlJyuDhlRR06cTWpuNXHpRdrVogmV6m/YbtDg==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@nx/nx-linux-arm64-musl@20.8.2': - resolution: {integrity: sha512-4Ev+jM0VAxDHV/dFgMXjQTCXS4I8W4oMe7FSkXpG8RUn6JK659DC8ExIDPoGIh+Cyqq6r6mw1CSia+ciQWICWQ==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@nx/nx-linux-x64-gnu@20.8.2': - resolution: {integrity: sha512-nR0ev+wxu+nQYRd7bhqggOxK7UfkV6h+Ko1mumUFyrM5GvPpz/ELhjJFSnMcOkOMcvH0b6G5uTBJvN1XWCkbmg==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@nx/nx-linux-x64-musl@20.8.2': - resolution: {integrity: sha512-ost41l5yc2aq2Gc9bMMpaPi/jkXqbXEMEPHrxWKuKmaek3K2zbVDQzvBBNcQKxf/mlCsrqN4QO0mKYSRRqag5A==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@nx/nx-win32-arm64-msvc@20.8.2': - resolution: {integrity: sha512-0SEOqT/daBG5WtM9vOGilrYaAuf1tiALdrFavY62+/arXYxXemUKmRI5qoKDTnvoLMBGkJs6kxhMO5b7aUXIvQ==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [win32] - - '@nx/nx-win32-x64-msvc@20.8.2': - resolution: {integrity: sha512-iIsY+tVqes/NOqTbJmggL9Juie/iaDYlWgXA9IUv88FE9thqWKhVj4/tCcPjsOwzD+1SVna3YISEEFsx5UV4ew==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - - '@octokit/auth-token@4.0.0': - resolution: {integrity: sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==} - engines: {node: '>= 18'} - - '@octokit/core@5.2.2': - resolution: {integrity: sha512-/g2d4sW9nUDJOMz3mabVQvOGhVa4e/BN/Um7yca9Bb2XTzPPnfTWHWQg+IsEYO7M3Vx+EXvaM/I2pJWIMun1bg==} - engines: {node: '>= 18'} - - '@octokit/endpoint@9.0.6': - resolution: {integrity: sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==} - engines: {node: '>= 18'} - - '@octokit/graphql@7.1.1': - resolution: {integrity: sha512-3mkDltSfcDUoa176nlGoA32RGjeWjl3K7F/BwHwRMJUW/IteSa4bnSV8p2ThNkcIcZU2umkZWxwETSSCJf2Q7g==} - engines: {node: '>= 18'} - - '@octokit/openapi-types@24.2.0': - resolution: {integrity: sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==} - - '@octokit/plugin-enterprise-rest@6.0.1': - resolution: {integrity: sha512-93uGjlhUD+iNg1iWhUENAtJata6w5nE+V4urXOAlIXdco6xNZtUSfYY8dzp3Udy74aqO/B5UZL80x/YMa5PKRw==} - - '@octokit/plugin-paginate-rest@11.4.4-cjs.2': - resolution: {integrity: sha512-2dK6z8fhs8lla5PaOTgqfCGBxgAv/le+EhPs27KklPhm1bKObpu6lXzwfUEQ16ajXzqNrKMujsFyo9K2eaoISw==} - engines: {node: '>= 18'} - peerDependencies: - '@octokit/core': '5' - - '@octokit/plugin-request-log@4.0.1': - resolution: {integrity: sha512-GihNqNpGHorUrO7Qa9JbAl0dbLnqJVrV8OXe2Zm5/Y4wFkZQDfTreBzVmiRfJVfE4mClXdihHnbpyyO9FSX4HA==} - engines: {node: '>= 18'} - peerDependencies: - '@octokit/core': '5' - - '@octokit/plugin-rest-endpoint-methods@13.3.2-cjs.1': - resolution: {integrity: sha512-VUjIjOOvF2oELQmiFpWA1aOPdawpyaCUqcEBc/UOUnj3Xp6DJGrJ1+bjUIIDzdHjnFNO6q57ODMfdEZnoBkCwQ==} - engines: {node: '>= 18'} - peerDependencies: - '@octokit/core': ^5 - - '@octokit/request-error@5.1.1': - resolution: {integrity: sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==} - engines: {node: '>= 18'} - - '@octokit/request@8.4.1': - resolution: {integrity: sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==} - engines: {node: '>= 18'} - - '@octokit/rest@20.1.2': - resolution: {integrity: sha512-GmYiltypkHHtihFwPRxlaorG5R9VAHuk/vbszVoRTGXnAsY60wYLkh/E2XiFmdZmqrisw+9FaazS1i5SbdWYgA==} - engines: {node: '>= 18'} - - '@octokit/types@13.10.0': - resolution: {integrity: sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==} - - '@open-draft/deferred-promise@2.2.0': - resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} - - '@open-draft/logger@0.3.0': - resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==} - - '@open-draft/until@2.1.0': - resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} - - '@pkgjs/parseargs@0.11.0': - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} - - '@playwright/test@1.56.1': - resolution: {integrity: sha512-vSMYtL/zOcFpvJCW71Q/OEGQb7KYBPAdKh35WNSkaZA75JlAO8ED8UN6GUNTm3drWomcbcqRPFqQbLae8yBTdg==} - engines: {node: '>=18'} - hasBin: true - - '@radix-ui/number@1.1.1': - resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==} - - '@radix-ui/primitive@1.1.3': - resolution: {integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==} - - '@radix-ui/react-accordion@1.2.12': - resolution: {integrity: sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-alert-dialog@1.1.15': - resolution: {integrity: sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-arrow@1.1.7': - resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-avatar@1.1.10': - resolution: {integrity: sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-checkbox@1.3.3': - resolution: {integrity: sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-collapsible@1.1.12': - resolution: {integrity: sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-collection@1.1.7': - resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-compose-refs@1.1.2': - resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-context-menu@2.2.16': - resolution: {integrity: sha512-O8morBEW+HsVG28gYDZPTrT9UUovQUlJue5YO836tiTJhuIWBm/zQHc7j388sHWtdH/xUZurK9olD2+pcqx5ww==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-context@1.1.2': - resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-dialog@1.1.15': - resolution: {integrity: sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-direction@1.1.1': - resolution: {integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-dismissable-layer@1.1.11': - resolution: {integrity: sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-dropdown-menu@2.1.16': - resolution: {integrity: sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-focus-guards@1.1.3': - resolution: {integrity: sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-focus-scope@1.1.7': - resolution: {integrity: sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-id@1.1.1': - resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-label@2.1.7': - resolution: {integrity: sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-menu@2.1.16': - resolution: {integrity: sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-popover@1.1.15': - resolution: {integrity: sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-popper@1.2.8': - resolution: {integrity: sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-portal@1.1.9': - resolution: {integrity: sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-presence@1.1.5': - resolution: {integrity: sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-primitive@2.1.3': - resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-radio-group@1.3.8': - resolution: {integrity: sha512-VBKYIYImA5zsxACdisNQ3BjCBfmbGH3kQlnFVqlWU4tXwjy7cGX8ta80BcrO+WJXIn5iBylEH3K6ZTlee//lgQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-roving-focus@1.1.11': - resolution: {integrity: sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-scroll-area@1.2.10': - resolution: {integrity: sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-select@2.2.6': - resolution: {integrity: sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-slot@1.2.3': - resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-switch@1.2.6': - resolution: {integrity: sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-tabs@1.1.13': - resolution: {integrity: sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-toast@1.2.15': - resolution: {integrity: sha512-3OSz3TacUWy4WtOXV38DggwxoqJK4+eDkNMl5Z/MJZaoUPaP4/9lf81xXMe1I2ReTAptverZUpbPY4wWwWyL5g==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-tooltip@1.2.8': - resolution: {integrity: sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-use-callback-ref@1.1.1': - resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-controllable-state@1.2.2': - resolution: {integrity: sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-effect-event@0.0.2': - resolution: {integrity: sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-escape-keydown@1.1.1': - resolution: {integrity: sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-is-hydrated@0.1.0': - resolution: {integrity: sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-layout-effect@1.1.1': - resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-previous@1.1.1': - resolution: {integrity: sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-rect@1.1.1': - resolution: {integrity: sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-size@1.1.1': - resolution: {integrity: sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-visually-hidden@1.2.3': - resolution: {integrity: sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/rect@1.1.1': - resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} - - '@rtsao/scc@1.1.0': - resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} - - '@rushstack/eslint-patch@1.12.0': - resolution: {integrity: sha512-5EwMtOqvJMMa3HbmxLlF74e+3/HhwBTMcvt3nqVJgGCozO6hzIPOBlwm8mGVNR9SN2IJpxSnlxczyDjcn7qIyw==} - - '@sigstore/bundle@2.3.2': - resolution: {integrity: sha512-wueKWDk70QixNLB363yHc2D2ItTgYiMTdPwK8D9dKQMR3ZQ0c35IxP5xnwQ8cNLoCgCRcHf14kE+CLIvNX1zmA==} - engines: {node: ^16.14.0 || >=18.0.0} - - '@sigstore/core@1.1.0': - resolution: {integrity: sha512-JzBqdVIyqm2FRQCulY6nbQzMpJJpSiJ8XXWMhtOX9eKgaXXpfNOF53lzQEjIydlStnd/eFtuC1dW4VYdD93oRg==} - engines: {node: ^16.14.0 || >=18.0.0} - - '@sigstore/protobuf-specs@0.3.3': - resolution: {integrity: sha512-RpacQhBlwpBWd7KEJsRKcBQalbV28fvkxwTOJIqhIuDysMMaJW47V4OqW30iJB9uRpqOSxxEAQFdr8tTattReQ==} - engines: {node: ^18.17.0 || >=20.5.0} - - '@sigstore/sign@2.3.2': - resolution: {integrity: sha512-5Vz5dPVuunIIvC5vBb0APwo7qKA4G9yM48kPWJT+OEERs40md5GoUR1yedwpekWZ4m0Hhw44m6zU+ObsON+iDA==} - engines: {node: ^16.14.0 || >=18.0.0} - - '@sigstore/tuf@2.3.4': - resolution: {integrity: sha512-44vtsveTPUpqhm9NCrbU8CWLe3Vck2HO1PNLw7RIajbB7xhtn5RBPm1VNSCMwqGYHhDsBJG8gDF0q4lgydsJvw==} - engines: {node: ^16.14.0 || >=18.0.0} - - '@sigstore/verify@1.2.1': - resolution: {integrity: sha512-8iKx79/F73DKbGfRf7+t4dqrc0bRr0thdPrxAtCKWRm/F0tG71i6O1rvlnScncJLLBZHn3h8M3c1BSUAb9yu8g==} - engines: {node: ^16.14.0 || >=18.0.0} - - '@sinclair/typebox@0.27.8': - resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} - - '@sinclair/typebox@0.34.41': - resolution: {integrity: sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==} - - '@sindresorhus/merge-streams@2.3.0': - resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==} - engines: {node: '>=18'} - - '@sinonjs/commons@3.0.1': - resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} - - '@sinonjs/fake-timers@10.3.0': - resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} - - '@sinonjs/fake-timers@13.0.5': - resolution: {integrity: sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==} - - '@standard-schema/spec@1.0.0': - resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} - - '@swc/core-darwin-arm64@1.13.19': - resolution: {integrity: sha512-NxDyte9tCJSJ8+R62WDtqwg8eI57lubD52sHyGOfezpJBOPr36bUSGGLyO3Vod9zTGlOu2CpkuzA/2iVw92u1g==} - engines: {node: '>=10'} - cpu: [arm64] - os: [darwin] - - '@swc/core-darwin-x64@1.13.19': - resolution: {integrity: sha512-+w5DYrJndSygFFRDcuPYmx5BljD6oYnAohZ15K1L6SfORHp/BTSIbgSFRKPoyhjuIkDiq3W0um8RoMTOBAcQjQ==} - engines: {node: '>=10'} - cpu: [x64] - os: [darwin] - - '@swc/core-linux-arm-gnueabihf@1.13.19': - resolution: {integrity: sha512-7LlfgpdwwYq2q7himNkAAFo4q6jysMLFNoBH6GRP7WL29NcSsl5mPMJjmYZymK+sYq/9MTVieDTQvChzYDsapw==} - engines: {node: '>=10'} - cpu: [arm] - os: [linux] - - '@swc/core-linux-arm64-gnu@1.13.19': - resolution: {integrity: sha512-ml3I6Lm2marAQ3UC/TS9t/yILBh/eDSVHAdPpikp652xouWAVW1znUeV6bBSxe1sSZIenv+p55ubKAWq/u84sQ==} - engines: {node: '>=10'} - cpu: [arm64] - os: [linux] - - '@swc/core-linux-arm64-musl@1.13.19': - resolution: {integrity: sha512-M/otFc3/rWWkbF6VgbOXVzUKVoE7MFcphTaStxJp4bwb7oP5slYlxMZN51Dk/OTOfvCDo9pTAFDKNyixbkXMDQ==} - engines: {node: '>=10'} - cpu: [arm64] - os: [linux] - - '@swc/core-linux-x64-gnu@1.13.19': - resolution: {integrity: sha512-NoMUKaOJEdouU4tKF88ggdDHFiRRING+gYLxDqnTfm+sUXaizB5OGBRzvSVDYSXQb1SuUuChnXFPFzwTWbt3ZQ==} - engines: {node: '>=10'} - cpu: [x64] - os: [linux] - - '@swc/core-linux-x64-musl@1.13.19': - resolution: {integrity: sha512-r6krlZwyu8SBaw24QuS1lau2I9q8M+eJV6ITz0rpb6P1Bx0elf9ii5Bhh8ddmIqXXH8kOGSjC/dwcdHbZqAhgw==} - engines: {node: '>=10'} - cpu: [x64] - os: [linux] - - '@swc/core-win32-arm64-msvc@1.13.19': - resolution: {integrity: sha512-awcZSIuxyVn0Dw28VjMvgk1qiDJ6CeQwHkZNUjg2UxVlq23zE01NMMp+zkoGFypmLG9gaGmJSzuoqvk/WCQ5tw==} - engines: {node: '>=10'} - cpu: [arm64] - os: [win32] - - '@swc/core-win32-ia32-msvc@1.13.19': - resolution: {integrity: sha512-H5d+KO7ISoLNgYvTbOcCQjJZNM3R7yaYlrMAF13lUr6GSiOUX+92xtM31B+HvzAWI7HtvVe74d29aC1b1TpXFA==} - engines: {node: '>=10'} - cpu: [ia32] - os: [win32] - - '@swc/core-win32-x64-msvc@1.13.19': - resolution: {integrity: sha512-qNoyCpXvv2O3JqXKanRIeoMn03Fho/As+N4Fhe7u0FsYh4VYqGQah4DGDzEP/yjl4Gx1IElhqLGDhCCGMwWaDw==} - engines: {node: '>=10'} - cpu: [x64] - os: [win32] - - '@swc/core@1.13.19': - resolution: {integrity: sha512-V1r4wFdjaZIUIZZrV2Mb/prEeu03xvSm6oatPxsvnXKF9lNh5Jtk9QvUdiVfD9rrvi7bXrAVhg9Wpbmv/2Fl1g==} - engines: {node: '>=10'} - peerDependencies: - '@swc/helpers': '>=0.5.17' - peerDependenciesMeta: - '@swc/helpers': - optional: true - - '@swc/counter@0.1.3': - resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} - - '@swc/helpers@0.5.15': - resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} - - '@swc/helpers@0.5.17': - resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} - - '@swc/types@0.1.25': - resolution: {integrity: sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==} - - '@swc/wasm-web@1.13.19': - resolution: {integrity: sha512-RNscfp1u7at6SulXTmux8E4EwFI4u1NRO0JCrcIBKo5gNwLPJF+a4/wa/HJF2fhSXTvPxh0J9uZeu45NWdHMHw==} - - '@swc/wasm@1.13.19': - resolution: {integrity: sha512-CtmxrM/VgT/x6U3O3FcT/RAE1/MtTEIgq3jtHeAE0TpiTOor/nl2lib7iMXkUy4jx9F4HZGyoVzyATYDsNK0jg==} - - '@tanstack/query-core@5.90.2': - resolution: {integrity: sha512-k/TcR3YalnzibscALLwxeiLUub6jN5EDLwKDiO7q5f4ICEoptJ+n9+7vcEFy5/x/i6Q+Lb/tXrsKCggf5uQJXQ==} - - '@tanstack/react-query@5.90.2': - resolution: {integrity: sha512-CLABiR+h5PYfOWr/z+vWFt5VsOA2ekQeRQBFSKlcoW6Ndx/f8rfyVmq4LbgOM4GG2qtxAxjLYLOpCNTYm4uKzw==} - peerDependencies: - react: ^18 || ^19 - - '@testing-library/dom@10.4.1': - resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} - engines: {node: '>=18'} - - '@testing-library/jest-dom@6.9.1': - resolution: {integrity: sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==} - engines: {node: '>=14', npm: '>=6', yarn: '>=1'} - - '@testing-library/react-hooks@8.0.1': - resolution: {integrity: sha512-Aqhl2IVmLt8IovEVarNDFuJDVWVvhnr9/GCU6UUnrYXwgDFF9h2L2o2P9KBni1AST5sT6riAyoukFLyjQUgD/g==} - engines: {node: '>=12'} - peerDependencies: - '@types/react': ^16.9.0 || ^17.0.0 - react: ^16.9.0 || ^17.0.0 - react-dom: ^16.9.0 || ^17.0.0 - react-test-renderer: ^16.9.0 || ^17.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - react-dom: - optional: true - react-test-renderer: - optional: true - - '@testing-library/react@16.3.0': - resolution: {integrity: sha512-kFSyxiEDwv1WLl2fgsq6pPBbw5aWKrsY2/noi1Id0TK0UParSF62oFQFGHXIyaG4pp2tEub/Zlel+fjjZILDsw==} - engines: {node: '>=18'} - peerDependencies: - '@testing-library/dom': ^10.0.0 - '@types/react': ^18.0.0 || ^19.0.0 - '@types/react-dom': ^18.0.0 || ^19.0.0 - react: ^18.0.0 || ^19.0.0 - react-dom: ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@testing-library/user-event@14.6.1': - resolution: {integrity: sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==} - engines: {node: '>=12', npm: '>=6'} - peerDependencies: - '@testing-library/dom': '>=7.21.4' - - '@tsconfig/node10@1.0.11': - resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} - - '@tsconfig/node12@1.0.11': - resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} - - '@tsconfig/node14@1.0.3': - resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} - - '@tsconfig/node16@1.0.4': - resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} - - '@tufjs/canonical-json@2.0.0': - resolution: {integrity: sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==} - engines: {node: ^16.14.0 || >=18.0.0} - - '@tufjs/models@2.0.1': - resolution: {integrity: sha512-92F7/SFyufn4DXsha9+QfKnN03JGqtMFMXgSHbZOo8JG59WkTni7UzAouNQDf7AuP9OAMxVOPQcqG3sB7w+kkg==} - engines: {node: ^16.14.0 || >=18.0.0} - - '@tybys/wasm-util@0.10.1': - resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} - - '@tybys/wasm-util@0.9.0': - resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} - - '@types/aria-query@5.0.4': - resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} - - '@types/babel__core@7.20.5': - resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} - - '@types/babel__generator@7.27.0': - resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} - - '@types/babel__template@7.4.4': - resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} - - '@types/babel__traverse@7.28.0': - resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} - - '@types/debug@4.1.12': - resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} - - '@types/estree-jsx@1.0.5': - resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} - - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - - '@types/graceful-fs@4.1.9': - resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} - - '@types/hast@2.3.10': - resolution: {integrity: sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==} - - '@types/hast@3.0.4': - resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} - - '@types/inquirer@9.0.9': - resolution: {integrity: sha512-/mWx5136gts2Z2e5izdoRCo46lPp5TMs9R15GTSsgg/XnZyxDWVqoVU3R9lWnccKpqwsJLvRoxbCjoJtZB7DSw==} - - '@types/istanbul-lib-coverage@2.0.6': - resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} - - '@types/istanbul-lib-report@3.0.3': - resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} - - '@types/istanbul-reports@3.0.4': - resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} - - '@types/jest@29.5.14': - resolution: {integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==} - - '@types/js-yaml@4.0.9': - resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} - - '@types/jsdom@21.1.7': - resolution: {integrity: sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA==} - - '@types/json5@0.0.29': - resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} - - '@types/mdast@4.0.4': - resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} - - '@types/minimatch@3.0.5': - resolution: {integrity: sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==} - - '@types/minimist@1.2.5': - resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} - - '@types/ms@2.1.0': - resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - - '@types/node@20.19.17': - resolution: {integrity: sha512-gfehUI8N1z92kygssiuWvLiwcbOB3IRktR6hTDgJlXMYh5OvkPSRmgfoBUmfZt+vhwJtX7v1Yw4KvvAf7c5QKQ==} - - '@types/node@22.18.6': - resolution: {integrity: sha512-r8uszLPpeIWbNKtvWRt/DbVi5zbqZyj1PTmhRMqBMvDnaz1QpmSKujUtJLrqGZeoM8v72MfYggDceY4K1itzWQ==} - - '@types/normalize-package-data@2.4.4': - resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} - - '@types/pg@8.15.5': - resolution: {integrity: sha512-LF7lF6zWEKxuT3/OR8wAZGzkg4ENGXFNyiV/JeOt9z5B+0ZVwbql9McqX5c/WStFq1GaGso7H1AzP/qSzmlCKQ==} - - '@types/prop-types@15.7.15': - resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} - - '@types/react-dom@18.3.7': - resolution: {integrity: sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==} - peerDependencies: - '@types/react': ^18.0.0 - - '@types/react-syntax-highlighter@15.5.13': - resolution: {integrity: sha512-uLGJ87j6Sz8UaBAooU0T6lWJ0dBmjZgN1PZTrj05TNql2/XpC6+4HhMT5syIdFUUt+FASfCeLLv4kBygNU+8qA==} - - '@types/react@18.3.24': - resolution: {integrity: sha512-0dLEBsA1kI3OezMBF8nSsb7Nk19ZnsyE1LLhB8r27KbgU5H4pvuqZLdtE+aUkJVoXgTVuA+iLIwmZ0TuK4tx6A==} - - '@types/stack-utils@2.0.3': - resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} - - '@types/statuses@2.0.6': - resolution: {integrity: sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==} - - '@types/through@0.0.33': - resolution: {integrity: sha512-HsJ+z3QuETzP3cswwtzt2vEIiHBk/dCcHGhbmG5X3ecnwFD/lPrMpliGXxSCg03L9AhrdwA4Oz/qfspkDW+xGQ==} - - '@types/tough-cookie@4.0.5': - resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} - - '@types/unist@2.0.11': - resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} - - '@types/unist@3.0.3': - resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} - - '@types/yargs-parser@21.0.3': - resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} - - '@types/yargs@17.0.33': - resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} - - '@typescript-eslint/eslint-plugin@8.44.1': - resolution: {integrity: sha512-molgphGqOBT7t4YKCSkbasmu1tb1MgrZ2szGzHbclF7PNmOkSTQVHy+2jXOSnxvR3+Xe1yySHFZoqMpz3TfQsw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - '@typescript-eslint/parser': ^8.44.1 - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/parser@6.21.0': - resolution: {integrity: sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - eslint: ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@typescript-eslint/parser@8.44.1': - resolution: {integrity: sha512-EHrrEsyhOhxYt8MTg4zTF+DJMuNBzWwgvvOYNj/zm1vnaD/IC5zCXFehZv94Piqa2cRFfXrTFxIvO95L7Qc/cw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/project-service@8.44.1': - resolution: {integrity: sha512-ycSa60eGg8GWAkVsKV4E6Nz33h+HjTXbsDT4FILyL8Obk5/mx4tbvCNsLf9zret3ipSumAOG89UcCs/KRaKYrA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/scope-manager@6.21.0': - resolution: {integrity: sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==} - engines: {node: ^16.0.0 || >=18.0.0} - - '@typescript-eslint/scope-manager@8.44.1': - resolution: {integrity: sha512-NdhWHgmynpSvyhchGLXh+w12OMT308Gm25JoRIyTZqEbApiBiQHD/8xgb6LqCWCFcxFtWwaVdFsLPQI3jvhywg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/tsconfig-utils@8.44.1': - resolution: {integrity: sha512-B5OyACouEjuIvof3o86lRMvyDsFwZm+4fBOqFHccIctYgBjqR3qT39FBYGN87khcgf0ExpdCBeGKpKRhSFTjKQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/type-utils@8.44.1': - resolution: {integrity: sha512-KdEerZqHWXsRNKjF9NYswNISnFzXfXNDfPxoTh7tqohU/PRIbwTmsjGK6V9/RTYWau7NZvfo52lgVk+sJh0K3g==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/types@6.21.0': - resolution: {integrity: sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==} - engines: {node: ^16.0.0 || >=18.0.0} - - '@typescript-eslint/types@8.44.1': - resolution: {integrity: sha512-Lk7uj7y9uQUOEguiDIDLYLJOrYHQa7oBiURYVFqIpGxclAFQ78f6VUOM8lI2XEuNOKNB7XuvM2+2cMXAoq4ALQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/typescript-estree@6.21.0': - resolution: {integrity: sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@typescript-eslint/typescript-estree@8.44.1': - resolution: {integrity: sha512-qnQJ+mVa7szevdEyvfItbO5Vo+GfZ4/GZWWDRRLjrxYPkhM+6zYB2vRYwCsoJLzqFCdZT4mEqyJoyzkunsZ96A==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/utils@8.44.1': - resolution: {integrity: sha512-DpX5Fp6edTlocMCwA+mHY8Mra+pPjRZ0TfHkXI8QFelIKcbADQz1LUPNtzOFUriBB2UYqw4Pi9+xV4w9ZczHFg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/visitor-keys@6.21.0': - resolution: {integrity: sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==} - engines: {node: ^16.0.0 || >=18.0.0} - - '@typescript-eslint/visitor-keys@8.44.1': - resolution: {integrity: sha512-576+u0QD+Jp3tZzvfRfxon0EA2lzcDt3lhUbsC6Lgzy9x2VR4E+JUiNyGHi5T8vk0TV+fpJ5GLG1JsJuWCaKhw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@ungap/structured-clone@1.3.0': - resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} - - '@unrs/resolver-binding-android-arm-eabi@1.11.1': - resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} - cpu: [arm] - os: [android] - - '@unrs/resolver-binding-android-arm64@1.11.1': - resolution: {integrity: sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==} - cpu: [arm64] - os: [android] - - '@unrs/resolver-binding-darwin-arm64@1.11.1': - resolution: {integrity: sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==} - cpu: [arm64] - os: [darwin] - - '@unrs/resolver-binding-darwin-x64@1.11.1': - resolution: {integrity: sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==} - cpu: [x64] - os: [darwin] - - '@unrs/resolver-binding-freebsd-x64@1.11.1': - resolution: {integrity: sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==} - cpu: [x64] - os: [freebsd] - - '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': - resolution: {integrity: sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==} - cpu: [arm] - os: [linux] - - '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': - resolution: {integrity: sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==} - cpu: [arm] - os: [linux] - - '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': - resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} - cpu: [arm64] - os: [linux] - - '@unrs/resolver-binding-linux-arm64-musl@1.11.1': - resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} - cpu: [arm64] - os: [linux] - - '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': - resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} - cpu: [ppc64] - os: [linux] - - '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': - resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} - cpu: [riscv64] - os: [linux] - - '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': - resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} - cpu: [riscv64] - os: [linux] - - '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': - resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} - cpu: [s390x] - os: [linux] - - '@unrs/resolver-binding-linux-x64-gnu@1.11.1': - resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} - cpu: [x64] - os: [linux] - - '@unrs/resolver-binding-linux-x64-musl@1.11.1': - resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} - cpu: [x64] - os: [linux] - - '@unrs/resolver-binding-wasm32-wasi@1.11.1': - resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} - engines: {node: '>=14.0.0'} - cpu: [wasm32] - - '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': - resolution: {integrity: sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==} - cpu: [arm64] - os: [win32] - - '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': - resolution: {integrity: sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==} - cpu: [ia32] - os: [win32] - - '@unrs/resolver-binding-win32-x64-msvc@1.11.1': - resolution: {integrity: sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==} - cpu: [x64] - os: [win32] - - '@yarnpkg/lockfile@1.1.0': - resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==} - - '@yarnpkg/parsers@3.0.2': - resolution: {integrity: sha512-/HcYgtUSiJiot/XWGLOlGxPYUG65+/31V8oqk17vZLW1xlCoR4PampyePljOxY2n8/3jz9+tIFzICsyGujJZoA==} - engines: {node: '>=18.12.0'} - - '@zag-js/accordion@1.24.1': - resolution: {integrity: sha512-JOlmXjO+1tTlyeZ93S+chIlV8uDr8fodj3/XCjLFHc/G116O8cN18KG0Ug9pImy1vT2Kkwb9Ag9QOTyUAXM3PA==} - - '@zag-js/anatomy@1.24.1': - resolution: {integrity: sha512-mRkpetNjnjgvdyEX880AOjhMhcgdRMLjOM+aEgoDRnhultC4im+nriNoCShJLeVpwsRrEQCU7YVXO4mZaqWUMg==} - - '@zag-js/angle-slider@1.24.1': - resolution: {integrity: sha512-pcWIpVZDMbujMK0nFaKa0wd7uGkP4E5D7x8cmvoiKMT4E1vZpg2kZeN9qmdnhum9ye7nb80IPKhcDl9C0JuSLw==} - - '@zag-js/aria-hidden@1.24.1': - resolution: {integrity: sha512-R/a80ZjITZi4rotN7Q9+RTCYCdmJZf3rZi9bObczbR7h5j5GSsjikByUjksWAYzPvFxQxBWTs4GqlCI9dU2f9A==} - - '@zag-js/async-list@1.24.1': - resolution: {integrity: sha512-EZE3wORLOhMtT1tiDA0kTHrtY7XNkOoNyn5jCs8Ec1GfqIHSRzQB+2jt+wPIBwUhDcgQksXgOy91s/i9XfQe1g==} - - '@zag-js/auto-resize@1.24.1': - resolution: {integrity: sha512-OH1VTeObddMiN2PUK+7SpkPV8Znlkdq+10odmbbe9K2MZPh352RNcPYytIZTWT0X4/4czhn2MTU6IhZ2lZp2hw==} - - '@zag-js/avatar@1.24.1': - resolution: {integrity: sha512-zYGUdkxsMoN8OAFYYCZBrsQx++kjWEBdYZew4en9g8vw7yonNjzywtfF/Vd3Dv6mUZ2r5JtaltbK/qp4aBdZvg==} - - '@zag-js/carousel@1.24.1': - resolution: {integrity: sha512-7WGlFtF4JoIK4kduiFgucdTe9eD+884d9BF9Sh308MlpiL0KZnO3l3Pyq58yi4R0KUTy7zILLGSsUesifVAuEA==} - - '@zag-js/checkbox@1.24.1': - resolution: {integrity: sha512-eU/RKaO44Tgt1iTGg26M2nUd12p+gTuq2rNjqVuPfN3dvRzYNi5rGKk6yTQI2T4DH4D+fDMz6gUneiBuGcVoJA==} - - '@zag-js/clipboard@1.24.1': - resolution: {integrity: sha512-GfmjjiEDS9NB6Wo/ThbbzO10BgOYzTSeG00a/pJ5QpvSgvOCz+oLV5NBQHOd8XjOw0e0GQEyfsif0i6wQExSIQ==} - - '@zag-js/collapsible@1.24.1': - resolution: {integrity: sha512-U6AP4nE6jwMC3kirFQmOL9i3CSfp8mJqb+Gv3opbClpjqCa8hn9v4PNiimKmd0Qr3kynuVRpAshaUaLeg33YiA==} - - '@zag-js/collection@1.24.1': - resolution: {integrity: sha512-aWNDI0iZ5Wb8vCZLJWPjRQOK5/B2wvhhR1+pYaScxZfWy2das2DVKam8tnR0p1GrRfBi/kZNaCXtvM1ZNPjlOQ==} - - '@zag-js/color-picker@1.24.1': - resolution: {integrity: sha512-vLW11JrySJR5fGeXXdmlCJuNm7yE0Tsx/SjkX0WBnrPC4PYaGfiwF7LT59bs5XsQp65kEaIca6mw/J0Bouc8Sw==} - - '@zag-js/color-utils@1.24.1': - resolution: {integrity: sha512-8KPTa3I9+WbDLrYPH5knEYMW3CjAC20ikosdrgYshGTFIPuqinAnsxD7H0fZO4I+jSjuhtIyNQuvgwJar9A2rg==} - - '@zag-js/combobox@1.24.1': - resolution: {integrity: sha512-BhjQOL/Ssr5lQLPCyEersCqOqllFlNuR8nvQOgl1u8Y0EaZR+ZPQbgXum6kE5AuH3SlcY9+1kDK1ZLswOagL1Q==} - - '@zag-js/core@1.24.1': - resolution: {integrity: sha512-0e7QdxBaY9PMHQfDY/Xu/7MKyRxNsriNscpkZI7L4MHMGPmxdfedGBpteI3gFfqWsdJ5NvvpqxdLUwkbYk5Q5A==} - - '@zag-js/date-picker@1.24.1': - resolution: {integrity: sha512-8jLv074sGJQw4L+5YTDv7l2bwb1x9E7YhvklCffhf/7OzW7RB/ELkljFhmjueuJp7W/sD4xhJyigjp/mDEg1XA==} - peerDependencies: - '@internationalized/date': '>=3.0.0' - - '@zag-js/date-utils@1.24.1': - resolution: {integrity: sha512-Rgll6P4Imq479WxH3uMvwQri4o4lF2cxWX2Hka/W7Nhv1DhPBnmfBw30INyWPXzx5agEVzKdGX/br8MU5DV33Q==} - peerDependencies: - '@internationalized/date': '>=3.0.0' - - '@zag-js/dialog@1.24.1': - resolution: {integrity: sha512-ITzOoXBC92vIkhNvxM0GMMKwboLLk7hSU9dsplk/X9bpX+fQywgc6d5O4I7WHCMmgUWI5y3/aWjqsWATWwufWg==} - - '@zag-js/dismissable@1.24.1': - resolution: {integrity: sha512-Oca+nbwaqHGt0rmkKfmpExwL+kVYLbVi6fxhzHP1WBrip//IUThoTrPH/gqB51o1DT1z/VNE+8BhWhsHSgkQfw==} - - '@zag-js/dom-query@1.24.1': - resolution: {integrity: sha512-ww3tS5hrB2s6ywGtjMjSOajP19CnQOH0IAGgzjE+lbvDD+ZroXWn9O3Z/v2kTfKNwZFQ4TOb8oSymuSRQsFOYg==} - - '@zag-js/editable@1.24.1': - resolution: {integrity: sha512-SV8X7jd95ZAx4VnlhoEcbAiW8jhoGkPf7L0JFB2KWX+NFacEVCKGQpDjZpdzD6j7C10750v3blbkjr6iyzeIqw==} - - '@zag-js/file-upload@1.24.1': - resolution: {integrity: sha512-Un0+qDlkoC93pf7/Nvq9DBVKR6PBKybbNE/En/PC4XLJybK448bY85UuEdBPgXEoR6hIGA3t8NdeHZ+PUoZXIw==} - - '@zag-js/file-utils@1.24.1': - resolution: {integrity: sha512-ydMct0iyd4uPxf+NP4gfyPq1gJlvW29WWIm5ez9El9L+z5tDBhXYNc73s2kSdDBKXkO4fp6Mwoqbz/wZOw99/Q==} - - '@zag-js/floating-panel@1.24.1': - resolution: {integrity: sha512-qVVtnKCQE2C//0q7utRvpfRKsZedL8gnSqwHDX4ie8nKmLLSLn6jDGuAzxrscsGPHEjCOru9NlTHlAAMtB3ybQ==} - - '@zag-js/focus-trap@1.24.1': - resolution: {integrity: sha512-cpgYWWaiKx9eycm4Mahv6Dng5+CbDiTtyz/gnbZUv6sqcM4b9N+UqdmBdWYPLHV4gZYrzuO+X4P1C/Ew/rA+xg==} - - '@zag-js/focus-visible@1.24.1': - resolution: {integrity: sha512-HzUf8cRl5tbIil6rVe24CxC3s1pdFGpfYSt5NyaFoFd0HuWhobp+De1kVUvlLU0DDUU6Kgw6DB1w8APEPzb8gg==} - - '@zag-js/highlight-word@1.24.1': - resolution: {integrity: sha512-paDF/sWKDMMclpCzrG60vD4/AFQ3EOu2lzQxl7S21uD/B8Rir4w1CkxK/9+cm1Bu7mj4mkR4t+VJxycEZ7YuIw==} - - '@zag-js/hover-card@1.24.1': - resolution: {integrity: sha512-zXTcLEb8YOFoEjDMsMcxqidRDN2fY0C94j+XdZYj5eZtKBIgbyCyAjvZrEu9yyPqqrXCNwYU0fTFjac3t9IV4g==} - - '@zag-js/i18n-utils@1.24.1': - resolution: {integrity: sha512-dI9M73FTJcE40s/TPBLLKsypmBoMNe5NoRSBW64PWdmn0fCq65qcAUMgwQ0MVenh4oofoDYyffl8pIStr8T1tA==} - - '@zag-js/interact-outside@1.24.1': - resolution: {integrity: sha512-xKyGT295WVrlJaOPCVBrundlXqL4YEvl36SHNSi7EZs/AYpzxR/aBtnFCRN1/7nWvdqvfGs7ya0kl/ly0H7VBg==} - - '@zag-js/json-tree-utils@1.24.1': - resolution: {integrity: sha512-TWVg+Y4fLr9o0YaB3OnX4xmV91Te/vzRwnNKntsz3GIWJ5fLNngg4hm3E+eaYnJIlKMHrvJv4T/UB4IGYUF+EQ==} - - '@zag-js/listbox@1.24.1': - resolution: {integrity: sha512-fTJ125SWVZ+NxgkT6s8LWpdJQMeADk9Lm+Ur1pi0mZnRCmuHI3nwPkg1dfqynjVyrKs6P8wBmUxt3hlr2cc6TQ==} - - '@zag-js/live-region@1.24.1': - resolution: {integrity: sha512-A/55dOyRhfdgVtCBP05Uf2UGz/58H0TMWP69GdVYM4uADtfCLNPy6yxHAt9p334qJsWicg/YWSzBdEAVTThNag==} - - '@zag-js/menu@1.24.1': - resolution: {integrity: sha512-XPNQbkIxSbNuYNLLQZlgXbj6Ptn2XHT5BXkUSw2hSbIg35S7Lq8gckiZVtxmUiX8zbv7krTBSD7zThSnwx1TOA==} - - '@zag-js/number-input@1.24.1': - resolution: {integrity: sha512-F5nX0VvuRmSxddJ8byHYp4OSHLU1C5Fv1rT4L1AnSXud8q6C+zCy4Vy8772pUKNobZf0q8Ru4SgnOe5TQcvRpg==} - - '@zag-js/pagination@1.24.1': - resolution: {integrity: sha512-IO9Q5SiYmk00pjJAD18qFjOkpN1qb9iSeuX6A9Bdo8sMBFSigI6c7tGo1MPYGENma3b+aX7LbUpt8hYFufqUow==} - - '@zag-js/password-input@1.24.1': - resolution: {integrity: sha512-TWgTRNsaAZ6IE1QmCQKhPY6uSRPDGjgdxGSpG7wOuYsbxHw/hD3v5sUAhAo9teIL0wV8COZIh6hyG2UAAgT2kg==} - - '@zag-js/pin-input@1.24.1': - resolution: {integrity: sha512-ytJK/1ekU06VmOpe7KdSkIQ3If+fffrA/EpbktZBuRepsz80QHB64+X6QQ6H1lEMbLWPNZ0TuFPaYhFfqH7cTQ==} - - '@zag-js/popover@1.24.1': - resolution: {integrity: sha512-auNy7/5/VMeNUYbKfcvSz7OHkbrUWdODtA6gB/d/weAxvEHyMSk0+Ms4c5lmN8KDChrBAPJs4CfKSPv1U4I4zw==} - - '@zag-js/popper@1.24.1': - resolution: {integrity: sha512-VWbOjBy/haIDmXhwfyMT1rRcQhSfYmPX67YzQwLA7863kXkoTH1r9fR+1f9uq3VuXQLhw2Cg/lkSzlkg9TIp+g==} - - '@zag-js/presence@1.24.1': - resolution: {integrity: sha512-MMcw4iOsGdSGM3hmvd0gcMuk1X9rE/xE3Ndm113vc+lkhk93COiuJPz1ZpyBb8l1CIJwlZ5nnRpx4Lx8Do6aNQ==} - - '@zag-js/progress@1.24.1': - resolution: {integrity: sha512-ocp6zkl5Y3sVMzPVIRLZtqtDfMkc365JYIrOUsdUqwJMvZJhSP1IbsbtIJS1ycOaHfLdK27E//GVyjxA7SHGhw==} - - '@zag-js/qr-code@1.24.1': - resolution: {integrity: sha512-Hy722PNwLs1tnXFQkTqtrEILypZcUDiC8YdvGn57mmmvPGtZdAzhs4G8ghoP9ahJ02ztREjIt8Qnmct344fALA==} - - '@zag-js/radio-group@1.24.1': - resolution: {integrity: sha512-49S+nmaZzjf98206VeevmfTNTf+WjLveKCOGz5SVWPX3R8maZJgka1ZlIDuWlnRK1JfL+4Ls10/ZxAk3HrI7sg==} - - '@zag-js/rating-group@1.24.1': - resolution: {integrity: sha512-EGGObQDmulon5N9s5ElGZv9yQmky10s7ps7wyVgW1+vJTsWr8gaoFMJwf6nbXOsUjqW8iDuzsF68Rel9CgjxIQ==} - - '@zag-js/react@1.24.1': - resolution: {integrity: sha512-oiaiuR7FKVHOEJtzoYZ2QBQ5+J/j086eebhLCIWkh2ie6QBJM73LHsMUxfZp2D2G1is8EoyUhrH3v2MPMlYMXg==} - peerDependencies: - react: '>=18.0.0' - react-dom: '>=18.0.0' - - '@zag-js/rect-utils@1.24.1': - resolution: {integrity: sha512-6JkVq71feW9Yyt7Pynyf199ugDFVgRT+jPpg2ECRHgY2oHvn5atBP3PA1uM2cx7ZydiajnBgk4n1ePnGYD2xNw==} - - '@zag-js/remove-scroll@1.24.1': - resolution: {integrity: sha512-SAK3ZsnDUcJve5q3OHsMjrl0JOW9sv1fGbBFXyyid9Uu8s79LMh7EZw2na5jXDNzdMWmk1Euu82OaZSlLl9Kew==} - - '@zag-js/scroll-area@1.24.1': - resolution: {integrity: sha512-eRZKs6Yyl8Zp+YkIxzr1QsgRDDsNMxXshwpIzt/L5xK+EV34mv760FOkX/unG/WxQ1Z0gBogPm9ZY53/m4bhJA==} - - '@zag-js/scroll-snap@1.24.1': - resolution: {integrity: sha512-Co/NlccX4XDg6OzQeRgv8bANbsCkMog1FZ0BveN8+2Mso/svOLVkB6UGswWZk/DyqY8DlxvfZAdPltmQpu5h8w==} - - '@zag-js/select@1.24.1': - resolution: {integrity: sha512-boU5m3Qd//EGe1M2i4a2SbCXQpcPP9Ewe6DvjEpOhxP+dwdbZzDrtRBdZ4ByhMJ+1bT5B6TqsfvsQHhAI0LunA==} - - '@zag-js/signature-pad@1.24.1': - resolution: {integrity: sha512-CRTcefUGMwdhxqmB8yGkHU3gweMfXw0CCoMc0LhMmla12hMJOBi+mpMVaBJnQHYGSG8uFUh2IKdPbe2Vtp4T3Q==} - - '@zag-js/slider@1.24.1': - resolution: {integrity: sha512-HClZBKcT+9tihZArRNRj35YOIUbztCcyYzggYYIrK4+OFD0RLYihA+yBO4hxs7xZVenzma9i0pc6q/Vo4z2tvA==} - - '@zag-js/splitter@1.24.1': - resolution: {integrity: sha512-UUqiCD0T8kfgm/vRTY1QrPlrpxbzxqZ+8QvysUchnibmStetkHnuzAXC4ZD9jlJbToqzE4p1eLOiWGaVXRdB/Q==} - - '@zag-js/steps@1.24.1': - resolution: {integrity: sha512-njL1SMKef0JfYzw5KUhpeVuzOtgBjSxVUwDrPR9s095WUCUiOYlxzqummg3VBY8IDuT/pS/K6LDSY11YCRzeNw==} - - '@zag-js/store@1.24.1': - resolution: {integrity: sha512-iVl+NX2CcxEDLL3hrj31mqSqBZYBqHEBqa/Z7FwKVoTImMQ1AabMF5XPreTtB8KFbaVJlNlM6D5qngDPpVj/xw==} - - '@zag-js/switch@1.24.1': - resolution: {integrity: sha512-RI2bG2AtsQ4ci8T7RA3XVSjd9urpNQXIwEatpa8cw9GCWFI421rt4Xcab5jy/IOu6VzXl6pwh11/cWAC/PBYCw==} - - '@zag-js/tabs@1.24.1': - resolution: {integrity: sha512-RjdW4opxhvCWTwHoCqq+lfNCthiyPu376hto6j4Ybl/UN3UFTV4zfTbwbMbAH7dyqj8m1nkKxidLaO0Yhx3zZA==} - - '@zag-js/tags-input@1.24.1': - resolution: {integrity: sha512-HY1ebBZE2j3/fuzfKw4z/44S9WWe50auMWLlFg47j6zVBcyNdXEeMO1OvvfyfQFJOcvOKXGxW8Hi4MXGxLWqmA==} - - '@zag-js/timer@1.24.1': - resolution: {integrity: sha512-cjD8+I8CgSugsj5DI+kqzgvuQ2vYeArRdjO3iSjB4AjR+j08W8NKZvr7aawhYq636vrE9LeJGbxxZ3DBV12ELw==} - - '@zag-js/toast@1.24.1': - resolution: {integrity: sha512-gmHv65EYdypfMoF9WYIp7Y8z6XN5tebXEdjIWF8bJBaqW5zPn2VLdUYpfXv7wrHW2YtSTnF/xtgIhJ7MIX7HxA==} - - '@zag-js/toggle-group@1.24.1': - resolution: {integrity: sha512-GVBay9XzmXjp1GgAmHUMpeYq3iMMevH+n0TyC0NcRe00prAEL9S4/q9pVy0P33PIOa20dxcvQ/Q3Tf+n5PFQcg==} - - '@zag-js/toggle@1.24.1': - resolution: {integrity: sha512-dMN9Q4XFqr7jPlUZsLCFdUc1rtW88FzUaXcFVaeNCy8y8XGc+MG9AJJqjBiBL9EUeeR+LIp8yUIhJQEEDBm0kw==} - - '@zag-js/tooltip@1.24.1': - resolution: {integrity: sha512-gdD5C9AF6JD8LC6mxXzUGWjnHqY3MS7ZvtNx/nuNGJAqKCD32dPT73fuv0up1UVh1yJhX4IrXg3H6q52Pm+jPw==} - - '@zag-js/tour@1.24.1': - resolution: {integrity: sha512-e+UR8xauKyRhE6tA8gRsR1GuOn1QGjj2YAmtRC8lIb5tD+QrGCPy0jX2xBeR7M7eY1IPSSyi0gCUGE2CbaRK8Q==} - - '@zag-js/tree-view@1.24.1': - resolution: {integrity: sha512-HXCoqW6j2RunFxaIVRevgRTrRUEP05lpdOvc1Smzne7sC2mczwIqN68Vei6e83gRhXSF80v6Fc4TcHdPiW6wJA==} - - '@zag-js/types@1.24.1': - resolution: {integrity: sha512-XyINtxe5JK7A+RtTmBdCQElNoElDiTw6NSWpjKZGRAXXGU9HIZ9JIFeaS77uq1aVs0JhAOFwqJiPs2NJzaYHLA==} - - '@zag-js/utils@1.24.1': - resolution: {integrity: sha512-4nU9lfFlLLW/4T+/HaP+HdHYFeWvacxSVcccv0JSf+ZTC110IldV48kZELP+wFg9xDL/jCPPjlRtO1K64EIwgA==} - - '@zkochan/js-yaml@0.0.7': - resolution: {integrity: sha512-nrUSn7hzt7J6JWgWGz78ZYI8wj+gdIJdk0Ynjpp8l+trkn58Uqsf6RYrYkEK+3X18EX+TNdtJI0WxAtc+L84SQ==} - hasBin: true - - JSONStream@1.3.5: - resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} - hasBin: true - - abbrev@2.0.0: - resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - acorn-jsx@5.3.2: - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - - acorn-walk@8.3.4: - resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} - engines: {node: '>=0.4.0'} - - acorn@8.15.0: - resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} - engines: {node: '>=0.4.0'} - hasBin: true - - add-stream@1.0.0: - resolution: {integrity: sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==} - - agent-base@7.1.4: - resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} - engines: {node: '>= 14'} - - agentic-kit@0.1.2: - resolution: {integrity: sha512-VnGdH2zmP6j+XC7z2bxm04+IZl72XT14AC8BqTWYAV02vrfomFEhv6bSvhPQcMEa60qUFaQsUAQyGVS6XWNe3w==} - - aggregate-error@3.1.0: - resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} - engines: {node: '>=8'} - - ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - - ansi-colors@4.1.3: - resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} - engines: {node: '>=6'} - - ansi-escapes@4.3.2: - resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} - engines: {node: '>=8'} - - ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - - ansi-regex@6.2.2: - resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} - engines: {node: '>=12'} - - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - - ansi-styles@5.2.0: - resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} - engines: {node: '>=10'} - - ansi-styles@6.2.3: - resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} - engines: {node: '>=12'} - - any-promise@1.3.0: - resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} - - anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} - - aproba@2.0.0: - resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} - - arg@4.1.3: - resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} - - arg@5.0.2: - resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} - - argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} - - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - - aria-hidden@1.2.6: - resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} - engines: {node: '>=10'} - - aria-query@5.3.0: - resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} - - aria-query@5.3.2: - resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} - engines: {node: '>= 0.4'} - - array-buffer-byte-length@1.0.2: - resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} - engines: {node: '>= 0.4'} - - array-differ@3.0.0: - resolution: {integrity: sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==} - engines: {node: '>=8'} - - array-ify@1.0.0: - resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} - - array-includes@3.1.9: - resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==} - engines: {node: '>= 0.4'} - - array-union@2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} - - array.prototype.findlast@1.2.5: - resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} - engines: {node: '>= 0.4'} - - array.prototype.findlastindex@1.2.6: - resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==} - engines: {node: '>= 0.4'} - - array.prototype.flat@1.3.3: - resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} - engines: {node: '>= 0.4'} - - array.prototype.flatmap@1.3.3: - resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} - engines: {node: '>= 0.4'} - - array.prototype.tosorted@1.1.4: - resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} - engines: {node: '>= 0.4'} - - arraybuffer.prototype.slice@1.0.4: - resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} - engines: {node: '>= 0.4'} - - arrify@1.0.1: - resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} - engines: {node: '>=0.10.0'} - - arrify@2.0.1: - resolution: {integrity: sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==} - engines: {node: '>=8'} - - ast-types-flow@0.0.8: - resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} - - async-function@1.0.0: - resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} - engines: {node: '>= 0.4'} - - async@3.2.6: - resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} - - asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - - autoprefixer@10.4.21: - resolution: {integrity: sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==} - engines: {node: ^10 || ^12 || >=14} - hasBin: true - peerDependencies: - postcss: ^8.1.0 - - available-typed-arrays@1.0.7: - resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} - engines: {node: '>= 0.4'} - - axe-core@4.10.3: - resolution: {integrity: sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==} - engines: {node: '>=4'} - - axios@1.12.2: - resolution: {integrity: sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==} - - axobject-query@4.1.0: - resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} - engines: {node: '>= 0.4'} - - babel-jest@29.7.0: - resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@babel/core': ^7.8.0 - - babel-plugin-istanbul@6.1.1: - resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} - engines: {node: '>=8'} - - babel-plugin-jest-hoist@29.6.3: - resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - babel-preset-current-node-syntax@1.2.0: - resolution: {integrity: sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==} - peerDependencies: - '@babel/core': ^7.0.0 || ^8.0.0-0 - - babel-preset-jest@29.6.3: - resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@babel/core': ^7.0.0 - - bail@2.0.2: - resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} - - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - - base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - - baseline-browser-mapping@2.8.7: - resolution: {integrity: sha512-bxxN2M3a4d1CRoQC//IqsR5XrLh0IJ8TCv2x6Y9N0nckNz/rTjZB3//GGscZziZOxmjP55rzxg/ze7usFI9FqQ==} - hasBin: true - - before-after-hook@2.2.3: - resolution: {integrity: sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==} - - bin-links@4.0.4: - resolution: {integrity: sha512-cMtq4W5ZsEwcutJrVId+a/tjt8GSbS+h0oNkdl6+6rBuEv8Ot33Bevj5KPm40t309zuhVic8NjpuL42QCiJWWA==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - binary-extensions@2.3.0: - resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} - engines: {node: '>=8'} - - bl@4.1.0: - resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - - brace-expansion@1.1.12: - resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} - - brace-expansion@2.0.2: - resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} - - braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} - - browserslist@4.26.2: - resolution: {integrity: sha512-ECFzp6uFOSB+dcZ5BK/IBaGWssbSYBHvuMeMt3MMFyhI0Z8SqGgEkBLARgpRH3hutIgPVsALcMwbDrJqPxQ65A==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - - bs-logger@0.2.6: - resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} - engines: {node: '>= 6'} - - bser@2.1.1: - resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} - - buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - - buffer@5.7.1: - resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} - - buffer@6.0.3: - resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} - - byte-size@8.1.1: - resolution: {integrity: sha512-tUkzZWK0M/qdoLEqikxBWe4kumyuwjl3HO6zHTr4yEI23EojPtLYXdG1+AQY7MN0cGyNDvEaJ8wiYQm6P2bPxg==} - engines: {node: '>=12.17'} - - cacache@18.0.4: - resolution: {integrity: sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==} - engines: {node: ^16.14.0 || >=18.0.0} - - call-bind-apply-helpers@1.0.2: - resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} - engines: {node: '>= 0.4'} - - call-bind@1.0.8: - resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} - engines: {node: '>= 0.4'} - - call-bound@1.0.4: - resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} - engines: {node: '>= 0.4'} - - callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - - camelcase-css@2.0.1: - resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} - engines: {node: '>= 6'} - - camelcase-keys@6.2.2: - resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==} - engines: {node: '>=8'} - - camelcase@5.3.1: - resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} - engines: {node: '>=6'} - - camelcase@6.3.0: - resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} - engines: {node: '>=10'} - - caniuse-lite@1.0.30001745: - resolution: {integrity: sha512-ywt6i8FzvdgrrrGbr1jZVObnVv6adj+0if2/omv9cmR2oiZs30zL4DIyaptKcbOrBdOIc74QTMoJvSE2QHh5UQ==} - - ccount@2.0.1: - resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} - - chalk@4.1.0: - resolution: {integrity: sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==} - engines: {node: '>=10'} - - chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} - - char-regex@1.0.2: - resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} - engines: {node: '>=10'} - - character-entities-html4@2.1.0: - resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} - - character-entities-legacy@1.1.4: - resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==} - - character-entities-legacy@3.0.0: - resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} - - character-entities@1.2.4: - resolution: {integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==} - - character-entities@2.0.2: - resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} - - character-reference-invalid@1.1.4: - resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==} - - character-reference-invalid@2.0.1: - resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} - - chardet@2.1.0: - resolution: {integrity: sha512-bNFETTG/pM5ryzQ9Ad0lJOTa6HWD/YsScAR3EnCPZRPlQh77JocYktSHOUHelyhm8IARL+o4c4F1bP5KVOjiRA==} - - chokidar@3.6.0: - resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} - engines: {node: '>= 8.10.0'} - - chownr@2.0.0: - resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} - engines: {node: '>=10'} - - ci-info@3.9.0: - resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} - engines: {node: '>=8'} - - ci-info@4.3.0: - resolution: {integrity: sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==} - engines: {node: '>=8'} - - cjs-module-lexer@1.4.3: - resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} - - class-variance-authority@0.7.1: - resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} - - clean-stack@2.2.0: - resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} - engines: {node: '>=6'} - - cli-cursor@3.1.0: - resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} - engines: {node: '>=8'} - - cli-spinners@2.6.1: - resolution: {integrity: sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==} - engines: {node: '>=6'} - - cli-spinners@2.9.2: - resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} - engines: {node: '>=6'} - - cli-width@3.0.0: - resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} - engines: {node: '>= 10'} - - cli-width@4.1.0: - resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} - engines: {node: '>= 12'} - - client-only@0.0.1: - resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} - - cliui@7.0.4: - resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} - - cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} - - clone-deep@4.0.1: - resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} - engines: {node: '>=6'} - - clone@1.0.4: - resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} - engines: {node: '>=0.8'} - - clsx@2.1.1: - resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} - engines: {node: '>=6'} - - cmd-shim@6.0.3: - resolution: {integrity: sha512-FMabTRlc5t5zjdenF6mS0MBeFZm0XqHqeOkcskKFb/LYCcRQ5fVgLOHVc4Lq9CqABd9zhjwPjMBCJvMCziSVtA==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - co@4.6.0: - resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} - engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} - - collect-v8-coverage@1.0.2: - resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} - - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - - color-support@1.1.3: - resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} - hasBin: true - - columnify@1.6.0: - resolution: {integrity: sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q==} - engines: {node: '>=8.0.0'} - - combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - - comma-separated-tokens@1.0.8: - resolution: {integrity: sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==} - - comma-separated-tokens@2.0.3: - resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} - - commander@11.1.0: - resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} - engines: {node: '>=16'} - - commander@4.1.1: - resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} - engines: {node: '>= 6'} - - common-ancestor-path@1.0.1: - resolution: {integrity: sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==} - - compare-func@2.0.0: - resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} - - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - - concat-stream@2.0.0: - resolution: {integrity: sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==} - engines: {'0': node >= 6.0} - - console-control-strings@1.1.0: - resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} - - conventional-changelog-angular@7.0.0: - resolution: {integrity: sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==} - engines: {node: '>=16'} - - conventional-changelog-core@5.0.1: - resolution: {integrity: sha512-Rvi5pH+LvgsqGwZPZ3Cq/tz4ty7mjijhr3qR4m9IBXNbxGGYgTVVO+duXzz9aArmHxFtwZ+LRkrNIMDQzgoY4A==} - engines: {node: '>=14'} - - conventional-changelog-preset-loader@3.0.0: - resolution: {integrity: sha512-qy9XbdSLmVnwnvzEisjxdDiLA4OmV3o8db+Zdg4WiFw14fP3B6XNz98X0swPPpkTd/pc1K7+adKgEDM1JCUMiA==} - engines: {node: '>=14'} - - conventional-changelog-writer@6.0.1: - resolution: {integrity: sha512-359t9aHorPw+U+nHzUXHS5ZnPBOizRxfQsWT5ZDHBfvfxQOAik+yfuhKXG66CN5LEWPpMNnIMHUTCKeYNprvHQ==} - engines: {node: '>=14'} - hasBin: true - - conventional-commits-filter@3.0.0: - resolution: {integrity: sha512-1ymej8b5LouPx9Ox0Dw/qAO2dVdfpRFq28e5Y0jJEU8ZrLdy0vOSkkIInwmxErFGhg6SALro60ZrwYFVTUDo4Q==} - engines: {node: '>=14'} - - conventional-commits-parser@4.0.0: - resolution: {integrity: sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==} - engines: {node: '>=14'} - hasBin: true - - conventional-recommended-bump@7.0.1: - resolution: {integrity: sha512-Ft79FF4SlOFvX4PkwFDRnaNiIVX7YbmqGU0RwccUaiGvgp3S0a8ipR2/Qxk31vclDNM+GSdJOVs2KrsUCjblVA==} - engines: {node: '>=14'} - hasBin: true - - convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - - cookie@1.0.2: - resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} - engines: {node: '>=18'} - - copy-file@11.1.0: - resolution: {integrity: sha512-X8XDzyvYaA6msMyAM575CUoygY5b44QzLcGRKsK3MFmXcOvQa518dNPLsKYwkYsn72g3EiW+LE0ytd/FlqWmyw==} - engines: {node: '>=18'} - - core-util-is@1.0.3: - resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - - cosmiconfig@9.0.0: - resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} - engines: {node: '>=14'} - peerDependencies: - typescript: '>=4.9.5' - peerDependenciesMeta: - typescript: - optional: true - - cpy-cli@6.0.0: - resolution: {integrity: sha512-q7GUqTDnRymCbScJ4Ph1IUM86wWdKG8JbgrvKLgvvehH4wrbRcVN+jRwOTlxJdwm7ykdXMKSp6IESksFeHa0eA==} - engines: {node: '>=20'} - hasBin: true - - cpy@12.0.1: - resolution: {integrity: sha512-hCnNla4AB27lUncMuO7KFjge0u0C5R74iKMBOajKOMB9ONGXcIek314ZTpxg16BuNYRTjPz7UW3tPXgJVLxUww==} - engines: {node: '>=20'} - - create-jest@29.7.0: - resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - - create-require@1.1.1: - resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - - cross-fetch@4.1.0: - resolution: {integrity: sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==} - - cross-spawn@7.0.6: - resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} - engines: {node: '>= 8'} - - css.escape@1.5.1: - resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} - - cssesc@3.0.0: - resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} - engines: {node: '>=4'} - hasBin: true - - cssstyle@4.6.0: - resolution: {integrity: sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==} - engines: {node: '>=18'} - - csstype@3.1.3: - resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} - - damerau-levenshtein@1.0.8: - resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} - - dargs@7.0.0: - resolution: {integrity: sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==} - engines: {node: '>=8'} - - data-uri-to-buffer@4.0.1: - resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} - engines: {node: '>= 12'} - - data-urls@5.0.0: - resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} - engines: {node: '>=18'} - - data-view-buffer@1.0.2: - resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} - engines: {node: '>= 0.4'} - - data-view-byte-length@1.0.2: - resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} - engines: {node: '>= 0.4'} - - data-view-byte-offset@1.0.1: - resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} - engines: {node: '>= 0.4'} - - dateformat@3.0.3: - resolution: {integrity: sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==} - - dayjs@1.11.18: - resolution: {integrity: sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==} - - debug@3.2.7: - resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - debug@4.4.3: - resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - decamelize-keys@1.1.1: - resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} - engines: {node: '>=0.10.0'} - - decamelize@1.2.0: - resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} - engines: {node: '>=0.10.0'} - - decimal.js@10.6.0: - resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} - - decode-named-character-reference@1.2.0: - resolution: {integrity: sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==} - - dedent@1.5.3: - resolution: {integrity: sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==} - peerDependencies: - babel-plugin-macros: ^3.1.0 - peerDependenciesMeta: - babel-plugin-macros: - optional: true - - dedent@1.7.0: - resolution: {integrity: sha512-HGFtf8yhuhGhqO07SV79tRp+br4MnbdjeVxotpn1QBl30pcLLCQjX5b2295ll0fv8RKDKsmWYrl05usHM9CewQ==} - peerDependencies: - babel-plugin-macros: ^3.1.0 - peerDependenciesMeta: - babel-plugin-macros: - optional: true - - deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - - deepmerge@4.3.1: - resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} - engines: {node: '>=0.10.0'} - - defaults@1.0.4: - resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} - - define-data-property@1.1.4: - resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} - engines: {node: '>= 0.4'} - - define-lazy-prop@2.0.0: - resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} - engines: {node: '>=8'} - - define-properties@1.2.1: - resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} - engines: {node: '>= 0.4'} - - delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - - deprecation@2.3.1: - resolution: {integrity: sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==} - - dequal@2.0.3: - resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} - engines: {node: '>=6'} - - detect-indent@5.0.0: - resolution: {integrity: sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g==} - engines: {node: '>=4'} - - detect-libc@2.1.1: - resolution: {integrity: sha512-ecqj/sy1jcK1uWrwpR67UhYrIFQ+5WlGxth34WquCbamhFA6hkkwiu37o6J5xCHdo1oixJRfVRw+ywV+Hq/0Aw==} - engines: {node: '>=8'} - - detect-newline@3.1.0: - resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} - engines: {node: '>=8'} - - detect-node-es@1.1.0: - resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} - - devlop@1.1.0: - resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} - - didyoumean@1.2.2: - resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} - - diff-sequences@29.6.3: - resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - diff@4.0.2: - resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} - engines: {node: '>=0.3.1'} - - dir-glob@3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} - - dlv@1.1.3: - resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} - - doctrine@2.1.0: - resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} - engines: {node: '>=0.10.0'} - - doctrine@3.0.0: - resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} - engines: {node: '>=6.0.0'} - - dom-accessibility-api@0.5.16: - resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} - - dom-accessibility-api@0.6.3: - resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} - - dot-prop@5.3.0: - resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} - engines: {node: '>=8'} - - dotenv-expand@11.0.7: - resolution: {integrity: sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==} - engines: {node: '>=12'} - - dotenv@16.4.7: - resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} - engines: {node: '>=12'} - - dunder-proto@1.0.1: - resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} - engines: {node: '>= 0.4'} - - eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - - ejs@3.1.10: - resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} - engines: {node: '>=0.10.0'} - hasBin: true - - electron-to-chromium@1.5.224: - resolution: {integrity: sha512-kWAoUu/bwzvnhpdZSIc6KUyvkI1rbRXMT0Eq8pKReyOyaPZcctMli+EgvcN1PAvwVc7Tdo4Fxi2PsLNDU05mdg==} - - embla-carousel-react@8.6.0: - resolution: {integrity: sha512-0/PjqU7geVmo6F734pmPqpyHqiM99olvyecY7zdweCw+6tKEXnrE90pBiBbMMU8s5tICemzpQ3hi5EpxzGW+JA==} - peerDependencies: - react: ^16.8.0 || ^17.0.1 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - - embla-carousel-reactive-utils@8.6.0: - resolution: {integrity: sha512-fMVUDUEx0/uIEDM0Mz3dHznDhfX+znCCDCeIophYb1QGVM7YThSWX+wz11zlYwWFOr74b4QLGg0hrGPJeG2s4A==} - peerDependencies: - embla-carousel: 8.6.0 - - embla-carousel@8.6.0: - resolution: {integrity: sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==} - - emittery@0.13.1: - resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} - engines: {node: '>=12'} - - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - - emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - - encoding@0.1.13: - resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} - - end-of-stream@1.4.5: - resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} - - enquirer@2.3.6: - resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} - engines: {node: '>=8.6'} - - entities@6.0.1: - resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} - engines: {node: '>=0.12'} - - env-paths@2.2.1: - resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} - engines: {node: '>=6'} - - envinfo@7.13.0: - resolution: {integrity: sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==} - engines: {node: '>=4'} - hasBin: true - - err-code@2.0.3: - resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} - - error-ex@1.3.4: - resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} - - es-abstract@1.24.0: - resolution: {integrity: sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==} - engines: {node: '>= 0.4'} - - es-define-property@1.0.1: - resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} - engines: {node: '>= 0.4'} - - es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} - - es-iterator-helpers@1.2.1: - resolution: {integrity: sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==} - engines: {node: '>= 0.4'} - - es-object-atoms@1.1.1: - resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} - engines: {node: '>= 0.4'} - - es-set-tostringtag@2.1.0: - resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} - engines: {node: '>= 0.4'} - - es-shim-unscopables@1.1.0: - resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} - engines: {node: '>= 0.4'} - - es-to-primitive@1.3.0: - resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} - engines: {node: '>= 0.4'} - - escalade@3.2.0: - resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} - engines: {node: '>=6'} - - escape-string-regexp@1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} - - escape-string-regexp@2.0.0: - resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} - engines: {node: '>=8'} - - escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - - escape-string-regexp@5.0.0: - resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} - engines: {node: '>=12'} - - eslint-config-next@14.1.0: - resolution: {integrity: sha512-SBX2ed7DoRFXC6CQSLc/SbLY9Ut6HxNB2wPTcoIWjUMd7aF7O/SIE7111L8FdZ9TXsNV4pulUDnfthpyPtbFUg==} - peerDependencies: - eslint: ^7.23.0 || ^8.0.0 - typescript: '>=3.3.1' - peerDependenciesMeta: - typescript: - optional: true - - eslint-config-prettier@9.1.2: - resolution: {integrity: sha512-iI1f+D2ViGn+uvv5HuHVUamg8ll4tN+JRHGc6IJi4TP9Kl976C57fzPXgseXNs8v0iA8aSJpHsTWjDb9QJamGQ==} - hasBin: true - peerDependencies: - eslint: '>=7.0.0' - - eslint-import-resolver-node@0.3.9: - resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} - - eslint-import-resolver-typescript@3.10.1: - resolution: {integrity: sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - eslint: '*' - eslint-plugin-import: '*' - eslint-plugin-import-x: '*' - peerDependenciesMeta: - eslint-plugin-import: - optional: true - eslint-plugin-import-x: - optional: true - - eslint-module-utils@2.12.1: - resolution: {integrity: sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: '*' - eslint-import-resolver-node: '*' - eslint-import-resolver-typescript: '*' - eslint-import-resolver-webpack: '*' - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - eslint: - optional: true - eslint-import-resolver-node: - optional: true - eslint-import-resolver-typescript: - optional: true - eslint-import-resolver-webpack: - optional: true - - eslint-plugin-import@2.32.0: - resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - - eslint-plugin-jest@29.0.1: - resolution: {integrity: sha512-EE44T0OSMCeXhDrrdsbKAhprobKkPtJTbQz5yEktysNpHeDZTAL1SfDTNKmcFfJkY6yrQLtTKZALrD3j/Gpmiw==} - engines: {node: ^20.12.0 || ^22.0.0 || >=24.0.0} - peerDependencies: - '@typescript-eslint/eslint-plugin': ^8.0.0 - eslint: ^8.57.0 || ^9.0.0 - jest: '*' - peerDependenciesMeta: - '@typescript-eslint/eslint-plugin': - optional: true - jest: - optional: true - - eslint-plugin-jsx-a11y@6.10.2: - resolution: {integrity: sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==} - engines: {node: '>=4.0'} - peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 - - eslint-plugin-react-hooks@5.0.0-canary-7118f5dd7-20230705: - resolution: {integrity: sha512-AZYbMo/NW9chdL7vk6HQzQhT+PvTAEVqWk9ziruUoW2kAOcN5qNyelv70e0F1VNQAbvutOC9oc+xfWycI9FxDw==} - engines: {node: '>=10'} - peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 - - eslint-plugin-react@7.37.5: - resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==} - engines: {node: '>=4'} - peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 - - eslint-plugin-simple-import-sort@12.1.1: - resolution: {integrity: sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA==} - peerDependencies: - eslint: '>=5.0.0' - - eslint-plugin-unused-imports@4.2.0: - resolution: {integrity: sha512-hLbJ2/wnjKq4kGA9AUaExVFIbNzyxYdVo49QZmKCnhk5pc9wcYRbfgLHvWJ8tnsdcseGhoUAddm9gn/lt+d74w==} - peerDependencies: - '@typescript-eslint/eslint-plugin': ^8.0.0-0 || ^7.0.0 || ^6.0.0 || ^5.0.0 - eslint: ^9.0.0 || ^8.0.0 - peerDependenciesMeta: - '@typescript-eslint/eslint-plugin': - optional: true - - eslint-scope@7.2.2: - resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - eslint-visitor-keys@3.4.3: - resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - eslint-visitor-keys@4.2.1: - resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - eslint@8.57.1: - resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. - hasBin: true - - espree@9.6.1: - resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - - esquery@1.6.0: - resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} - engines: {node: '>=0.10'} - - esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} - - estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - - estree-util-is-identifier-name@3.0.0: - resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} - - esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - - eventemitter3@4.0.7: - resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} - - execa@5.0.0: - resolution: {integrity: sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==} - engines: {node: '>=10'} - - execa@5.1.1: - resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} - engines: {node: '>=10'} - - exit@0.1.2: - resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} - engines: {node: '>= 0.8.0'} - - expect@29.7.0: - resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - exponential-backoff@3.1.2: - resolution: {integrity: sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA==} - - extend-shallow@2.0.1: - resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} - engines: {node: '>=0.10.0'} - - extend@3.0.2: - resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - - fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - - fast-glob@3.3.3: - resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} - engines: {node: '>=8.6.0'} - - fast-json-patch@3.1.1: - resolution: {integrity: sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==} - - fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - - fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - - fastq@1.19.1: - resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} - - fault@1.0.4: - resolution: {integrity: sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==} - - fb-watchman@2.0.2: - resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} - - fdir@6.5.0: - resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} - engines: {node: '>=12.0.0'} - peerDependencies: - picomatch: ^3 || ^4 - peerDependenciesMeta: - picomatch: - optional: true - - fetch-blob@3.2.0: - resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} - engines: {node: ^12.20 || >= 14.13} - - figures@3.2.0: - resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} - engines: {node: '>=8'} - - file-entry-cache@6.0.1: - resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} - engines: {node: ^10.12.0 || >=12.0.0} - - filelist@1.0.4: - resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} - - fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} - - find-up@2.1.0: - resolution: {integrity: sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==} - engines: {node: '>=4'} - - find-up@4.1.0: - resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} - engines: {node: '>=8'} - - find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} - - flat-cache@3.2.0: - resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} - engines: {node: ^10.12.0 || >=12.0.0} - - flat@5.0.2: - resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} - hasBin: true - - flatted@3.3.3: - resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} - - follow-redirects@1.15.11: - resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - - for-each@0.3.5: - resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} - engines: {node: '>= 0.4'} - - foreground-child@3.3.1: - resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} - engines: {node: '>=14'} - - form-data@4.0.4: - resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} - engines: {node: '>= 6'} - - format@0.2.2: - resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} - engines: {node: '>=0.4.x'} - - formdata-polyfill@4.0.10: - resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} - engines: {node: '>=12.20.0'} - - fraction.js@4.3.7: - resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} - - front-matter@4.0.2: - resolution: {integrity: sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==} - - fs-constants@1.0.0: - resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} - - fs-extra@11.3.2: - resolution: {integrity: sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==} - engines: {node: '>=14.14'} - - fs-minipass@2.1.0: - resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} - engines: {node: '>= 8'} - - fs-minipass@3.0.3: - resolution: {integrity: sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - - fsevents@2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - - function.prototype.name@1.1.8: - resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} - engines: {node: '>= 0.4'} - - functions-have-names@1.2.3: - resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} - - gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} - - get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - - get-intrinsic@1.3.0: - resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} - engines: {node: '>= 0.4'} - - get-nonce@1.0.1: - resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} - engines: {node: '>=6'} - - get-package-type@0.1.0: - resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} - engines: {node: '>=8.0.0'} - - get-pkg-repo@4.2.1: - resolution: {integrity: sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==} - engines: {node: '>=6.9.0'} - hasBin: true - - get-port@5.1.1: - resolution: {integrity: sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==} - engines: {node: '>=8'} - - get-proto@1.0.1: - resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} - engines: {node: '>= 0.4'} - - get-stream@6.0.0: - resolution: {integrity: sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==} - engines: {node: '>=10'} - - get-stream@6.0.1: - resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} - engines: {node: '>=10'} - - get-symbol-description@1.1.0: - resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} - engines: {node: '>= 0.4'} - - get-tsconfig@4.10.1: - resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==} - - git-raw-commits@3.0.0: - resolution: {integrity: sha512-b5OHmZ3vAgGrDn/X0kS+9qCfNKWe4K/jFnhwzVWWg0/k5eLa3060tZShrRg8Dja5kPc+YjS0Gc6y7cRr44Lpjw==} - engines: {node: '>=14'} - hasBin: true - - git-remote-origin-url@2.0.0: - resolution: {integrity: sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw==} - engines: {node: '>=4'} - - git-semver-tags@5.0.1: - resolution: {integrity: sha512-hIvOeZwRbQ+7YEUmCkHqo8FOLQZCEn18yevLHADlFPZY02KJGsu5FZt9YW/lybfK2uhWFI7Qg/07LekJiTv7iA==} - engines: {node: '>=14'} - hasBin: true - - git-up@7.0.0: - resolution: {integrity: sha512-ONdIrbBCFusq1Oy0sC71F5azx8bVkvtZtMJAsv+a6lz5YAmbNnLD6HAB4gptHZVLPR8S2/kVN6Gab7lryq5+lQ==} - - git-url-parse@14.0.0: - resolution: {integrity: sha512-NnLweV+2A4nCvn4U/m2AoYu0pPKlsmhK9cknG7IMwsjFY1S2jxM+mAhsDxyxfCIGfGaD+dozsyX4b6vkYc83yQ==} - - gitconfiglocal@1.0.0: - resolution: {integrity: sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ==} - - glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - - glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} - - glob@10.3.10: - resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==} - engines: {node: '>=16 || 14 >=14.17'} - hasBin: true - - glob@10.4.5: - resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} - hasBin: true - - glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported - - glob@9.3.5: - resolution: {integrity: sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==} - engines: {node: '>=16 || 14 >=14.17'} - - globals@13.24.0: - resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} - engines: {node: '>=8'} - - globalthis@1.0.4: - resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} - engines: {node: '>= 0.4'} - - globby@11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} - - globby@14.1.0: - resolution: {integrity: sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==} - engines: {node: '>=18'} - - gopd@1.2.0: - resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} - engines: {node: '>= 0.4'} - - graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - - graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - - graphql@16.11.0: - resolution: {integrity: sha512-mS1lbMsxgQj6hge1XZ6p7GPhbrtFwUFYi3wRzXAC/FmYnyXMTvvI3td3rjmQ2u8ewXueaSvRPWaEcgVVOT9Jnw==} - engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} - - gray-matter@4.0.3: - resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} - engines: {node: '>=6.0'} - - handlebars@4.7.8: - resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} - engines: {node: '>=0.4.7'} - hasBin: true - - hard-rejection@2.1.0: - resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==} - engines: {node: '>=6'} - - has-bigints@1.1.0: - resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} - engines: {node: '>= 0.4'} - - has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - - has-property-descriptors@1.0.2: - resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} - - has-proto@1.2.0: - resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} - engines: {node: '>= 0.4'} - - has-symbols@1.1.0: - resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} - engines: {node: '>= 0.4'} - - has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} - - has-unicode@2.0.1: - resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} - - hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} - - hast-util-parse-selector@2.2.5: - resolution: {integrity: sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==} - - hast-util-to-jsx-runtime@2.3.6: - resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} - - hast-util-whitespace@3.0.0: - resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} - - hastscript@6.0.0: - resolution: {integrity: sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==} - - headers-polyfill@4.0.3: - resolution: {integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==} - - highlight.js@10.7.3: - resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} - - highlightjs-vue@1.0.0: - resolution: {integrity: sha512-PDEfEF102G23vHmPhLyPboFCD+BkMGu+GuJe2d9/eH4FsCwvgBpnc9n0pGE+ffKdph38s6foEZiEjdgHdzp+IA==} - - hosted-git-info@2.8.9: - resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} - - hosted-git-info@4.1.0: - resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} - engines: {node: '>=10'} - - hosted-git-info@7.0.2: - resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} - engines: {node: ^16.14.0 || >=18.0.0} - - html-encoding-sniffer@4.0.0: - resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==} - engines: {node: '>=18'} - - html-escaper@2.0.2: - resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - - html-url-attributes@3.0.1: - resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==} - - http-cache-semantics@4.2.0: - resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} - - http-proxy-agent@7.0.2: - resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} - engines: {node: '>= 14'} - - https-proxy-agent@7.0.6: - resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} - engines: {node: '>= 14'} - - human-signals@2.1.0: - resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} - engines: {node: '>=10.17.0'} - - iconv-lite@0.6.3: - resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} - engines: {node: '>=0.10.0'} - - iconv-lite@0.7.0: - resolution: {integrity: sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==} - engines: {node: '>=0.10.0'} - - ieee754@1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - - ignore-walk@6.0.5: - resolution: {integrity: sha512-VuuG0wCnjhnylG1ABXT3dAuIpTNDs/G8jlpmwXY03fXoXy/8ZK8/T+hMzt8L4WnrLCJgdybqgPagnF/f97cg3A==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - ignore@5.3.2: - resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} - engines: {node: '>= 4'} - - ignore@7.0.5: - resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} - engines: {node: '>= 4'} - - import-fresh@3.3.1: - resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} - engines: {node: '>=6'} - - import-local@3.1.0: - resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==} - engines: {node: '>=8'} - hasBin: true - - import-local@3.2.0: - resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==} - engines: {node: '>=8'} - hasBin: true - - imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - - indent-string@4.0.0: - resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} - engines: {node: '>=8'} - - inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. - - inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - - ini@1.3.8: - resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} - - ini@4.1.3: - resolution: {integrity: sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - init-package-json@6.0.3: - resolution: {integrity: sha512-Zfeb5ol+H+eqJWHTaGca9BovufyGeIfr4zaaBorPmJBMrJ+KBnN+kQx2ZtXdsotUTgldHmHQV44xvUWOUA7E2w==} - engines: {node: ^16.14.0 || >=18.0.0} - - inline-style-parser@0.2.4: - resolution: {integrity: sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==} - - inquirer@8.2.7: - resolution: {integrity: sha512-UjOaSel/iddGZJ5xP/Eixh6dY1XghiBw4XK13rCCIJcJfyhhoul/7KhLLUGtebEj6GDYM6Vnx/mVsjx2L/mFIA==} - engines: {node: '>=12.0.0'} - - inquirer@9.3.8: - resolution: {integrity: sha512-pFGGdaHrmRKMh4WoDDSowddgjT1Vkl90atobmTeSmcPGdYiwikch/m/Ef5wRaiamHejtw0cUUMMerzDUXCci2w==} - engines: {node: '>=18'} - - internal-slot@1.1.0: - resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} - engines: {node: '>= 0.4'} - - ip-address@10.0.1: - resolution: {integrity: sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==} - engines: {node: '>= 12'} - - is-alphabetical@1.0.4: - resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==} - - is-alphabetical@2.0.1: - resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} - - is-alphanumerical@1.0.4: - resolution: {integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==} - - is-alphanumerical@2.0.1: - resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} - - is-array-buffer@3.0.5: - resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} - engines: {node: '>= 0.4'} - - is-arrayish@0.2.1: - resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - - is-async-function@2.1.1: - resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} - engines: {node: '>= 0.4'} - - is-bigint@1.1.0: - resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} - engines: {node: '>= 0.4'} - - is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} - - is-boolean-object@1.2.2: - resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} - engines: {node: '>= 0.4'} - - is-bun-module@2.0.0: - resolution: {integrity: sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==} - - is-callable@1.2.7: - resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} - engines: {node: '>= 0.4'} - - is-ci@3.0.1: - resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} - hasBin: true - - is-core-module@2.16.1: - resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} - engines: {node: '>= 0.4'} - - is-data-view@1.0.2: - resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} - engines: {node: '>= 0.4'} - - is-date-object@1.1.0: - resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} - engines: {node: '>= 0.4'} - - is-decimal@1.0.4: - resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==} - - is-decimal@2.0.1: - resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} - - is-docker@2.2.1: - resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} - engines: {node: '>=8'} - hasBin: true - - is-extendable@0.1.1: - resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} - engines: {node: '>=0.10.0'} - - is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - - is-finalizationregistry@1.1.1: - resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} - engines: {node: '>= 0.4'} - - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - - is-generator-fn@2.1.0: - resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} - engines: {node: '>=6'} - - is-generator-function@1.1.0: - resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} - engines: {node: '>= 0.4'} - - is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - - is-hexadecimal@1.0.4: - resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==} - - is-hexadecimal@2.0.1: - resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} - - is-interactive@1.0.0: - resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} - engines: {node: '>=8'} - - is-lambda@1.0.1: - resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} - - is-map@2.0.3: - resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} - engines: {node: '>= 0.4'} - - is-negative-zero@2.0.3: - resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} - engines: {node: '>= 0.4'} - - is-node-process@1.2.0: - resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==} - - is-number-object@1.1.1: - resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} - engines: {node: '>= 0.4'} - - is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - - is-obj@2.0.0: - resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} - engines: {node: '>=8'} - - is-path-inside@3.0.3: - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} - engines: {node: '>=8'} - - is-plain-obj@1.1.0: - resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} - engines: {node: '>=0.10.0'} - - is-plain-obj@4.1.0: - resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} - engines: {node: '>=12'} - - is-plain-object@2.0.4: - resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} - engines: {node: '>=0.10.0'} - - is-potential-custom-element-name@1.0.1: - resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} - - is-regex@1.2.1: - resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} - engines: {node: '>= 0.4'} - - is-set@2.0.3: - resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} - engines: {node: '>= 0.4'} - - is-shared-array-buffer@1.0.4: - resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} - engines: {node: '>= 0.4'} - - is-ssh@1.4.1: - resolution: {integrity: sha512-JNeu1wQsHjyHgn9NcWTaXq6zWSR6hqE0++zhfZlkFBbScNkyvxCdeV8sRkSBaeLKxmbpR21brail63ACNxJ0Tg==} - - is-stream@2.0.0: - resolution: {integrity: sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==} - engines: {node: '>=8'} - - is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} - - is-string@1.1.1: - resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} - engines: {node: '>= 0.4'} - - is-symbol@1.1.1: - resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} - engines: {node: '>= 0.4'} - - is-text-path@1.0.1: - resolution: {integrity: sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==} - engines: {node: '>=0.10.0'} - - is-typed-array@1.1.15: - resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} - engines: {node: '>= 0.4'} - - is-unicode-supported@0.1.0: - resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} - engines: {node: '>=10'} - - is-weakmap@2.0.2: - resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} - engines: {node: '>= 0.4'} - - is-weakref@1.1.1: - resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} - engines: {node: '>= 0.4'} - - is-weakset@2.0.4: - resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} - engines: {node: '>= 0.4'} - - is-wsl@2.2.0: - resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} - engines: {node: '>=8'} - - isarray@1.0.0: - resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} - - isarray@2.0.5: - resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - isexe@3.1.1: - resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} - engines: {node: '>=16'} - - isobject@3.0.1: - resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} - engines: {node: '>=0.10.0'} - - isomorphic-fetch@3.0.0: - resolution: {integrity: sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==} - - istanbul-lib-coverage@3.2.2: - resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} - engines: {node: '>=8'} - - istanbul-lib-instrument@5.2.1: - resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} - engines: {node: '>=8'} - - istanbul-lib-instrument@6.0.3: - resolution: {integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==} - engines: {node: '>=10'} - - istanbul-lib-report@3.0.1: - resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} - engines: {node: '>=10'} - - istanbul-lib-source-maps@4.0.1: - resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} - engines: {node: '>=10'} - - istanbul-reports@3.2.0: - resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} - engines: {node: '>=8'} - - iterator.prototype@1.1.5: - resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} - engines: {node: '>= 0.4'} - - jackspeak@2.3.6: - resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} - engines: {node: '>=14'} - - jackspeak@3.4.3: - resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} - - jake@10.9.4: - resolution: {integrity: sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==} - engines: {node: '>=10'} - hasBin: true - - jest-changed-files@29.7.0: - resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-circus@29.7.0: - resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-cli@29.7.0: - resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - - jest-config@29.7.0: - resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@types/node': '*' - ts-node: '>=9.0.0' - peerDependenciesMeta: - '@types/node': - optional: true - ts-node: - optional: true - - jest-diff@29.7.0: - resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-docblock@29.7.0: - resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-each@29.7.0: - resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-environment-jsdom@30.2.0: - resolution: {integrity: sha512-zbBTiqr2Vl78pKp/laGBREYzbZx9ZtqPjOK4++lL4BNDhxRnahg51HtoDrk9/VjIy9IthNEWdKVd7H5bqBhiWQ==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - peerDependencies: - canvas: ^3.0.0 - peerDependenciesMeta: - canvas: - optional: true - - jest-environment-node@29.7.0: - resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-fixed-jsdom@0.0.10: - resolution: {integrity: sha512-WaEVX+FripJh+Hn/7dysIgqP66h0KT1NNC22NGmNYANExtCoYNk1q2yjwwcdSboBMkkhn0NtmvKad/cmisnCLg==} - engines: {node: '>=18.0.0'} - peerDependencies: - jest-environment-jsdom: '>=28.0.0' - - jest-get-type@29.6.3: - resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-haste-map@29.7.0: - resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-leak-detector@29.7.0: - resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-matcher-utils@29.7.0: - resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-message-util@29.7.0: - resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-message-util@30.2.0: - resolution: {integrity: sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - jest-mock@29.7.0: - resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-mock@30.2.0: - resolution: {integrity: sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - jest-pnp-resolver@1.2.3: - resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} - engines: {node: '>=6'} - peerDependencies: - jest-resolve: '*' - peerDependenciesMeta: - jest-resolve: - optional: true - - jest-regex-util@29.6.3: - resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-regex-util@30.0.1: - resolution: {integrity: sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - jest-resolve-dependencies@29.7.0: - resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-resolve@29.7.0: - resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-runner@29.7.0: - resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-runtime@29.7.0: - resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-snapshot@29.7.0: - resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-util@29.7.0: - resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-util@30.2.0: - resolution: {integrity: sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - jest-validate@29.7.0: - resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-watcher@29.7.0: - resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-worker@29.7.0: - resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest@29.7.0: - resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - - jiti@1.21.7: - resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} - hasBin: true - - js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - - js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} - hasBin: true - - js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true - - jsdom@26.1.0: - resolution: {integrity: sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==} - engines: {node: '>=18'} - peerDependencies: - canvas: ^3.0.0 - peerDependenciesMeta: - canvas: - optional: true - - jsesc@3.1.0: - resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} - engines: {node: '>=6'} - hasBin: true - - json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - - json-parse-better-errors@1.0.2: - resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} - - json-parse-even-better-errors@2.3.1: - resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - - json-parse-even-better-errors@3.0.2: - resolution: {integrity: sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - - json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - - json-stringify-nice@1.1.4: - resolution: {integrity: sha512-5Z5RFW63yxReJ7vANgW6eZFGWaQvnPE3WNmZoOJrSkGju2etKA2L5rrOa1sm877TVTFt57A80BH1bArcmlLfPw==} - - json-stringify-safe@5.0.1: - resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} - - json5@1.0.2: - resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} - hasBin: true - - json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} - hasBin: true - - jsonc-parser@3.2.0: - resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} - - jsonfile@6.2.0: - resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} - - jsonparse@1.3.1: - resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} - engines: {'0': node >= 0.2.0} - - jsx-ast-utils@3.3.5: - resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} - engines: {node: '>=4.0'} - - junk@4.0.1: - resolution: {integrity: sha512-Qush0uP+G8ZScpGMZvHUiRfI0YBWuB3gVBYlI0v0vvOJt5FLicco+IkP0a50LqTTQhmts/m6tP5SWE+USyIvcQ==} - engines: {node: '>=12.20'} - - just-diff-apply@5.5.0: - resolution: {integrity: sha512-OYTthRfSh55WOItVqwpefPtNt2VdKsq5AnAK6apdtR6yCH8pr0CmSr710J0Mf+WdQy7K/OzMy7K2MgAfdQURDw==} - - just-diff@6.0.2: - resolution: {integrity: sha512-S59eriX5u3/QhMNq3v/gm8Kd0w8OS6Tz2FS1NG4blv+z0MuQcBRJyFWjdovM0Rad4/P4aUPFtnkNjMjyMlMSYA==} - - keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - - kind-of@6.0.3: - resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} - engines: {node: '>=0.10.0'} - - kleur@3.0.3: - resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} - engines: {node: '>=6'} - - kubernetesjs@0.6.2: - resolution: {integrity: sha512-pGo1uaVnAg4M6T18Y32xkIZ2KBgt7GfWHMi2yBXSlkijCIRDuv6kOpPC6JamtC8B7wCnbNmm/f6JK8WLFS+UPg==} - - kubernetesjs@0.7.2: - resolution: {integrity: sha512-WzvmRiZiW1fstCgVLXGWloV/0yv7n9tuMPX640caIIK5nRviCOEux85cCgrumZ3AGZ3hFM5rxhkOH40e2FF6wg==} - - language-subtag-registry@0.3.23: - resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} - - language-tags@1.0.9: - resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} - engines: {node: '>=0.10'} - - lerna@8.2.4: - resolution: {integrity: sha512-0gaVWDIVT7fLfprfwpYcQajb7dBJv3EGavjG7zvJ+TmGx3/wovl5GklnSwM2/WeE0Z2wrIz7ndWhBcDUHVjOcQ==} - engines: {node: '>=18.0.0'} - hasBin: true - - leven@3.1.0: - resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} - engines: {node: '>=6'} - - levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} - - libnpmaccess@8.0.6: - resolution: {integrity: sha512-uM8DHDEfYG6G5gVivVl+yQd4pH3uRclHC59lzIbSvy7b5FEwR+mU49Zq1jEyRtRFv7+M99mUW9S0wL/4laT4lw==} - engines: {node: ^16.14.0 || >=18.0.0} - - libnpmpublish@9.0.9: - resolution: {integrity: sha512-26zzwoBNAvX9AWOPiqqF6FG4HrSCPsHFkQm7nT+xU1ggAujL/eae81RnCv4CJ2In9q9fh10B88sYSzKCUh/Ghg==} - engines: {node: ^16.14.0 || >=18.0.0} - - lilconfig@3.1.3: - resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} - engines: {node: '>=14'} - - lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - - lines-and-columns@2.0.3: - resolution: {integrity: sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - load-json-file@4.0.0: - resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} - engines: {node: '>=4'} - - load-json-file@6.2.0: - resolution: {integrity: sha512-gUD/epcRms75Cw8RT1pUdHugZYM5ce64ucs2GEISABwkRsOQr0q2wm/MV2TKThycIe5e0ytRweW2RZxclogCdQ==} - engines: {node: '>=8'} - - locate-path@2.0.0: - resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==} - engines: {node: '>=4'} - - locate-path@5.0.0: - resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} - engines: {node: '>=8'} - - locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} - - lodash-es@4.17.21: - resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} - - lodash.ismatch@4.4.0: - resolution: {integrity: sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==} - - lodash.memoize@4.1.2: - resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} - - lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - - lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - - log-symbols@4.1.0: - resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} - engines: {node: '>=10'} - - longest-streak@3.1.0: - resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} - - loose-envify@1.4.0: - resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} - hasBin: true - - lowlight@1.20.0: - resolution: {integrity: sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==} - - lru-cache@10.4.3: - resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - - lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - - lru-cache@6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} - - lucide-react@0.454.0: - resolution: {integrity: sha512-hw7zMDwykCLnEzgncEEjHeA6+45aeEzRYuKHuyRSOPkhko+J3ySGjGIzu+mmMfDFG1vazHepMaYFYHbTFAZAAQ==} - peerDependencies: - react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc - - lz-string@1.5.0: - resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} - hasBin: true - - make-dir@2.1.0: - resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} - engines: {node: '>=6'} - - make-dir@4.0.0: - resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} - engines: {node: '>=10'} - - make-error@1.3.6: - resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} - - make-fetch-happen@13.0.1: - resolution: {integrity: sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==} - engines: {node: ^16.14.0 || >=18.0.0} - - makeerror@1.0.12: - resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} - - map-obj@1.0.1: - resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} - engines: {node: '>=0.10.0'} - - map-obj@4.3.0: - resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==} - engines: {node: '>=8'} - - markdown-table@3.0.4: - resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} - - match-sorter@8.1.0: - resolution: {integrity: sha512-0HX3BHPixkbECX+Vt7nS1vJ6P2twPgGTU3PMXjWrl1eyVCL24tFHeyYN1FN5RKLzve0TyzNI9qntqQGbebnfPQ==} - - math-intrinsics@1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} - engines: {node: '>= 0.4'} - - mdast-util-find-and-replace@3.0.2: - resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} - - mdast-util-from-markdown@2.0.2: - resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==} - - mdast-util-gfm-autolink-literal@2.0.1: - resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} - - mdast-util-gfm-footnote@2.1.0: - resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} - - mdast-util-gfm-strikethrough@2.0.0: - resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} - - mdast-util-gfm-table@2.0.0: - resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} - - mdast-util-gfm-task-list-item@2.0.0: - resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} - - mdast-util-gfm@3.1.0: - resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} - - mdast-util-mdx-expression@2.0.1: - resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} - - mdast-util-mdx-jsx@3.2.0: - resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} - - mdast-util-mdxjs-esm@2.0.1: - resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} - - mdast-util-phrasing@4.1.0: - resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} - - mdast-util-to-hast@13.2.0: - resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==} - - mdast-util-to-markdown@2.1.2: - resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} - - mdast-util-to-string@4.0.0: - resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} - - meow@13.2.0: - resolution: {integrity: sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==} - engines: {node: '>=18'} - - meow@8.1.2: - resolution: {integrity: sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==} - engines: {node: '>=10'} - - merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - - merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - - micromark-core-commonmark@2.0.3: - resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} - - micromark-extension-gfm-autolink-literal@2.1.0: - resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} - - micromark-extension-gfm-footnote@2.1.0: - resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} - - micromark-extension-gfm-strikethrough@2.1.0: - resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} - - micromark-extension-gfm-table@2.1.1: - resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} - - micromark-extension-gfm-tagfilter@2.0.0: - resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} - - micromark-extension-gfm-task-list-item@2.1.0: - resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} - - micromark-extension-gfm@3.0.0: - resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} - - micromark-factory-destination@2.0.1: - resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} - - micromark-factory-label@2.0.1: - resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} - - micromark-factory-space@2.0.1: - resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} - - micromark-factory-title@2.0.1: - resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} - - micromark-factory-whitespace@2.0.1: - resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} - - micromark-util-character@2.1.1: - resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} - - micromark-util-chunked@2.0.1: - resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} - - micromark-util-classify-character@2.0.1: - resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} - - micromark-util-combine-extensions@2.0.1: - resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} - - micromark-util-decode-numeric-character-reference@2.0.2: - resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} - - micromark-util-decode-string@2.0.1: - resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} - - micromark-util-encode@2.0.1: - resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} - - micromark-util-html-tag-name@2.0.1: - resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} - - micromark-util-normalize-identifier@2.0.1: - resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} - - micromark-util-resolve-all@2.0.1: - resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} - - micromark-util-sanitize-uri@2.0.1: - resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} - - micromark-util-subtokenize@2.1.0: - resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} - - micromark-util-symbol@2.0.1: - resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} - - micromark-util-types@2.0.2: - resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} - - micromark@4.0.2: - resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} - - micromatch@4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} - engines: {node: '>=8.6'} - - mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - - mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - - mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} - - min-indent@1.0.1: - resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} - engines: {node: '>=4'} - - minimatch@3.0.5: - resolution: {integrity: sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==} - - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - - minimatch@5.1.6: - resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} - engines: {node: '>=10'} - - minimatch@8.0.4: - resolution: {integrity: sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==} - engines: {node: '>=16 || 14 >=14.17'} - - minimatch@9.0.3: - resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} - engines: {node: '>=16 || 14 >=14.17'} - - minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} - engines: {node: '>=16 || 14 >=14.17'} - - minimist-options@4.1.0: - resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} - engines: {node: '>= 6'} - - minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - - minipass-collect@2.0.1: - resolution: {integrity: sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==} - engines: {node: '>=16 || 14 >=14.17'} - - minipass-fetch@3.0.5: - resolution: {integrity: sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - minipass-flush@1.0.5: - resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} - engines: {node: '>= 8'} - - minipass-pipeline@1.2.4: - resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==} - engines: {node: '>=8'} - - minipass-sized@1.0.3: - resolution: {integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==} - engines: {node: '>=8'} - - minipass@3.3.6: - resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} - engines: {node: '>=8'} - - minipass@4.2.8: - resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==} - engines: {node: '>=8'} - - minipass@5.0.0: - resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} - engines: {node: '>=8'} - - minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} - engines: {node: '>=16 || 14 >=14.17'} - - minizlib@2.1.2: - resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} - engines: {node: '>= 8'} - - mkdirp@1.0.4: - resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} - engines: {node: '>=10'} - hasBin: true - - modify-values@1.0.1: - resolution: {integrity: sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==} - engines: {node: '>=0.10.0'} - - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - msw@2.11.5: - resolution: {integrity: sha512-atFI4GjKSJComxcigz273honh8h4j5zzpk5kwG4tGm0TPcYne6bqmVrufeRll6auBeouIkXqZYXxVbWSWxM3RA==} - engines: {node: '>=18'} - hasBin: true - peerDependencies: - typescript: '>= 4.8.x' - peerDependenciesMeta: - typescript: - optional: true - - multimatch@5.0.0: - resolution: {integrity: sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==} - engines: {node: '>=10'} - - mute-stream@0.0.8: - resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} - - mute-stream@1.0.0: - resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - mute-stream@2.0.0: - resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} - engines: {node: ^18.17.0 || >=20.5.0} - - mz@2.7.0: - resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} - - nanoid@3.3.11: - resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - - napi-postinstall@0.3.3: - resolution: {integrity: sha512-uTp172LLXSxuSYHv/kou+f6KW3SMppU9ivthaVTXian9sOt3XM/zHYHpRZiLgQoxeWfYUnslNWQHF1+G71xcow==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - hasBin: true - - natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - - negotiator@0.6.4: - resolution: {integrity: sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==} - engines: {node: '>= 0.6'} - - neo-async@2.6.2: - resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - - next-seo@6.8.0: - resolution: {integrity: sha512-zcxaV67PFXCSf8e6SXxbxPaOTgc8St/esxfsYXfQXMM24UESUVSXFm7f2A9HMkAwa0Gqn4s64HxYZAGfdF4Vhg==} - peerDependencies: - next: ^8.1.1-canary.54 || >=9.0.0 - react: '>=16.0.0' - react-dom: '>=16.0.0' - - next-themes@0.3.0: - resolution: {integrity: sha512-/QHIrsYpd6Kfk7xakK4svpDI5mmXP0gfvCoJdGpZQ2TOrQZmsW0QxjaiLn8wbIKjtm4BTSqLoix4lxYYOnLJ/w==} - peerDependencies: - react: ^16.8 || ^17 || ^18 - react-dom: ^16.8 || ^17 || ^18 - - next@15.5.4: - resolution: {integrity: sha512-xH4Yjhb82sFYQfY3vbkJfgSDgXvBB6a8xPs9i35k6oZJRoQRihZH+4s9Yo2qsWpzBmZ3lPXaJ2KPXLfkvW4LnA==} - engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} - hasBin: true - peerDependencies: - '@opentelemetry/api': ^1.1.0 - '@playwright/test': ^1.51.1 - babel-plugin-react-compiler: '*' - react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 - react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 - sass: ^1.3.0 - peerDependenciesMeta: - '@opentelemetry/api': - optional: true - '@playwright/test': - optional: true - babel-plugin-react-compiler: - optional: true - sass: - optional: true - - node-domexception@1.0.0: - resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} - engines: {node: '>=10.5.0'} - deprecated: Use your platform's native DOMException instead - - node-fetch@2.6.7: - resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - - node-fetch@2.7.0: - resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - - node-fetch@3.3.2: - resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - node-gyp@10.3.1: - resolution: {integrity: sha512-Pp3nFHBThHzVtNY7U6JfPjvT/DTE8+o/4xKsLQtBoU+j2HLsGlhcfzflAoUreaJbNmYnX+LlLi0qjV8kpyO6xQ==} - engines: {node: ^16.14.0 || >=18.0.0} - hasBin: true - - node-int64@0.4.0: - resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} - - node-machine-id@1.1.12: - resolution: {integrity: sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==} - - node-releases@2.0.21: - resolution: {integrity: sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw==} - - nopt@7.2.1: - resolution: {integrity: sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - hasBin: true - - normalize-package-data@2.5.0: - resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} - - normalize-package-data@3.0.3: - resolution: {integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==} - engines: {node: '>=10'} - - normalize-package-data@6.0.2: - resolution: {integrity: sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==} - engines: {node: ^16.14.0 || >=18.0.0} - - normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} - - normalize-range@0.1.2: - resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} - engines: {node: '>=0.10.0'} - - npm-bundled@3.0.1: - resolution: {integrity: sha512-+AvaheE/ww1JEwRHOrn4WHNzOxGtVp+adrg2AeZS/7KuxGUYFuBta98wYpfHBbJp6Tg6j1NKSEVHNcfZzJHQwQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - npm-install-checks@6.3.0: - resolution: {integrity: sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - npm-normalize-package-bin@3.0.1: - resolution: {integrity: sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - npm-package-arg@11.0.2: - resolution: {integrity: sha512-IGN0IAwmhDJwy13Wc8k+4PEbTPhpJnMtfR53ZbOyjkvmEcLS4nCwp6mvMWjS5sUjeiW3mpx6cHmuhKEu9XmcQw==} - engines: {node: ^16.14.0 || >=18.0.0} - - npm-packlist@8.0.2: - resolution: {integrity: sha512-shYrPFIS/JLP4oQmAwDyk5HcyysKW8/JLTEA32S0Z5TzvpaeeX2yMFfoK1fjEBnCBvVyIB/Jj/GBFdm0wsgzbA==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - npm-pick-manifest@9.1.0: - resolution: {integrity: sha512-nkc+3pIIhqHVQr085X9d2JzPzLyjzQS96zbruppqC9aZRm/x8xx6xhI98gHtsfELP2bE+loHq8ZaHFHhe+NauA==} - engines: {node: ^16.14.0 || >=18.0.0} - - npm-registry-fetch@17.1.0: - resolution: {integrity: sha512-5+bKQRH0J1xG1uZ1zMNvxW0VEyoNWgJpY9UDuluPFLKDfJ9u2JmmjmTJV1srBGQOROfdBMiVvnH2Zvpbm+xkVA==} - engines: {node: ^16.14.0 || >=18.0.0} - - npm-run-path@4.0.1: - resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} - engines: {node: '>=8'} - - nuqs@2.6.0: - resolution: {integrity: sha512-EvIKBvfJeyL8n6lxfebxoAbkHJutNsxmy1oo4noFUYNUESbnecxWxgnxXoa0/4fYiFwdEuyMQx1Z9rV0h4bnkg==} - peerDependencies: - '@remix-run/react': '>=2' - '@tanstack/react-router': ^1 - next: '>=14.2.0' - react: '>=18.2.0 || ^19.0.0-0' - react-router: ^6 || ^7 - react-router-dom: ^6 || ^7 - peerDependenciesMeta: - '@remix-run/react': - optional: true - '@tanstack/react-router': - optional: true - next: - optional: true - react-router: - optional: true - react-router-dom: - optional: true - - nwsapi@2.2.22: - resolution: {integrity: sha512-ujSMe1OWVn55euT1ihwCI1ZcAaAU3nxUiDwfDQldc51ZXaB9m2AyOn6/jh1BLe2t/G8xd6uKG1UBF2aZJeg2SQ==} - - nx@20.8.2: - resolution: {integrity: sha512-mDKpbH3vEpUFDx0rrLh+tTqLq1PYU8KiD/R7OVZGd1FxQxghx2HOl32MiqNsfPcw6AvKlXhslbwIESV+N55FLQ==} - hasBin: true - peerDependencies: - '@swc-node/register': ^1.8.0 - '@swc/core': ^1.3.85 - peerDependenciesMeta: - '@swc-node/register': - optional: true - '@swc/core': - optional: true - - object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - - object-hash@3.0.0: - resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} - engines: {node: '>= 6'} - - object-inspect@1.13.4: - resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} - engines: {node: '>= 0.4'} - - object-keys@1.1.1: - resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} - engines: {node: '>= 0.4'} - - object.assign@4.1.7: - resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} - engines: {node: '>= 0.4'} - - object.entries@1.1.9: - resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==} - engines: {node: '>= 0.4'} - - object.fromentries@2.0.8: - resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} - engines: {node: '>= 0.4'} - - object.groupby@1.0.3: - resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} - engines: {node: '>= 0.4'} - - object.values@1.2.1: - resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} - engines: {node: '>= 0.4'} - - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - - onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} - - open@8.4.2: - resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} - engines: {node: '>=12'} - - optionator@0.9.4: - resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} - engines: {node: '>= 0.8.0'} - - ora@5.3.0: - resolution: {integrity: sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g==} - engines: {node: '>=10'} - - ora@5.4.1: - resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} - engines: {node: '>=10'} - - outvariant@1.4.3: - resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} - - own-keys@1.0.1: - resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} - engines: {node: '>= 0.4'} - - p-event@6.0.1: - resolution: {integrity: sha512-Q6Bekk5wpzW5qIyUP4gdMEujObYstZl6DMMOSenwBvV0BlE5LkDwkjs5yHbZmdCEq2o4RJx4tE1vwxFVf2FG1w==} - engines: {node: '>=16.17'} - - p-filter@4.1.0: - resolution: {integrity: sha512-37/tPdZ3oJwHaS3gNJdenCDB3Tz26i9sjhnguBtvN0vYlRIiDNnvTWkuh+0hETV9rLPdJ3rlL3yVOYPIAnM8rw==} - engines: {node: '>=18'} - - p-finally@1.0.0: - resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} - engines: {node: '>=4'} - - p-limit@1.3.0: - resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==} - engines: {node: '>=4'} - - p-limit@2.3.0: - resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} - engines: {node: '>=6'} - - p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - - p-locate@2.0.0: - resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==} - engines: {node: '>=4'} - - p-locate@4.1.0: - resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} - engines: {node: '>=8'} - - p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} - - p-map-series@2.1.0: - resolution: {integrity: sha512-RpYIIK1zXSNEOdwxcfe7FdvGcs7+y5n8rifMhMNWvaxRNMPINJHF5GDeuVxWqnfrcHPSCnp7Oo5yNXHId9Av2Q==} - engines: {node: '>=8'} - - p-map@4.0.0: - resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} - engines: {node: '>=10'} - - p-map@7.0.3: - resolution: {integrity: sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==} - engines: {node: '>=18'} - - p-pipe@3.1.0: - resolution: {integrity: sha512-08pj8ATpzMR0Y80x50yJHn37NF6vjrqHutASaX5LiH5npS9XPvrUmscd9MF5R4fuYRHOxQR1FfMIlF7AzwoPqw==} - engines: {node: '>=8'} - - p-queue@6.6.2: - resolution: {integrity: sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==} - engines: {node: '>=8'} - - p-reduce@2.1.0: - resolution: {integrity: sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw==} - engines: {node: '>=8'} - - p-timeout@3.2.0: - resolution: {integrity: sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==} - engines: {node: '>=8'} - - p-timeout@6.1.4: - resolution: {integrity: sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==} - engines: {node: '>=14.16'} - - p-try@1.0.0: - resolution: {integrity: sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==} - engines: {node: '>=4'} - - p-try@2.2.0: - resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} - engines: {node: '>=6'} - - p-waterfall@2.1.1: - resolution: {integrity: sha512-RRTnDb2TBG/epPRI2yYXsimO0v3BXC8Yd3ogr1545IaqKK17VGhbWVeGGN+XfCm/08OK8635nH31c8bATkHuSw==} - engines: {node: '>=8'} - - package-json-from-dist@1.0.1: - resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} - - pacote@18.0.6: - resolution: {integrity: sha512-+eK3G27SMwsB8kLIuj4h1FUhHtwiEUo21Tw8wNjmvdlpOEr613edv+8FUsTj/4F/VN5ywGE19X18N7CC2EJk6A==} - engines: {node: ^16.14.0 || >=18.0.0} - hasBin: true - - parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} - - parse-conflict-json@3.0.1: - resolution: {integrity: sha512-01TvEktc68vwbJOtWZluyWeVGWjP+bZwXtPDMQVbBKzbJ/vZBif0L69KH1+cHv1SZ6e0FKLvjyHe8mqsIqYOmw==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - parse-entities@2.0.0: - resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==} - - parse-entities@4.0.2: - resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} - - parse-json@4.0.0: - resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} - engines: {node: '>=4'} - - parse-json@5.2.0: - resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} - engines: {node: '>=8'} - - parse-path@7.1.0: - resolution: {integrity: sha512-EuCycjZtfPcjWk7KTksnJ5xPMvWGA/6i4zrLYhRG0hGvC3GPU/jGUj3Cy+ZR0v30duV3e23R95T1lE2+lsndSw==} - - parse-url@8.1.0: - resolution: {integrity: sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w==} - - parse5@7.3.0: - resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} - - path-exists@3.0.0: - resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} - engines: {node: '>=4'} - - path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - - path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - - path-scurry@1.11.1: - resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} - engines: {node: '>=16 || 14 >=14.18'} - - path-to-regexp@6.3.0: - resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} - - path-type@3.0.0: - resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} - engines: {node: '>=4'} - - path-type@4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} - - path-type@6.0.0: - resolution: {integrity: sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==} - engines: {node: '>=18'} - - perfect-freehand@1.2.2: - resolution: {integrity: sha512-eh31l019WICQ03pkF3FSzHxB8n07ItqIQ++G5UV8JX0zVOXzgTGCqnRR0jJ2h9U8/2uW4W4mtGJELt9kEV0CFQ==} - - pg-cloudflare@1.2.7: - resolution: {integrity: sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==} - - pg-connection-string@2.9.1: - resolution: {integrity: sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w==} - - pg-int8@1.0.1: - resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} - engines: {node: '>=4.0.0'} - - pg-pool@3.10.1: - resolution: {integrity: sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg==} - peerDependencies: - pg: '>=8.0' - - pg-protocol@1.10.3: - resolution: {integrity: sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==} - - pg-types@2.2.0: - resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} - engines: {node: '>=4'} - - pg@8.16.3: - resolution: {integrity: sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==} - engines: {node: '>= 16.0.0'} - peerDependencies: - pg-native: '>=3.0.1' - peerDependenciesMeta: - pg-native: - optional: true - - pgpass@1.0.5: - resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==} - - picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - - picomatch@4.0.3: - resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} - engines: {node: '>=12'} - - pify@2.3.0: - resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} - engines: {node: '>=0.10.0'} - - pify@3.0.0: - resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} - engines: {node: '>=4'} - - pify@4.0.1: - resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} - engines: {node: '>=6'} - - pify@5.0.0: - resolution: {integrity: sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==} - engines: {node: '>=10'} - - pirates@4.0.7: - resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} - engines: {node: '>= 6'} - - pkg-dir@4.2.0: - resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} - engines: {node: '>=8'} - - playwright-core@1.56.1: - resolution: {integrity: sha512-hutraynyn31F+Bifme+Ps9Vq59hKuUCz7H1kDOcBs+2oGguKkWTU50bBWrtz34OUWmIwpBTWDxaRPXrIXkgvmQ==} - engines: {node: '>=18'} - hasBin: true - - playwright@1.56.1: - resolution: {integrity: sha512-aFi5B0WovBHTEvpM3DzXTUaeN6eN0qWnTkKx4NQaH4Wvcmc153PdaY2UBdSYKaGYw+UyWXSVyxDUg5DoPEttjw==} - engines: {node: '>=18'} - hasBin: true - - possible-typed-array-names@1.1.0: - resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} - engines: {node: '>= 0.4'} - - postcss-import@15.1.0: - resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} - engines: {node: '>=14.0.0'} - peerDependencies: - postcss: ^8.0.0 - - postcss-js@4.1.0: - resolution: {integrity: sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==} - engines: {node: ^12 || ^14 || >= 16} - peerDependencies: - postcss: ^8.4.21 - - postcss-load-config@4.0.2: - resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} - engines: {node: '>= 14'} - peerDependencies: - postcss: '>=8.0.9' - ts-node: '>=9.0.0' - peerDependenciesMeta: - postcss: - optional: true - ts-node: - optional: true - - postcss-nested@6.2.0: - resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} - engines: {node: '>=12.0'} - peerDependencies: - postcss: ^8.2.14 - - postcss-selector-parser@6.1.2: - resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} - engines: {node: '>=4'} - - postcss-value-parser@4.2.0: - resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - - postcss@8.4.31: - resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} - engines: {node: ^10 || ^12 || >=14} - - postcss@8.5.6: - resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} - engines: {node: ^10 || ^12 || >=14} - - postgres-array@2.0.0: - resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} - engines: {node: '>=4'} - - postgres-bytea@1.0.0: - resolution: {integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==} - engines: {node: '>=0.10.0'} - - postgres-date@1.0.7: - resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} - engines: {node: '>=0.10.0'} - - postgres-interval@1.2.0: - resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} - engines: {node: '>=0.10.0'} - - prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - - prettier@3.6.2: - resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} - engines: {node: '>=14'} - hasBin: true - - pretty-format@27.5.1: - resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} - engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} - - pretty-format@29.7.0: - resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - pretty-format@30.2.0: - resolution: {integrity: sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - prismjs@1.27.0: - resolution: {integrity: sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==} - engines: {node: '>=6'} - - prismjs@1.30.0: - resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} - engines: {node: '>=6'} - - proc-log@4.2.0: - resolution: {integrity: sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - process-nextick-args@2.0.1: - resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} - - proggy@2.0.0: - resolution: {integrity: sha512-69agxLtnI8xBs9gUGqEnK26UfiexpHy+KUpBQWabiytQjnn5wFY8rklAi7GRfABIuPNnQ/ik48+LGLkYYJcy4A==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - promise-all-reject-late@1.0.1: - resolution: {integrity: sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==} - - promise-call-limit@3.0.2: - resolution: {integrity: sha512-mRPQO2T1QQVw11E7+UdCJu7S61eJVWknzml9sC1heAdj1jxl0fWMBypIt9ZOcLFf8FkG995ZD7RnVk7HH72fZw==} - - promise-inflight@1.0.1: - resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==} - peerDependencies: - bluebird: '*' - peerDependenciesMeta: - bluebird: - optional: true - - promise-retry@2.0.1: - resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} - engines: {node: '>=10'} - - prompts@2.4.2: - resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} - engines: {node: '>= 6'} - - promzard@1.0.2: - resolution: {integrity: sha512-2FPputGL+mP3jJ3UZg/Dl9YOkovB7DX0oOr+ck5QbZ5MtORtds8k/BZdn+02peDLI8/YWbmzx34k5fA+fHvCVQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - prop-types@15.8.1: - resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} - - property-information@5.6.0: - resolution: {integrity: sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==} - - property-information@7.1.0: - resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} - - protocols@2.0.2: - resolution: {integrity: sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ==} - - proxy-compare@3.0.1: - resolution: {integrity: sha512-V9plBAt3qjMlS1+nC8771KNf6oJ12gExvaxnNzN/9yVRLdTv/lc+oJlnSzrdYDAvBfTStPCoiaCOTmTs0adv7Q==} - - proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - - proxy-memoize@3.0.1: - resolution: {integrity: sha512-VDdG/VYtOgdGkWJx7y0o7p+zArSf2383Isci8C+BP3YXgMYDoPd3cCBjw0JdWb6YBb9sFiOPbAADDVTPJnh+9g==} - - punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} - - pure-rand@6.1.0: - resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} - - queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - - quick-lru@4.0.1: - resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} - engines: {node: '>=8'} - - react-dom@18.3.1: - resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} - peerDependencies: - react: ^18.3.1 - - react-error-boundary@3.1.4: - resolution: {integrity: sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==} - engines: {node: '>=10', npm: '>=6'} - peerDependencies: - react: '>=16.13.1' - - react-hook-form@7.63.0: - resolution: {integrity: sha512-ZwueDMvUeucovM2VjkCf7zIHcs1aAlDimZu2Hvel5C5907gUzMpm4xCrQXtRzCvsBqFjonB4m3x4LzCFI1ZKWA==} - engines: {node: '>=18.0.0'} - peerDependencies: - react: ^16.8.0 || ^17 || ^18 || ^19 - - react-is@16.13.1: - resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} - - react-is@17.0.2: - resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} - - react-is@18.3.1: - resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} - - react-markdown@9.1.0: - resolution: {integrity: sha512-xaijuJB0kzGiUdG7nc2MOMDUDBWPyGAjZtUrow9XxUeua8IqeP+VlIfAZ3bphpcLTnSZXz6z9jcVC/TCwbfgdw==} - peerDependencies: - '@types/react': '>=18' - react: '>=18' - - react-remove-scroll-bar@2.3.8: - resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - - react-remove-scroll@2.7.1: - resolution: {integrity: sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - react-style-singleton@2.2.3: - resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - react-syntax-highlighter@15.6.6: - resolution: {integrity: sha512-DgXrc+AZF47+HvAPEmn7Ua/1p10jNoVZVI/LoPiYdtY+OM+/nG5yefLHKJwdKqY1adMuHFbeyBaG9j64ML7vTw==} - peerDependencies: - react: '>= 0.14.0' - - react@18.3.1: - resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} - engines: {node: '>=0.10.0'} - - read-cache@1.0.0: - resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} - - read-cmd-shim@4.0.0: - resolution: {integrity: sha512-yILWifhaSEEytfXI76kB9xEEiG1AiozaCJZ83A87ytjRiN+jVibXjedjCRNjoZviinhG+4UkalO3mWTd8u5O0Q==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - read-package-json-fast@3.0.2: - resolution: {integrity: sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - read-pkg-up@3.0.0: - resolution: {integrity: sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==} - engines: {node: '>=4'} - - read-pkg-up@7.0.1: - resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} - engines: {node: '>=8'} - - read-pkg@3.0.0: - resolution: {integrity: sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==} - engines: {node: '>=4'} - - read-pkg@5.2.0: - resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} - engines: {node: '>=8'} - - read@3.0.1: - resolution: {integrity: sha512-SLBrDU/Srs/9EoWhU5GdbAoxG1GzpQHo/6qiGItaoLJ1thmYpcNIM1qISEUvyHBzfGlWIyd6p2DNi1oV1VmAuw==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - readable-stream@2.3.8: - resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} - - readable-stream@3.6.2: - resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} - engines: {node: '>= 6'} - - readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} - - redent@3.0.0: - resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} - engines: {node: '>=8'} - - reflect.getprototypeof@1.0.10: - resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} - engines: {node: '>= 0.4'} - - refractor@3.6.0: - resolution: {integrity: sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==} - - regexp.prototype.flags@1.5.4: - resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} - engines: {node: '>= 0.4'} - - remark-gfm@4.0.1: - resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} - - remark-parse@11.0.0: - resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} - - remark-rehype@11.1.2: - resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==} - - remark-stringify@11.0.0: - resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} - - remark@15.0.1: - resolution: {integrity: sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A==} - - remove-accents@0.5.0: - resolution: {integrity: sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==} - - require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - - resolve-cwd@3.0.0: - resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} - engines: {node: '>=8'} - - resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - - resolve-from@5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} - - resolve-pkg-maps@1.0.0: - resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - - resolve.exports@2.0.3: - resolution: {integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==} - engines: {node: '>=10'} - - resolve@1.22.10: - resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} - engines: {node: '>= 0.4'} - hasBin: true - - resolve@2.0.0-next.5: - resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} - hasBin: true - - restore-cursor@3.1.0: - resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} - engines: {node: '>=8'} - - retry@0.12.0: - resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} - engines: {node: '>= 4'} - - rettime@0.7.0: - resolution: {integrity: sha512-LPRKoHnLKd/r3dVxcwO7vhCW+orkOGj9ViueosEBK6ie89CijnfRlhaDhHq/3Hxu4CkWQtxwlBG0mzTQY6uQjw==} - - reusify@1.1.0: - resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - - rimraf@3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - deprecated: Rimraf versions prior to v4 are no longer supported - hasBin: true - - rimraf@4.4.1: - resolution: {integrity: sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==} - engines: {node: '>=14'} - hasBin: true - - rrweb-cssom@0.8.0: - resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==} - - run-async@2.4.1: - resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} - engines: {node: '>=0.12.0'} - - run-async@3.0.0: - resolution: {integrity: sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==} - engines: {node: '>=0.12.0'} - - run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - - rxjs@7.8.2: - resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} - - safe-array-concat@1.1.3: - resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} - engines: {node: '>=0.4'} - - safe-buffer@5.1.2: - resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} - - safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - - safe-push-apply@1.0.0: - resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} - engines: {node: '>= 0.4'} - - safe-regex-test@1.1.0: - resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} - engines: {node: '>= 0.4'} - - safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - - saxes@6.0.0: - resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} - engines: {node: '>=v12.22.7'} - - scheduler@0.23.2: - resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} - - schema-sdk@0.11.3: - resolution: {integrity: sha512-clsw2kq2jkXAEhVw7qc1vV1xVBNUSbDc9OqhxU69XlKtiZaOfjz1viPB1FAFW4vFBM98YTzKNDDPA/jEh5Rr8A==} - - schema-sdk@0.15.0: - resolution: {integrity: sha512-O7FFduWsrdjUew42oQ1cj66ckW5ElYB0iX+khV8f1W5Q7pC3cCCcPK7meH7EypEQEOHENTrW/kWziCX/dR9Mbg==} - - schema-typescript@0.12.1: - resolution: {integrity: sha512-dgfQrLjqsXEAC7vZ3fJDBsIPpUDJ2SrzuQFvXslrEjVjOSQyVykBua2tNmM4uFn4uIL7K3Ux64pXbaUnngkhhw==} - - section-matter@1.0.0: - resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} - engines: {node: '>=4'} - - semver@5.7.2: - resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} - hasBin: true - - semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} - hasBin: true - - semver@7.7.2: - resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} - engines: {node: '>=10'} - hasBin: true - - set-blocking@2.0.0: - resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} - - set-function-length@1.2.2: - resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} - engines: {node: '>= 0.4'} - - set-function-name@2.0.2: - resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} - engines: {node: '>= 0.4'} - - set-proto@1.0.0: - resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} - engines: {node: '>= 0.4'} - - shallow-clone@3.0.1: - resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} - engines: {node: '>=8'} - - sharp@0.34.4: - resolution: {integrity: sha512-FUH39xp3SBPnxWvd5iib1X8XY7J0K0X7d93sie9CJg2PO8/7gmg89Nve6OjItK53/MlAushNNxteBYfM6DEuoA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - side-channel-list@1.0.0: - resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} - engines: {node: '>= 0.4'} - - side-channel-map@1.0.1: - resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} - engines: {node: '>= 0.4'} - - side-channel-weakmap@1.0.2: - resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} - engines: {node: '>= 0.4'} - - side-channel@1.1.0: - resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} - engines: {node: '>= 0.4'} - - signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - - signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} - - sigstore@2.3.1: - resolution: {integrity: sha512-8G+/XDU8wNsJOQS5ysDVO0Etg9/2uA5gR9l4ZwijjlwxBcrU6RPfwi2+jJmbP+Ap1Hlp/nVAaEO4Fj22/SL2gQ==} - engines: {node: ^16.14.0 || >=18.0.0} - - sisteransi@1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - - slash@3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} - - slash@5.1.0: - resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} - engines: {node: '>=14.16'} - - smart-buffer@4.2.0: - resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} - engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} - - socks-proxy-agent@8.0.5: - resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==} - engines: {node: '>= 14'} - - socks@2.8.7: - resolution: {integrity: sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==} - engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} - - sort-keys@2.0.0: - resolution: {integrity: sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg==} - engines: {node: '>=4'} - - source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} - - source-map-support@0.5.13: - resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} - - source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - - space-separated-tokens@1.1.5: - resolution: {integrity: sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==} - - space-separated-tokens@2.0.2: - resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} - - spdx-correct@3.2.0: - resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} - - spdx-exceptions@2.5.0: - resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} - - spdx-expression-parse@3.0.1: - resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} - - spdx-license-ids@3.0.22: - resolution: {integrity: sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==} - - split2@3.2.2: - resolution: {integrity: sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==} - - split2@4.2.0: - resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} - engines: {node: '>= 10.x'} - - split@1.0.1: - resolution: {integrity: sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==} - - sprintf-js@1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - - ssri@10.0.6: - resolution: {integrity: sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - stable-hash@0.0.5: - resolution: {integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==} - - stack-utils@2.0.6: - resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} - engines: {node: '>=10'} - - statuses@2.0.2: - resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} - engines: {node: '>= 0.8'} - - stop-iteration-iterator@1.1.0: - resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} - engines: {node: '>= 0.4'} - - strict-event-emitter@0.5.1: - resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} - - string-length@4.0.2: - resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} - engines: {node: '>=10'} - - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - - string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} - - string.prototype.includes@2.0.1: - resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==} - engines: {node: '>= 0.4'} - - string.prototype.matchall@4.0.12: - resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} - engines: {node: '>= 0.4'} - - string.prototype.repeat@1.0.0: - resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} - - string.prototype.trim@1.2.10: - resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} - engines: {node: '>= 0.4'} - - string.prototype.trimend@1.0.9: - resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} - engines: {node: '>= 0.4'} - - string.prototype.trimstart@1.0.8: - resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} - engines: {node: '>= 0.4'} - - string_decoder@1.1.1: - resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} - - string_decoder@1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} - - stringify-entities@4.0.4: - resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} - - strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - - strip-ansi@7.1.2: - resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} - engines: {node: '>=12'} - - strip-bom-string@1.0.0: - resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} - engines: {node: '>=0.10.0'} - - strip-bom@3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} - - strip-bom@4.0.0: - resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} - engines: {node: '>=8'} - - strip-final-newline@2.0.0: - resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} - engines: {node: '>=6'} - - strip-indent@3.0.0: - resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} - engines: {node: '>=8'} - - strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - - style-to-js@1.1.17: - resolution: {integrity: sha512-xQcBGDxJb6jjFCTzvQtfiPn6YvvP2O8U1MDIPNfJQlWMYfktPy+iGsHE7cssjs7y84d9fQaK4UF3RIJaAHSoYA==} - - style-to-object@1.0.9: - resolution: {integrity: sha512-G4qppLgKu/k6FwRpHiGiKPaPTFcG3g4wNVX/Qsfu+RqQM30E7Tyu/TEgxcL9PNLF5pdRLwQdE3YKKf+KF2Dzlw==} - - styled-jsx@5.1.6: - resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} - engines: {node: '>= 12.0.0'} - peerDependencies: - '@babel/core': '*' - babel-plugin-macros: '*' - react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' - peerDependenciesMeta: - '@babel/core': - optional: true - babel-plugin-macros: - optional: true - - sucrase@3.35.0: - resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} - engines: {node: '>=16 || 14 >=14.17'} - hasBin: true - - supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - - supports-color@8.1.1: - resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} - engines: {node: '>=10'} - - supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - - symbol-tree@3.2.4: - resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} - - tailwind-merge@2.6.0: - resolution: {integrity: sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==} - - tailwindcss-animate@1.0.7: - resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==} - peerDependencies: - tailwindcss: '>=3.0.0 || insiders' - - tailwindcss@3.4.17: - resolution: {integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==} - engines: {node: '>=14.0.0'} - hasBin: true - - tar-stream@2.2.0: - resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} - engines: {node: '>=6'} - - tar@6.2.1: - resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} - engines: {node: '>=10'} - - temp-dir@1.0.0: - resolution: {integrity: sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ==} - engines: {node: '>=4'} - - test-exclude@6.0.0: - resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} - engines: {node: '>=8'} - - text-extensions@1.9.0: - resolution: {integrity: sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==} - engines: {node: '>=0.10'} - - text-table@0.2.0: - resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} - - thenify-all@1.6.0: - resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} - engines: {node: '>=0.8'} - - thenify@3.3.1: - resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} - - through2@2.0.5: - resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} - - through@2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - - tinyglobby@0.2.12: - resolution: {integrity: sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==} - engines: {node: '>=12.0.0'} - - tinyglobby@0.2.15: - resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} - engines: {node: '>=12.0.0'} - - tldts-core@6.1.86: - resolution: {integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==} - - tldts-core@7.0.17: - resolution: {integrity: sha512-DieYoGrP78PWKsrXr8MZwtQ7GLCUeLxihtjC1jZsW1DnvSMdKPitJSe8OSYDM2u5H6g3kWJZpePqkp43TfLh0g==} - - tldts@6.1.86: - resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} - hasBin: true - - tldts@7.0.17: - resolution: {integrity: sha512-Y1KQBgDd/NUc+LfOtKS6mNsC9CCaH+m2P1RoIZy7RAPo3C3/t8X45+zgut31cRZtZ3xKPjfn3TkGTrctC2TQIQ==} - hasBin: true - - tmp@0.2.5: - resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} - engines: {node: '>=14.14'} - - tmpl@1.0.5: - resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} - - to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - - tough-cookie@5.1.2: - resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==} - engines: {node: '>=16'} - - tough-cookie@6.0.0: - resolution: {integrity: sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==} - engines: {node: '>=16'} - - tr46@0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - - tr46@5.1.1: - resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==} - engines: {node: '>=18'} - - treeverse@3.0.0: - resolution: {integrity: sha512-gcANaAnd2QDZFmHFEOF4k7uc1J/6a6z3DJMd/QwEyxLoKGiptJRwid582r7QIsFlFMIZ3SnxfS52S4hm2DHkuQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - trim-lines@3.0.1: - resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} - - trim-newlines@3.0.1: - resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} - engines: {node: '>=8'} - - trough@2.2.0: - resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} - - ts-api-utils@1.4.3: - resolution: {integrity: sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==} - engines: {node: '>=16'} - peerDependencies: - typescript: '>=4.2.0' - - ts-api-utils@2.1.0: - resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} - engines: {node: '>=18.12'} - peerDependencies: - typescript: '>=4.8.4' - - ts-interface-checker@0.1.13: - resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} - - ts-jest@29.4.4: - resolution: {integrity: sha512-ccVcRABct5ZELCT5U0+DZwkXMCcOCLi2doHRrKy1nK/s7J7bch6TzJMsrY09WxgUUIP/ITfmcDS8D2yl63rnXw==} - engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@babel/core': '>=7.0.0-beta.0 <8' - '@jest/transform': ^29.0.0 || ^30.0.0 - '@jest/types': ^29.0.0 || ^30.0.0 - babel-jest: ^29.0.0 || ^30.0.0 - esbuild: '*' - jest: ^29.0.0 || ^30.0.0 - jest-util: ^29.0.0 || ^30.0.0 - typescript: '>=4.3 <6' - peerDependenciesMeta: - '@babel/core': - optional: true - '@jest/transform': - optional: true - '@jest/types': - optional: true - babel-jest: - optional: true - esbuild: - optional: true - jest-util: - optional: true - - ts-node@10.9.2: - resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} - hasBin: true - 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 - - tsconfig-paths@3.15.0: - resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} - - tsconfig-paths@4.2.0: - resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} - engines: {node: '>=6'} - - tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - - tuf-js@2.2.1: - resolution: {integrity: sha512-GwIJau9XaA8nLVbUXsN3IlFi7WmQ48gBUrl3FTkkL/XLu/POhBzfmX9hd33FNMX1qAsfl6ozO1iMmW9NC8YniA==} - engines: {node: ^16.14.0 || >=18.0.0} - - type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} - - type-detect@4.0.8: - resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} - engines: {node: '>=4'} - - type-fest@0.18.1: - resolution: {integrity: sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==} - engines: {node: '>=10'} - - type-fest@0.20.2: - resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} - engines: {node: '>=10'} - - type-fest@0.21.3: - resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} - engines: {node: '>=10'} - - type-fest@0.4.1: - resolution: {integrity: sha512-IwzA/LSfD2vC1/YDYMv/zHP4rDF1usCwllsDpbolT3D4fUepIO7f9K70jjmUewU/LmGUKJcwcVtDCpnKk4BPMw==} - engines: {node: '>=6'} - - type-fest@0.6.0: - resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} - engines: {node: '>=8'} - - type-fest@0.8.1: - resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} - engines: {node: '>=8'} - - type-fest@4.41.0: - resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} - engines: {node: '>=16'} - - typed-array-buffer@1.0.3: - resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} - engines: {node: '>= 0.4'} - - typed-array-byte-length@1.0.3: - resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} - engines: {node: '>= 0.4'} - - typed-array-byte-offset@1.0.4: - resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} - engines: {node: '>= 0.4'} - - typed-array-length@1.0.7: - resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} - engines: {node: '>= 0.4'} - - typedarray@0.0.6: - resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} - - typescript@5.9.2: - resolution: {integrity: sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==} - engines: {node: '>=14.17'} - hasBin: true - - uglify-js@3.19.3: - resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} - engines: {node: '>=0.8.0'} - hasBin: true - - unbox-primitive@1.1.0: - resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} - engines: {node: '>= 0.4'} - - undici-types@6.21.0: - resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - - undici@7.16.0: - resolution: {integrity: sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g==} - engines: {node: '>=20.18.1'} - - unicorn-magic@0.3.0: - resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} - engines: {node: '>=18'} - - unified@11.0.5: - resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} - - unique-filename@3.0.0: - resolution: {integrity: sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - unique-slug@4.0.0: - resolution: {integrity: sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - unist-util-is@6.0.0: - resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} - - unist-util-position@5.0.0: - resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} - - unist-util-stringify-position@4.0.0: - resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} - - unist-util-visit-parents@6.0.1: - resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} - - unist-util-visit@5.0.0: - resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} - - universal-user-agent@6.0.1: - resolution: {integrity: sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==} - - universalify@2.0.1: - resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} - engines: {node: '>= 10.0.0'} - - unrs-resolver@1.11.1: - resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} - - until-async@3.0.2: - resolution: {integrity: sha512-IiSk4HlzAMqTUseHHe3VhIGyuFmN90zMTpD3Z3y8jeQbzLIq500MVM7Jq2vUAnTKAFPJrqwkzr6PoTcPhGcOiw==} - - upath@2.0.1: - resolution: {integrity: sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==} - engines: {node: '>=4'} - - update-browserslist-db@1.1.3: - resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - - uqr@0.1.2: - resolution: {integrity: sha512-MJu7ypHq6QasgF5YRTjqscSzQp/W11zoUk6kvmlH+fmWEs63Y0Eib13hYFwAzagRJcVY8WVnlV+eBDUGMJ5IbA==} - - uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - - use-callback-ref@1.3.3: - resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - use-debounce@10.0.6: - resolution: {integrity: sha512-C5OtPyhAZgVoteO9heXMTdW7v/IbFI+8bSVKYCJrSmiWWCLsbUxiBSp4t9v0hNBTGY97bT72ydDIDyGSFWfwXg==} - engines: {node: '>= 16.0.0'} - peerDependencies: - react: '*' - - use-sidecar@1.1.3: - resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - use-sync-external-store@1.5.0: - resolution: {integrity: sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - - util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - - uuid@10.0.0: - resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} - hasBin: true - - uuid@11.1.0: - resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} - hasBin: true - - v8-compile-cache-lib@3.0.1: - resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} - - v8-to-istanbul@9.3.0: - resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} - engines: {node: '>=10.12.0'} - - validate-npm-package-license@3.0.4: - resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} - - validate-npm-package-name@5.0.1: - resolution: {integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - vfile-message@4.0.3: - resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} - - vfile@6.0.3: - resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} - - w3c-xmlserializer@5.0.0: - resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} - engines: {node: '>=18'} - - walk-up-path@3.0.1: - resolution: {integrity: sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==} - - walker@1.0.8: - resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} - - wcwidth@1.0.1: - resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} - - web-streams-polyfill@3.3.3: - resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} - engines: {node: '>= 8'} - - webidl-conversions@3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - - webidl-conversions@7.0.0: - resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} - engines: {node: '>=12'} - - whatwg-encoding@3.1.1: - resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} - engines: {node: '>=18'} - - whatwg-fetch@3.6.20: - resolution: {integrity: sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==} - - whatwg-mimetype@4.0.0: - resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} - engines: {node: '>=18'} - - whatwg-url@14.2.0: - resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==} - engines: {node: '>=18'} - - whatwg-url@5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} - - which-boxed-primitive@1.1.1: - resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} - engines: {node: '>= 0.4'} - - which-builtin-type@1.2.1: - resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} - engines: {node: '>= 0.4'} - - which-collection@1.0.2: - resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} - engines: {node: '>= 0.4'} - - which-typed-array@1.1.19: - resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} - engines: {node: '>= 0.4'} - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - - which@4.0.0: - resolution: {integrity: sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==} - engines: {node: ^16.13.0 || >=18.0.0} - hasBin: true - - wide-align@1.1.5: - resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} - - word-wrap@1.2.5: - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} - engines: {node: '>=0.10.0'} - - wordwrap@1.0.0: - resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} - - wrap-ansi@6.2.0: - resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} - engines: {node: '>=8'} - - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - - wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} - - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - - write-file-atomic@2.4.3: - resolution: {integrity: sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==} - - write-file-atomic@4.0.2: - resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - - write-file-atomic@5.0.1: - resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - write-json-file@3.2.0: - resolution: {integrity: sha512-3xZqT7Byc2uORAatYiP3DHUUAVEkNOswEWNs9H5KXiicRTvzYzYqKjYc4G7p+8pltvAw641lVByKVtMpf+4sYQ==} - engines: {node: '>=6'} - - write-pkg@4.0.0: - resolution: {integrity: sha512-v2UQ+50TNf2rNHJ8NyWttfm/EJUBWMJcx6ZTYZr6Qp52uuegWw/lBkCtCbnYZEmPRNL61m+u67dAmGxo+HTULA==} - engines: {node: '>=8'} - - ws@8.18.3: - resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - - xml-name-validator@5.0.0: - resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} - engines: {node: '>=18'} - - xmlchars@2.2.0: - resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} - - xtend@4.0.2: - resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} - engines: {node: '>=0.4'} - - y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - - yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - - yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - - yaml@2.8.1: - resolution: {integrity: sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==} - engines: {node: '>= 14.6'} - hasBin: true - - yargs-parser@20.2.9: - resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} - engines: {node: '>=10'} - - yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} - - yargs@16.2.0: - resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} - engines: {node: '>=10'} - - yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} - - yn@3.1.1: - resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} - engines: {node: '>=6'} - - yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - - yoctocolors-cjs@2.1.3: - resolution: {integrity: sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==} - engines: {node: '>=18'} - - zwitch@2.0.4: - resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} - -snapshots: - - '@adobe/css-tools@4.4.4': {} - - '@agentic-kit/bradie@0.1.2(encoding@0.1.13)': - dependencies: - cross-fetch: 4.1.0(encoding@0.1.13) - transitivePeerDependencies: - - encoding - - '@agentic-kit/ollama@0.1.2(encoding@0.1.13)': - dependencies: - cross-fetch: 4.1.0(encoding@0.1.13) - transitivePeerDependencies: - - encoding - - '@alloc/quick-lru@5.2.0': {} - - '@ark-ui/react@5.25.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@internationalized/date': 3.9.0 - '@zag-js/accordion': 1.24.1 - '@zag-js/anatomy': 1.24.1 - '@zag-js/angle-slider': 1.24.1 - '@zag-js/async-list': 1.24.1 - '@zag-js/auto-resize': 1.24.1 - '@zag-js/avatar': 1.24.1 - '@zag-js/carousel': 1.24.1 - '@zag-js/checkbox': 1.24.1 - '@zag-js/clipboard': 1.24.1 - '@zag-js/collapsible': 1.24.1 - '@zag-js/collection': 1.24.1 - '@zag-js/color-picker': 1.24.1 - '@zag-js/color-utils': 1.24.1 - '@zag-js/combobox': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/date-picker': 1.24.1(@internationalized/date@3.9.0) - '@zag-js/date-utils': 1.24.1(@internationalized/date@3.9.0) - '@zag-js/dialog': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/editable': 1.24.1 - '@zag-js/file-upload': 1.24.1 - '@zag-js/file-utils': 1.24.1 - '@zag-js/floating-panel': 1.24.1 - '@zag-js/focus-trap': 1.24.1 - '@zag-js/highlight-word': 1.24.1 - '@zag-js/hover-card': 1.24.1 - '@zag-js/i18n-utils': 1.24.1 - '@zag-js/json-tree-utils': 1.24.1 - '@zag-js/listbox': 1.24.1 - '@zag-js/menu': 1.24.1 - '@zag-js/number-input': 1.24.1 - '@zag-js/pagination': 1.24.1 - '@zag-js/password-input': 1.24.1 - '@zag-js/pin-input': 1.24.1 - '@zag-js/popover': 1.24.1 - '@zag-js/presence': 1.24.1 - '@zag-js/progress': 1.24.1 - '@zag-js/qr-code': 1.24.1 - '@zag-js/radio-group': 1.24.1 - '@zag-js/rating-group': 1.24.1 - '@zag-js/react': 1.24.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@zag-js/scroll-area': 1.24.1 - '@zag-js/select': 1.24.1 - '@zag-js/signature-pad': 1.24.1 - '@zag-js/slider': 1.24.1 - '@zag-js/splitter': 1.24.1 - '@zag-js/steps': 1.24.1 - '@zag-js/switch': 1.24.1 - '@zag-js/tabs': 1.24.1 - '@zag-js/tags-input': 1.24.1 - '@zag-js/timer': 1.24.1 - '@zag-js/toast': 1.24.1 - '@zag-js/toggle': 1.24.1 - '@zag-js/toggle-group': 1.24.1 - '@zag-js/tooltip': 1.24.1 - '@zag-js/tour': 1.24.1 - '@zag-js/tree-view': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - '@asamuzakjp/css-color@3.2.0': - dependencies: - '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) - '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) - '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) - '@csstools/css-tokenizer': 3.0.4 - lru-cache: 10.4.3 - - '@babel/code-frame@7.27.1': - dependencies: - '@babel/helper-validator-identifier': 7.27.1 - js-tokens: 4.0.0 - picocolors: 1.1.1 - - '@babel/compat-data@7.28.4': {} - - '@babel/core@7.28.4': - dependencies: - '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.3 - '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.4) - '@babel/helpers': 7.28.4 - '@babel/parser': 7.28.4 - '@babel/template': 7.27.2 - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.4 - '@jridgewell/remapping': 2.3.5 - convert-source-map: 2.0.0 - debug: 4.4.3 - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - '@babel/generator@7.28.3': - dependencies: - '@babel/parser': 7.28.4 - '@babel/types': 7.28.4 - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - jsesc: 3.1.0 - - '@babel/helper-annotate-as-pure@7.27.3': - dependencies: - '@babel/types': 7.28.4 - - '@babel/helper-compilation-targets@7.27.2': - dependencies: - '@babel/compat-data': 7.28.4 - '@babel/helper-validator-option': 7.27.1 - browserslist: 4.26.2 - lru-cache: 5.1.1 - semver: 6.3.1 - - '@babel/helper-create-class-features-plugin@7.28.3(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-member-expression-to-functions': 7.27.1 - '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.4) - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/traverse': 7.28.4 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - '@babel/helper-globals@7.28.0': {} - - '@babel/helper-member-expression-to-functions@7.27.1': - dependencies: - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.4 - transitivePeerDependencies: - - supports-color - - '@babel/helper-module-imports@7.27.1': - dependencies: - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.4 - transitivePeerDependencies: - - supports-color - - '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-module-imports': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 - '@babel/traverse': 7.28.4 - transitivePeerDependencies: - - supports-color - - '@babel/helper-optimise-call-expression@7.27.1': - dependencies: - '@babel/types': 7.28.4 - - '@babel/helper-plugin-utils@7.27.1': {} - - '@babel/helper-replace-supers@7.27.1(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-member-expression-to-functions': 7.27.1 - '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/traverse': 7.28.4 - transitivePeerDependencies: - - supports-color - - '@babel/helper-skip-transparent-expression-wrappers@7.27.1': - dependencies: - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.4 - transitivePeerDependencies: - - supports-color - - '@babel/helper-string-parser@7.27.1': {} - - '@babel/helper-validator-identifier@7.27.1': {} - - '@babel/helper-validator-option@7.27.1': {} - - '@babel/helpers@7.28.4': - dependencies: - '@babel/template': 7.27.2 - '@babel/types': 7.28.4 - - '@babel/parser@7.28.4': - dependencies: - '@babel/types': 7.28.4 - - '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.4) - '@babel/helper-plugin-utils': 7.27.1 - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-typescript@7.28.0(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.4) - '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.4) - transitivePeerDependencies: - - supports-color - - '@babel/preset-typescript@7.27.1(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-typescript': 7.28.0(@babel/core@7.28.4) - transitivePeerDependencies: - - supports-color - - '@babel/runtime@7.28.4': {} - - '@babel/template@7.27.2': - dependencies: - '@babel/code-frame': 7.27.1 - '@babel/parser': 7.28.4 - '@babel/types': 7.28.4 - - '@babel/traverse@7.28.4': - dependencies: - '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.3 - '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.28.4 - '@babel/template': 7.27.2 - '@babel/types': 7.28.4 - debug: 4.4.3 - transitivePeerDependencies: - - supports-color - - '@babel/types@7.28.4': - dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 - - '@bcoe/v8-coverage@0.2.3': {} - - '@cspotcode/source-map-support@0.8.1': - dependencies: - '@jridgewell/trace-mapping': 0.3.9 - - '@csstools/color-helpers@5.1.0': {} - - '@csstools/css-calc@2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': - dependencies: - '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) - '@csstools/css-tokenizer': 3.0.4 - - '@csstools/css-color-parser@3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': - dependencies: - '@csstools/color-helpers': 5.1.0 - '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) - '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) - '@csstools/css-tokenizer': 3.0.4 - - '@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4)': - dependencies: - '@csstools/css-tokenizer': 3.0.4 - - '@csstools/css-tokenizer@3.0.4': {} - - '@emnapi/core@1.5.0': - dependencies: - '@emnapi/wasi-threads': 1.1.0 - tslib: 2.8.1 - - '@emnapi/runtime@1.5.0': - dependencies: - tslib: 2.8.1 - - '@emnapi/wasi-threads@1.1.0': - dependencies: - tslib: 2.8.1 - - '@eslint-community/eslint-utils@4.9.0(eslint@8.57.1)': - dependencies: - eslint: 8.57.1 - eslint-visitor-keys: 3.4.3 - - '@eslint-community/regexpp@4.12.1': {} - - '@eslint/eslintrc@2.1.4': - dependencies: - ajv: 6.12.6 - debug: 4.4.3 - espree: 9.6.1 - globals: 13.24.0 - ignore: 5.3.2 - import-fresh: 3.3.1 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - - '@eslint/js@8.57.1': {} - - '@eslint/js@9.36.0': {} - - '@floating-ui/core@1.7.3': - dependencies: - '@floating-ui/utils': 0.2.10 - - '@floating-ui/dom@1.7.4': - dependencies: - '@floating-ui/core': 1.7.3 - '@floating-ui/utils': 0.2.10 - - '@floating-ui/react-dom@2.1.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@floating-ui/dom': 1.7.4 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - '@floating-ui/utils@0.2.10': {} - - '@humanwhocodes/config-array@0.13.0': - dependencies: - '@humanwhocodes/object-schema': 2.0.3 - debug: 4.4.3 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - - '@humanwhocodes/module-importer@1.0.1': {} - - '@humanwhocodes/object-schema@2.0.3': {} - - '@hutson/parse-repository-url@3.0.2': {} - - '@img/colour@1.0.0': - optional: true - - '@img/sharp-darwin-arm64@0.34.4': - optionalDependencies: - '@img/sharp-libvips-darwin-arm64': 1.2.3 - optional: true - - '@img/sharp-darwin-x64@0.34.4': - optionalDependencies: - '@img/sharp-libvips-darwin-x64': 1.2.3 - optional: true - - '@img/sharp-libvips-darwin-arm64@1.2.3': - optional: true - - '@img/sharp-libvips-darwin-x64@1.2.3': - optional: true - - '@img/sharp-libvips-linux-arm64@1.2.3': - optional: true - - '@img/sharp-libvips-linux-arm@1.2.3': - optional: true - - '@img/sharp-libvips-linux-ppc64@1.2.3': - optional: true - - '@img/sharp-libvips-linux-s390x@1.2.3': - optional: true - - '@img/sharp-libvips-linux-x64@1.2.3': - optional: true - - '@img/sharp-libvips-linuxmusl-arm64@1.2.3': - optional: true - - '@img/sharp-libvips-linuxmusl-x64@1.2.3': - optional: true - - '@img/sharp-linux-arm64@0.34.4': - optionalDependencies: - '@img/sharp-libvips-linux-arm64': 1.2.3 - optional: true - - '@img/sharp-linux-arm@0.34.4': - optionalDependencies: - '@img/sharp-libvips-linux-arm': 1.2.3 - optional: true - - '@img/sharp-linux-ppc64@0.34.4': - optionalDependencies: - '@img/sharp-libvips-linux-ppc64': 1.2.3 - optional: true - - '@img/sharp-linux-s390x@0.34.4': - optionalDependencies: - '@img/sharp-libvips-linux-s390x': 1.2.3 - optional: true - - '@img/sharp-linux-x64@0.34.4': - optionalDependencies: - '@img/sharp-libvips-linux-x64': 1.2.3 - optional: true - - '@img/sharp-linuxmusl-arm64@0.34.4': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-arm64': 1.2.3 - optional: true - - '@img/sharp-linuxmusl-x64@0.34.4': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-x64': 1.2.3 - optional: true - - '@img/sharp-wasm32@0.34.4': - dependencies: - '@emnapi/runtime': 1.5.0 - optional: true - - '@img/sharp-win32-arm64@0.34.4': - optional: true - - '@img/sharp-win32-ia32@0.34.4': - optional: true - - '@img/sharp-win32-x64@0.34.4': - optional: true - - '@inquirer/ansi@1.0.0': {} - - '@inquirer/confirm@5.1.18(@types/node@20.19.17)': - dependencies: - '@inquirer/core': 10.2.2(@types/node@20.19.17) - '@inquirer/type': 3.0.8(@types/node@20.19.17) - optionalDependencies: - '@types/node': 20.19.17 - - '@inquirer/core@10.2.2(@types/node@20.19.17)': - dependencies: - '@inquirer/ansi': 1.0.0 - '@inquirer/figures': 1.0.13 - '@inquirer/type': 3.0.8(@types/node@20.19.17) - cli-width: 4.1.0 - mute-stream: 2.0.0 - signal-exit: 4.1.0 - wrap-ansi: 6.2.0 - yoctocolors-cjs: 2.1.3 - optionalDependencies: - '@types/node': 20.19.17 - - '@inquirer/external-editor@1.0.2(@types/node@22.18.6)': - dependencies: - chardet: 2.1.0 - iconv-lite: 0.7.0 - optionalDependencies: - '@types/node': 22.18.6 - - '@inquirer/figures@1.0.13': {} - - '@inquirer/type@3.0.8(@types/node@20.19.17)': - optionalDependencies: - '@types/node': 20.19.17 - - '@internationalized/date@3.9.0': - dependencies: - '@swc/helpers': 0.5.17 - - '@internationalized/number@3.6.5': - dependencies: - '@swc/helpers': 0.5.17 - - '@interweb-utils/casing@0.2.0': {} - - '@interweb/fetch-api-client@0.6.1(encoding@0.1.13)': - dependencies: - '@interweb/http-errors': 0.1.1 - isomorphic-fetch: 3.0.0(encoding@0.1.13) - transitivePeerDependencies: - - encoding - - '@interweb/http-errors@0.1.1': {} - - '@isaacs/cliui@8.0.2': - dependencies: - string-width: 5.1.2 - string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.2 - strip-ansi-cjs: strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: wrap-ansi@7.0.0 - - '@isaacs/string-locale-compare@1.1.0': {} - - '@istanbuljs/load-nyc-config@1.1.0': - dependencies: - camelcase: 5.3.1 - find-up: 4.1.0 - get-package-type: 0.1.0 - js-yaml: 3.14.1 - resolve-from: 5.0.0 - - '@istanbuljs/schema@0.1.3': {} - - '@jest/console@29.7.0': - dependencies: - '@jest/types': 29.6.3 - '@types/node': 22.18.6 - chalk: 4.1.2 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - slash: 3.0.0 - - '@jest/core@29.7.0(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@20.19.17)(typescript@5.9.2))': - dependencies: - '@jest/console': 29.7.0 - '@jest/reporters': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 22.18.6 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - ci-info: 3.9.0 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@22.18.6)(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@20.19.17)(typescript@5.9.2)) - jest-haste-map: 29.7.0 - jest-message-util: 29.7.0 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-resolve-dependencies: 29.7.0 - jest-runner: 29.7.0 - jest-runtime: 29.7.0 - jest-snapshot: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 - jest-watcher: 29.7.0 - micromatch: 4.0.8 - pretty-format: 29.7.0 - slash: 3.0.0 - strip-ansi: 6.0.1 - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - ts-node - - '@jest/core@29.7.0(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@22.18.6)(typescript@5.9.2))': - dependencies: - '@jest/console': 29.7.0 - '@jest/reporters': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 22.18.6 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - ci-info: 3.9.0 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@22.18.6)(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@22.18.6)(typescript@5.9.2)) - jest-haste-map: 29.7.0 - jest-message-util: 29.7.0 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-resolve-dependencies: 29.7.0 - jest-runner: 29.7.0 - jest-runtime: 29.7.0 - jest-snapshot: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 - jest-watcher: 29.7.0 - micromatch: 4.0.8 - pretty-format: 29.7.0 - slash: 3.0.0 - strip-ansi: 6.0.1 - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - ts-node - - '@jest/environment-jsdom-abstract@30.2.0(jsdom@26.1.0)': - dependencies: - '@jest/environment': 30.2.0 - '@jest/fake-timers': 30.2.0 - '@jest/types': 30.2.0 - '@types/jsdom': 21.1.7 - '@types/node': 22.18.6 - jest-mock: 30.2.0 - jest-util: 30.2.0 - jsdom: 26.1.0 - - '@jest/environment@29.7.0': - dependencies: - '@jest/fake-timers': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 22.18.6 - jest-mock: 29.7.0 - - '@jest/environment@30.2.0': - dependencies: - '@jest/fake-timers': 30.2.0 - '@jest/types': 30.2.0 - '@types/node': 22.18.6 - jest-mock: 30.2.0 - - '@jest/expect-utils@29.7.0': - dependencies: - jest-get-type: 29.6.3 - - '@jest/expect@29.7.0': - dependencies: - expect: 29.7.0 - jest-snapshot: 29.7.0 - transitivePeerDependencies: - - supports-color - - '@jest/fake-timers@29.7.0': - dependencies: - '@jest/types': 29.6.3 - '@sinonjs/fake-timers': 10.3.0 - '@types/node': 22.18.6 - jest-message-util: 29.7.0 - jest-mock: 29.7.0 - jest-util: 29.7.0 - - '@jest/fake-timers@30.2.0': - dependencies: - '@jest/types': 30.2.0 - '@sinonjs/fake-timers': 13.0.5 - '@types/node': 22.18.6 - jest-message-util: 30.2.0 - jest-mock: 30.2.0 - jest-util: 30.2.0 - - '@jest/globals@29.7.0': - dependencies: - '@jest/environment': 29.7.0 - '@jest/expect': 29.7.0 - '@jest/types': 29.6.3 - jest-mock: 29.7.0 - transitivePeerDependencies: - - supports-color - - '@jest/pattern@30.0.1': - dependencies: - '@types/node': 22.18.6 - jest-regex-util: 30.0.1 - - '@jest/reporters@29.7.0': - dependencies: - '@bcoe/v8-coverage': 0.2.3 - '@jest/console': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@jridgewell/trace-mapping': 0.3.31 - '@types/node': 22.18.6 - chalk: 4.1.2 - collect-v8-coverage: 1.0.2 - exit: 0.1.2 - glob: 7.2.3 - graceful-fs: 4.2.11 - istanbul-lib-coverage: 3.2.2 - istanbul-lib-instrument: 6.0.3 - istanbul-lib-report: 3.0.1 - istanbul-lib-source-maps: 4.0.1 - istanbul-reports: 3.2.0 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - jest-worker: 29.7.0 - slash: 3.0.0 - string-length: 4.0.2 - strip-ansi: 6.0.1 - v8-to-istanbul: 9.3.0 - transitivePeerDependencies: - - supports-color - - '@jest/schemas@29.6.3': - dependencies: - '@sinclair/typebox': 0.27.8 - - '@jest/schemas@30.0.5': - dependencies: - '@sinclair/typebox': 0.34.41 - - '@jest/source-map@29.6.3': - dependencies: - '@jridgewell/trace-mapping': 0.3.31 - callsites: 3.1.0 - graceful-fs: 4.2.11 - - '@jest/test-result@29.7.0': - dependencies: - '@jest/console': 29.7.0 - '@jest/types': 29.6.3 - '@types/istanbul-lib-coverage': 2.0.6 - collect-v8-coverage: 1.0.2 - - '@jest/test-sequencer@29.7.0': - dependencies: - '@jest/test-result': 29.7.0 - graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - slash: 3.0.0 - - '@jest/transform@29.7.0': - dependencies: - '@babel/core': 7.28.4 - '@jest/types': 29.6.3 - '@jridgewell/trace-mapping': 0.3.31 - babel-plugin-istanbul: 6.1.1 - chalk: 4.1.2 - convert-source-map: 2.0.0 - fast-json-stable-stringify: 2.1.0 - graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - jest-regex-util: 29.6.3 - jest-util: 29.7.0 - micromatch: 4.0.8 - pirates: 4.0.7 - slash: 3.0.0 - write-file-atomic: 4.0.2 - transitivePeerDependencies: - - supports-color - - '@jest/types@29.6.3': - dependencies: - '@jest/schemas': 29.6.3 - '@types/istanbul-lib-coverage': 2.0.6 - '@types/istanbul-reports': 3.0.4 - '@types/node': 22.18.6 - '@types/yargs': 17.0.33 - chalk: 4.1.2 - - '@jest/types@30.2.0': - dependencies: - '@jest/pattern': 30.0.1 - '@jest/schemas': 30.0.5 - '@types/istanbul-lib-coverage': 2.0.6 - '@types/istanbul-reports': 3.0.4 - '@types/node': 22.18.6 - '@types/yargs': 17.0.33 - chalk: 4.1.2 - - '@jridgewell/gen-mapping@0.3.13': - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.31 - - '@jridgewell/remapping@2.3.5': - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/sourcemap-codec@1.5.5': {} - - '@jridgewell/trace-mapping@0.3.31': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 - - '@jridgewell/trace-mapping@0.3.9': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 - - '@lerna/create@8.2.4(@swc/core@1.13.19(@swc/helpers@0.5.17))(@types/node@22.18.6)(encoding@0.1.13)(typescript@5.9.2)': - dependencies: - '@npmcli/arborist': 7.5.4 - '@npmcli/package-json': 5.2.0 - '@npmcli/run-script': 8.1.0 - '@nx/devkit': 20.8.2(nx@20.8.2(@swc/core@1.13.19(@swc/helpers@0.5.17))) - '@octokit/plugin-enterprise-rest': 6.0.1 - '@octokit/rest': 20.1.2 - aproba: 2.0.0 - byte-size: 8.1.1 - chalk: 4.1.0 - clone-deep: 4.0.1 - cmd-shim: 6.0.3 - color-support: 1.1.3 - columnify: 1.6.0 - console-control-strings: 1.1.0 - conventional-changelog-core: 5.0.1 - conventional-recommended-bump: 7.0.1 - cosmiconfig: 9.0.0(typescript@5.9.2) - dedent: 1.5.3 - execa: 5.0.0 - fs-extra: 11.3.2 - get-stream: 6.0.0 - git-url-parse: 14.0.0 - glob-parent: 6.0.2 - graceful-fs: 4.2.11 - has-unicode: 2.0.1 - ini: 1.3.8 - init-package-json: 6.0.3 - inquirer: 8.2.7(@types/node@22.18.6) - is-ci: 3.0.1 - is-stream: 2.0.0 - js-yaml: 4.1.0 - libnpmpublish: 9.0.9 - load-json-file: 6.2.0 - make-dir: 4.0.0 - minimatch: 3.0.5 - multimatch: 5.0.0 - node-fetch: 2.6.7(encoding@0.1.13) - npm-package-arg: 11.0.2 - npm-packlist: 8.0.2 - npm-registry-fetch: 17.1.0 - nx: 20.8.2(@swc/core@1.13.19(@swc/helpers@0.5.17)) - p-map: 4.0.0 - p-map-series: 2.1.0 - p-queue: 6.6.2 - p-reduce: 2.1.0 - pacote: 18.0.6 - pify: 5.0.0 - read-cmd-shim: 4.0.0 - resolve-from: 5.0.0 - rimraf: 4.4.1 - semver: 7.7.2 - set-blocking: 2.0.0 - signal-exit: 3.0.7 - slash: 3.0.0 - ssri: 10.0.6 - string-width: 4.2.3 - tar: 6.2.1 - temp-dir: 1.0.0 - through: 2.3.8 - tinyglobby: 0.2.12 - upath: 2.0.1 - uuid: 10.0.0 - validate-npm-package-license: 3.0.4 - validate-npm-package-name: 5.0.1 - wide-align: 1.1.5 - write-file-atomic: 5.0.1 - write-pkg: 4.0.0 - yargs: 17.7.2 - yargs-parser: 21.1.1 - transitivePeerDependencies: - - '@swc-node/register' - - '@swc/core' - - '@types/node' - - babel-plugin-macros - - bluebird - - debug - - encoding - - supports-color - - typescript - - '@mswjs/interceptors@0.39.7': - dependencies: - '@open-draft/deferred-promise': 2.2.0 - '@open-draft/logger': 0.3.0 - '@open-draft/until': 2.1.0 - is-node-process: 1.2.0 - outvariant: 1.4.3 - strict-event-emitter: 0.5.1 - - '@napi-rs/wasm-runtime@0.2.12': - dependencies: - '@emnapi/core': 1.5.0 - '@emnapi/runtime': 1.5.0 - '@tybys/wasm-util': 0.10.1 - optional: true - - '@napi-rs/wasm-runtime@0.2.4': - dependencies: - '@emnapi/core': 1.5.0 - '@emnapi/runtime': 1.5.0 - '@tybys/wasm-util': 0.9.0 - - '@next/env@15.5.4': {} - - '@next/eslint-plugin-next@14.1.0': - dependencies: - glob: 10.3.10 - - '@next/swc-darwin-arm64@15.5.4': - optional: true - - '@next/swc-darwin-x64@15.5.4': - optional: true - - '@next/swc-linux-arm64-gnu@15.5.4': - optional: true - - '@next/swc-linux-arm64-musl@15.5.4': - optional: true - - '@next/swc-linux-x64-gnu@15.5.4': - optional: true - - '@next/swc-linux-x64-musl@15.5.4': - optional: true - - '@next/swc-win32-arm64-msvc@15.5.4': - optional: true - - '@next/swc-win32-x64-msvc@15.5.4': - optional: true - - '@nodelib/fs.scandir@2.1.5': - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - - '@nodelib/fs.stat@2.0.5': {} - - '@nodelib/fs.walk@1.2.8': - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.19.1 - - '@nolyfill/is-core-module@1.0.39': {} - - '@npmcli/agent@2.2.2': - dependencies: - agent-base: 7.1.4 - http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.6 - lru-cache: 10.4.3 - socks-proxy-agent: 8.0.5 - transitivePeerDependencies: - - supports-color - - '@npmcli/arborist@7.5.4': - dependencies: - '@isaacs/string-locale-compare': 1.1.0 - '@npmcli/fs': 3.1.1 - '@npmcli/installed-package-contents': 2.1.0 - '@npmcli/map-workspaces': 3.0.6 - '@npmcli/metavuln-calculator': 7.1.1 - '@npmcli/name-from-folder': 2.0.0 - '@npmcli/node-gyp': 3.0.0 - '@npmcli/package-json': 5.2.0 - '@npmcli/query': 3.1.0 - '@npmcli/redact': 2.0.1 - '@npmcli/run-script': 8.1.0 - bin-links: 4.0.4 - cacache: 18.0.4 - common-ancestor-path: 1.0.1 - hosted-git-info: 7.0.2 - json-parse-even-better-errors: 3.0.2 - json-stringify-nice: 1.1.4 - lru-cache: 10.4.3 - minimatch: 9.0.5 - nopt: 7.2.1 - npm-install-checks: 6.3.0 - npm-package-arg: 11.0.2 - npm-pick-manifest: 9.1.0 - npm-registry-fetch: 17.1.0 - pacote: 18.0.6 - parse-conflict-json: 3.0.1 - proc-log: 4.2.0 - proggy: 2.0.0 - promise-all-reject-late: 1.0.1 - promise-call-limit: 3.0.2 - read-package-json-fast: 3.0.2 - semver: 7.7.2 - ssri: 10.0.6 - treeverse: 3.0.0 - walk-up-path: 3.0.1 - transitivePeerDependencies: - - bluebird - - supports-color - - '@npmcli/fs@3.1.1': - dependencies: - semver: 7.7.2 - - '@npmcli/git@5.0.8': - dependencies: - '@npmcli/promise-spawn': 7.0.2 - ini: 4.1.3 - lru-cache: 10.4.3 - npm-pick-manifest: 9.1.0 - proc-log: 4.2.0 - promise-inflight: 1.0.1 - promise-retry: 2.0.1 - semver: 7.7.2 - which: 4.0.0 - transitivePeerDependencies: - - bluebird - - '@npmcli/installed-package-contents@2.1.0': - dependencies: - npm-bundled: 3.0.1 - npm-normalize-package-bin: 3.0.1 - - '@npmcli/map-workspaces@3.0.6': - dependencies: - '@npmcli/name-from-folder': 2.0.0 - glob: 10.4.5 - minimatch: 9.0.5 - read-package-json-fast: 3.0.2 - - '@npmcli/metavuln-calculator@7.1.1': - dependencies: - cacache: 18.0.4 - json-parse-even-better-errors: 3.0.2 - pacote: 18.0.6 - proc-log: 4.2.0 - semver: 7.7.2 - transitivePeerDependencies: - - bluebird - - supports-color - - '@npmcli/name-from-folder@2.0.0': {} - - '@npmcli/node-gyp@3.0.0': {} - - '@npmcli/package-json@5.2.0': - dependencies: - '@npmcli/git': 5.0.8 - glob: 10.4.5 - hosted-git-info: 7.0.2 - json-parse-even-better-errors: 3.0.2 - normalize-package-data: 6.0.2 - proc-log: 4.2.0 - semver: 7.7.2 - transitivePeerDependencies: - - bluebird - - '@npmcli/promise-spawn@7.0.2': - dependencies: - which: 4.0.0 - - '@npmcli/query@3.1.0': - dependencies: - postcss-selector-parser: 6.1.2 - - '@npmcli/redact@2.0.1': {} - - '@npmcli/run-script@8.1.0': - dependencies: - '@npmcli/node-gyp': 3.0.0 - '@npmcli/package-json': 5.2.0 - '@npmcli/promise-spawn': 7.0.2 - node-gyp: 10.3.1 - proc-log: 4.2.0 - which: 4.0.0 - transitivePeerDependencies: - - bluebird - - supports-color - - '@nx/devkit@20.8.2(nx@20.8.2(@swc/core@1.13.19(@swc/helpers@0.5.17)))': - dependencies: - ejs: 3.1.10 - enquirer: 2.3.6 - ignore: 5.3.2 - minimatch: 9.0.3 - nx: 20.8.2(@swc/core@1.13.19(@swc/helpers@0.5.17)) - semver: 7.7.2 - tmp: 0.2.5 - tslib: 2.8.1 - yargs-parser: 21.1.1 - - '@nx/nx-darwin-arm64@20.8.2': - optional: true - - '@nx/nx-darwin-x64@20.8.2': - optional: true - - '@nx/nx-freebsd-x64@20.8.2': - optional: true - - '@nx/nx-linux-arm-gnueabihf@20.8.2': - optional: true - - '@nx/nx-linux-arm64-gnu@20.8.2': - optional: true - - '@nx/nx-linux-arm64-musl@20.8.2': - optional: true - - '@nx/nx-linux-x64-gnu@20.8.2': - optional: true - - '@nx/nx-linux-x64-musl@20.8.2': - optional: true - - '@nx/nx-win32-arm64-msvc@20.8.2': - optional: true - - '@nx/nx-win32-x64-msvc@20.8.2': - optional: true - - '@octokit/auth-token@4.0.0': {} - - '@octokit/core@5.2.2': - dependencies: - '@octokit/auth-token': 4.0.0 - '@octokit/graphql': 7.1.1 - '@octokit/request': 8.4.1 - '@octokit/request-error': 5.1.1 - '@octokit/types': 13.10.0 - before-after-hook: 2.2.3 - universal-user-agent: 6.0.1 - - '@octokit/endpoint@9.0.6': - dependencies: - '@octokit/types': 13.10.0 - universal-user-agent: 6.0.1 - - '@octokit/graphql@7.1.1': - dependencies: - '@octokit/request': 8.4.1 - '@octokit/types': 13.10.0 - universal-user-agent: 6.0.1 - - '@octokit/openapi-types@24.2.0': {} - - '@octokit/plugin-enterprise-rest@6.0.1': {} - - '@octokit/plugin-paginate-rest@11.4.4-cjs.2(@octokit/core@5.2.2)': - dependencies: - '@octokit/core': 5.2.2 - '@octokit/types': 13.10.0 - - '@octokit/plugin-request-log@4.0.1(@octokit/core@5.2.2)': - dependencies: - '@octokit/core': 5.2.2 - - '@octokit/plugin-rest-endpoint-methods@13.3.2-cjs.1(@octokit/core@5.2.2)': - dependencies: - '@octokit/core': 5.2.2 - '@octokit/types': 13.10.0 - - '@octokit/request-error@5.1.1': - dependencies: - '@octokit/types': 13.10.0 - deprecation: 2.3.1 - once: 1.4.0 - - '@octokit/request@8.4.1': - dependencies: - '@octokit/endpoint': 9.0.6 - '@octokit/request-error': 5.1.1 - '@octokit/types': 13.10.0 - universal-user-agent: 6.0.1 - - '@octokit/rest@20.1.2': - dependencies: - '@octokit/core': 5.2.2 - '@octokit/plugin-paginate-rest': 11.4.4-cjs.2(@octokit/core@5.2.2) - '@octokit/plugin-request-log': 4.0.1(@octokit/core@5.2.2) - '@octokit/plugin-rest-endpoint-methods': 13.3.2-cjs.1(@octokit/core@5.2.2) - - '@octokit/types@13.10.0': - dependencies: - '@octokit/openapi-types': 24.2.0 - - '@open-draft/deferred-promise@2.2.0': {} - - '@open-draft/logger@0.3.0': - dependencies: - is-node-process: 1.2.0 - outvariant: 1.4.3 - - '@open-draft/until@2.1.0': {} - - '@pkgjs/parseargs@0.11.0': - optional: true - - '@playwright/test@1.56.1': - dependencies: - playwright: 1.56.1 - - '@radix-ui/number@1.1.1': {} - - '@radix-ui/primitive@1.1.3': {} - - '@radix-ui/react-accordion@1.2.12(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.24)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.24 - '@types/react-dom': 18.3.7(@types/react@18.3.24) - - '@radix-ui/react-alert-dialog@1.1.15(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-dialog': 1.1.15(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.2.3(@types/react@18.3.24)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.24 - '@types/react-dom': 18.3.7(@types/react@18.3.24) - - '@radix-ui/react-arrow@1.1.7(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.24 - '@types/react-dom': 18.3.7(@types/react@18.3.24) - - '@radix-ui/react-avatar@1.1.10(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/react-context': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.24)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.24 - '@types/react-dom': 18.3.7(@types/react@18.3.24) - - '@radix-ui/react-checkbox@1.3.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.1(@types/react@18.3.24)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.24 - '@types/react-dom': 18.3.7(@types/react@18.3.24) - - '@radix-ui/react-collapsible@1.1.12(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.24)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.24 - '@types/react-dom': 18.3.7(@types/react@18.3.24) - - '@radix-ui/react-collection@1.1.7(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.2.3(@types/react@18.3.24)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.24 - '@types/react-dom': 18.3.7(@types/react@18.3.24) - - '@radix-ui/react-compose-refs@1.1.2(@types/react@18.3.24)(react@18.3.1)': - dependencies: - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.24 - - '@radix-ui/react-context-menu@2.2.16(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-context': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-menu': 2.1.16(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.24)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.24 - '@types/react-dom': 18.3.7(@types/react@18.3.24) - - '@radix-ui/react-context@1.1.2(@types/react@18.3.24)(react@18.3.1)': - dependencies: - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.24 - - '@radix-ui/react-dialog@1.1.15(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.2.3(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.24)(react@18.3.1) - aria-hidden: 1.2.6 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.7.1(@types/react@18.3.24)(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.24 - '@types/react-dom': 18.3.7(@types/react@18.3.24) - - '@radix-ui/react-direction@1.1.1(@types/react@18.3.24)(react@18.3.1)': - dependencies: - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.24 - - '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@18.3.24)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.24 - '@types/react-dom': 18.3.7(@types/react@18.3.24) - - '@radix-ui/react-dropdown-menu@2.1.16(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-menu': 2.1.16(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.24)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.24 - '@types/react-dom': 18.3.7(@types/react@18.3.24) - - '@radix-ui/react-focus-guards@1.1.3(@types/react@18.3.24)(react@18.3.1)': - dependencies: - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.24 - - '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.24)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.24 - '@types/react-dom': 18.3.7(@types/react@18.3.24) - - '@radix-ui/react-id@1.1.1(@types/react@18.3.24)(react@18.3.1)': - dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.24)(react@18.3.1) - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.24 - - '@radix-ui/react-label@2.1.7(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.24 - '@types/react-dom': 18.3.7(@types/react@18.3.24) - - '@radix-ui/react-menu@2.1.16(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.2.3(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.24)(react@18.3.1) - aria-hidden: 1.2.6 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.7.1(@types/react@18.3.24)(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.24 - '@types/react-dom': 18.3.7(@types/react@18.3.24) - - '@radix-ui/react-popover@1.1.15(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.2.3(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.24)(react@18.3.1) - aria-hidden: 1.2.6 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.7.1(@types/react@18.3.24)(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.24 - '@types/react-dom': 18.3.7(@types/react@18.3.24) - - '@radix-ui/react-popper@1.2.8(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@floating-ui/react-dom': 2.1.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-arrow': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-use-rect': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/rect': 1.1.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.24 - '@types/react-dom': 18.3.7(@types/react@18.3.24) - - '@radix-ui/react-portal@1.1.9(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.24)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.24 - '@types/react-dom': 18.3.7(@types/react@18.3.24) - - '@radix-ui/react-presence@1.1.5(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.24)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.24 - '@types/react-dom': 18.3.7(@types/react@18.3.24) - - '@radix-ui/react-primitive@2.1.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/react-slot': 1.2.3(@types/react@18.3.24)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.24 - '@types/react-dom': 18.3.7(@types/react@18.3.24) - - '@radix-ui/react-radio-group@1.3.8(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.1(@types/react@18.3.24)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.24 - '@types/react-dom': 18.3.7(@types/react@18.3.24) - - '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.24)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.24 - '@types/react-dom': 18.3.7(@types/react@18.3.24) - - '@radix-ui/react-scroll-area@1.2.10(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/number': 1.1.1 - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.24)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.24 - '@types/react-dom': 18.3.7(@types/react@18.3.24) - - '@radix-ui/react-select@2.2.6(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/number': 1.1.1 - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.2.3(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - aria-hidden: 1.2.6 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.7.1(@types/react@18.3.24)(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.24 - '@types/react-dom': 18.3.7(@types/react@18.3.24) - - '@radix-ui/react-slot@1.2.3(@types/react@18.3.24)(react@18.3.1)': - dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.24)(react@18.3.1) - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.24 - - '@radix-ui/react-switch@1.2.6(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.1(@types/react@18.3.24)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.24 - '@types/react-dom': 18.3.7(@types/react@18.3.24) - - '@radix-ui/react-tabs@1.1.13(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-context': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.24)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.24 - '@types/react-dom': 18.3.7(@types/react@18.3.24) - - '@radix-ui/react-toast@1.2.15(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.24 - '@types/react-dom': 18.3.7(@types/react@18.3.24) - - '@radix-ui/react-tooltip@1.2.8(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.2.3(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.24 - '@types/react-dom': 18.3.7(@types/react@18.3.24) - - '@radix-ui/react-use-callback-ref@1.1.1(@types/react@18.3.24)(react@18.3.1)': - dependencies: - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.24 - - '@radix-ui/react-use-controllable-state@1.2.2(@types/react@18.3.24)(react@18.3.1)': - dependencies: - '@radix-ui/react-use-effect-event': 0.0.2(@types/react@18.3.24)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.24)(react@18.3.1) - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.24 - - '@radix-ui/react-use-effect-event@0.0.2(@types/react@18.3.24)(react@18.3.1)': - dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.24)(react@18.3.1) - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.24 - - '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@18.3.24)(react@18.3.1)': - dependencies: - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.24)(react@18.3.1) - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.24 - - '@radix-ui/react-use-is-hydrated@0.1.0(@types/react@18.3.24)(react@18.3.1)': - dependencies: - react: 18.3.1 - use-sync-external-store: 1.5.0(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.24 - - '@radix-ui/react-use-layout-effect@1.1.1(@types/react@18.3.24)(react@18.3.1)': - dependencies: - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.24 - - '@radix-ui/react-use-previous@1.1.1(@types/react@18.3.24)(react@18.3.1)': - dependencies: - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.24 - - '@radix-ui/react-use-rect@1.1.1(@types/react@18.3.24)(react@18.3.1)': - dependencies: - '@radix-ui/rect': 1.1.1 - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.24 - - '@radix-ui/react-use-size@1.1.1(@types/react@18.3.24)(react@18.3.1)': - dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.24)(react@18.3.1) - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.24 - - '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.24 - '@types/react-dom': 18.3.7(@types/react@18.3.24) - - '@radix-ui/rect@1.1.1': {} - - '@rtsao/scc@1.1.0': {} - - '@rushstack/eslint-patch@1.12.0': {} - - '@sigstore/bundle@2.3.2': - dependencies: - '@sigstore/protobuf-specs': 0.3.3 - - '@sigstore/core@1.1.0': {} - - '@sigstore/protobuf-specs@0.3.3': {} - - '@sigstore/sign@2.3.2': - dependencies: - '@sigstore/bundle': 2.3.2 - '@sigstore/core': 1.1.0 - '@sigstore/protobuf-specs': 0.3.3 - make-fetch-happen: 13.0.1 - proc-log: 4.2.0 - promise-retry: 2.0.1 - transitivePeerDependencies: - - supports-color - - '@sigstore/tuf@2.3.4': - dependencies: - '@sigstore/protobuf-specs': 0.3.3 - tuf-js: 2.2.1 - transitivePeerDependencies: - - supports-color - - '@sigstore/verify@1.2.1': - dependencies: - '@sigstore/bundle': 2.3.2 - '@sigstore/core': 1.1.0 - '@sigstore/protobuf-specs': 0.3.3 - - '@sinclair/typebox@0.27.8': {} - - '@sinclair/typebox@0.34.41': {} - - '@sindresorhus/merge-streams@2.3.0': {} - - '@sinonjs/commons@3.0.1': - dependencies: - type-detect: 4.0.8 - - '@sinonjs/fake-timers@10.3.0': - dependencies: - '@sinonjs/commons': 3.0.1 - - '@sinonjs/fake-timers@13.0.5': - dependencies: - '@sinonjs/commons': 3.0.1 - - '@standard-schema/spec@1.0.0': {} - - '@swc/core-darwin-arm64@1.13.19': - optional: true - - '@swc/core-darwin-x64@1.13.19': - optional: true - - '@swc/core-linux-arm-gnueabihf@1.13.19': - optional: true - - '@swc/core-linux-arm64-gnu@1.13.19': - optional: true - - '@swc/core-linux-arm64-musl@1.13.19': - optional: true - - '@swc/core-linux-x64-gnu@1.13.19': - optional: true - - '@swc/core-linux-x64-musl@1.13.19': - optional: true - - '@swc/core-win32-arm64-msvc@1.13.19': - optional: true - - '@swc/core-win32-ia32-msvc@1.13.19': - optional: true - - '@swc/core-win32-x64-msvc@1.13.19': - optional: true - - '@swc/core@1.13.19(@swc/helpers@0.5.17)': - dependencies: - '@swc/counter': 0.1.3 - '@swc/types': 0.1.25 - optionalDependencies: - '@swc/core-darwin-arm64': 1.13.19 - '@swc/core-darwin-x64': 1.13.19 - '@swc/core-linux-arm-gnueabihf': 1.13.19 - '@swc/core-linux-arm64-gnu': 1.13.19 - '@swc/core-linux-arm64-musl': 1.13.19 - '@swc/core-linux-x64-gnu': 1.13.19 - '@swc/core-linux-x64-musl': 1.13.19 - '@swc/core-win32-arm64-msvc': 1.13.19 - '@swc/core-win32-ia32-msvc': 1.13.19 - '@swc/core-win32-x64-msvc': 1.13.19 - '@swc/helpers': 0.5.17 - - '@swc/counter@0.1.3': {} - - '@swc/helpers@0.5.15': - dependencies: - tslib: 2.8.1 - - '@swc/helpers@0.5.17': - dependencies: - tslib: 2.8.1 - - '@swc/types@0.1.25': - dependencies: - '@swc/counter': 0.1.3 - - '@swc/wasm-web@1.13.19': {} - - '@swc/wasm@1.13.19': {} - - '@tanstack/query-core@5.90.2': {} - - '@tanstack/react-query@5.90.2(react@18.3.1)': - dependencies: - '@tanstack/query-core': 5.90.2 - react: 18.3.1 - - '@testing-library/dom@10.4.1': - dependencies: - '@babel/code-frame': 7.27.1 - '@babel/runtime': 7.28.4 - '@types/aria-query': 5.0.4 - aria-query: 5.3.0 - dom-accessibility-api: 0.5.16 - lz-string: 1.5.0 - picocolors: 1.1.1 - pretty-format: 27.5.1 - - '@testing-library/jest-dom@6.9.1': - dependencies: - '@adobe/css-tools': 4.4.4 - aria-query: 5.3.2 - css.escape: 1.5.1 - dom-accessibility-api: 0.6.3 - picocolors: 1.1.1 - redent: 3.0.0 - - '@testing-library/react-hooks@8.0.1(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@babel/runtime': 7.28.4 - react: 18.3.1 - react-error-boundary: 3.1.4(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.24 - react-dom: 18.3.1(react@18.3.1) - - '@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@babel/runtime': 7.28.4 - '@testing-library/dom': 10.4.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.24 - '@types/react-dom': 18.3.7(@types/react@18.3.24) - - '@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1)': - dependencies: - '@testing-library/dom': 10.4.1 - - '@tsconfig/node10@1.0.11': {} - - '@tsconfig/node12@1.0.11': {} - - '@tsconfig/node14@1.0.3': {} - - '@tsconfig/node16@1.0.4': {} - - '@tufjs/canonical-json@2.0.0': {} - - '@tufjs/models@2.0.1': - dependencies: - '@tufjs/canonical-json': 2.0.0 - minimatch: 9.0.5 - - '@tybys/wasm-util@0.10.1': - dependencies: - tslib: 2.8.1 - optional: true - - '@tybys/wasm-util@0.9.0': - dependencies: - tslib: 2.8.1 - - '@types/aria-query@5.0.4': {} - - '@types/babel__core@7.20.5': - dependencies: - '@babel/parser': 7.28.4 - '@babel/types': 7.28.4 - '@types/babel__generator': 7.27.0 - '@types/babel__template': 7.4.4 - '@types/babel__traverse': 7.28.0 - - '@types/babel__generator@7.27.0': - dependencies: - '@babel/types': 7.28.4 - - '@types/babel__template@7.4.4': - dependencies: - '@babel/parser': 7.28.4 - '@babel/types': 7.28.4 - - '@types/babel__traverse@7.28.0': - dependencies: - '@babel/types': 7.28.4 - - '@types/debug@4.1.12': - dependencies: - '@types/ms': 2.1.0 - - '@types/estree-jsx@1.0.5': - dependencies: - '@types/estree': 1.0.8 - - '@types/estree@1.0.8': {} - - '@types/graceful-fs@4.1.9': - dependencies: - '@types/node': 22.18.6 - - '@types/hast@2.3.10': - dependencies: - '@types/unist': 2.0.11 - - '@types/hast@3.0.4': - dependencies: - '@types/unist': 3.0.3 - - '@types/inquirer@9.0.9': - dependencies: - '@types/through': 0.0.33 - rxjs: 7.8.2 - - '@types/istanbul-lib-coverage@2.0.6': {} - - '@types/istanbul-lib-report@3.0.3': - dependencies: - '@types/istanbul-lib-coverage': 2.0.6 - - '@types/istanbul-reports@3.0.4': - dependencies: - '@types/istanbul-lib-report': 3.0.3 - - '@types/jest@29.5.14': - dependencies: - expect: 29.7.0 - pretty-format: 29.7.0 - - '@types/js-yaml@4.0.9': {} - - '@types/jsdom@21.1.7': - dependencies: - '@types/node': 22.18.6 - '@types/tough-cookie': 4.0.5 - parse5: 7.3.0 - - '@types/json5@0.0.29': {} - - '@types/mdast@4.0.4': - dependencies: - '@types/unist': 3.0.3 - - '@types/minimatch@3.0.5': {} - - '@types/minimist@1.2.5': {} - - '@types/ms@2.1.0': {} - - '@types/node@20.19.17': - dependencies: - undici-types: 6.21.0 - - '@types/node@22.18.6': - dependencies: - undici-types: 6.21.0 - - '@types/normalize-package-data@2.4.4': {} - - '@types/pg@8.15.5': - dependencies: - '@types/node': 20.19.17 - pg-protocol: 1.10.3 - pg-types: 2.2.0 - - '@types/prop-types@15.7.15': {} - - '@types/react-dom@18.3.7(@types/react@18.3.24)': - dependencies: - '@types/react': 18.3.24 - - '@types/react-syntax-highlighter@15.5.13': - dependencies: - '@types/react': 18.3.24 - - '@types/react@18.3.24': - dependencies: - '@types/prop-types': 15.7.15 - csstype: 3.1.3 - - '@types/stack-utils@2.0.3': {} - - '@types/statuses@2.0.6': {} - - '@types/through@0.0.33': - dependencies: - '@types/node': 22.18.6 - - '@types/tough-cookie@4.0.5': {} - - '@types/unist@2.0.11': {} - - '@types/unist@3.0.3': {} - - '@types/yargs-parser@21.0.3': {} - - '@types/yargs@17.0.33': - dependencies: - '@types/yargs-parser': 21.0.3 - - '@typescript-eslint/eslint-plugin@8.44.1(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2)': - dependencies: - '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.44.1(eslint@8.57.1)(typescript@5.9.2) - '@typescript-eslint/scope-manager': 8.44.1 - '@typescript-eslint/type-utils': 8.44.1(eslint@8.57.1)(typescript@5.9.2) - '@typescript-eslint/utils': 8.44.1(eslint@8.57.1)(typescript@5.9.2) - '@typescript-eslint/visitor-keys': 8.44.1 - eslint: 8.57.1 - graphemer: 1.4.0 - ignore: 7.0.5 - natural-compare: 1.4.0 - ts-api-utils: 2.1.0(typescript@5.9.2) - typescript: 5.9.2 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.2)': - dependencies: - '@typescript-eslint/scope-manager': 6.21.0 - '@typescript-eslint/types': 6.21.0 - '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.9.2) - '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.3 - eslint: 8.57.1 - optionalDependencies: - typescript: 5.9.2 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2)': - dependencies: - '@typescript-eslint/scope-manager': 8.44.1 - '@typescript-eslint/types': 8.44.1 - '@typescript-eslint/typescript-estree': 8.44.1(typescript@5.9.2) - '@typescript-eslint/visitor-keys': 8.44.1 - debug: 4.4.3 - eslint: 8.57.1 - typescript: 5.9.2 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/project-service@8.44.1(typescript@5.9.2)': - dependencies: - '@typescript-eslint/tsconfig-utils': 8.44.1(typescript@5.9.2) - '@typescript-eslint/types': 8.44.1 - debug: 4.4.3 - typescript: 5.9.2 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/scope-manager@6.21.0': - dependencies: - '@typescript-eslint/types': 6.21.0 - '@typescript-eslint/visitor-keys': 6.21.0 - - '@typescript-eslint/scope-manager@8.44.1': - dependencies: - '@typescript-eslint/types': 8.44.1 - '@typescript-eslint/visitor-keys': 8.44.1 - - '@typescript-eslint/tsconfig-utils@8.44.1(typescript@5.9.2)': - dependencies: - typescript: 5.9.2 - - '@typescript-eslint/type-utils@8.44.1(eslint@8.57.1)(typescript@5.9.2)': - dependencies: - '@typescript-eslint/types': 8.44.1 - '@typescript-eslint/typescript-estree': 8.44.1(typescript@5.9.2) - '@typescript-eslint/utils': 8.44.1(eslint@8.57.1)(typescript@5.9.2) - debug: 4.4.3 - eslint: 8.57.1 - ts-api-utils: 2.1.0(typescript@5.9.2) - typescript: 5.9.2 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/types@6.21.0': {} - - '@typescript-eslint/types@8.44.1': {} - - '@typescript-eslint/typescript-estree@6.21.0(typescript@5.9.2)': - dependencies: - '@typescript-eslint/types': 6.21.0 - '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.3 - globby: 11.1.0 - is-glob: 4.0.3 - minimatch: 9.0.3 - semver: 7.7.2 - ts-api-utils: 1.4.3(typescript@5.9.2) - optionalDependencies: - typescript: 5.9.2 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/typescript-estree@8.44.1(typescript@5.9.2)': - dependencies: - '@typescript-eslint/project-service': 8.44.1(typescript@5.9.2) - '@typescript-eslint/tsconfig-utils': 8.44.1(typescript@5.9.2) - '@typescript-eslint/types': 8.44.1 - '@typescript-eslint/visitor-keys': 8.44.1 - debug: 4.4.3 - fast-glob: 3.3.3 - is-glob: 4.0.3 - minimatch: 9.0.5 - semver: 7.7.2 - ts-api-utils: 2.1.0(typescript@5.9.2) - typescript: 5.9.2 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/utils@8.44.1(eslint@8.57.1)(typescript@5.9.2)': - dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@8.57.1) - '@typescript-eslint/scope-manager': 8.44.1 - '@typescript-eslint/types': 8.44.1 - '@typescript-eslint/typescript-estree': 8.44.1(typescript@5.9.2) - eslint: 8.57.1 - typescript: 5.9.2 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/visitor-keys@6.21.0': - dependencies: - '@typescript-eslint/types': 6.21.0 - eslint-visitor-keys: 3.4.3 - - '@typescript-eslint/visitor-keys@8.44.1': - dependencies: - '@typescript-eslint/types': 8.44.1 - eslint-visitor-keys: 4.2.1 - - '@ungap/structured-clone@1.3.0': {} - - '@unrs/resolver-binding-android-arm-eabi@1.11.1': - optional: true - - '@unrs/resolver-binding-android-arm64@1.11.1': - optional: true - - '@unrs/resolver-binding-darwin-arm64@1.11.1': - optional: true - - '@unrs/resolver-binding-darwin-x64@1.11.1': - optional: true - - '@unrs/resolver-binding-freebsd-x64@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-arm64-musl@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-x64-gnu@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-x64-musl@1.11.1': - optional: true - - '@unrs/resolver-binding-wasm32-wasi@1.11.1': - dependencies: - '@napi-rs/wasm-runtime': 0.2.12 - optional: true - - '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': - optional: true - - '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': - optional: true - - '@unrs/resolver-binding-win32-x64-msvc@1.11.1': - optional: true - - '@yarnpkg/lockfile@1.1.0': {} - - '@yarnpkg/parsers@3.0.2': - dependencies: - js-yaml: 3.14.1 - tslib: 2.8.1 - - '@zag-js/accordion@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/anatomy@1.24.1': {} - - '@zag-js/angle-slider@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/rect-utils': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/aria-hidden@1.24.1': {} - - '@zag-js/async-list@1.24.1': - dependencies: - '@zag-js/core': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/auto-resize@1.24.1': - dependencies: - '@zag-js/dom-query': 1.24.1 - - '@zag-js/avatar@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/carousel@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/scroll-snap': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/checkbox@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/focus-visible': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/clipboard@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/collapsible@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/collection@1.24.1': - dependencies: - '@zag-js/utils': 1.24.1 - - '@zag-js/color-picker@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/color-utils': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dismissable': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/popper': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/color-utils@1.24.1': - dependencies: - '@zag-js/utils': 1.24.1 - - '@zag-js/combobox@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/aria-hidden': 1.24.1 - '@zag-js/collection': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dismissable': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/popper': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/core@1.24.1': - dependencies: - '@zag-js/dom-query': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/date-picker@1.24.1(@internationalized/date@3.9.0)': - dependencies: - '@internationalized/date': 3.9.0 - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/date-utils': 1.24.1(@internationalized/date@3.9.0) - '@zag-js/dismissable': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/live-region': 1.24.1 - '@zag-js/popper': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/date-utils@1.24.1(@internationalized/date@3.9.0)': - dependencies: - '@internationalized/date': 3.9.0 - - '@zag-js/dialog@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/aria-hidden': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dismissable': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/focus-trap': 1.24.1 - '@zag-js/remove-scroll': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/dismissable@1.24.1': - dependencies: - '@zag-js/dom-query': 1.24.1 - '@zag-js/interact-outside': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/dom-query@1.24.1': - dependencies: - '@zag-js/types': 1.24.1 - - '@zag-js/editable@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/interact-outside': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/file-upload@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/file-utils': 1.24.1 - '@zag-js/i18n-utils': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/file-utils@1.24.1': - dependencies: - '@zag-js/i18n-utils': 1.24.1 - - '@zag-js/floating-panel@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/popper': 1.24.1 - '@zag-js/rect-utils': 1.24.1 - '@zag-js/store': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/focus-trap@1.24.1': - dependencies: - '@zag-js/dom-query': 1.24.1 - - '@zag-js/focus-visible@1.24.1': - dependencies: - '@zag-js/dom-query': 1.24.1 - - '@zag-js/highlight-word@1.24.1': {} - - '@zag-js/hover-card@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dismissable': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/popper': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/i18n-utils@1.24.1': - dependencies: - '@zag-js/dom-query': 1.24.1 - - '@zag-js/interact-outside@1.24.1': - dependencies: - '@zag-js/dom-query': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/json-tree-utils@1.24.1': {} - - '@zag-js/listbox@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/collection': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/focus-visible': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/live-region@1.24.1': {} - - '@zag-js/menu@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dismissable': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/popper': 1.24.1 - '@zag-js/rect-utils': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/number-input@1.24.1': - dependencies: - '@internationalized/number': 3.6.5 - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/pagination@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/password-input@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/pin-input@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/popover@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/aria-hidden': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dismissable': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/focus-trap': 1.24.1 - '@zag-js/popper': 1.24.1 - '@zag-js/remove-scroll': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/popper@1.24.1': - dependencies: - '@floating-ui/dom': 1.7.4 - '@zag-js/dom-query': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/presence@1.24.1': - dependencies: - '@zag-js/core': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/types': 1.24.1 - - '@zag-js/progress@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/qr-code@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - proxy-memoize: 3.0.1 - uqr: 0.1.2 - - '@zag-js/radio-group@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/focus-visible': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/rating-group@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/react@1.24.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@zag-js/core': 1.24.1 - '@zag-js/store': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - '@zag-js/rect-utils@1.24.1': {} - - '@zag-js/remove-scroll@1.24.1': - dependencies: - '@zag-js/dom-query': 1.24.1 - - '@zag-js/scroll-area@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/scroll-snap@1.24.1': - dependencies: - '@zag-js/dom-query': 1.24.1 - - '@zag-js/select@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/collection': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dismissable': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/popper': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/signature-pad@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - perfect-freehand: 1.2.2 - - '@zag-js/slider@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/splitter@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/steps@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/store@1.24.1': - dependencies: - proxy-compare: 3.0.1 - - '@zag-js/switch@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/focus-visible': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/tabs@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/tags-input@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/auto-resize': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/interact-outside': 1.24.1 - '@zag-js/live-region': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/timer@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/toast@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dismissable': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/toggle-group@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/toggle@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/tooltip@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/focus-visible': 1.24.1 - '@zag-js/popper': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/tour@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dismissable': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/focus-trap': 1.24.1 - '@zag-js/interact-outside': 1.24.1 - '@zag-js/popper': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/tree-view@1.24.1': - dependencies: - '@zag-js/anatomy': 1.24.1 - '@zag-js/collection': 1.24.1 - '@zag-js/core': 1.24.1 - '@zag-js/dom-query': 1.24.1 - '@zag-js/types': 1.24.1 - '@zag-js/utils': 1.24.1 - - '@zag-js/types@1.24.1': - dependencies: - csstype: 3.1.3 - - '@zag-js/utils@1.24.1': {} - - '@zkochan/js-yaml@0.0.7': - dependencies: - argparse: 2.0.1 - - JSONStream@1.3.5: - dependencies: - jsonparse: 1.3.1 - through: 2.3.8 - - abbrev@2.0.0: {} - - acorn-jsx@5.3.2(acorn@8.15.0): - dependencies: - acorn: 8.15.0 - - acorn-walk@8.3.4: - dependencies: - acorn: 8.15.0 - - acorn@8.15.0: {} - - add-stream@1.0.0: {} - - agent-base@7.1.4: {} - - agentic-kit@0.1.2(encoding@0.1.13): - dependencies: - '@agentic-kit/bradie': 0.1.2(encoding@0.1.13) - '@agentic-kit/ollama': 0.1.2(encoding@0.1.13) - transitivePeerDependencies: - - encoding - - aggregate-error@3.1.0: - dependencies: - clean-stack: 2.2.0 - indent-string: 4.0.0 - - ajv@6.12.6: - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - - ansi-colors@4.1.3: {} - - ansi-escapes@4.3.2: - dependencies: - type-fest: 0.21.3 - - ansi-regex@5.0.1: {} - - ansi-regex@6.2.2: {} - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - ansi-styles@5.2.0: {} - - ansi-styles@6.2.3: {} - - any-promise@1.3.0: {} - - anymatch@3.1.3: - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 - - aproba@2.0.0: {} - - arg@4.1.3: {} - - arg@5.0.2: {} - - argparse@1.0.10: - dependencies: - sprintf-js: 1.0.3 - - argparse@2.0.1: {} - - aria-hidden@1.2.6: - dependencies: - tslib: 2.8.1 - - aria-query@5.3.0: - dependencies: - dequal: 2.0.3 - - aria-query@5.3.2: {} - - array-buffer-byte-length@1.0.2: - dependencies: - call-bound: 1.0.4 - is-array-buffer: 3.0.5 - - array-differ@3.0.0: {} - - array-ify@1.0.0: {} - - array-includes@3.1.9: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-object-atoms: 1.1.1 - get-intrinsic: 1.3.0 - is-string: 1.1.1 - math-intrinsics: 1.1.0 - - array-union@2.1.0: {} - - array.prototype.findlast@1.2.5: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - es-shim-unscopables: 1.1.0 - - array.prototype.findlastindex@1.2.6: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - es-shim-unscopables: 1.1.0 - - array.prototype.flat@1.3.3: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-shim-unscopables: 1.1.0 - - array.prototype.flatmap@1.3.3: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-shim-unscopables: 1.1.0 - - array.prototype.tosorted@1.1.4: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-shim-unscopables: 1.1.0 - - arraybuffer.prototype.slice@1.0.4: - dependencies: - array-buffer-byte-length: 1.0.2 - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - is-array-buffer: 3.0.5 - - arrify@1.0.1: {} - - arrify@2.0.1: {} - - ast-types-flow@0.0.8: {} - - async-function@1.0.0: {} - - async@3.2.6: {} - - asynckit@0.4.0: {} - - autoprefixer@10.4.21(postcss@8.5.6): - dependencies: - browserslist: 4.26.2 - caniuse-lite: 1.0.30001745 - fraction.js: 4.3.7 - normalize-range: 0.1.2 - picocolors: 1.1.1 - postcss: 8.5.6 - postcss-value-parser: 4.2.0 - - available-typed-arrays@1.0.7: - dependencies: - possible-typed-array-names: 1.1.0 - - axe-core@4.10.3: {} - - axios@1.12.2: - dependencies: - follow-redirects: 1.15.11 - form-data: 4.0.4 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - - axobject-query@4.1.0: {} - - babel-jest@29.7.0(@babel/core@7.28.4): - dependencies: - '@babel/core': 7.28.4 - '@jest/transform': 29.7.0 - '@types/babel__core': 7.20.5 - babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.6.3(@babel/core@7.28.4) - chalk: 4.1.2 - graceful-fs: 4.2.11 - slash: 3.0.0 - transitivePeerDependencies: - - supports-color - - babel-plugin-istanbul@6.1.1: - dependencies: - '@babel/helper-plugin-utils': 7.27.1 - '@istanbuljs/load-nyc-config': 1.1.0 - '@istanbuljs/schema': 0.1.3 - istanbul-lib-instrument: 5.2.1 - test-exclude: 6.0.0 - transitivePeerDependencies: - - supports-color - - babel-plugin-jest-hoist@29.6.3: - dependencies: - '@babel/template': 7.27.2 - '@babel/types': 7.28.4 - '@types/babel__core': 7.20.5 - '@types/babel__traverse': 7.28.0 - - babel-preset-current-node-syntax@1.2.0(@babel/core@7.28.4): - dependencies: - '@babel/core': 7.28.4 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.28.4) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.28.4) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.28.4) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.28.4) - '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.28.4) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.28.4) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.28.4) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.28.4) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.28.4) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.28.4) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.28.4) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.28.4) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.28.4) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.28.4) - - babel-preset-jest@29.6.3(@babel/core@7.28.4): - dependencies: - '@babel/core': 7.28.4 - babel-plugin-jest-hoist: 29.6.3 - babel-preset-current-node-syntax: 1.2.0(@babel/core@7.28.4) - - bail@2.0.2: {} - - balanced-match@1.0.2: {} - - base64-js@1.5.1: {} - - baseline-browser-mapping@2.8.7: {} - - before-after-hook@2.2.3: {} - - bin-links@4.0.4: - dependencies: - cmd-shim: 6.0.3 - npm-normalize-package-bin: 3.0.1 - read-cmd-shim: 4.0.0 - write-file-atomic: 5.0.1 - - binary-extensions@2.3.0: {} - - bl@4.1.0: - dependencies: - buffer: 5.7.1 - inherits: 2.0.4 - readable-stream: 3.6.2 - - brace-expansion@1.1.12: - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - - brace-expansion@2.0.2: - dependencies: - balanced-match: 1.0.2 - - braces@3.0.3: - dependencies: - fill-range: 7.1.1 - - browserslist@4.26.2: - dependencies: - baseline-browser-mapping: 2.8.7 - caniuse-lite: 1.0.30001745 - electron-to-chromium: 1.5.224 - node-releases: 2.0.21 - update-browserslist-db: 1.1.3(browserslist@4.26.2) - - bs-logger@0.2.6: - dependencies: - fast-json-stable-stringify: 2.1.0 - - bser@2.1.1: - dependencies: - node-int64: 0.4.0 - - buffer-from@1.1.2: {} - - buffer@5.7.1: - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - - buffer@6.0.3: - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - - byte-size@8.1.1: {} - - cacache@18.0.4: - dependencies: - '@npmcli/fs': 3.1.1 - fs-minipass: 3.0.3 - glob: 10.4.5 - lru-cache: 10.4.3 - minipass: 7.1.2 - minipass-collect: 2.0.1 - minipass-flush: 1.0.5 - minipass-pipeline: 1.2.4 - p-map: 4.0.0 - ssri: 10.0.6 - tar: 6.2.1 - unique-filename: 3.0.0 - - call-bind-apply-helpers@1.0.2: - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - - call-bind@1.0.8: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - get-intrinsic: 1.3.0 - set-function-length: 1.2.2 - - call-bound@1.0.4: - dependencies: - call-bind-apply-helpers: 1.0.2 - get-intrinsic: 1.3.0 - - callsites@3.1.0: {} - - camelcase-css@2.0.1: {} - - camelcase-keys@6.2.2: - dependencies: - camelcase: 5.3.1 - map-obj: 4.3.0 - quick-lru: 4.0.1 - - camelcase@5.3.1: {} - - camelcase@6.3.0: {} - - caniuse-lite@1.0.30001745: {} - - ccount@2.0.1: {} - - chalk@4.1.0: - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - - chalk@4.1.2: - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - - char-regex@1.0.2: {} - - character-entities-html4@2.1.0: {} - - character-entities-legacy@1.1.4: {} - - character-entities-legacy@3.0.0: {} - - character-entities@1.2.4: {} - - character-entities@2.0.2: {} - - character-reference-invalid@1.1.4: {} - - character-reference-invalid@2.0.1: {} - - chardet@2.1.0: {} - - chokidar@3.6.0: - dependencies: - anymatch: 3.1.3 - braces: 3.0.3 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 - - chownr@2.0.0: {} - - ci-info@3.9.0: {} - - ci-info@4.3.0: {} - - cjs-module-lexer@1.4.3: {} - - class-variance-authority@0.7.1: - dependencies: - clsx: 2.1.1 - - clean-stack@2.2.0: {} - - cli-cursor@3.1.0: - dependencies: - restore-cursor: 3.1.0 - - cli-spinners@2.6.1: {} - - cli-spinners@2.9.2: {} - - cli-width@3.0.0: {} - - cli-width@4.1.0: {} - - client-only@0.0.1: {} - - cliui@7.0.4: - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - - cliui@8.0.1: - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - - clone-deep@4.0.1: - dependencies: - is-plain-object: 2.0.4 - kind-of: 6.0.3 - shallow-clone: 3.0.1 - - clone@1.0.4: {} - - clsx@2.1.1: {} - - cmd-shim@6.0.3: {} - - co@4.6.0: {} - - collect-v8-coverage@1.0.2: {} - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.4: {} - - color-support@1.1.3: {} - - columnify@1.6.0: - dependencies: - strip-ansi: 6.0.1 - wcwidth: 1.0.1 - - combined-stream@1.0.8: - dependencies: - delayed-stream: 1.0.0 - - comma-separated-tokens@1.0.8: {} - - comma-separated-tokens@2.0.3: {} - - commander@11.1.0: {} - - commander@4.1.1: {} - - common-ancestor-path@1.0.1: {} - - compare-func@2.0.0: - dependencies: - array-ify: 1.0.0 - dot-prop: 5.3.0 - - concat-map@0.0.1: {} - - concat-stream@2.0.0: - dependencies: - buffer-from: 1.1.2 - inherits: 2.0.4 - readable-stream: 3.6.2 - typedarray: 0.0.6 - - console-control-strings@1.1.0: {} - - conventional-changelog-angular@7.0.0: - dependencies: - compare-func: 2.0.0 - - conventional-changelog-core@5.0.1: - dependencies: - add-stream: 1.0.0 - conventional-changelog-writer: 6.0.1 - conventional-commits-parser: 4.0.0 - dateformat: 3.0.3 - get-pkg-repo: 4.2.1 - git-raw-commits: 3.0.0 - git-remote-origin-url: 2.0.0 - git-semver-tags: 5.0.1 - normalize-package-data: 3.0.3 - read-pkg: 3.0.0 - read-pkg-up: 3.0.0 - - conventional-changelog-preset-loader@3.0.0: {} - - conventional-changelog-writer@6.0.1: - dependencies: - conventional-commits-filter: 3.0.0 - dateformat: 3.0.3 - handlebars: 4.7.8 - json-stringify-safe: 5.0.1 - meow: 8.1.2 - semver: 7.7.2 - split: 1.0.1 - - conventional-commits-filter@3.0.0: - dependencies: - lodash.ismatch: 4.4.0 - modify-values: 1.0.1 - - conventional-commits-parser@4.0.0: - dependencies: - JSONStream: 1.3.5 - is-text-path: 1.0.1 - meow: 8.1.2 - split2: 3.2.2 - - conventional-recommended-bump@7.0.1: - dependencies: - concat-stream: 2.0.0 - conventional-changelog-preset-loader: 3.0.0 - conventional-commits-filter: 3.0.0 - conventional-commits-parser: 4.0.0 - git-raw-commits: 3.0.0 - git-semver-tags: 5.0.1 - meow: 8.1.2 - - convert-source-map@2.0.0: {} - - cookie@1.0.2: {} - - copy-file@11.1.0: - dependencies: - graceful-fs: 4.2.11 - p-event: 6.0.1 - - core-util-is@1.0.3: {} - - cosmiconfig@9.0.0(typescript@5.9.2): - dependencies: - env-paths: 2.2.1 - import-fresh: 3.3.1 - js-yaml: 4.1.0 - parse-json: 5.2.0 - optionalDependencies: - typescript: 5.9.2 - - cpy-cli@6.0.0: - dependencies: - cpy: 12.0.1 - meow: 13.2.0 - - cpy@12.0.1: - dependencies: - copy-file: 11.1.0 - globby: 14.1.0 - junk: 4.0.1 - micromatch: 4.0.8 - p-filter: 4.1.0 - p-map: 7.0.3 - - create-jest@29.7.0(@types/node@20.19.17)(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@20.19.17)(typescript@5.9.2)): - dependencies: - '@jest/types': 29.6.3 - chalk: 4.1.2 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.19.17)(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@20.19.17)(typescript@5.9.2)) - jest-util: 29.7.0 - prompts: 2.4.2 - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node - - create-jest@29.7.0(@types/node@22.18.6)(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@22.18.6)(typescript@5.9.2)): - dependencies: - '@jest/types': 29.6.3 - chalk: 4.1.2 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@22.18.6)(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@22.18.6)(typescript@5.9.2)) - jest-util: 29.7.0 - prompts: 2.4.2 - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node - - create-require@1.1.1: {} - - cross-fetch@4.1.0(encoding@0.1.13): - dependencies: - node-fetch: 2.7.0(encoding@0.1.13) - transitivePeerDependencies: - - encoding - - cross-spawn@7.0.6: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - css.escape@1.5.1: {} - - cssesc@3.0.0: {} - - cssstyle@4.6.0: - dependencies: - '@asamuzakjp/css-color': 3.2.0 - rrweb-cssom: 0.8.0 - - csstype@3.1.3: {} - - damerau-levenshtein@1.0.8: {} - - dargs@7.0.0: {} - - data-uri-to-buffer@4.0.1: {} - - data-urls@5.0.0: - dependencies: - whatwg-mimetype: 4.0.0 - whatwg-url: 14.2.0 - - data-view-buffer@1.0.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-data-view: 1.0.2 - - data-view-byte-length@1.0.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-data-view: 1.0.2 - - data-view-byte-offset@1.0.1: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-data-view: 1.0.2 - - dateformat@3.0.3: {} - - dayjs@1.11.18: {} - - debug@3.2.7: - dependencies: - ms: 2.1.3 - - debug@4.4.3: - dependencies: - ms: 2.1.3 - - decamelize-keys@1.1.1: - dependencies: - decamelize: 1.2.0 - map-obj: 1.0.1 - - decamelize@1.2.0: {} - - decimal.js@10.6.0: {} - - decode-named-character-reference@1.2.0: - dependencies: - character-entities: 2.0.2 - - dedent@1.5.3: {} - - dedent@1.7.0: {} - - deep-is@0.1.4: {} - - deepmerge@4.3.1: {} - - defaults@1.0.4: - dependencies: - clone: 1.0.4 - - define-data-property@1.1.4: - dependencies: - es-define-property: 1.0.1 - es-errors: 1.3.0 - gopd: 1.2.0 - - define-lazy-prop@2.0.0: {} - - define-properties@1.2.1: - dependencies: - define-data-property: 1.1.4 - has-property-descriptors: 1.0.2 - object-keys: 1.1.1 - - delayed-stream@1.0.0: {} - - deprecation@2.3.1: {} - - dequal@2.0.3: {} - - detect-indent@5.0.0: {} - - detect-libc@2.1.1: - optional: true - - detect-newline@3.1.0: {} - - detect-node-es@1.1.0: {} - - devlop@1.1.0: - dependencies: - dequal: 2.0.3 - - didyoumean@1.2.2: {} - - diff-sequences@29.6.3: {} - - diff@4.0.2: {} - - dir-glob@3.0.1: - dependencies: - path-type: 4.0.0 - - dlv@1.1.3: {} - - doctrine@2.1.0: - dependencies: - esutils: 2.0.3 - - doctrine@3.0.0: - dependencies: - esutils: 2.0.3 - - dom-accessibility-api@0.5.16: {} - - dom-accessibility-api@0.6.3: {} - - dot-prop@5.3.0: - dependencies: - is-obj: 2.0.0 - - dotenv-expand@11.0.7: - dependencies: - dotenv: 16.4.7 - - dotenv@16.4.7: {} - - dunder-proto@1.0.1: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-errors: 1.3.0 - gopd: 1.2.0 - - eastasianwidth@0.2.0: {} - - ejs@3.1.10: - dependencies: - jake: 10.9.4 - - electron-to-chromium@1.5.224: {} - - embla-carousel-react@8.6.0(react@18.3.1): - dependencies: - embla-carousel: 8.6.0 - embla-carousel-reactive-utils: 8.6.0(embla-carousel@8.6.0) - react: 18.3.1 - - embla-carousel-reactive-utils@8.6.0(embla-carousel@8.6.0): - dependencies: - embla-carousel: 8.6.0 - - embla-carousel@8.6.0: {} - - emittery@0.13.1: {} - - emoji-regex@8.0.0: {} - - emoji-regex@9.2.2: {} - - encoding@0.1.13: - dependencies: - iconv-lite: 0.6.3 - optional: true - - end-of-stream@1.4.5: - dependencies: - once: 1.4.0 - - enquirer@2.3.6: - dependencies: - ansi-colors: 4.1.3 - - entities@6.0.1: {} - - env-paths@2.2.1: {} - - envinfo@7.13.0: {} - - err-code@2.0.3: {} - - error-ex@1.3.4: - dependencies: - is-arrayish: 0.2.1 - - es-abstract@1.24.0: - dependencies: - array-buffer-byte-length: 1.0.2 - arraybuffer.prototype.slice: 1.0.4 - available-typed-arrays: 1.0.7 - call-bind: 1.0.8 - call-bound: 1.0.4 - data-view-buffer: 1.0.2 - data-view-byte-length: 1.0.2 - data-view-byte-offset: 1.0.1 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - es-set-tostringtag: 2.1.0 - es-to-primitive: 1.3.0 - function.prototype.name: 1.1.8 - get-intrinsic: 1.3.0 - get-proto: 1.0.1 - get-symbol-description: 1.1.0 - globalthis: 1.0.4 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - has-proto: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.2 - internal-slot: 1.1.0 - is-array-buffer: 3.0.5 - is-callable: 1.2.7 - is-data-view: 1.0.2 - is-negative-zero: 2.0.3 - is-regex: 1.2.1 - is-set: 2.0.3 - is-shared-array-buffer: 1.0.4 - is-string: 1.1.1 - is-typed-array: 1.1.15 - is-weakref: 1.1.1 - math-intrinsics: 1.1.0 - object-inspect: 1.13.4 - object-keys: 1.1.1 - object.assign: 4.1.7 - own-keys: 1.0.1 - regexp.prototype.flags: 1.5.4 - safe-array-concat: 1.1.3 - safe-push-apply: 1.0.0 - safe-regex-test: 1.1.0 - set-proto: 1.0.0 - stop-iteration-iterator: 1.1.0 - string.prototype.trim: 1.2.10 - string.prototype.trimend: 1.0.9 - string.prototype.trimstart: 1.0.8 - typed-array-buffer: 1.0.3 - typed-array-byte-length: 1.0.3 - typed-array-byte-offset: 1.0.4 - typed-array-length: 1.0.7 - unbox-primitive: 1.1.0 - which-typed-array: 1.1.19 - - es-define-property@1.0.1: {} - - es-errors@1.3.0: {} - - es-iterator-helpers@1.2.1: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-set-tostringtag: 2.1.0 - function-bind: 1.1.2 - get-intrinsic: 1.3.0 - globalthis: 1.0.4 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - has-proto: 1.2.0 - has-symbols: 1.1.0 - internal-slot: 1.1.0 - iterator.prototype: 1.1.5 - safe-array-concat: 1.1.3 - - es-object-atoms@1.1.1: - dependencies: - es-errors: 1.3.0 - - es-set-tostringtag@2.1.0: - dependencies: - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - has-tostringtag: 1.0.2 - hasown: 2.0.2 - - es-shim-unscopables@1.1.0: - dependencies: - hasown: 2.0.2 - - es-to-primitive@1.3.0: - dependencies: - is-callable: 1.2.7 - is-date-object: 1.1.0 - is-symbol: 1.1.1 - - escalade@3.2.0: {} - - escape-string-regexp@1.0.5: {} - - escape-string-regexp@2.0.0: {} - - escape-string-regexp@4.0.0: {} - - escape-string-regexp@5.0.0: {} - - eslint-config-next@14.1.0(eslint@8.57.1)(typescript@5.9.2): - dependencies: - '@next/eslint-plugin-next': 14.1.0 - '@rushstack/eslint-patch': 1.12.0 - '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.9.2) - eslint: 8.57.1 - eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.1) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1) - eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1) - eslint-plugin-react: 7.37.5(eslint@8.57.1) - eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.57.1) - optionalDependencies: - typescript: 5.9.2 - transitivePeerDependencies: - - eslint-import-resolver-webpack - - eslint-plugin-import-x - - supports-color - - eslint-config-prettier@9.1.2(eslint@8.57.1): - dependencies: - eslint: 8.57.1 - - eslint-import-resolver-node@0.3.9: - dependencies: - debug: 3.2.7 - is-core-module: 2.16.1 - resolve: 1.22.10 - transitivePeerDependencies: - - supports-color - - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.1): - dependencies: - '@nolyfill/is-core-module': 1.0.39 - debug: 4.4.3 - eslint: 8.57.1 - get-tsconfig: 4.10.1 - is-bun-module: 2.0.0 - stable-hash: 0.0.5 - tinyglobby: 0.2.15 - unrs-resolver: 1.11.1 - optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1) - transitivePeerDependencies: - - supports-color - - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1): - dependencies: - debug: 3.2.7 - optionalDependencies: - '@typescript-eslint/parser': 8.44.1(eslint@8.57.1)(typescript@5.9.2) - eslint: 8.57.1 - eslint-import-resolver-node: 0.3.9 - transitivePeerDependencies: - - supports-color - - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1): - dependencies: - '@rtsao/scc': 1.1.0 - array-includes: 3.1.9 - array.prototype.findlastindex: 1.2.6 - array.prototype.flat: 1.3.3 - array.prototype.flatmap: 1.3.3 - debug: 3.2.7 - doctrine: 2.1.0 - eslint: 8.57.1 - eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1) - hasown: 2.0.2 - is-core-module: 2.16.1 - is-glob: 4.0.3 - minimatch: 3.1.2 - object.fromentries: 2.0.8 - object.groupby: 1.0.3 - object.values: 1.2.1 - semver: 6.3.1 - string.prototype.trimend: 1.0.9 - tsconfig-paths: 3.15.0 - optionalDependencies: - '@typescript-eslint/parser': 8.44.1(eslint@8.57.1)(typescript@5.9.2) - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - - eslint-plugin-jest@29.0.1(@typescript-eslint/eslint-plugin@8.44.1(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(jest@29.7.0(@types/node@22.18.6)(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@22.18.6)(typescript@5.9.2)))(typescript@5.9.2): - dependencies: - '@typescript-eslint/utils': 8.44.1(eslint@8.57.1)(typescript@5.9.2) - eslint: 8.57.1 - optionalDependencies: - '@typescript-eslint/eslint-plugin': 8.44.1(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2) - jest: 29.7.0(@types/node@22.18.6)(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@22.18.6)(typescript@5.9.2)) - transitivePeerDependencies: - - supports-color - - typescript - - eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.1): - dependencies: - aria-query: 5.3.2 - array-includes: 3.1.9 - array.prototype.flatmap: 1.3.3 - ast-types-flow: 0.0.8 - axe-core: 4.10.3 - axobject-query: 4.1.0 - damerau-levenshtein: 1.0.8 - emoji-regex: 9.2.2 - eslint: 8.57.1 - hasown: 2.0.2 - jsx-ast-utils: 3.3.5 - language-tags: 1.0.9 - minimatch: 3.1.2 - object.fromentries: 2.0.8 - safe-regex-test: 1.1.0 - string.prototype.includes: 2.0.1 - - eslint-plugin-react-hooks@5.0.0-canary-7118f5dd7-20230705(eslint@8.57.1): - dependencies: - eslint: 8.57.1 - - eslint-plugin-react@7.37.5(eslint@8.57.1): - dependencies: - array-includes: 3.1.9 - array.prototype.findlast: 1.2.5 - array.prototype.flatmap: 1.3.3 - array.prototype.tosorted: 1.1.4 - doctrine: 2.1.0 - es-iterator-helpers: 1.2.1 - eslint: 8.57.1 - estraverse: 5.3.0 - hasown: 2.0.2 - jsx-ast-utils: 3.3.5 - minimatch: 3.1.2 - object.entries: 1.1.9 - object.fromentries: 2.0.8 - object.values: 1.2.1 - prop-types: 15.8.1 - resolve: 2.0.0-next.5 - semver: 6.3.1 - string.prototype.matchall: 4.0.12 - string.prototype.repeat: 1.0.0 - - eslint-plugin-simple-import-sort@12.1.1(eslint@8.57.1): - dependencies: - eslint: 8.57.1 - - eslint-plugin-unused-imports@4.2.0(@typescript-eslint/eslint-plugin@8.44.1(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1): - dependencies: - eslint: 8.57.1 - optionalDependencies: - '@typescript-eslint/eslint-plugin': 8.44.1(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2) - - eslint-scope@7.2.2: - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - - eslint-visitor-keys@3.4.3: {} - - eslint-visitor-keys@4.2.1: {} - - eslint@8.57.1: - dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@8.57.1) - '@eslint-community/regexpp': 4.12.1 - '@eslint/eslintrc': 2.1.4 - '@eslint/js': 8.57.1 - '@humanwhocodes/config-array': 0.13.0 - '@humanwhocodes/module-importer': 1.0.1 - '@nodelib/fs.walk': 1.2.8 - '@ungap/structured-clone': 1.3.0 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.6 - debug: 4.4.3 - doctrine: 3.0.0 - escape-string-regexp: 4.0.0 - eslint-scope: 7.2.2 - eslint-visitor-keys: 3.4.3 - espree: 9.6.1 - esquery: 1.6.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 6.0.1 - find-up: 5.0.0 - glob-parent: 6.0.2 - globals: 13.24.0 - graphemer: 1.4.0 - ignore: 5.3.2 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - is-path-inside: 3.0.3 - js-yaml: 4.1.0 - json-stable-stringify-without-jsonify: 1.0.1 - levn: 0.4.1 - lodash.merge: 4.6.2 - minimatch: 3.1.2 - natural-compare: 1.4.0 - optionator: 0.9.4 - strip-ansi: 6.0.1 - text-table: 0.2.0 - transitivePeerDependencies: - - supports-color - - espree@9.6.1: - dependencies: - acorn: 8.15.0 - acorn-jsx: 5.3.2(acorn@8.15.0) - eslint-visitor-keys: 3.4.3 - - esprima@4.0.1: {} - - esquery@1.6.0: - dependencies: - estraverse: 5.3.0 - - esrecurse@4.3.0: - dependencies: - estraverse: 5.3.0 - - estraverse@5.3.0: {} - - estree-util-is-identifier-name@3.0.0: {} - - esutils@2.0.3: {} - - eventemitter3@4.0.7: {} - - execa@5.0.0: - dependencies: - cross-spawn: 7.0.6 - 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.7 - strip-final-newline: 2.0.0 - - execa@5.1.1: - dependencies: - cross-spawn: 7.0.6 - get-stream: 6.0.1 - human-signals: 2.1.0 - is-stream: 2.0.1 - merge-stream: 2.0.0 - npm-run-path: 4.0.1 - onetime: 5.1.2 - signal-exit: 3.0.7 - strip-final-newline: 2.0.0 - - exit@0.1.2: {} - - expect@29.7.0: - dependencies: - '@jest/expect-utils': 29.7.0 - jest-get-type: 29.6.3 - jest-matcher-utils: 29.7.0 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - - exponential-backoff@3.1.2: {} - - extend-shallow@2.0.1: - dependencies: - is-extendable: 0.1.1 - - extend@3.0.2: {} - - fast-deep-equal@3.1.3: {} - - fast-glob@3.3.3: - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.8 - - fast-json-patch@3.1.1: {} - - fast-json-stable-stringify@2.1.0: {} - - fast-levenshtein@2.0.6: {} - - fastq@1.19.1: - dependencies: - reusify: 1.1.0 - - fault@1.0.4: - dependencies: - format: 0.2.2 - - fb-watchman@2.0.2: - dependencies: - bser: 2.1.1 - - fdir@6.5.0(picomatch@4.0.3): - optionalDependencies: - picomatch: 4.0.3 - - fetch-blob@3.2.0: - dependencies: - node-domexception: 1.0.0 - web-streams-polyfill: 3.3.3 - - figures@3.2.0: - dependencies: - escape-string-regexp: 1.0.5 - - file-entry-cache@6.0.1: - dependencies: - flat-cache: 3.2.0 - - filelist@1.0.4: - dependencies: - minimatch: 5.1.6 - - fill-range@7.1.1: - dependencies: - to-regex-range: 5.0.1 - - find-up@2.1.0: - dependencies: - locate-path: 2.0.0 - - find-up@4.1.0: - dependencies: - locate-path: 5.0.0 - path-exists: 4.0.0 - - find-up@5.0.0: - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - - flat-cache@3.2.0: - dependencies: - flatted: 3.3.3 - keyv: 4.5.4 - rimraf: 3.0.2 - - flat@5.0.2: {} - - flatted@3.3.3: {} - - follow-redirects@1.15.11: {} - - for-each@0.3.5: - dependencies: - is-callable: 1.2.7 - - foreground-child@3.3.1: - dependencies: - cross-spawn: 7.0.6 - signal-exit: 4.1.0 - - form-data@4.0.4: - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - es-set-tostringtag: 2.1.0 - hasown: 2.0.2 - mime-types: 2.1.35 - - format@0.2.2: {} - - formdata-polyfill@4.0.10: - dependencies: - fetch-blob: 3.2.0 - - fraction.js@4.3.7: {} - - front-matter@4.0.2: - dependencies: - js-yaml: 3.14.1 - - fs-constants@1.0.0: {} - - fs-extra@11.3.2: - dependencies: - graceful-fs: 4.2.11 - jsonfile: 6.2.0 - universalify: 2.0.1 - - fs-minipass@2.1.0: - dependencies: - minipass: 3.3.6 - - fs-minipass@3.0.3: - dependencies: - minipass: 7.1.2 - - fs.realpath@1.0.0: {} - - fsevents@2.3.2: - optional: true - - fsevents@2.3.3: - optional: true - - function-bind@1.1.2: {} - - function.prototype.name@1.1.8: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - functions-have-names: 1.2.3 - hasown: 2.0.2 - is-callable: 1.2.7 - - functions-have-names@1.2.3: {} - - gensync@1.0.0-beta.2: {} - - get-caller-file@2.0.5: {} - - get-intrinsic@1.3.0: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - function-bind: 1.1.2 - get-proto: 1.0.1 - gopd: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.2 - math-intrinsics: 1.1.0 - - get-nonce@1.0.1: {} - - get-package-type@0.1.0: {} - - get-pkg-repo@4.2.1: - dependencies: - '@hutson/parse-repository-url': 3.0.2 - hosted-git-info: 4.1.0 - through2: 2.0.5 - yargs: 16.2.0 - - get-port@5.1.1: {} - - get-proto@1.0.1: - dependencies: - dunder-proto: 1.0.1 - es-object-atoms: 1.1.1 - - get-stream@6.0.0: {} - - get-stream@6.0.1: {} - - get-symbol-description@1.1.0: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - - get-tsconfig@4.10.1: - dependencies: - resolve-pkg-maps: 1.0.0 - - git-raw-commits@3.0.0: - dependencies: - dargs: 7.0.0 - meow: 8.1.2 - split2: 3.2.2 - - git-remote-origin-url@2.0.0: - dependencies: - gitconfiglocal: 1.0.0 - pify: 2.3.0 - - git-semver-tags@5.0.1: - dependencies: - meow: 8.1.2 - semver: 7.7.2 - - git-up@7.0.0: - dependencies: - is-ssh: 1.4.1 - parse-url: 8.1.0 - - git-url-parse@14.0.0: - dependencies: - git-up: 7.0.0 - - gitconfiglocal@1.0.0: - dependencies: - ini: 1.3.8 - - glob-parent@5.1.2: - dependencies: - is-glob: 4.0.3 - - glob-parent@6.0.2: - dependencies: - is-glob: 4.0.3 - - glob@10.3.10: - dependencies: - foreground-child: 3.3.1 - jackspeak: 2.3.6 - minimatch: 9.0.5 - minipass: 7.1.2 - path-scurry: 1.11.1 - - glob@10.4.5: - dependencies: - foreground-child: 3.3.1 - jackspeak: 3.4.3 - minimatch: 9.0.5 - minipass: 7.1.2 - package-json-from-dist: 1.0.1 - path-scurry: 1.11.1 - - glob@7.2.3: - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - - glob@9.3.5: - dependencies: - fs.realpath: 1.0.0 - minimatch: 8.0.4 - minipass: 4.2.8 - path-scurry: 1.11.1 - - globals@13.24.0: - dependencies: - type-fest: 0.20.2 - - globalthis@1.0.4: - dependencies: - define-properties: 1.2.1 - gopd: 1.2.0 - - globby@11.1.0: - dependencies: - array-union: 2.1.0 - dir-glob: 3.0.1 - fast-glob: 3.3.3 - ignore: 5.3.2 - merge2: 1.4.1 - slash: 3.0.0 - - globby@14.1.0: - dependencies: - '@sindresorhus/merge-streams': 2.3.0 - fast-glob: 3.3.3 - ignore: 7.0.5 - path-type: 6.0.0 - slash: 5.1.0 - unicorn-magic: 0.3.0 - - gopd@1.2.0: {} - - graceful-fs@4.2.11: {} - - graphemer@1.4.0: {} - - graphql@16.11.0: {} - - gray-matter@4.0.3: - dependencies: - js-yaml: 3.14.1 - kind-of: 6.0.3 - section-matter: 1.0.0 - strip-bom-string: 1.0.0 - - handlebars@4.7.8: - dependencies: - minimist: 1.2.8 - neo-async: 2.6.2 - source-map: 0.6.1 - wordwrap: 1.0.0 - optionalDependencies: - uglify-js: 3.19.3 - - hard-rejection@2.1.0: {} - - has-bigints@1.1.0: {} - - has-flag@4.0.0: {} - - has-property-descriptors@1.0.2: - dependencies: - es-define-property: 1.0.1 - - has-proto@1.2.0: - dependencies: - dunder-proto: 1.0.1 - - has-symbols@1.1.0: {} - - has-tostringtag@1.0.2: - dependencies: - has-symbols: 1.1.0 - - has-unicode@2.0.1: {} - - hasown@2.0.2: - dependencies: - function-bind: 1.1.2 - - hast-util-parse-selector@2.2.5: {} - - hast-util-to-jsx-runtime@2.3.6: - dependencies: - '@types/estree': 1.0.8 - '@types/hast': 3.0.4 - '@types/unist': 3.0.3 - comma-separated-tokens: 2.0.3 - devlop: 1.1.0 - estree-util-is-identifier-name: 3.0.0 - hast-util-whitespace: 3.0.0 - mdast-util-mdx-expression: 2.0.1 - mdast-util-mdx-jsx: 3.2.0 - mdast-util-mdxjs-esm: 2.0.1 - property-information: 7.1.0 - space-separated-tokens: 2.0.2 - style-to-js: 1.1.17 - unist-util-position: 5.0.0 - vfile-message: 4.0.3 - transitivePeerDependencies: - - supports-color - - hast-util-whitespace@3.0.0: - dependencies: - '@types/hast': 3.0.4 - - hastscript@6.0.0: - dependencies: - '@types/hast': 2.3.10 - comma-separated-tokens: 1.0.8 - hast-util-parse-selector: 2.2.5 - property-information: 5.6.0 - space-separated-tokens: 1.1.5 - - headers-polyfill@4.0.3: {} - - highlight.js@10.7.3: {} - - highlightjs-vue@1.0.0: {} - - hosted-git-info@2.8.9: {} - - hosted-git-info@4.1.0: - dependencies: - lru-cache: 6.0.0 - - hosted-git-info@7.0.2: - dependencies: - lru-cache: 10.4.3 - - html-encoding-sniffer@4.0.0: - dependencies: - whatwg-encoding: 3.1.1 - - html-escaper@2.0.2: {} - - html-url-attributes@3.0.1: {} - - http-cache-semantics@4.2.0: {} - - http-proxy-agent@7.0.2: - dependencies: - agent-base: 7.1.4 - debug: 4.4.3 - transitivePeerDependencies: - - supports-color - - https-proxy-agent@7.0.6: - dependencies: - agent-base: 7.1.4 - debug: 4.4.3 - transitivePeerDependencies: - - supports-color - - human-signals@2.1.0: {} - - iconv-lite@0.6.3: - dependencies: - safer-buffer: 2.1.2 - - iconv-lite@0.7.0: - dependencies: - safer-buffer: 2.1.2 - - ieee754@1.2.1: {} - - ignore-walk@6.0.5: - dependencies: - minimatch: 9.0.5 - - ignore@5.3.2: {} - - ignore@7.0.5: {} - - import-fresh@3.3.1: - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - - import-local@3.1.0: - dependencies: - pkg-dir: 4.2.0 - resolve-cwd: 3.0.0 - - import-local@3.2.0: - dependencies: - pkg-dir: 4.2.0 - resolve-cwd: 3.0.0 - - imurmurhash@0.1.4: {} - - indent-string@4.0.0: {} - - inflight@1.0.6: - dependencies: - once: 1.4.0 - wrappy: 1.0.2 - - inherits@2.0.4: {} - - ini@1.3.8: {} - - ini@4.1.3: {} - - init-package-json@6.0.3: - dependencies: - '@npmcli/package-json': 5.2.0 - npm-package-arg: 11.0.2 - promzard: 1.0.2 - read: 3.0.1 - semver: 7.7.2 - validate-npm-package-license: 3.0.4 - validate-npm-package-name: 5.0.1 - transitivePeerDependencies: - - bluebird - - inline-style-parser@0.2.4: {} - - inquirer@8.2.7(@types/node@22.18.6): - dependencies: - '@inquirer/external-editor': 1.0.2(@types/node@22.18.6) - ansi-escapes: 4.3.2 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-width: 3.0.0 - figures: 3.2.0 - lodash: 4.17.21 - mute-stream: 0.0.8 - ora: 5.4.1 - run-async: 2.4.1 - rxjs: 7.8.2 - string-width: 4.2.3 - strip-ansi: 6.0.1 - through: 2.3.8 - wrap-ansi: 6.2.0 - transitivePeerDependencies: - - '@types/node' - - inquirer@9.3.8(@types/node@22.18.6): - dependencies: - '@inquirer/external-editor': 1.0.2(@types/node@22.18.6) - '@inquirer/figures': 1.0.13 - ansi-escapes: 4.3.2 - cli-width: 4.1.0 - mute-stream: 1.0.0 - ora: 5.4.1 - run-async: 3.0.0 - rxjs: 7.8.2 - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 6.2.0 - yoctocolors-cjs: 2.1.3 - transitivePeerDependencies: - - '@types/node' - - internal-slot@1.1.0: - dependencies: - es-errors: 1.3.0 - hasown: 2.0.2 - side-channel: 1.1.0 - - ip-address@10.0.1: {} - - is-alphabetical@1.0.4: {} - - is-alphabetical@2.0.1: {} - - is-alphanumerical@1.0.4: - dependencies: - is-alphabetical: 1.0.4 - is-decimal: 1.0.4 - - is-alphanumerical@2.0.1: - dependencies: - is-alphabetical: 2.0.1 - is-decimal: 2.0.1 - - is-array-buffer@3.0.5: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - - is-arrayish@0.2.1: {} - - is-async-function@2.1.1: - dependencies: - async-function: 1.0.0 - call-bound: 1.0.4 - get-proto: 1.0.1 - has-tostringtag: 1.0.2 - safe-regex-test: 1.1.0 - - is-bigint@1.1.0: - dependencies: - has-bigints: 1.1.0 - - is-binary-path@2.1.0: - dependencies: - binary-extensions: 2.3.0 - - is-boolean-object@1.2.2: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - - is-bun-module@2.0.0: - dependencies: - semver: 7.7.2 - - is-callable@1.2.7: {} - - is-ci@3.0.1: - dependencies: - ci-info: 3.9.0 - - is-core-module@2.16.1: - dependencies: - hasown: 2.0.2 - - is-data-view@1.0.2: - dependencies: - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - is-typed-array: 1.1.15 - - is-date-object@1.1.0: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - - is-decimal@1.0.4: {} - - is-decimal@2.0.1: {} - - is-docker@2.2.1: {} - - is-extendable@0.1.1: {} - - is-extglob@2.1.1: {} - - is-finalizationregistry@1.1.1: - dependencies: - call-bound: 1.0.4 - - is-fullwidth-code-point@3.0.0: {} - - is-generator-fn@2.1.0: {} - - is-generator-function@1.1.0: - dependencies: - call-bound: 1.0.4 - get-proto: 1.0.1 - has-tostringtag: 1.0.2 - safe-regex-test: 1.1.0 - - is-glob@4.0.3: - dependencies: - is-extglob: 2.1.1 - - is-hexadecimal@1.0.4: {} - - is-hexadecimal@2.0.1: {} - - is-interactive@1.0.0: {} - - is-lambda@1.0.1: {} - - is-map@2.0.3: {} - - is-negative-zero@2.0.3: {} - - is-node-process@1.2.0: {} - - is-number-object@1.1.1: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - - is-number@7.0.0: {} - - is-obj@2.0.0: {} - - is-path-inside@3.0.3: {} - - is-plain-obj@1.1.0: {} - - is-plain-obj@4.1.0: {} - - is-plain-object@2.0.4: - dependencies: - isobject: 3.0.1 - - is-potential-custom-element-name@1.0.1: {} - - is-regex@1.2.1: - dependencies: - call-bound: 1.0.4 - gopd: 1.2.0 - has-tostringtag: 1.0.2 - hasown: 2.0.2 - - is-set@2.0.3: {} - - is-shared-array-buffer@1.0.4: - dependencies: - call-bound: 1.0.4 - - is-ssh@1.4.1: - dependencies: - protocols: 2.0.2 - - is-stream@2.0.0: {} - - is-stream@2.0.1: {} - - is-string@1.1.1: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - - is-symbol@1.1.1: - dependencies: - call-bound: 1.0.4 - has-symbols: 1.1.0 - safe-regex-test: 1.1.0 - - is-text-path@1.0.1: - dependencies: - text-extensions: 1.9.0 - - is-typed-array@1.1.15: - dependencies: - which-typed-array: 1.1.19 - - is-unicode-supported@0.1.0: {} - - is-weakmap@2.0.2: {} - - is-weakref@1.1.1: - dependencies: - call-bound: 1.0.4 - - is-weakset@2.0.4: - dependencies: - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - - is-wsl@2.2.0: - dependencies: - is-docker: 2.2.1 - - isarray@1.0.0: {} - - isarray@2.0.5: {} - - isexe@2.0.0: {} - - isexe@3.1.1: {} - - isobject@3.0.1: {} - - isomorphic-fetch@3.0.0(encoding@0.1.13): - dependencies: - node-fetch: 2.7.0(encoding@0.1.13) - whatwg-fetch: 3.6.20 - transitivePeerDependencies: - - encoding - - istanbul-lib-coverage@3.2.2: {} - - istanbul-lib-instrument@5.2.1: - dependencies: - '@babel/core': 7.28.4 - '@babel/parser': 7.28.4 - '@istanbuljs/schema': 0.1.3 - istanbul-lib-coverage: 3.2.2 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - istanbul-lib-instrument@6.0.3: - dependencies: - '@babel/core': 7.28.4 - '@babel/parser': 7.28.4 - '@istanbuljs/schema': 0.1.3 - istanbul-lib-coverage: 3.2.2 - semver: 7.7.2 - transitivePeerDependencies: - - supports-color - - istanbul-lib-report@3.0.1: - dependencies: - istanbul-lib-coverage: 3.2.2 - make-dir: 4.0.0 - supports-color: 7.2.0 - - istanbul-lib-source-maps@4.0.1: - dependencies: - debug: 4.4.3 - istanbul-lib-coverage: 3.2.2 - source-map: 0.6.1 - transitivePeerDependencies: - - supports-color - - istanbul-reports@3.2.0: - dependencies: - html-escaper: 2.0.2 - istanbul-lib-report: 3.0.1 - - iterator.prototype@1.1.5: - dependencies: - define-data-property: 1.1.4 - es-object-atoms: 1.1.1 - get-intrinsic: 1.3.0 - get-proto: 1.0.1 - has-symbols: 1.1.0 - set-function-name: 2.0.2 - - jackspeak@2.3.6: - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 - - jackspeak@3.4.3: - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 - - jake@10.9.4: - dependencies: - async: 3.2.6 - filelist: 1.0.4 - picocolors: 1.1.1 - - jest-changed-files@29.7.0: - dependencies: - execa: 5.1.1 - jest-util: 29.7.0 - p-limit: 3.1.0 - - jest-circus@29.7.0: - dependencies: - '@jest/environment': 29.7.0 - '@jest/expect': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 22.18.6 - chalk: 4.1.2 - co: 4.6.0 - dedent: 1.7.0 - is-generator-fn: 2.1.0 - jest-each: 29.7.0 - jest-matcher-utils: 29.7.0 - jest-message-util: 29.7.0 - jest-runtime: 29.7.0 - jest-snapshot: 29.7.0 - jest-util: 29.7.0 - p-limit: 3.1.0 - pretty-format: 29.7.0 - pure-rand: 6.1.0 - slash: 3.0.0 - stack-utils: 2.0.6 - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - jest-cli@29.7.0(@types/node@20.19.17)(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@20.19.17)(typescript@5.9.2)): - dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@20.19.17)(typescript@5.9.2)) - '@jest/test-result': 29.7.0 - '@jest/types': 29.6.3 - chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.19.17)(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@20.19.17)(typescript@5.9.2)) - exit: 0.1.2 - import-local: 3.2.0 - jest-config: 29.7.0(@types/node@20.19.17)(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@20.19.17)(typescript@5.9.2)) - jest-util: 29.7.0 - jest-validate: 29.7.0 - yargs: 17.7.2 - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node - - jest-cli@29.7.0(@types/node@22.18.6)(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@22.18.6)(typescript@5.9.2)): - dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@22.18.6)(typescript@5.9.2)) - '@jest/test-result': 29.7.0 - '@jest/types': 29.6.3 - chalk: 4.1.2 - create-jest: 29.7.0(@types/node@22.18.6)(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@22.18.6)(typescript@5.9.2)) - exit: 0.1.2 - import-local: 3.2.0 - jest-config: 29.7.0(@types/node@22.18.6)(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@22.18.6)(typescript@5.9.2)) - jest-util: 29.7.0 - jest-validate: 29.7.0 - yargs: 17.7.2 - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node - - jest-config@29.7.0(@types/node@20.19.17)(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@20.19.17)(typescript@5.9.2)): - dependencies: - '@babel/core': 7.28.4 - '@jest/test-sequencer': 29.7.0 - '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.28.4) - chalk: 4.1.2 - ci-info: 3.9.0 - deepmerge: 4.3.1 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-circus: 29.7.0 - jest-environment-node: 29.7.0 - jest-get-type: 29.6.3 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-runner: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 - micromatch: 4.0.8 - parse-json: 5.2.0 - pretty-format: 29.7.0 - slash: 3.0.0 - strip-json-comments: 3.1.1 - optionalDependencies: - '@types/node': 20.19.17 - ts-node: 10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@20.19.17)(typescript@5.9.2) - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - jest-config@29.7.0(@types/node@22.18.6)(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@20.19.17)(typescript@5.9.2)): - dependencies: - '@babel/core': 7.28.4 - '@jest/test-sequencer': 29.7.0 - '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.28.4) - chalk: 4.1.2 - ci-info: 3.9.0 - deepmerge: 4.3.1 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-circus: 29.7.0 - jest-environment-node: 29.7.0 - jest-get-type: 29.6.3 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-runner: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 - micromatch: 4.0.8 - parse-json: 5.2.0 - pretty-format: 29.7.0 - slash: 3.0.0 - strip-json-comments: 3.1.1 - optionalDependencies: - '@types/node': 22.18.6 - ts-node: 10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@20.19.17)(typescript@5.9.2) - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - jest-config@29.7.0(@types/node@22.18.6)(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@22.18.6)(typescript@5.9.2)): - dependencies: - '@babel/core': 7.28.4 - '@jest/test-sequencer': 29.7.0 - '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.28.4) - chalk: 4.1.2 - ci-info: 3.9.0 - deepmerge: 4.3.1 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-circus: 29.7.0 - jest-environment-node: 29.7.0 - jest-get-type: 29.6.3 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-runner: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 - micromatch: 4.0.8 - parse-json: 5.2.0 - pretty-format: 29.7.0 - slash: 3.0.0 - strip-json-comments: 3.1.1 - optionalDependencies: - '@types/node': 22.18.6 - ts-node: 10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@22.18.6)(typescript@5.9.2) - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - jest-diff@29.7.0: - dependencies: - chalk: 4.1.2 - diff-sequences: 29.6.3 - jest-get-type: 29.6.3 - pretty-format: 29.7.0 - - jest-docblock@29.7.0: - dependencies: - detect-newline: 3.1.0 - - jest-each@29.7.0: - dependencies: - '@jest/types': 29.6.3 - chalk: 4.1.2 - jest-get-type: 29.6.3 - jest-util: 29.7.0 - pretty-format: 29.7.0 - - jest-environment-jsdom@30.2.0: - dependencies: - '@jest/environment': 30.2.0 - '@jest/environment-jsdom-abstract': 30.2.0(jsdom@26.1.0) - '@types/jsdom': 21.1.7 - '@types/node': 22.18.6 - jsdom: 26.1.0 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - jest-environment-node@29.7.0: - dependencies: - '@jest/environment': 29.7.0 - '@jest/fake-timers': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 22.18.6 - jest-mock: 29.7.0 - jest-util: 29.7.0 - - jest-fixed-jsdom@0.0.10(jest-environment-jsdom@30.2.0): - dependencies: - jest-environment-jsdom: 30.2.0 - - jest-get-type@29.6.3: {} - - jest-haste-map@29.7.0: - dependencies: - '@jest/types': 29.6.3 - '@types/graceful-fs': 4.1.9 - '@types/node': 22.18.6 - anymatch: 3.1.3 - fb-watchman: 2.0.2 - graceful-fs: 4.2.11 - jest-regex-util: 29.6.3 - jest-util: 29.7.0 - jest-worker: 29.7.0 - micromatch: 4.0.8 - walker: 1.0.8 - optionalDependencies: - fsevents: 2.3.3 - - jest-leak-detector@29.7.0: - dependencies: - jest-get-type: 29.6.3 - pretty-format: 29.7.0 - - jest-matcher-utils@29.7.0: - dependencies: - chalk: 4.1.2 - jest-diff: 29.7.0 - jest-get-type: 29.6.3 - pretty-format: 29.7.0 - - jest-message-util@29.7.0: - dependencies: - '@babel/code-frame': 7.27.1 - '@jest/types': 29.6.3 - '@types/stack-utils': 2.0.3 - chalk: 4.1.2 - graceful-fs: 4.2.11 - micromatch: 4.0.8 - pretty-format: 29.7.0 - slash: 3.0.0 - stack-utils: 2.0.6 - - jest-message-util@30.2.0: - dependencies: - '@babel/code-frame': 7.27.1 - '@jest/types': 30.2.0 - '@types/stack-utils': 2.0.3 - chalk: 4.1.2 - graceful-fs: 4.2.11 - micromatch: 4.0.8 - pretty-format: 30.2.0 - slash: 3.0.0 - stack-utils: 2.0.6 - - jest-mock@29.7.0: - dependencies: - '@jest/types': 29.6.3 - '@types/node': 22.18.6 - jest-util: 29.7.0 - - jest-mock@30.2.0: - dependencies: - '@jest/types': 30.2.0 - '@types/node': 22.18.6 - jest-util: 30.2.0 - - jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): - optionalDependencies: - jest-resolve: 29.7.0 - - jest-regex-util@29.6.3: {} - - jest-regex-util@30.0.1: {} - - jest-resolve-dependencies@29.7.0: - dependencies: - jest-regex-util: 29.6.3 - jest-snapshot: 29.7.0 - transitivePeerDependencies: - - supports-color - - jest-resolve@29.7.0: - dependencies: - chalk: 4.1.2 - graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0) - jest-util: 29.7.0 - jest-validate: 29.7.0 - resolve: 1.22.10 - resolve.exports: 2.0.3 - slash: 3.0.0 - - jest-runner@29.7.0: - dependencies: - '@jest/console': 29.7.0 - '@jest/environment': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 22.18.6 - chalk: 4.1.2 - emittery: 0.13.1 - graceful-fs: 4.2.11 - jest-docblock: 29.7.0 - jest-environment-node: 29.7.0 - jest-haste-map: 29.7.0 - jest-leak-detector: 29.7.0 - jest-message-util: 29.7.0 - jest-resolve: 29.7.0 - jest-runtime: 29.7.0 - jest-util: 29.7.0 - jest-watcher: 29.7.0 - jest-worker: 29.7.0 - p-limit: 3.1.0 - source-map-support: 0.5.13 - transitivePeerDependencies: - - supports-color - - jest-runtime@29.7.0: - dependencies: - '@jest/environment': 29.7.0 - '@jest/fake-timers': 29.7.0 - '@jest/globals': 29.7.0 - '@jest/source-map': 29.6.3 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 22.18.6 - chalk: 4.1.2 - cjs-module-lexer: 1.4.3 - collect-v8-coverage: 1.0.2 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - jest-message-util: 29.7.0 - jest-mock: 29.7.0 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-snapshot: 29.7.0 - jest-util: 29.7.0 - slash: 3.0.0 - strip-bom: 4.0.0 - transitivePeerDependencies: - - supports-color - - jest-snapshot@29.7.0: - dependencies: - '@babel/core': 7.28.4 - '@babel/generator': 7.28.3 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.4) - '@babel/types': 7.28.4 - '@jest/expect-utils': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - babel-preset-current-node-syntax: 1.2.0(@babel/core@7.28.4) - chalk: 4.1.2 - expect: 29.7.0 - graceful-fs: 4.2.11 - jest-diff: 29.7.0 - jest-get-type: 29.6.3 - jest-matcher-utils: 29.7.0 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - natural-compare: 1.4.0 - pretty-format: 29.7.0 - semver: 7.7.2 - transitivePeerDependencies: - - supports-color - - jest-util@29.7.0: - dependencies: - '@jest/types': 29.6.3 - '@types/node': 22.18.6 - chalk: 4.1.2 - ci-info: 3.9.0 - graceful-fs: 4.2.11 - picomatch: 2.3.1 - - jest-util@30.2.0: - dependencies: - '@jest/types': 30.2.0 - '@types/node': 22.18.6 - chalk: 4.1.2 - ci-info: 4.3.0 - graceful-fs: 4.2.11 - picomatch: 4.0.3 - - jest-validate@29.7.0: - dependencies: - '@jest/types': 29.6.3 - camelcase: 6.3.0 - chalk: 4.1.2 - jest-get-type: 29.6.3 - leven: 3.1.0 - pretty-format: 29.7.0 - - jest-watcher@29.7.0: - dependencies: - '@jest/test-result': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 22.18.6 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - emittery: 0.13.1 - jest-util: 29.7.0 - string-length: 4.0.2 - - jest-worker@29.7.0: - dependencies: - '@types/node': 22.18.6 - jest-util: 29.7.0 - merge-stream: 2.0.0 - supports-color: 8.1.1 - - jest@29.7.0(@types/node@20.19.17)(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@20.19.17)(typescript@5.9.2)): - dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@20.19.17)(typescript@5.9.2)) - '@jest/types': 29.6.3 - import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@20.19.17)(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@20.19.17)(typescript@5.9.2)) - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node - - jest@29.7.0(@types/node@22.18.6)(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@22.18.6)(typescript@5.9.2)): - dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@22.18.6)(typescript@5.9.2)) - '@jest/types': 29.6.3 - import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@22.18.6)(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@22.18.6)(typescript@5.9.2)) - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node - - jiti@1.21.7: {} - - js-tokens@4.0.0: {} - - js-yaml@3.14.1: - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 - - js-yaml@4.1.0: - dependencies: - argparse: 2.0.1 - - jsdom@26.1.0: - dependencies: - cssstyle: 4.6.0 - data-urls: 5.0.0 - decimal.js: 10.6.0 - html-encoding-sniffer: 4.0.0 - http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.6 - is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.22 - parse5: 7.3.0 - rrweb-cssom: 0.8.0 - saxes: 6.0.0 - symbol-tree: 3.2.4 - tough-cookie: 5.1.2 - w3c-xmlserializer: 5.0.0 - webidl-conversions: 7.0.0 - whatwg-encoding: 3.1.1 - whatwg-mimetype: 4.0.0 - whatwg-url: 14.2.0 - ws: 8.18.3 - xml-name-validator: 5.0.0 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - jsesc@3.1.0: {} - - json-buffer@3.0.1: {} - - json-parse-better-errors@1.0.2: {} - - json-parse-even-better-errors@2.3.1: {} - - json-parse-even-better-errors@3.0.2: {} - - json-schema-traverse@0.4.1: {} - - json-stable-stringify-without-jsonify@1.0.1: {} - - json-stringify-nice@1.1.4: {} - - json-stringify-safe@5.0.1: {} - - json5@1.0.2: - dependencies: - minimist: 1.2.8 - - json5@2.2.3: {} - - jsonc-parser@3.2.0: {} - - jsonfile@6.2.0: - dependencies: - universalify: 2.0.1 - optionalDependencies: - graceful-fs: 4.2.11 - - jsonparse@1.3.1: {} - - jsx-ast-utils@3.3.5: - dependencies: - array-includes: 3.1.9 - array.prototype.flat: 1.3.3 - object.assign: 4.1.7 - object.values: 1.2.1 - - junk@4.0.1: {} - - just-diff-apply@5.5.0: {} - - just-diff@6.0.2: {} - - keyv@4.5.4: - dependencies: - json-buffer: 3.0.1 - - kind-of@6.0.3: {} - - kleur@3.0.3: {} - - kubernetesjs@0.6.2: {} - - kubernetesjs@0.7.2: {} - - language-subtag-registry@0.3.23: {} - - language-tags@1.0.9: - dependencies: - language-subtag-registry: 0.3.23 - - lerna@8.2.4(@swc/core@1.13.19(@swc/helpers@0.5.17))(@types/node@22.18.6)(encoding@0.1.13): - dependencies: - '@lerna/create': 8.2.4(@swc/core@1.13.19(@swc/helpers@0.5.17))(@types/node@22.18.6)(encoding@0.1.13)(typescript@5.9.2) - '@npmcli/arborist': 7.5.4 - '@npmcli/package-json': 5.2.0 - '@npmcli/run-script': 8.1.0 - '@nx/devkit': 20.8.2(nx@20.8.2(@swc/core@1.13.19(@swc/helpers@0.5.17))) - '@octokit/plugin-enterprise-rest': 6.0.1 - '@octokit/rest': 20.1.2 - aproba: 2.0.0 - byte-size: 8.1.1 - chalk: 4.1.0 - clone-deep: 4.0.1 - cmd-shim: 6.0.3 - color-support: 1.1.3 - columnify: 1.6.0 - console-control-strings: 1.1.0 - conventional-changelog-angular: 7.0.0 - conventional-changelog-core: 5.0.1 - conventional-recommended-bump: 7.0.1 - cosmiconfig: 9.0.0(typescript@5.9.2) - dedent: 1.5.3 - envinfo: 7.13.0 - execa: 5.0.0 - fs-extra: 11.3.2 - get-port: 5.1.1 - get-stream: 6.0.0 - git-url-parse: 14.0.0 - glob-parent: 6.0.2 - graceful-fs: 4.2.11 - has-unicode: 2.0.1 - import-local: 3.1.0 - ini: 1.3.8 - init-package-json: 6.0.3 - inquirer: 8.2.7(@types/node@22.18.6) - is-ci: 3.0.1 - is-stream: 2.0.0 - jest-diff: 29.7.0 - js-yaml: 4.1.0 - libnpmaccess: 8.0.6 - libnpmpublish: 9.0.9 - load-json-file: 6.2.0 - make-dir: 4.0.0 - minimatch: 3.0.5 - multimatch: 5.0.0 - node-fetch: 2.6.7(encoding@0.1.13) - npm-package-arg: 11.0.2 - npm-packlist: 8.0.2 - npm-registry-fetch: 17.1.0 - nx: 20.8.2(@swc/core@1.13.19(@swc/helpers@0.5.17)) - p-map: 4.0.0 - p-map-series: 2.1.0 - p-pipe: 3.1.0 - p-queue: 6.6.2 - p-reduce: 2.1.0 - p-waterfall: 2.1.1 - pacote: 18.0.6 - pify: 5.0.0 - read-cmd-shim: 4.0.0 - resolve-from: 5.0.0 - rimraf: 4.4.1 - semver: 7.7.2 - set-blocking: 2.0.0 - signal-exit: 3.0.7 - slash: 3.0.0 - ssri: 10.0.6 - string-width: 4.2.3 - tar: 6.2.1 - temp-dir: 1.0.0 - through: 2.3.8 - tinyglobby: 0.2.12 - typescript: 5.9.2 - upath: 2.0.1 - uuid: 10.0.0 - validate-npm-package-license: 3.0.4 - validate-npm-package-name: 5.0.1 - wide-align: 1.1.5 - write-file-atomic: 5.0.1 - write-pkg: 4.0.0 - yargs: 17.7.2 - yargs-parser: 21.1.1 - transitivePeerDependencies: - - '@swc-node/register' - - '@swc/core' - - '@types/node' - - babel-plugin-macros - - bluebird - - debug - - encoding - - supports-color - - leven@3.1.0: {} - - levn@0.4.1: - dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 - - libnpmaccess@8.0.6: - dependencies: - npm-package-arg: 11.0.2 - npm-registry-fetch: 17.1.0 - transitivePeerDependencies: - - supports-color - - libnpmpublish@9.0.9: - dependencies: - ci-info: 4.3.0 - normalize-package-data: 6.0.2 - npm-package-arg: 11.0.2 - npm-registry-fetch: 17.1.0 - proc-log: 4.2.0 - semver: 7.7.2 - sigstore: 2.3.1 - ssri: 10.0.6 - transitivePeerDependencies: - - supports-color - - lilconfig@3.1.3: {} - - lines-and-columns@1.2.4: {} - - lines-and-columns@2.0.3: {} - - load-json-file@4.0.0: - dependencies: - graceful-fs: 4.2.11 - parse-json: 4.0.0 - pify: 3.0.0 - strip-bom: 3.0.0 - - load-json-file@6.2.0: - dependencies: - graceful-fs: 4.2.11 - parse-json: 5.2.0 - strip-bom: 4.0.0 - type-fest: 0.6.0 - - locate-path@2.0.0: - dependencies: - p-locate: 2.0.0 - path-exists: 3.0.0 - - locate-path@5.0.0: - dependencies: - p-locate: 4.1.0 - - locate-path@6.0.0: - dependencies: - p-locate: 5.0.0 - - lodash-es@4.17.21: {} - - lodash.ismatch@4.4.0: {} - - lodash.memoize@4.1.2: {} - - lodash.merge@4.6.2: {} - - lodash@4.17.21: {} - - log-symbols@4.1.0: - dependencies: - chalk: 4.1.2 - is-unicode-supported: 0.1.0 - - longest-streak@3.1.0: {} - - loose-envify@1.4.0: - dependencies: - js-tokens: 4.0.0 - - lowlight@1.20.0: - dependencies: - fault: 1.0.4 - highlight.js: 10.7.3 - - lru-cache@10.4.3: {} - - lru-cache@5.1.1: - dependencies: - yallist: 3.1.1 - - lru-cache@6.0.0: - dependencies: - yallist: 4.0.0 - - lucide-react@0.454.0(react@18.3.1): - dependencies: - react: 18.3.1 - - lz-string@1.5.0: {} - - make-dir@2.1.0: - dependencies: - pify: 4.0.1 - semver: 5.7.2 - - make-dir@4.0.0: - dependencies: - semver: 7.7.2 - - make-error@1.3.6: {} - - make-fetch-happen@13.0.1: - dependencies: - '@npmcli/agent': 2.2.2 - cacache: 18.0.4 - http-cache-semantics: 4.2.0 - is-lambda: 1.0.1 - minipass: 7.1.2 - minipass-fetch: 3.0.5 - minipass-flush: 1.0.5 - minipass-pipeline: 1.2.4 - negotiator: 0.6.4 - proc-log: 4.2.0 - promise-retry: 2.0.1 - ssri: 10.0.6 - transitivePeerDependencies: - - supports-color - - makeerror@1.0.12: - dependencies: - tmpl: 1.0.5 - - map-obj@1.0.1: {} - - map-obj@4.3.0: {} - - markdown-table@3.0.4: {} - - match-sorter@8.1.0: - dependencies: - '@babel/runtime': 7.28.4 - remove-accents: 0.5.0 - - math-intrinsics@1.1.0: {} - - mdast-util-find-and-replace@3.0.2: - dependencies: - '@types/mdast': 4.0.4 - escape-string-regexp: 5.0.0 - unist-util-is: 6.0.0 - unist-util-visit-parents: 6.0.1 - - mdast-util-from-markdown@2.0.2: - dependencies: - '@types/mdast': 4.0.4 - '@types/unist': 3.0.3 - decode-named-character-reference: 1.2.0 - devlop: 1.1.0 - mdast-util-to-string: 4.0.0 - micromark: 4.0.2 - micromark-util-decode-numeric-character-reference: 2.0.2 - micromark-util-decode-string: 2.0.1 - micromark-util-normalize-identifier: 2.0.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - unist-util-stringify-position: 4.0.0 - transitivePeerDependencies: - - supports-color - - mdast-util-gfm-autolink-literal@2.0.1: - dependencies: - '@types/mdast': 4.0.4 - ccount: 2.0.1 - devlop: 1.1.0 - mdast-util-find-and-replace: 3.0.2 - micromark-util-character: 2.1.1 - - mdast-util-gfm-footnote@2.1.0: - dependencies: - '@types/mdast': 4.0.4 - devlop: 1.1.0 - mdast-util-from-markdown: 2.0.2 - mdast-util-to-markdown: 2.1.2 - micromark-util-normalize-identifier: 2.0.1 - transitivePeerDependencies: - - supports-color - - mdast-util-gfm-strikethrough@2.0.0: - dependencies: - '@types/mdast': 4.0.4 - mdast-util-from-markdown: 2.0.2 - mdast-util-to-markdown: 2.1.2 - transitivePeerDependencies: - - supports-color - - mdast-util-gfm-table@2.0.0: - dependencies: - '@types/mdast': 4.0.4 - devlop: 1.1.0 - markdown-table: 3.0.4 - mdast-util-from-markdown: 2.0.2 - mdast-util-to-markdown: 2.1.2 - transitivePeerDependencies: - - supports-color - - mdast-util-gfm-task-list-item@2.0.0: - dependencies: - '@types/mdast': 4.0.4 - devlop: 1.1.0 - mdast-util-from-markdown: 2.0.2 - mdast-util-to-markdown: 2.1.2 - transitivePeerDependencies: - - supports-color - - mdast-util-gfm@3.1.0: - dependencies: - mdast-util-from-markdown: 2.0.2 - mdast-util-gfm-autolink-literal: 2.0.1 - mdast-util-gfm-footnote: 2.1.0 - mdast-util-gfm-strikethrough: 2.0.0 - mdast-util-gfm-table: 2.0.0 - mdast-util-gfm-task-list-item: 2.0.0 - mdast-util-to-markdown: 2.1.2 - transitivePeerDependencies: - - supports-color - - mdast-util-mdx-expression@2.0.1: - dependencies: - '@types/estree-jsx': 1.0.5 - '@types/hast': 3.0.4 - '@types/mdast': 4.0.4 - devlop: 1.1.0 - mdast-util-from-markdown: 2.0.2 - mdast-util-to-markdown: 2.1.2 - transitivePeerDependencies: - - supports-color - - mdast-util-mdx-jsx@3.2.0: - dependencies: - '@types/estree-jsx': 1.0.5 - '@types/hast': 3.0.4 - '@types/mdast': 4.0.4 - '@types/unist': 3.0.3 - ccount: 2.0.1 - devlop: 1.1.0 - mdast-util-from-markdown: 2.0.2 - mdast-util-to-markdown: 2.1.2 - parse-entities: 4.0.2 - stringify-entities: 4.0.4 - unist-util-stringify-position: 4.0.0 - vfile-message: 4.0.3 - transitivePeerDependencies: - - supports-color - - mdast-util-mdxjs-esm@2.0.1: - dependencies: - '@types/estree-jsx': 1.0.5 - '@types/hast': 3.0.4 - '@types/mdast': 4.0.4 - devlop: 1.1.0 - mdast-util-from-markdown: 2.0.2 - mdast-util-to-markdown: 2.1.2 - transitivePeerDependencies: - - supports-color - - mdast-util-phrasing@4.1.0: - dependencies: - '@types/mdast': 4.0.4 - unist-util-is: 6.0.0 - - mdast-util-to-hast@13.2.0: - dependencies: - '@types/hast': 3.0.4 - '@types/mdast': 4.0.4 - '@ungap/structured-clone': 1.3.0 - devlop: 1.1.0 - micromark-util-sanitize-uri: 2.0.1 - trim-lines: 3.0.1 - unist-util-position: 5.0.0 - unist-util-visit: 5.0.0 - vfile: 6.0.3 - - mdast-util-to-markdown@2.1.2: - dependencies: - '@types/mdast': 4.0.4 - '@types/unist': 3.0.3 - longest-streak: 3.1.0 - mdast-util-phrasing: 4.1.0 - mdast-util-to-string: 4.0.0 - micromark-util-classify-character: 2.0.1 - micromark-util-decode-string: 2.0.1 - unist-util-visit: 5.0.0 - zwitch: 2.0.4 - - mdast-util-to-string@4.0.0: - dependencies: - '@types/mdast': 4.0.4 - - meow@13.2.0: {} - - meow@8.1.2: - dependencies: - '@types/minimist': 1.2.5 - camelcase-keys: 6.2.2 - decamelize-keys: 1.1.1 - hard-rejection: 2.1.0 - minimist-options: 4.1.0 - normalize-package-data: 3.0.3 - read-pkg-up: 7.0.1 - redent: 3.0.0 - trim-newlines: 3.0.1 - type-fest: 0.18.1 - yargs-parser: 20.2.9 - - merge-stream@2.0.0: {} - - merge2@1.4.1: {} - - micromark-core-commonmark@2.0.3: - dependencies: - decode-named-character-reference: 1.2.0 - devlop: 1.1.0 - micromark-factory-destination: 2.0.1 - micromark-factory-label: 2.0.1 - micromark-factory-space: 2.0.1 - micromark-factory-title: 2.0.1 - micromark-factory-whitespace: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-chunked: 2.0.1 - micromark-util-classify-character: 2.0.1 - micromark-util-html-tag-name: 2.0.1 - micromark-util-normalize-identifier: 2.0.1 - micromark-util-resolve-all: 2.0.1 - micromark-util-subtokenize: 2.1.0 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-extension-gfm-autolink-literal@2.1.0: - dependencies: - micromark-util-character: 2.1.1 - micromark-util-sanitize-uri: 2.0.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-extension-gfm-footnote@2.1.0: - dependencies: - devlop: 1.1.0 - micromark-core-commonmark: 2.0.3 - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-normalize-identifier: 2.0.1 - micromark-util-sanitize-uri: 2.0.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-extension-gfm-strikethrough@2.1.0: - dependencies: - devlop: 1.1.0 - micromark-util-chunked: 2.0.1 - micromark-util-classify-character: 2.0.1 - micromark-util-resolve-all: 2.0.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-extension-gfm-table@2.1.1: - dependencies: - devlop: 1.1.0 - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-extension-gfm-tagfilter@2.0.0: - dependencies: - micromark-util-types: 2.0.2 - - micromark-extension-gfm-task-list-item@2.1.0: - dependencies: - devlop: 1.1.0 - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-extension-gfm@3.0.0: - dependencies: - micromark-extension-gfm-autolink-literal: 2.1.0 - micromark-extension-gfm-footnote: 2.1.0 - micromark-extension-gfm-strikethrough: 2.1.0 - micromark-extension-gfm-table: 2.1.1 - micromark-extension-gfm-tagfilter: 2.0.0 - micromark-extension-gfm-task-list-item: 2.1.0 - micromark-util-combine-extensions: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-factory-destination@2.0.1: - dependencies: - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-factory-label@2.0.1: - dependencies: - devlop: 1.1.0 - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-factory-space@2.0.1: - dependencies: - micromark-util-character: 2.1.1 - micromark-util-types: 2.0.2 - - micromark-factory-title@2.0.1: - dependencies: - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-factory-whitespace@2.0.1: - dependencies: - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-util-character@2.1.1: - dependencies: - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-util-chunked@2.0.1: - dependencies: - micromark-util-symbol: 2.0.1 - - micromark-util-classify-character@2.0.1: - dependencies: - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-util-combine-extensions@2.0.1: - dependencies: - micromark-util-chunked: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-util-decode-numeric-character-reference@2.0.2: - dependencies: - micromark-util-symbol: 2.0.1 - - micromark-util-decode-string@2.0.1: - dependencies: - decode-named-character-reference: 1.2.0 - micromark-util-character: 2.1.1 - micromark-util-decode-numeric-character-reference: 2.0.2 - micromark-util-symbol: 2.0.1 - - micromark-util-encode@2.0.1: {} - - micromark-util-html-tag-name@2.0.1: {} - - micromark-util-normalize-identifier@2.0.1: - dependencies: - micromark-util-symbol: 2.0.1 - - micromark-util-resolve-all@2.0.1: - dependencies: - micromark-util-types: 2.0.2 - - micromark-util-sanitize-uri@2.0.1: - dependencies: - micromark-util-character: 2.1.1 - micromark-util-encode: 2.0.1 - micromark-util-symbol: 2.0.1 - - micromark-util-subtokenize@2.1.0: - dependencies: - devlop: 1.1.0 - micromark-util-chunked: 2.0.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-util-symbol@2.0.1: {} - - micromark-util-types@2.0.2: {} - - micromark@4.0.2: - dependencies: - '@types/debug': 4.1.12 - debug: 4.4.3 - decode-named-character-reference: 1.2.0 - devlop: 1.1.0 - micromark-core-commonmark: 2.0.3 - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-chunked: 2.0.1 - micromark-util-combine-extensions: 2.0.1 - micromark-util-decode-numeric-character-reference: 2.0.2 - micromark-util-encode: 2.0.1 - micromark-util-normalize-identifier: 2.0.1 - micromark-util-resolve-all: 2.0.1 - micromark-util-sanitize-uri: 2.0.1 - micromark-util-subtokenize: 2.1.0 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - transitivePeerDependencies: - - supports-color - - micromatch@4.0.8: - dependencies: - braces: 3.0.3 - picomatch: 2.3.1 - - mime-db@1.52.0: {} - - mime-types@2.1.35: - dependencies: - mime-db: 1.52.0 - - mimic-fn@2.1.0: {} - - min-indent@1.0.1: {} - - minimatch@3.0.5: - dependencies: - brace-expansion: 1.1.12 - - minimatch@3.1.2: - dependencies: - brace-expansion: 1.1.12 - - minimatch@5.1.6: - dependencies: - brace-expansion: 2.0.2 - - minimatch@8.0.4: - dependencies: - brace-expansion: 2.0.2 - - minimatch@9.0.3: - dependencies: - brace-expansion: 2.0.2 - - minimatch@9.0.5: - dependencies: - brace-expansion: 2.0.2 - - minimist-options@4.1.0: - dependencies: - arrify: 1.0.1 - is-plain-obj: 1.1.0 - kind-of: 6.0.3 - - minimist@1.2.8: {} - - minipass-collect@2.0.1: - dependencies: - minipass: 7.1.2 - - minipass-fetch@3.0.5: - dependencies: - minipass: 7.1.2 - minipass-sized: 1.0.3 - minizlib: 2.1.2 - optionalDependencies: - encoding: 0.1.13 - - minipass-flush@1.0.5: - dependencies: - minipass: 3.3.6 - - minipass-pipeline@1.2.4: - dependencies: - minipass: 3.3.6 - - minipass-sized@1.0.3: - dependencies: - minipass: 3.3.6 - - minipass@3.3.6: - dependencies: - yallist: 4.0.0 - - minipass@4.2.8: {} - - minipass@5.0.0: {} - - minipass@7.1.2: {} - - minizlib@2.1.2: - dependencies: - minipass: 3.3.6 - yallist: 4.0.0 - - mkdirp@1.0.4: {} - - modify-values@1.0.1: {} - - ms@2.1.3: {} - - msw@2.11.5(@types/node@20.19.17)(typescript@5.9.2): - dependencies: - '@inquirer/confirm': 5.1.18(@types/node@20.19.17) - '@mswjs/interceptors': 0.39.7 - '@open-draft/deferred-promise': 2.2.0 - '@types/statuses': 2.0.6 - cookie: 1.0.2 - graphql: 16.11.0 - headers-polyfill: 4.0.3 - is-node-process: 1.2.0 - outvariant: 1.4.3 - path-to-regexp: 6.3.0 - picocolors: 1.1.1 - rettime: 0.7.0 - statuses: 2.0.2 - strict-event-emitter: 0.5.1 - tough-cookie: 6.0.0 - type-fest: 4.41.0 - until-async: 3.0.2 - yargs: 17.7.2 - optionalDependencies: - typescript: 5.9.2 - transitivePeerDependencies: - - '@types/node' - - multimatch@5.0.0: - dependencies: - '@types/minimatch': 3.0.5 - array-differ: 3.0.0 - array-union: 2.1.0 - arrify: 2.0.1 - minimatch: 3.0.5 - - mute-stream@0.0.8: {} - - mute-stream@1.0.0: {} - - mute-stream@2.0.0: {} - - mz@2.7.0: - dependencies: - any-promise: 1.3.0 - object-assign: 4.1.1 - thenify-all: 1.6.0 - - nanoid@3.3.11: {} - - napi-postinstall@0.3.3: {} - - natural-compare@1.4.0: {} - - negotiator@0.6.4: {} - - neo-async@2.6.2: {} - - next-seo@6.8.0(next@15.5.4(@babel/core@7.28.4)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - next: 15.5.4(@babel/core@7.28.4)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - next-themes@0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - next@15.5.4(@babel/core@7.28.4)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@next/env': 15.5.4 - '@swc/helpers': 0.5.15 - caniuse-lite: 1.0.30001745 - postcss: 8.4.31 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - styled-jsx: 5.1.6(@babel/core@7.28.4)(react@18.3.1) - optionalDependencies: - '@next/swc-darwin-arm64': 15.5.4 - '@next/swc-darwin-x64': 15.5.4 - '@next/swc-linux-arm64-gnu': 15.5.4 - '@next/swc-linux-arm64-musl': 15.5.4 - '@next/swc-linux-x64-gnu': 15.5.4 - '@next/swc-linux-x64-musl': 15.5.4 - '@next/swc-win32-arm64-msvc': 15.5.4 - '@next/swc-win32-x64-msvc': 15.5.4 - '@playwright/test': 1.56.1 - sharp: 0.34.4 - transitivePeerDependencies: - - '@babel/core' - - babel-plugin-macros - - node-domexception@1.0.0: {} - - node-fetch@2.6.7(encoding@0.1.13): - dependencies: - whatwg-url: 5.0.0 - optionalDependencies: - encoding: 0.1.13 - - node-fetch@2.7.0(encoding@0.1.13): - dependencies: - whatwg-url: 5.0.0 - optionalDependencies: - encoding: 0.1.13 - - node-fetch@3.3.2: - dependencies: - data-uri-to-buffer: 4.0.1 - fetch-blob: 3.2.0 - formdata-polyfill: 4.0.10 - - node-gyp@10.3.1: - dependencies: - env-paths: 2.2.1 - exponential-backoff: 3.1.2 - glob: 10.4.5 - graceful-fs: 4.2.11 - make-fetch-happen: 13.0.1 - nopt: 7.2.1 - proc-log: 4.2.0 - semver: 7.7.2 - tar: 6.2.1 - which: 4.0.0 - transitivePeerDependencies: - - supports-color - - node-int64@0.4.0: {} - - node-machine-id@1.1.12: {} - - node-releases@2.0.21: {} - - nopt@7.2.1: - dependencies: - abbrev: 2.0.0 - - normalize-package-data@2.5.0: - dependencies: - hosted-git-info: 2.8.9 - resolve: 1.22.10 - semver: 5.7.2 - validate-npm-package-license: 3.0.4 - - normalize-package-data@3.0.3: - dependencies: - hosted-git-info: 4.1.0 - is-core-module: 2.16.1 - semver: 7.7.2 - validate-npm-package-license: 3.0.4 - - normalize-package-data@6.0.2: - dependencies: - hosted-git-info: 7.0.2 - semver: 7.7.2 - validate-npm-package-license: 3.0.4 - - normalize-path@3.0.0: {} - - normalize-range@0.1.2: {} - - npm-bundled@3.0.1: - dependencies: - npm-normalize-package-bin: 3.0.1 - - npm-install-checks@6.3.0: - dependencies: - semver: 7.7.2 - - npm-normalize-package-bin@3.0.1: {} - - npm-package-arg@11.0.2: - dependencies: - hosted-git-info: 7.0.2 - proc-log: 4.2.0 - semver: 7.7.2 - validate-npm-package-name: 5.0.1 - - npm-packlist@8.0.2: - dependencies: - ignore-walk: 6.0.5 - - npm-pick-manifest@9.1.0: - dependencies: - npm-install-checks: 6.3.0 - npm-normalize-package-bin: 3.0.1 - npm-package-arg: 11.0.2 - semver: 7.7.2 - - npm-registry-fetch@17.1.0: - dependencies: - '@npmcli/redact': 2.0.1 - jsonparse: 1.3.1 - make-fetch-happen: 13.0.1 - minipass: 7.1.2 - minipass-fetch: 3.0.5 - minizlib: 2.1.2 - npm-package-arg: 11.0.2 - proc-log: 4.2.0 - transitivePeerDependencies: - - supports-color - - npm-run-path@4.0.1: - dependencies: - path-key: 3.1.1 - - nuqs@2.6.0(next@15.5.4(@babel/core@7.28.4)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1): - dependencies: - '@standard-schema/spec': 1.0.0 - react: 18.3.1 - optionalDependencies: - next: 15.5.4(@babel/core@7.28.4)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - - nwsapi@2.2.22: {} - - nx@20.8.2(@swc/core@1.13.19(@swc/helpers@0.5.17)): - dependencies: - '@napi-rs/wasm-runtime': 0.2.4 - '@yarnpkg/lockfile': 1.1.0 - '@yarnpkg/parsers': 3.0.2 - '@zkochan/js-yaml': 0.0.7 - axios: 1.12.2 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-spinners: 2.6.1 - cliui: 8.0.1 - dotenv: 16.4.7 - dotenv-expand: 11.0.7 - enquirer: 2.3.6 - figures: 3.2.0 - flat: 5.0.2 - front-matter: 4.0.2 - ignore: 5.3.2 - jest-diff: 29.7.0 - jsonc-parser: 3.2.0 - lines-and-columns: 2.0.3 - minimatch: 9.0.3 - node-machine-id: 1.1.12 - npm-run-path: 4.0.1 - open: 8.4.2 - ora: 5.3.0 - resolve.exports: 2.0.3 - semver: 7.7.2 - string-width: 4.2.3 - tar-stream: 2.2.0 - tmp: 0.2.5 - tsconfig-paths: 4.2.0 - tslib: 2.8.1 - yaml: 2.8.1 - yargs: 17.7.2 - yargs-parser: 21.1.1 - optionalDependencies: - '@nx/nx-darwin-arm64': 20.8.2 - '@nx/nx-darwin-x64': 20.8.2 - '@nx/nx-freebsd-x64': 20.8.2 - '@nx/nx-linux-arm-gnueabihf': 20.8.2 - '@nx/nx-linux-arm64-gnu': 20.8.2 - '@nx/nx-linux-arm64-musl': 20.8.2 - '@nx/nx-linux-x64-gnu': 20.8.2 - '@nx/nx-linux-x64-musl': 20.8.2 - '@nx/nx-win32-arm64-msvc': 20.8.2 - '@nx/nx-win32-x64-msvc': 20.8.2 - '@swc/core': 1.13.19(@swc/helpers@0.5.17) - transitivePeerDependencies: - - debug - - object-assign@4.1.1: {} - - object-hash@3.0.0: {} - - object-inspect@1.13.4: {} - - object-keys@1.1.1: {} - - object.assign@4.1.7: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - has-symbols: 1.1.0 - object-keys: 1.1.1 - - object.entries@1.1.9: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - - object.fromentries@2.0.8: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-object-atoms: 1.1.1 - - object.groupby@1.0.3: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - - object.values@1.2.1: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - - once@1.4.0: - dependencies: - wrappy: 1.0.2 - - onetime@5.1.2: - dependencies: - mimic-fn: 2.1.0 - - open@8.4.2: - dependencies: - define-lazy-prop: 2.0.0 - is-docker: 2.2.1 - is-wsl: 2.2.0 - - optionator@0.9.4: - dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 - word-wrap: 1.2.5 - - ora@5.3.0: - dependencies: - bl: 4.1.0 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-spinners: 2.6.1 - is-interactive: 1.0.0 - log-symbols: 4.1.0 - strip-ansi: 6.0.1 - wcwidth: 1.0.1 - - ora@5.4.1: - dependencies: - bl: 4.1.0 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-spinners: 2.9.2 - is-interactive: 1.0.0 - is-unicode-supported: 0.1.0 - log-symbols: 4.1.0 - strip-ansi: 6.0.1 - wcwidth: 1.0.1 - - outvariant@1.4.3: {} - - own-keys@1.0.1: - dependencies: - get-intrinsic: 1.3.0 - object-keys: 1.1.1 - safe-push-apply: 1.0.0 - - p-event@6.0.1: - dependencies: - p-timeout: 6.1.4 - - p-filter@4.1.0: - dependencies: - p-map: 7.0.3 - - p-finally@1.0.0: {} - - p-limit@1.3.0: - dependencies: - p-try: 1.0.0 - - p-limit@2.3.0: - dependencies: - p-try: 2.2.0 - - p-limit@3.1.0: - dependencies: - yocto-queue: 0.1.0 - - p-locate@2.0.0: - dependencies: - p-limit: 1.3.0 - - p-locate@4.1.0: - dependencies: - p-limit: 2.3.0 - - p-locate@5.0.0: - dependencies: - p-limit: 3.1.0 - - p-map-series@2.1.0: {} - - p-map@4.0.0: - dependencies: - aggregate-error: 3.1.0 - - p-map@7.0.3: {} - - p-pipe@3.1.0: {} - - p-queue@6.6.2: - dependencies: - eventemitter3: 4.0.7 - p-timeout: 3.2.0 - - p-reduce@2.1.0: {} - - p-timeout@3.2.0: - dependencies: - p-finally: 1.0.0 - - p-timeout@6.1.4: {} - - p-try@1.0.0: {} - - p-try@2.2.0: {} - - p-waterfall@2.1.1: - dependencies: - p-reduce: 2.1.0 - - package-json-from-dist@1.0.1: {} - - pacote@18.0.6: - dependencies: - '@npmcli/git': 5.0.8 - '@npmcli/installed-package-contents': 2.1.0 - '@npmcli/package-json': 5.2.0 - '@npmcli/promise-spawn': 7.0.2 - '@npmcli/run-script': 8.1.0 - cacache: 18.0.4 - fs-minipass: 3.0.3 - minipass: 7.1.2 - npm-package-arg: 11.0.2 - npm-packlist: 8.0.2 - npm-pick-manifest: 9.1.0 - npm-registry-fetch: 17.1.0 - proc-log: 4.2.0 - promise-retry: 2.0.1 - sigstore: 2.3.1 - ssri: 10.0.6 - tar: 6.2.1 - transitivePeerDependencies: - - bluebird - - supports-color - - parent-module@1.0.1: - dependencies: - callsites: 3.1.0 - - parse-conflict-json@3.0.1: - dependencies: - json-parse-even-better-errors: 3.0.2 - just-diff: 6.0.2 - just-diff-apply: 5.5.0 - - parse-entities@2.0.0: - dependencies: - character-entities: 1.2.4 - character-entities-legacy: 1.1.4 - character-reference-invalid: 1.1.4 - is-alphanumerical: 1.0.4 - is-decimal: 1.0.4 - is-hexadecimal: 1.0.4 - - parse-entities@4.0.2: - dependencies: - '@types/unist': 2.0.11 - character-entities-legacy: 3.0.0 - character-reference-invalid: 2.0.1 - decode-named-character-reference: 1.2.0 - is-alphanumerical: 2.0.1 - is-decimal: 2.0.1 - is-hexadecimal: 2.0.1 - - parse-json@4.0.0: - dependencies: - error-ex: 1.3.4 - json-parse-better-errors: 1.0.2 - - parse-json@5.2.0: - dependencies: - '@babel/code-frame': 7.27.1 - error-ex: 1.3.4 - json-parse-even-better-errors: 2.3.1 - lines-and-columns: 1.2.4 - - parse-path@7.1.0: - dependencies: - protocols: 2.0.2 - - parse-url@8.1.0: - dependencies: - parse-path: 7.1.0 - - parse5@7.3.0: - dependencies: - entities: 6.0.1 - - path-exists@3.0.0: {} - - path-exists@4.0.0: {} - - path-is-absolute@1.0.1: {} - - path-key@3.1.1: {} - - path-parse@1.0.7: {} - - path-scurry@1.11.1: - dependencies: - lru-cache: 10.4.3 - minipass: 7.1.2 - - path-to-regexp@6.3.0: {} - - path-type@3.0.0: - dependencies: - pify: 3.0.0 - - path-type@4.0.0: {} - - path-type@6.0.0: {} - - perfect-freehand@1.2.2: {} - - pg-cloudflare@1.2.7: - optional: true - - pg-connection-string@2.9.1: {} - - pg-int8@1.0.1: {} - - pg-pool@3.10.1(pg@8.16.3): - dependencies: - pg: 8.16.3 - - pg-protocol@1.10.3: {} - - pg-types@2.2.0: - dependencies: - pg-int8: 1.0.1 - postgres-array: 2.0.0 - postgres-bytea: 1.0.0 - postgres-date: 1.0.7 - postgres-interval: 1.2.0 - - pg@8.16.3: - dependencies: - pg-connection-string: 2.9.1 - pg-pool: 3.10.1(pg@8.16.3) - pg-protocol: 1.10.3 - pg-types: 2.2.0 - pgpass: 1.0.5 - optionalDependencies: - pg-cloudflare: 1.2.7 - - pgpass@1.0.5: - dependencies: - split2: 4.2.0 - - picocolors@1.1.1: {} - - picomatch@2.3.1: {} - - picomatch@4.0.3: {} - - pify@2.3.0: {} - - pify@3.0.0: {} - - pify@4.0.1: {} - - pify@5.0.0: {} - - pirates@4.0.7: {} - - pkg-dir@4.2.0: - dependencies: - find-up: 4.1.0 - - playwright-core@1.56.1: {} - - playwright@1.56.1: - dependencies: - playwright-core: 1.56.1 - optionalDependencies: - fsevents: 2.3.2 - - possible-typed-array-names@1.1.0: {} - - postcss-import@15.1.0(postcss@8.5.6): - dependencies: - postcss: 8.5.6 - postcss-value-parser: 4.2.0 - read-cache: 1.0.0 - resolve: 1.22.10 - - postcss-js@4.1.0(postcss@8.5.6): - dependencies: - camelcase-css: 2.0.1 - postcss: 8.5.6 - - postcss-load-config@4.0.2(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@20.19.17)(typescript@5.9.2)): - dependencies: - lilconfig: 3.1.3 - yaml: 2.8.1 - optionalDependencies: - postcss: 8.5.6 - ts-node: 10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@20.19.17)(typescript@5.9.2) - - postcss-nested@6.2.0(postcss@8.5.6): - dependencies: - postcss: 8.5.6 - postcss-selector-parser: 6.1.2 - - postcss-selector-parser@6.1.2: - dependencies: - cssesc: 3.0.0 - util-deprecate: 1.0.2 - - postcss-value-parser@4.2.0: {} - - postcss@8.4.31: - dependencies: - nanoid: 3.3.11 - picocolors: 1.1.1 - source-map-js: 1.2.1 - - postcss@8.5.6: - dependencies: - nanoid: 3.3.11 - picocolors: 1.1.1 - source-map-js: 1.2.1 - - postgres-array@2.0.0: {} - - postgres-bytea@1.0.0: {} - - postgres-date@1.0.7: {} - - postgres-interval@1.2.0: - dependencies: - xtend: 4.0.2 - - prelude-ls@1.2.1: {} - - prettier@3.6.2: {} - - pretty-format@27.5.1: - dependencies: - ansi-regex: 5.0.1 - ansi-styles: 5.2.0 - react-is: 17.0.2 - - pretty-format@29.7.0: - dependencies: - '@jest/schemas': 29.6.3 - ansi-styles: 5.2.0 - react-is: 18.3.1 - - pretty-format@30.2.0: - dependencies: - '@jest/schemas': 30.0.5 - ansi-styles: 5.2.0 - react-is: 18.3.1 - - prismjs@1.27.0: {} - - prismjs@1.30.0: {} - - proc-log@4.2.0: {} - - process-nextick-args@2.0.1: {} - - proggy@2.0.0: {} - - promise-all-reject-late@1.0.1: {} - - promise-call-limit@3.0.2: {} - - promise-inflight@1.0.1: {} - - promise-retry@2.0.1: - dependencies: - err-code: 2.0.3 - retry: 0.12.0 - - prompts@2.4.2: - dependencies: - kleur: 3.0.3 - sisteransi: 1.0.5 - - promzard@1.0.2: - dependencies: - read: 3.0.1 - - prop-types@15.8.1: - dependencies: - loose-envify: 1.4.0 - object-assign: 4.1.1 - react-is: 16.13.1 - - property-information@5.6.0: - dependencies: - xtend: 4.0.2 - - property-information@7.1.0: {} - - protocols@2.0.2: {} - - proxy-compare@3.0.1: {} - - proxy-from-env@1.1.0: {} - - proxy-memoize@3.0.1: - dependencies: - proxy-compare: 3.0.1 - - punycode@2.3.1: {} - - pure-rand@6.1.0: {} - - queue-microtask@1.2.3: {} - - quick-lru@4.0.1: {} - - react-dom@18.3.1(react@18.3.1): - dependencies: - loose-envify: 1.4.0 - react: 18.3.1 - scheduler: 0.23.2 - - react-error-boundary@3.1.4(react@18.3.1): - dependencies: - '@babel/runtime': 7.28.4 - react: 18.3.1 - - react-hook-form@7.63.0(react@18.3.1): - dependencies: - react: 18.3.1 - - react-is@16.13.1: {} - - react-is@17.0.2: {} - - react-is@18.3.1: {} - - react-markdown@9.1.0(@types/react@18.3.24)(react@18.3.1): - dependencies: - '@types/hast': 3.0.4 - '@types/mdast': 4.0.4 - '@types/react': 18.3.24 - devlop: 1.1.0 - hast-util-to-jsx-runtime: 2.3.6 - html-url-attributes: 3.0.1 - mdast-util-to-hast: 13.2.0 - react: 18.3.1 - remark-parse: 11.0.0 - remark-rehype: 11.1.2 - unified: 11.0.5 - unist-util-visit: 5.0.0 - vfile: 6.0.3 - transitivePeerDependencies: - - supports-color - - react-remove-scroll-bar@2.3.8(@types/react@18.3.24)(react@18.3.1): - dependencies: - react: 18.3.1 - react-style-singleton: 2.2.3(@types/react@18.3.24)(react@18.3.1) - tslib: 2.8.1 - optionalDependencies: - '@types/react': 18.3.24 - - react-remove-scroll@2.7.1(@types/react@18.3.24)(react@18.3.1): - dependencies: - react: 18.3.1 - react-remove-scroll-bar: 2.3.8(@types/react@18.3.24)(react@18.3.1) - react-style-singleton: 2.2.3(@types/react@18.3.24)(react@18.3.1) - tslib: 2.8.1 - use-callback-ref: 1.3.3(@types/react@18.3.24)(react@18.3.1) - use-sidecar: 1.1.3(@types/react@18.3.24)(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.24 - - react-style-singleton@2.2.3(@types/react@18.3.24)(react@18.3.1): - dependencies: - get-nonce: 1.0.1 - react: 18.3.1 - tslib: 2.8.1 - optionalDependencies: - '@types/react': 18.3.24 - - react-syntax-highlighter@15.6.6(react@18.3.1): - dependencies: - '@babel/runtime': 7.28.4 - highlight.js: 10.7.3 - highlightjs-vue: 1.0.0 - lowlight: 1.20.0 - prismjs: 1.30.0 - react: 18.3.1 - refractor: 3.6.0 - - react@18.3.1: - dependencies: - loose-envify: 1.4.0 - - read-cache@1.0.0: - dependencies: - pify: 2.3.0 - - read-cmd-shim@4.0.0: {} - - read-package-json-fast@3.0.2: - dependencies: - json-parse-even-better-errors: 3.0.2 - npm-normalize-package-bin: 3.0.1 - - read-pkg-up@3.0.0: - dependencies: - find-up: 2.1.0 - read-pkg: 3.0.0 - - read-pkg-up@7.0.1: - dependencies: - find-up: 4.1.0 - read-pkg: 5.2.0 - type-fest: 0.8.1 - - read-pkg@3.0.0: - dependencies: - load-json-file: 4.0.0 - normalize-package-data: 2.5.0 - path-type: 3.0.0 - - read-pkg@5.2.0: - dependencies: - '@types/normalize-package-data': 2.4.4 - normalize-package-data: 2.5.0 - parse-json: 5.2.0 - type-fest: 0.6.0 - - read@3.0.1: - dependencies: - mute-stream: 1.0.0 - - readable-stream@2.3.8: - dependencies: - core-util-is: 1.0.3 - inherits: 2.0.4 - isarray: 1.0.0 - process-nextick-args: 2.0.1 - safe-buffer: 5.1.2 - string_decoder: 1.1.1 - util-deprecate: 1.0.2 - - readable-stream@3.6.2: - dependencies: - inherits: 2.0.4 - string_decoder: 1.3.0 - util-deprecate: 1.0.2 - - readdirp@3.6.0: - dependencies: - picomatch: 2.3.1 - - redent@3.0.0: - dependencies: - indent-string: 4.0.0 - strip-indent: 3.0.0 - - reflect.getprototypeof@1.0.10: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - get-intrinsic: 1.3.0 - get-proto: 1.0.1 - which-builtin-type: 1.2.1 - - refractor@3.6.0: - dependencies: - hastscript: 6.0.0 - parse-entities: 2.0.0 - prismjs: 1.27.0 - - regexp.prototype.flags@1.5.4: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-errors: 1.3.0 - get-proto: 1.0.1 - gopd: 1.2.0 - set-function-name: 2.0.2 - - remark-gfm@4.0.1: - dependencies: - '@types/mdast': 4.0.4 - mdast-util-gfm: 3.1.0 - micromark-extension-gfm: 3.0.0 - remark-parse: 11.0.0 - remark-stringify: 11.0.0 - unified: 11.0.5 - transitivePeerDependencies: - - supports-color - - remark-parse@11.0.0: - dependencies: - '@types/mdast': 4.0.4 - mdast-util-from-markdown: 2.0.2 - micromark-util-types: 2.0.2 - unified: 11.0.5 - transitivePeerDependencies: - - supports-color - - remark-rehype@11.1.2: - dependencies: - '@types/hast': 3.0.4 - '@types/mdast': 4.0.4 - mdast-util-to-hast: 13.2.0 - unified: 11.0.5 - vfile: 6.0.3 - - remark-stringify@11.0.0: - dependencies: - '@types/mdast': 4.0.4 - mdast-util-to-markdown: 2.1.2 - unified: 11.0.5 - - remark@15.0.1: - dependencies: - '@types/mdast': 4.0.4 - remark-parse: 11.0.0 - remark-stringify: 11.0.0 - unified: 11.0.5 - transitivePeerDependencies: - - supports-color - - remove-accents@0.5.0: {} - - require-directory@2.1.1: {} - - resolve-cwd@3.0.0: - dependencies: - resolve-from: 5.0.0 - - resolve-from@4.0.0: {} - - resolve-from@5.0.0: {} - - resolve-pkg-maps@1.0.0: {} - - resolve.exports@2.0.3: {} - - resolve@1.22.10: - dependencies: - is-core-module: 2.16.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - - resolve@2.0.0-next.5: - dependencies: - is-core-module: 2.16.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - - restore-cursor@3.1.0: - dependencies: - onetime: 5.1.2 - signal-exit: 3.0.7 - - retry@0.12.0: {} - - rettime@0.7.0: {} - - reusify@1.1.0: {} - - rimraf@3.0.2: - dependencies: - glob: 7.2.3 - - rimraf@4.4.1: - dependencies: - glob: 9.3.5 - - rrweb-cssom@0.8.0: {} - - run-async@2.4.1: {} - - run-async@3.0.0: {} - - run-parallel@1.2.0: - dependencies: - queue-microtask: 1.2.3 - - rxjs@7.8.2: - dependencies: - tslib: 2.8.1 - - safe-array-concat@1.1.3: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - has-symbols: 1.1.0 - isarray: 2.0.5 - - safe-buffer@5.1.2: {} - - safe-buffer@5.2.1: {} - - safe-push-apply@1.0.0: - dependencies: - es-errors: 1.3.0 - isarray: 2.0.5 - - safe-regex-test@1.1.0: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-regex: 1.2.1 - - safer-buffer@2.1.2: {} - - saxes@6.0.0: - dependencies: - xmlchars: 2.2.0 - - scheduler@0.23.2: - dependencies: - loose-envify: 1.4.0 - - schema-sdk@0.11.3(encoding@0.1.13): - dependencies: - '@babel/generator': 7.28.3 - '@babel/types': 7.28.4 - '@interweb-utils/casing': 0.2.0 - '@interweb/fetch-api-client': 0.6.1(encoding@0.1.13) - deepmerge: 4.3.1 - schema-typescript: 0.12.1 - transitivePeerDependencies: - - encoding - - schema-sdk@0.15.0(encoding@0.1.13): - dependencies: - '@babel/generator': 7.28.3 - '@babel/types': 7.28.4 - '@interweb-utils/casing': 0.2.0 - '@interweb/fetch-api-client': 0.6.1(encoding@0.1.13) - deepmerge: 4.3.1 - fast-json-patch: 3.1.1 - schema-typescript: 0.12.1 - transitivePeerDependencies: - - encoding - - schema-typescript@0.12.1: - dependencies: - '@babel/generator': 7.28.3 - '@babel/types': 7.28.4 - '@interweb-utils/casing': 0.2.0 - deepmerge: 4.3.1 - minimatch: 9.0.5 - - section-matter@1.0.0: - dependencies: - extend-shallow: 2.0.1 - kind-of: 6.0.3 - - semver@5.7.2: {} - - semver@6.3.1: {} - - semver@7.7.2: {} - - set-blocking@2.0.0: {} - - set-function-length@1.2.2: - dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - function-bind: 1.1.2 - get-intrinsic: 1.3.0 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - - set-function-name@2.0.2: - dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - functions-have-names: 1.2.3 - has-property-descriptors: 1.0.2 - - set-proto@1.0.0: - dependencies: - dunder-proto: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - - shallow-clone@3.0.1: - dependencies: - kind-of: 6.0.3 - - sharp@0.34.4: - dependencies: - '@img/colour': 1.0.0 - detect-libc: 2.1.1 - semver: 7.7.2 - optionalDependencies: - '@img/sharp-darwin-arm64': 0.34.4 - '@img/sharp-darwin-x64': 0.34.4 - '@img/sharp-libvips-darwin-arm64': 1.2.3 - '@img/sharp-libvips-darwin-x64': 1.2.3 - '@img/sharp-libvips-linux-arm': 1.2.3 - '@img/sharp-libvips-linux-arm64': 1.2.3 - '@img/sharp-libvips-linux-ppc64': 1.2.3 - '@img/sharp-libvips-linux-s390x': 1.2.3 - '@img/sharp-libvips-linux-x64': 1.2.3 - '@img/sharp-libvips-linuxmusl-arm64': 1.2.3 - '@img/sharp-libvips-linuxmusl-x64': 1.2.3 - '@img/sharp-linux-arm': 0.34.4 - '@img/sharp-linux-arm64': 0.34.4 - '@img/sharp-linux-ppc64': 0.34.4 - '@img/sharp-linux-s390x': 0.34.4 - '@img/sharp-linux-x64': 0.34.4 - '@img/sharp-linuxmusl-arm64': 0.34.4 - '@img/sharp-linuxmusl-x64': 0.34.4 - '@img/sharp-wasm32': 0.34.4 - '@img/sharp-win32-arm64': 0.34.4 - '@img/sharp-win32-ia32': 0.34.4 - '@img/sharp-win32-x64': 0.34.4 - optional: true - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - - side-channel-list@1.0.0: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - - side-channel-map@1.0.1: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - object-inspect: 1.13.4 - - side-channel-weakmap@1.0.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - object-inspect: 1.13.4 - side-channel-map: 1.0.1 - - side-channel@1.1.0: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - side-channel-list: 1.0.0 - side-channel-map: 1.0.1 - side-channel-weakmap: 1.0.2 - - signal-exit@3.0.7: {} - - signal-exit@4.1.0: {} - - sigstore@2.3.1: - dependencies: - '@sigstore/bundle': 2.3.2 - '@sigstore/core': 1.1.0 - '@sigstore/protobuf-specs': 0.3.3 - '@sigstore/sign': 2.3.2 - '@sigstore/tuf': 2.3.4 - '@sigstore/verify': 1.2.1 - transitivePeerDependencies: - - supports-color - - sisteransi@1.0.5: {} - - slash@3.0.0: {} - - slash@5.1.0: {} - - smart-buffer@4.2.0: {} - - socks-proxy-agent@8.0.5: - dependencies: - agent-base: 7.1.4 - debug: 4.4.3 - socks: 2.8.7 - transitivePeerDependencies: - - supports-color - - socks@2.8.7: - dependencies: - ip-address: 10.0.1 - smart-buffer: 4.2.0 - - sort-keys@2.0.0: - dependencies: - is-plain-obj: 1.1.0 - - source-map-js@1.2.1: {} - - source-map-support@0.5.13: - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - - source-map@0.6.1: {} - - space-separated-tokens@1.1.5: {} - - space-separated-tokens@2.0.2: {} - - spdx-correct@3.2.0: - dependencies: - spdx-expression-parse: 3.0.1 - spdx-license-ids: 3.0.22 - - spdx-exceptions@2.5.0: {} - - spdx-expression-parse@3.0.1: - dependencies: - spdx-exceptions: 2.5.0 - spdx-license-ids: 3.0.22 - - spdx-license-ids@3.0.22: {} - - split2@3.2.2: - dependencies: - readable-stream: 3.6.2 - - split2@4.2.0: {} - - split@1.0.1: - dependencies: - through: 2.3.8 - - sprintf-js@1.0.3: {} - - ssri@10.0.6: - dependencies: - minipass: 7.1.2 - - stable-hash@0.0.5: {} - - stack-utils@2.0.6: - dependencies: - escape-string-regexp: 2.0.0 - - statuses@2.0.2: {} - - stop-iteration-iterator@1.1.0: - dependencies: - es-errors: 1.3.0 - internal-slot: 1.1.0 - - strict-event-emitter@0.5.1: {} - - string-length@4.0.2: - dependencies: - char-regex: 1.0.2 - strip-ansi: 6.0.1 - - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - string-width@5.1.2: - dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 - strip-ansi: 7.1.2 - - string.prototype.includes@2.0.1: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - - string.prototype.matchall@4.0.12: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - get-intrinsic: 1.3.0 - gopd: 1.2.0 - has-symbols: 1.1.0 - internal-slot: 1.1.0 - regexp.prototype.flags: 1.5.4 - set-function-name: 2.0.2 - side-channel: 1.1.0 - - string.prototype.repeat@1.0.0: - dependencies: - define-properties: 1.2.1 - es-abstract: 1.24.0 - - string.prototype.trim@1.2.10: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-data-property: 1.1.4 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-object-atoms: 1.1.1 - has-property-descriptors: 1.0.2 - - string.prototype.trimend@1.0.9: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - - string.prototype.trimstart@1.0.8: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - - string_decoder@1.1.1: - dependencies: - safe-buffer: 5.1.2 - - string_decoder@1.3.0: - dependencies: - safe-buffer: 5.2.1 - - stringify-entities@4.0.4: - dependencies: - character-entities-html4: 2.1.0 - character-entities-legacy: 3.0.0 - - strip-ansi@6.0.1: - dependencies: - ansi-regex: 5.0.1 - - strip-ansi@7.1.2: - dependencies: - ansi-regex: 6.2.2 - - strip-bom-string@1.0.0: {} - - strip-bom@3.0.0: {} - - strip-bom@4.0.0: {} - - strip-final-newline@2.0.0: {} - - strip-indent@3.0.0: - dependencies: - min-indent: 1.0.1 - - strip-json-comments@3.1.1: {} - - style-to-js@1.1.17: - dependencies: - style-to-object: 1.0.9 - - style-to-object@1.0.9: - dependencies: - inline-style-parser: 0.2.4 - - styled-jsx@5.1.6(@babel/core@7.28.4)(react@18.3.1): - dependencies: - client-only: 0.0.1 - react: 18.3.1 - optionalDependencies: - '@babel/core': 7.28.4 - - sucrase@3.35.0: - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - commander: 4.1.1 - glob: 10.4.5 - lines-and-columns: 1.2.4 - mz: 2.7.0 - pirates: 4.0.7 - ts-interface-checker: 0.1.13 - - supports-color@7.2.0: - dependencies: - has-flag: 4.0.0 - - supports-color@8.1.1: - dependencies: - has-flag: 4.0.0 - - supports-preserve-symlinks-flag@1.0.0: {} - - symbol-tree@3.2.4: {} - - tailwind-merge@2.6.0: {} - - tailwindcss-animate@1.0.7(tailwindcss@3.4.17(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@20.19.17)(typescript@5.9.2))): - dependencies: - tailwindcss: 3.4.17(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@20.19.17)(typescript@5.9.2)) - - tailwindcss@3.4.17(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@20.19.17)(typescript@5.9.2)): - dependencies: - '@alloc/quick-lru': 5.2.0 - arg: 5.0.2 - chokidar: 3.6.0 - didyoumean: 1.2.2 - dlv: 1.1.3 - fast-glob: 3.3.3 - glob-parent: 6.0.2 - is-glob: 4.0.3 - jiti: 1.21.7 - lilconfig: 3.1.3 - micromatch: 4.0.8 - normalize-path: 3.0.0 - object-hash: 3.0.0 - picocolors: 1.1.1 - postcss: 8.5.6 - postcss-import: 15.1.0(postcss@8.5.6) - postcss-js: 4.1.0(postcss@8.5.6) - postcss-load-config: 4.0.2(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@20.19.17)(typescript@5.9.2)) - postcss-nested: 6.2.0(postcss@8.5.6) - postcss-selector-parser: 6.1.2 - resolve: 1.22.10 - sucrase: 3.35.0 - transitivePeerDependencies: - - ts-node - - tar-stream@2.2.0: - dependencies: - bl: 4.1.0 - end-of-stream: 1.4.5 - fs-constants: 1.0.0 - inherits: 2.0.4 - readable-stream: 3.6.2 - - tar@6.2.1: - dependencies: - chownr: 2.0.0 - fs-minipass: 2.1.0 - minipass: 5.0.0 - minizlib: 2.1.2 - mkdirp: 1.0.4 - yallist: 4.0.0 - - temp-dir@1.0.0: {} - - test-exclude@6.0.0: - dependencies: - '@istanbuljs/schema': 0.1.3 - glob: 7.2.3 - minimatch: 3.1.2 - - text-extensions@1.9.0: {} - - text-table@0.2.0: {} - - thenify-all@1.6.0: - dependencies: - thenify: 3.3.1 - - thenify@3.3.1: - dependencies: - any-promise: 1.3.0 - - through2@2.0.5: - dependencies: - readable-stream: 2.3.8 - xtend: 4.0.2 - - through@2.3.8: {} - - tinyglobby@0.2.12: - dependencies: - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 - - tinyglobby@0.2.15: - dependencies: - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 - - tldts-core@6.1.86: {} - - tldts-core@7.0.17: {} - - tldts@6.1.86: - dependencies: - tldts-core: 6.1.86 - - tldts@7.0.17: - dependencies: - tldts-core: 7.0.17 - - tmp@0.2.5: {} - - tmpl@1.0.5: {} - - to-regex-range@5.0.1: - dependencies: - is-number: 7.0.0 - - tough-cookie@5.1.2: - dependencies: - tldts: 6.1.86 - - tough-cookie@6.0.0: - dependencies: - tldts: 7.0.17 - - tr46@0.0.3: {} - - tr46@5.1.1: - dependencies: - punycode: 2.3.1 - - treeverse@3.0.0: {} - - trim-lines@3.0.1: {} - - trim-newlines@3.0.1: {} - - trough@2.2.0: {} - - ts-api-utils@1.4.3(typescript@5.9.2): - dependencies: - typescript: 5.9.2 - - ts-api-utils@2.1.0(typescript@5.9.2): - dependencies: - typescript: 5.9.2 - - ts-interface-checker@0.1.13: {} - - ts-jest@29.4.4(@babel/core@7.28.4)(@jest/transform@29.7.0)(@jest/types@30.2.0)(babel-jest@29.7.0(@babel/core@7.28.4))(jest-util@30.2.0)(jest@29.7.0(@types/node@22.18.6)(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@22.18.6)(typescript@5.9.2)))(typescript@5.9.2): - dependencies: - bs-logger: 0.2.6 - fast-json-stable-stringify: 2.1.0 - handlebars: 4.7.8 - jest: 29.7.0(@types/node@22.18.6)(ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@22.18.6)(typescript@5.9.2)) - json5: 2.2.3 - lodash.memoize: 4.1.2 - make-error: 1.3.6 - semver: 7.7.2 - type-fest: 4.41.0 - typescript: 5.9.2 - yargs-parser: 21.1.1 - optionalDependencies: - '@babel/core': 7.28.4 - '@jest/transform': 29.7.0 - '@jest/types': 30.2.0 - babel-jest: 29.7.0(@babel/core@7.28.4) - jest-util: 30.2.0 - - ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@20.19.17)(typescript@5.9.2): - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.11 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 20.19.17 - acorn: 8.15.0 - acorn-walk: 8.3.4 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 5.9.2 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - optionalDependencies: - '@swc/core': 1.13.19(@swc/helpers@0.5.17) - '@swc/wasm': 1.13.19 - - ts-node@10.9.2(@swc/core@1.13.19(@swc/helpers@0.5.17))(@swc/wasm@1.13.19)(@types/node@22.18.6)(typescript@5.9.2): - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.11 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 22.18.6 - acorn: 8.15.0 - acorn-walk: 8.3.4 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 5.9.2 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - optionalDependencies: - '@swc/core': 1.13.19(@swc/helpers@0.5.17) - '@swc/wasm': 1.13.19 - - tsconfig-paths@3.15.0: - dependencies: - '@types/json5': 0.0.29 - json5: 1.0.2 - minimist: 1.2.8 - strip-bom: 3.0.0 - - tsconfig-paths@4.2.0: - dependencies: - json5: 2.2.3 - minimist: 1.2.8 - strip-bom: 3.0.0 - - tslib@2.8.1: {} - - tuf-js@2.2.1: - dependencies: - '@tufjs/models': 2.0.1 - debug: 4.4.3 - make-fetch-happen: 13.0.1 - transitivePeerDependencies: - - supports-color - - type-check@0.4.0: - dependencies: - prelude-ls: 1.2.1 - - type-detect@4.0.8: {} - - type-fest@0.18.1: {} - - type-fest@0.20.2: {} - - type-fest@0.21.3: {} - - type-fest@0.4.1: {} - - type-fest@0.6.0: {} - - type-fest@0.8.1: {} - - type-fest@4.41.0: {} - - typed-array-buffer@1.0.3: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-typed-array: 1.1.15 - - typed-array-byte-length@1.0.3: - dependencies: - call-bind: 1.0.8 - for-each: 0.3.5 - gopd: 1.2.0 - has-proto: 1.2.0 - is-typed-array: 1.1.15 - - typed-array-byte-offset@1.0.4: - dependencies: - available-typed-arrays: 1.0.7 - call-bind: 1.0.8 - for-each: 0.3.5 - gopd: 1.2.0 - has-proto: 1.2.0 - is-typed-array: 1.1.15 - reflect.getprototypeof: 1.0.10 - - typed-array-length@1.0.7: - dependencies: - call-bind: 1.0.8 - for-each: 0.3.5 - gopd: 1.2.0 - is-typed-array: 1.1.15 - possible-typed-array-names: 1.1.0 - reflect.getprototypeof: 1.0.10 - - typedarray@0.0.6: {} - - typescript@5.9.2: {} - - uglify-js@3.19.3: - optional: true - - unbox-primitive@1.1.0: - dependencies: - call-bound: 1.0.4 - has-bigints: 1.1.0 - has-symbols: 1.1.0 - which-boxed-primitive: 1.1.1 - - undici-types@6.21.0: {} - - undici@7.16.0: {} - - unicorn-magic@0.3.0: {} - - unified@11.0.5: - dependencies: - '@types/unist': 3.0.3 - bail: 2.0.2 - devlop: 1.1.0 - extend: 3.0.2 - is-plain-obj: 4.1.0 - trough: 2.2.0 - vfile: 6.0.3 - - unique-filename@3.0.0: - dependencies: - unique-slug: 4.0.0 - - unique-slug@4.0.0: - dependencies: - imurmurhash: 0.1.4 - - unist-util-is@6.0.0: - dependencies: - '@types/unist': 3.0.3 - - unist-util-position@5.0.0: - dependencies: - '@types/unist': 3.0.3 - - unist-util-stringify-position@4.0.0: - dependencies: - '@types/unist': 3.0.3 - - unist-util-visit-parents@6.0.1: - dependencies: - '@types/unist': 3.0.3 - unist-util-is: 6.0.0 - - unist-util-visit@5.0.0: - dependencies: - '@types/unist': 3.0.3 - unist-util-is: 6.0.0 - unist-util-visit-parents: 6.0.1 - - universal-user-agent@6.0.1: {} - - universalify@2.0.1: {} - - unrs-resolver@1.11.1: - dependencies: - napi-postinstall: 0.3.3 - optionalDependencies: - '@unrs/resolver-binding-android-arm-eabi': 1.11.1 - '@unrs/resolver-binding-android-arm64': 1.11.1 - '@unrs/resolver-binding-darwin-arm64': 1.11.1 - '@unrs/resolver-binding-darwin-x64': 1.11.1 - '@unrs/resolver-binding-freebsd-x64': 1.11.1 - '@unrs/resolver-binding-linux-arm-gnueabihf': 1.11.1 - '@unrs/resolver-binding-linux-arm-musleabihf': 1.11.1 - '@unrs/resolver-binding-linux-arm64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-arm64-musl': 1.11.1 - '@unrs/resolver-binding-linux-ppc64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-riscv64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-riscv64-musl': 1.11.1 - '@unrs/resolver-binding-linux-s390x-gnu': 1.11.1 - '@unrs/resolver-binding-linux-x64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-x64-musl': 1.11.1 - '@unrs/resolver-binding-wasm32-wasi': 1.11.1 - '@unrs/resolver-binding-win32-arm64-msvc': 1.11.1 - '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 - '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 - - until-async@3.0.2: {} - - upath@2.0.1: {} - - update-browserslist-db@1.1.3(browserslist@4.26.2): - dependencies: - browserslist: 4.26.2 - escalade: 3.2.0 - picocolors: 1.1.1 - - uqr@0.1.2: {} - - uri-js@4.4.1: - dependencies: - punycode: 2.3.1 - - use-callback-ref@1.3.3(@types/react@18.3.24)(react@18.3.1): - dependencies: - react: 18.3.1 - tslib: 2.8.1 - optionalDependencies: - '@types/react': 18.3.24 - - use-debounce@10.0.6(react@18.3.1): - dependencies: - react: 18.3.1 - - use-sidecar@1.1.3(@types/react@18.3.24)(react@18.3.1): - dependencies: - detect-node-es: 1.1.0 - react: 18.3.1 - tslib: 2.8.1 - optionalDependencies: - '@types/react': 18.3.24 - - use-sync-external-store@1.5.0(react@18.3.1): - dependencies: - react: 18.3.1 - - util-deprecate@1.0.2: {} - - uuid@10.0.0: {} - - uuid@11.1.0: {} - - v8-compile-cache-lib@3.0.1: {} - - v8-to-istanbul@9.3.0: - dependencies: - '@jridgewell/trace-mapping': 0.3.31 - '@types/istanbul-lib-coverage': 2.0.6 - convert-source-map: 2.0.0 - - validate-npm-package-license@3.0.4: - dependencies: - spdx-correct: 3.2.0 - spdx-expression-parse: 3.0.1 - - validate-npm-package-name@5.0.1: {} - - vfile-message@4.0.3: - dependencies: - '@types/unist': 3.0.3 - unist-util-stringify-position: 4.0.0 - - vfile@6.0.3: - dependencies: - '@types/unist': 3.0.3 - vfile-message: 4.0.3 - - w3c-xmlserializer@5.0.0: - dependencies: - xml-name-validator: 5.0.0 - - walk-up-path@3.0.1: {} - - walker@1.0.8: - dependencies: - makeerror: 1.0.12 - - wcwidth@1.0.1: - dependencies: - defaults: 1.0.4 - - web-streams-polyfill@3.3.3: {} - - webidl-conversions@3.0.1: {} - - webidl-conversions@7.0.0: {} - - whatwg-encoding@3.1.1: - dependencies: - iconv-lite: 0.6.3 - - whatwg-fetch@3.6.20: {} - - whatwg-mimetype@4.0.0: {} - - whatwg-url@14.2.0: - dependencies: - tr46: 5.1.1 - webidl-conversions: 7.0.0 - - whatwg-url@5.0.0: - dependencies: - tr46: 0.0.3 - webidl-conversions: 3.0.1 - - which-boxed-primitive@1.1.1: - dependencies: - is-bigint: 1.1.0 - is-boolean-object: 1.2.2 - is-number-object: 1.1.1 - is-string: 1.1.1 - is-symbol: 1.1.1 - - which-builtin-type@1.2.1: - dependencies: - call-bound: 1.0.4 - function.prototype.name: 1.1.8 - has-tostringtag: 1.0.2 - is-async-function: 2.1.1 - is-date-object: 1.1.0 - is-finalizationregistry: 1.1.1 - is-generator-function: 1.1.0 - is-regex: 1.2.1 - is-weakref: 1.1.1 - isarray: 2.0.5 - which-boxed-primitive: 1.1.1 - which-collection: 1.0.2 - which-typed-array: 1.1.19 - - which-collection@1.0.2: - dependencies: - is-map: 2.0.3 - is-set: 2.0.3 - is-weakmap: 2.0.2 - is-weakset: 2.0.4 - - which-typed-array@1.1.19: - dependencies: - available-typed-arrays: 1.0.7 - call-bind: 1.0.8 - call-bound: 1.0.4 - for-each: 0.3.5 - get-proto: 1.0.1 - gopd: 1.2.0 - has-tostringtag: 1.0.2 - - which@2.0.2: - dependencies: - isexe: 2.0.0 - - which@4.0.0: - dependencies: - isexe: 3.1.1 - - wide-align@1.1.5: - dependencies: - string-width: 4.2.3 - - word-wrap@1.2.5: {} - - wordwrap@1.0.0: {} - - wrap-ansi@6.2.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - wrap-ansi@7.0.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - wrap-ansi@8.1.0: - dependencies: - ansi-styles: 6.2.3 - string-width: 5.1.2 - strip-ansi: 7.1.2 - - wrappy@1.0.2: {} - - write-file-atomic@2.4.3: - dependencies: - graceful-fs: 4.2.11 - imurmurhash: 0.1.4 - signal-exit: 3.0.7 - - write-file-atomic@4.0.2: - dependencies: - imurmurhash: 0.1.4 - signal-exit: 3.0.7 - - write-file-atomic@5.0.1: - dependencies: - imurmurhash: 0.1.4 - signal-exit: 4.1.0 - - write-json-file@3.2.0: - dependencies: - detect-indent: 5.0.0 - graceful-fs: 4.2.11 - make-dir: 2.1.0 - pify: 4.0.1 - sort-keys: 2.0.0 - write-file-atomic: 2.4.3 - - write-pkg@4.0.0: - dependencies: - sort-keys: 2.0.0 - type-fest: 0.4.1 - write-json-file: 3.2.0 - - ws@8.18.3: {} - - xml-name-validator@5.0.0: {} - - xmlchars@2.2.0: {} - - xtend@4.0.2: {} - - y18n@5.0.8: {} - - yallist@3.1.1: {} - - yallist@4.0.0: {} - - yaml@2.8.1: {} - - yargs-parser@20.2.9: {} - - yargs-parser@21.1.1: {} - - yargs@16.2.0: - dependencies: - cliui: 7.0.4 - escalade: 3.2.0 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 20.2.9 - - yargs@17.7.2: - dependencies: - cliui: 8.0.1 - escalade: 3.2.0 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 21.1.1 - - yn@3.1.1: {} - - yocto-queue@0.1.0: {} - - yoctocolors-cjs@2.1.3: {} - - zwitch@2.0.4: {} diff --git a/interweb/pnpm-workspace.yaml b/interweb/pnpm-workspace.yaml deleted file mode 100644 index ca0f302..0000000 --- a/interweb/pnpm-workspace.yaml +++ /dev/null @@ -1,2 +0,0 @@ -packages: - - 'packages/*' \ No newline at end of file diff --git a/interweb/tsconfig.json b/interweb/tsconfig.json deleted file mode 100644 index 271e6b4..0000000 --- a/interweb/tsconfig.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "module": "commonjs", - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "strict": true, - "strictNullChecks": false, - "skipLibCheck": true, - "sourceMap": false, - "declaration": true, - "resolveJsonModule": true, - "moduleResolution": "node" - } -} From 9cce2a9c48d49b0901b21f42cdceea128538fa82 Mon Sep 17 00:00:00 2001 From: Anmol1696 Date: Sat, 8 Nov 2025 10:31:56 +0400 Subject: [PATCH 06/11] fix linter --- .eslintignore | 5 + apps/ops-dashboard/.eslintignore | 5 + apps/ops-dashboard/.eslintrc.js | 17 + apps/ops-dashboard/__mocks__/browser.ts | 9 +- apps/ops-dashboard/__mocks__/handlers.ts | 16 +- .../__mocks__/handlers/backups.ts | 65 +- .../__mocks__/handlers/cluster.ts | 32 +- .../__mocks__/handlers/common.ts | 2 +- .../__mocks__/handlers/configmaps.ts | 109 +- .../__mocks__/handlers/cronjobs.ts | 91 +- .../__mocks__/handlers/daemonsets.ts | 91 +- .../__mocks__/handlers/databases.ts | 127 +- .../__mocks__/handlers/deployments.ts | 143 +- .../__mocks__/handlers/endpoints.ts | 85 +- .../__mocks__/handlers/endpointslices.ts | 32 +- apps/ops-dashboard/__mocks__/handlers/hpas.ts | 85 +- .../ops-dashboard/__mocks__/handlers/index.ts | 4 +- .../__mocks__/handlers/ingresses.ts | 85 +- apps/ops-dashboard/__mocks__/handlers/jobs.ts | 85 +- .../__mocks__/handlers/namespaces.ts | 63 +- .../__mocks__/handlers/networkpolicies.ts | 85 +- .../__mocks__/handlers/operators.ts | 58 +- apps/ops-dashboard/__mocks__/handlers/pdbs.ts | 69 +- apps/ops-dashboard/__mocks__/handlers/pods.ts | 97 +- .../__mocks__/handlers/priorityclasses.ts | 47 +- apps/ops-dashboard/__mocks__/handlers/pvcs.ts | 36 +- apps/ops-dashboard/__mocks__/handlers/pvs.ts | 30 +- .../__mocks__/handlers/replicasets.ts | 119 +- .../__mocks__/handlers/resourcequotas.ts | 60 +- .../__mocks__/handlers/rolebindings.ts | 60 +- .../ops-dashboard/__mocks__/handlers/roles.ts | 46 +- .../__mocks__/handlers/runtimeclasses.ts | 47 +- .../__mocks__/handlers/secrets.ts | 119 +- .../__mocks__/handlers/serviceaccounts.ts | 36 +- .../__mocks__/handlers/services.ts | 115 +- .../__mocks__/handlers/statefulsets.ts | 101 +- .../__mocks__/handlers/storageclasses.ts | 24 +- .../__mocks__/handlers/volumeattachments.ts | 26 +- apps/ops-dashboard/__mocks__/server.ts | 7 +- .../__tests__/app/admin/backups/page.test.tsx | 9 +- .../app/admin/databases/page.test.tsx | 12 +- .../app/admin/operators/page.test.tsx | 7 +- .../__tests__/app/admin/page.test.tsx | 1 + .../__tests__/app/admin/pods/page.test.tsx | 5 +- .../app/admin/services/page.test.tsx | 1 + .../[namespace]/[name]/backups.test.ts | 1 + .../[namespace]/[name]/deploy.test.ts | 1 + .../[namespace]/[name]/status.test.ts | 1 + .../__tests__/app/api/init.test.ts | 3 +- .../__tests__/app/api/operators.test.ts | 1 + .../api/operators/[operator]/debug.test.ts | 1 + .../api/operators/[operator]/install.test.ts | 3 +- .../api/operators/[operator]/status.test.ts | 1 + .../__tests__/app/d/chains/page.test.tsx | 1 + .../__tests__/app/d/databases/page.test.tsx | 1 + .../__tests__/app/d/functions/page.test.tsx | 1 + .../__tests__/app/d/page.test.tsx | 1 + .../__tests__/app/d/registry/page.test.tsx | 1 + .../__tests__/app/d/relayers/page.test.tsx | 1 + .../__tests__/app/d/settings/page.test.tsx | 1 + .../__tests__/app/databases/page.test.tsx | 1 + .../__tests__/app/functions/page.test.tsx | 1 + .../__tests__/app/i/all/page.test.tsx | 1 + .../__tests__/app/i/configmaps/page.test.tsx | 1 + .../__tests__/app/i/cronjobs/page.test.tsx | 1 + .../__tests__/app/i/daemonsets/page.test.tsx | 1 + .../__tests__/app/i/deployments/page.test.tsx | 1 + .../__tests__/app/i/endpoints/page.test.tsx | 1 + .../app/i/endpointslices/page.test.tsx | 1 + .../__tests__/app/i/events/page.test.tsx | 1 + .../__tests__/app/i/hpas/page.test.tsx | 1 + .../__tests__/app/i/ingresses/page.test.tsx | 1 + .../__tests__/app/i/jobs/page.test.tsx | 1 + .../app/i/networkpolicies/page.test.tsx | 1 + .../__tests__/app/i/page.test.tsx | 1 + .../__tests__/app/i/pdbs/page.test.tsx | 1 + .../__tests__/app/i/pods/page.test.tsx | 1 + .../app/i/priorityclasses/page.test.tsx | 1 + .../__tests__/app/i/pvcs/page.test.tsx | 1 + .../__tests__/app/i/pvs/page.test.tsx | 1 + .../__tests__/app/i/replicasets/page.test.tsx | 1 + .../app/i/resourcequotas/page.test.tsx | 1 + .../app/i/rolebindings/page.test.tsx | 1 + .../__tests__/app/i/roles/page.test.tsx | 1 + .../app/i/runtimeclasses/page.test.tsx | 1 + .../__tests__/app/i/secrets/page.test.tsx | 1 + .../app/i/serviceaccounts/page.test.tsx | 1 + .../__tests__/app/i/services/page.test.tsx | 1 + .../app/i/statefulsets/page.test.tsx | 1 + .../app/i/storageclasses/page.test.tsx | 1 + .../__tests__/app/i/templates/page.test.tsx | 1 + .../app/i/volumeattachments/page.test.tsx | 1 + .../__tests__/app/layout.test.tsx | 1 + .../ops-dashboard/__tests__/app/page.test.tsx | 1 + .../__tests__/app/providers.test.tsx | 3 +- .../components/adaptive-layout.test.tsx | 2 +- .../admin/cluster-overview.test.tsx | 217 +- .../components/admin/operator-card.test.tsx | 103 +- .../admin/operator-filters.test.tsx | 396 ++-- .../components/admin/operator-grid.test.tsx | 81 +- .../components/admin/quick-actions.test.tsx | 53 +- .../components/admin/recent-activity.test.tsx | 255 +-- .../admin/resource-summary.test.tsx | 53 +- .../admin/status-indicator.test.tsx | 83 +- .../__tests__/components/app-layout.test.tsx | 3 +- .../components/common/spinner.test.tsx | 1 + .../components/context-switcher.test.tsx | 1 - .../components/create-backup-dialog.test.tsx | 268 +-- .../create-databases-dialog.test.tsx | 271 +-- .../create-deployment-dialog.test.tsx | 236 +- .../components/dashboard-layout.test.tsx | 8 +- .../components/headers/admin-header.test.tsx | 1 + .../components/headers/infra-header.test.tsx | 6 +- .../headers/smart-objects-header.test.tsx | 1 + .../components/namespace-switcher.test.tsx | 10 +- .../resources/all-resources.test.tsx | 429 ++-- .../components/resources/configmaps.test.tsx | 19 +- .../components/resources/cronjobs.test.tsx | 439 ++-- .../components/resources/daemonsets.test.tsx | 215 +- .../components/resources/deployments.test.tsx | 1182 +++++----- .../components/resources/endpoints.test.tsx | 453 ++-- .../resources/endpointslices.test.tsx | 327 +-- .../components/resources/events.test.tsx | 3 +- .../components/resources/hpas.test.tsx | 477 ++-- .../components/resources/ingresses.test.tsx | 463 ++-- .../components/resources/jobs.test.tsx | 411 ++-- .../resources/networkpolicies.test.tsx | 448 ++-- .../components/resources/pdbs.test.tsx | 17 +- .../components/resources/pods.test.tsx | 36 +- .../resources/priorityclasses.test.tsx | 18 +- .../components/resources/pvcs.test.tsx | 477 ++-- .../components/resources/pvs.test.tsx | 595 +++-- .../components/resources/replicasets.test.tsx | 124 +- .../resources/resourcequotas.test.tsx | 359 ++- .../resources/rolebindings.test.tsx | 439 ++-- .../components/resources/roles.test.tsx | 433 ++-- .../resources/runtimeclasses.test.tsx | 18 +- .../components/resources/secrets.test.tsx | 15 +- .../resources/serviceaccounts.test.tsx | 423 ++-- .../components/resources/services.test.tsx | 15 +- .../resources/statefulsets.test.tsx | 412 ++-- .../resources/storageclasses.test.tsx | 417 ++-- .../resources/volumeattachments.test.tsx | 302 +-- .../scale-deployment-dialog.test.tsx | 338 +-- .../components/template-dialog.test.tsx | 227 +- .../__tests__/components/templates.test.tsx | 237 +- .../components/theme-toggle.test.tsx | 3 +- .../view-edit-deployment-dialog.test.tsx | 226 +- .../__tests__/components/yaml-editor.test.tsx | 184 +- apps/ops-dashboard/__tests__/e2e/setup.ts | 2 +- .../__tests__/e2e/utils/deployment-helpers.ts | 8 +- .../__tests__/e2e/utils/page-objects.ts | 2 +- .../__tests__/e2e/utils/page-verification.ts | 2 +- .../__tests__/e2e/utils/test-helpers.ts | 2 +- .../__tests__/e2e/utils/workflow-helpers.ts | 5 +- .../e2e/workflow-deployment-lifecycle.spec.ts | 20 +- ...workflow-operator-database-focused.spec.ts | 4 +- .../__tests__/hooks/use-breakpoint.test.ts | 1 + .../hooks/use-cluster-status.test.tsx | 95 +- .../hooks/use-copy-to-clipboard.test.ts | 151 +- .../hooks/use-database-status.test.tsx | 141 +- .../hooks/use-google-analytics.test.tsx | 133 +- .../__tests__/hooks/use-image-cache.test.tsx | 218 +- .../__tests__/hooks/use-is-mounted.test.ts | 63 +- .../__tests__/hooks/use-media-query.test.ts | 89 +- .../__tests__/hooks/use-pagination.test.ts | 137 +- .../__tests__/hooks/use-routes.test.ts | 131 +- .../__tests__/hooks/use-search-data.test.ts | 118 +- .../__tests__/hooks/use-show-more.test.ts | 123 +- .../__tests__/hooks/use-toast.test.ts | 183 +- .../hooks/use-window-dimensions.test.ts | 93 +- .../__tests__/hooks/useAppMode.test.tsx | 148 +- .../__tests__/hooks/useConfigMaps.test.tsx | 401 ++-- .../__tests__/hooks/useConfirm.test.tsx | 80 +- .../__tests__/hooks/useDaemonSets.test.tsx | 295 +-- .../__tests__/hooks/useDatabases.test.tsx | 259 +-- .../__tests__/hooks/useDebounce.test.ts | 97 +- .../__tests__/hooks/useDeployments.test.tsx | 398 ++-- .../__tests__/hooks/useNamespaces.test.tsx | 337 ++- .../__tests__/hooks/useOperators.test.tsx | 378 ++- .../__tests__/hooks/usePods.test.tsx | 414 ++-- .../hooks/usePreferredNamespace.test.tsx | 134 +- .../__tests__/hooks/useReplicaSets.test.tsx | 399 ++-- .../__tests__/hooks/useSecrets.test.tsx | 437 ++-- .../__tests__/hooks/useServices.test.tsx | 399 ++-- .../__tests__/lib/agents/bradie.test.ts | 2 +- .../__tests__/lib/agents/index.test.ts | 2 +- .../__tests__/lib/agents/types.test.ts | 2 +- .../__tests__/lib/agents/utils-simple.test.ts | 10 +- .../__tests__/lib/agents/utils.test.ts | 10 +- .../ops-dashboard/__tests__/lib/color.test.ts | 2 +- .../__tests__/lib/format.test.ts | 12 +- .../__tests__/lib/markdown.test.ts | 11 +- .../ops-dashboard/__tests__/lib/utils.test.ts | 12 +- .../ops-dashboard/__tests__/msw-basic.test.ts | 76 +- apps/ops-dashboard/__tests__/setup.test.ts | 35 +- apps/ops-dashboard/__tests__/setup.test.tsx | 35 +- .../__tests__/utils/test-utils.tsx | 31 +- apps/ops-dashboard/app/admin/backups/page.tsx | 37 +- .../app/admin/databases/page.tsx | 53 +- .../app/admin/operators/page.tsx | 7 +- apps/ops-dashboard/app/admin/pods/page.tsx | 4 +- .../ops-dashboard/app/admin/services/page.tsx | 4 +- .../app/admin/templates/page.tsx | 39 +- .../[namespace]/[name]/backups/route.ts | 6 +- .../[namespace]/[name]/deploy/route.ts | 2 +- .../[namespace]/[name]/status/route.ts | 2 +- apps/ops-dashboard/app/api/init/route.ts | 22 +- .../app/api/instance-id/route.ts | 14 +- .../app/api/k8s/[...path]/route.ts | 14 +- .../api/operators/[operator]/debug/route.ts | 1 + .../api/operators/[operator]/install/route.ts | 7 +- apps/ops-dashboard/app/api/operators/route.ts | 3 +- .../app/api/templates/[template]/route.ts | 96 +- apps/ops-dashboard/app/d/chains/page.tsx | 11 +- apps/ops-dashboard/app/d/databases/page.tsx | 11 +- apps/ops-dashboard/app/d/functions/page.tsx | 11 +- apps/ops-dashboard/app/d/page.tsx | 5 +- apps/ops-dashboard/app/d/registry/page.tsx | 11 +- apps/ops-dashboard/app/d/relayers/page.tsx | 11 +- apps/ops-dashboard/app/d/settings/page.tsx | 10 +- apps/ops-dashboard/app/databases/page.tsx | 9 +- apps/ops-dashboard/app/functions/page.tsx | 9 +- apps/ops-dashboard/app/i/all/page.tsx | 4 +- apps/ops-dashboard/app/i/configmaps/page.tsx | 4 +- apps/ops-dashboard/app/i/cronjobs/page.tsx | 4 +- apps/ops-dashboard/app/i/daemonsets/page.tsx | 4 +- apps/ops-dashboard/app/i/deployments/page.tsx | 4 +- apps/ops-dashboard/app/i/endpoints/page.tsx | 4 +- .../app/i/endpointslices/page.tsx | 4 +- apps/ops-dashboard/app/i/events/page.tsx | 4 +- apps/ops-dashboard/app/i/hpas/page.tsx | 4 +- apps/ops-dashboard/app/i/ingresses/page.tsx | 4 +- apps/ops-dashboard/app/i/jobs/page.tsx | 4 +- .../app/i/networkpolicies/page.tsx | 4 +- apps/ops-dashboard/app/i/page.tsx | 6 +- apps/ops-dashboard/app/i/pdbs/page.tsx | 4 +- apps/ops-dashboard/app/i/pods/page.tsx | 4 +- .../app/i/priorityclasses/page.tsx | 4 +- apps/ops-dashboard/app/i/pvcs/page.tsx | 4 +- apps/ops-dashboard/app/i/pvs/page.tsx | 4 +- apps/ops-dashboard/app/i/replicasets/page.tsx | 4 +- .../app/i/resourcequotas/page.tsx | 4 +- .../ops-dashboard/app/i/rolebindings/page.tsx | 4 +- apps/ops-dashboard/app/i/roles/page.tsx | 4 +- .../app/i/runtimeclasses/page.tsx | 4 +- apps/ops-dashboard/app/i/secrets/page.tsx | 4 +- .../app/i/serviceaccounts/page.tsx | 4 +- apps/ops-dashboard/app/i/services/page.tsx | 4 +- .../ops-dashboard/app/i/statefulsets/page.tsx | 4 +- .../app/i/storageclasses/page.tsx | 4 +- .../app/i/volumeattachments/page.tsx | 4 +- apps/ops-dashboard/app/layout.tsx | 9 +- apps/ops-dashboard/app/page.tsx | 14 +- apps/ops-dashboard/app/providers.tsx | 6 +- .../components/adaptive-layout.tsx | 1 + .../components/admin/cluster-overview.tsx | 5 +- .../components/admin/operator-card.tsx | 15 +- .../components/admin/operator-filters.tsx | 3 +- .../components/admin/operator-grid.tsx | 7 +- .../components/admin/quick-actions.tsx | 5 +- .../components/admin/recent-activity.tsx | 3 +- .../components/admin/status-indicator.tsx | 3 +- .../components/admin/template-card.tsx | 120 +- .../components/admin/template-filters.tsx | 11 +- .../components/agent-manager-agentic.tsx | 234 +- .../components/agent-manager-global.tsx | 191 +- .../components/ai-chat-agentic.tsx | 211 +- .../components/ai-chat-global.tsx | 233 +- apps/ops-dashboard/components/app-layout.tsx | 1 + .../components/context-switcher.tsx | 66 +- .../components/create-backup-dialog.tsx | 76 +- .../components/create-databases-dialog.tsx | 75 +- .../components/create-deployment-dialog.tsx | 51 +- .../components/dashboard-layout.tsx | 91 +- .../components/headers/admin-header.tsx | 11 +- .../components/headers/infra-header.tsx | 17 +- .../headers/smart-objects-header.tsx | 11 +- .../components/namespace-switcher.tsx | 23 +- .../components/resources/all-resources.tsx | 102 +- .../components/resources/configmaps.tsx | 171 +- .../components/resources/cronjobs.tsx | 155 +- .../components/resources/daemonsets.tsx | 100 +- .../components/resources/deployments.tsx | 203 +- .../components/resources/endpoints.tsx | 148 +- .../components/resources/endpointslices.tsx | 141 +- .../components/resources/events.tsx | 135 +- .../components/resources/hpas.tsx | 156 +- .../components/resources/ingresses.tsx | 120 +- .../components/resources/jobs.tsx | 137 +- .../components/resources/networkpolicies.tsx | 110 +- .../components/resources/pdbs.tsx | 128 +- .../components/resources/pods.tsx | 148 +- .../components/resources/priorityclasses.tsx | 70 +- .../components/resources/pvcs.tsx | 162 +- .../components/resources/pvs.tsx | 178 +- .../components/resources/replicasets.tsx | 125 +- .../components/resources/resourcequotas.tsx | 100 +- .../components/resources/rolebindings.tsx | 128 +- .../components/resources/roles.tsx | 150 +- .../components/resources/runtimeclasses.tsx | 76 +- .../components/resources/secrets.tsx | 249 +- .../components/resources/serviceaccounts.tsx | 149 +- .../components/resources/services.tsx | 109 +- .../components/resources/statefulsets.tsx | 127 +- .../components/resources/storageclasses.tsx | 100 +- .../resources/volumeattachments.tsx | 128 +- .../components/scale-deployment-dialog.tsx | 77 +- .../components/templates/template-dialog.tsx | 153 +- .../components/templates/templates.tsx | 56 +- .../ops-dashboard/components/ui/accordion.tsx | 46 +- .../components/ui/alert-dialog.tsx | 84 +- apps/ops-dashboard/components/ui/alert.tsx | 5 +- apps/ops-dashboard/components/ui/avatar.tsx | 26 +- apps/ops-dashboard/components/ui/badge.tsx | 2 +- .../components/ui/breadcrumb.tsx | 88 +- apps/ops-dashboard/components/ui/button.tsx | 2 +- apps/ops-dashboard/components/ui/card.tsx | 2 +- apps/ops-dashboard/components/ui/carousel.tsx | 350 +-- apps/ops-dashboard/components/ui/checkbox.tsx | 26 +- .../components/ui/confirm-dialog.tsx | 3 +- .../components/ui/context-menu.tsx | 186 +- apps/ops-dashboard/components/ui/dialog.tsx | 12 +- .../components/ui/dropdown-menu.tsx | 14 +- apps/ops-dashboard/components/ui/form.tsx | 170 +- apps/ops-dashboard/components/ui/kbd.tsx | 78 +- apps/ops-dashboard/components/ui/label.tsx | 2 +- apps/ops-dashboard/components/ui/lightbox.tsx | 167 +- .../components/ui/overflow-list.tsx | 432 ++-- .../components/ui/pagination.tsx | 58 +- apps/ops-dashboard/components/ui/popover.tsx | 28 +- .../components/ui/radio-group.tsx | 32 +- .../components/ui/scroll-area.tsx | 38 +- apps/ops-dashboard/components/ui/select.tsx | 14 +- apps/ops-dashboard/components/ui/skeleton.tsx | 2 +- apps/ops-dashboard/components/ui/switch.tsx | 3 +- .../components/ui/tab-scroller.tsx | 212 +- apps/ops-dashboard/components/ui/table.tsx | 2 +- apps/ops-dashboard/components/ui/tabs.tsx | 5 +- .../components/ui/theme-toggle.tsx | 3 +- apps/ops-dashboard/components/ui/toast.tsx | 14 +- apps/ops-dashboard/components/ui/toaster.tsx | 38 +- apps/ops-dashboard/components/ui/tooltip.tsx | 26 +- apps/ops-dashboard/components/ui/treeview.tsx | 198 +- .../view-edit-deployment-dialog.tsx | 91 +- apps/ops-dashboard/components/yaml-editor.tsx | 34 +- apps/ops-dashboard/contexts/AppContext.tsx | 16 +- .../contexts/NamespaceContext.tsx | 2 +- apps/ops-dashboard/eslint.config.js | 17 - apps/ops-dashboard/hooks/index.ts | 18 +- apps/ops-dashboard/hooks/use-breakpoint.ts | 22 +- .../ops-dashboard/hooks/use-cluster-status.ts | 2 +- .../hooks/use-copy-to-clipboard.ts | 40 +- apps/ops-dashboard/hooks/use-debounce.ts | 22 +- .../hooks/use-google-analytics.ts | 34 +- apps/ops-dashboard/hooks/use-image-cache.ts | 76 +- apps/ops-dashboard/hooks/use-is-mounted.ts | 10 +- apps/ops-dashboard/hooks/use-media-query.ts | 38 +- apps/ops-dashboard/hooks/use-operators.ts | 2 +- apps/ops-dashboard/hooks/use-pagination.ts | 182 +- apps/ops-dashboard/hooks/use-search-data.ts | 83 +- apps/ops-dashboard/hooks/use-show-more.ts | 14 +- apps/ops-dashboard/hooks/use-templates.ts | 61 +- apps/ops-dashboard/hooks/use-toast.ts | 234 +- .../hooks/use-window-dimensions.ts | 34 +- apps/ops-dashboard/hooks/useConfigMaps.ts | 45 +- apps/ops-dashboard/hooks/useConfirm.tsx | 89 +- apps/ops-dashboard/hooks/useDaemonSets.ts | 28 +- apps/ops-dashboard/hooks/useDatabases.ts | 2 +- apps/ops-dashboard/hooks/useDeployments.ts | 51 +- apps/ops-dashboard/hooks/useNamespaces.ts | 22 +- apps/ops-dashboard/hooks/usePods.ts | 46 +- apps/ops-dashboard/hooks/useReplicaSets.ts | 39 +- apps/ops-dashboard/hooks/useSecrets.ts | 77 +- apps/ops-dashboard/hooks/useServices.ts | 47 +- apps/ops-dashboard/jest.polyfills.js | 12 +- apps/ops-dashboard/jest.setup.js | 42 +- apps/ops-dashboard/k8s/client.tsx | 2 +- apps/ops-dashboard/k8s/context.tsx | 32 +- apps/ops-dashboard/k8s/index.ts | 2031 ++++++++--------- apps/ops-dashboard/lib/agents/bradie.ts | 74 +- apps/ops-dashboard/lib/agents/index.ts | 8 +- apps/ops-dashboard/lib/agents/utils.ts | 48 +- apps/ops-dashboard/lib/color.ts | 24 +- apps/ops-dashboard/lib/constants.ts | 4 +- apps/ops-dashboard/lib/create-fluid-value.ts | 26 +- apps/ops-dashboard/lib/dom.ts | 4 +- apps/ops-dashboard/lib/format.ts | 22 +- apps/ops-dashboard/lib/logger.ts | 72 +- apps/ops-dashboard/lib/markdown.ts | 96 +- apps/ops-dashboard/lib/utils.ts | 168 +- apps/ops-dashboard/postcss.config.js | 2 +- .../services/kubernetes-client.ts | 68 +- apps/ops-dashboard/tailwind.config.ts | 3 +- packages/cli/.eslintignore | 3 + packages/cli/jest.config.js | 30 +- packages/cli/src/commands.ts | 20 +- packages/cli/src/commands/apply.ts | 124 +- packages/cli/src/commands/cluster-info.ts | 6 +- packages/cli/src/commands/config-handler.ts | 12 +- packages/cli/src/commands/config.ts | 5 +- packages/cli/src/commands/delete.ts | 203 +- packages/cli/src/commands/deploy.ts | 203 +- packages/cli/src/commands/describe.ts | 123 +- packages/cli/src/commands/exec.ts | 7 +- packages/cli/src/commands/get.ts | 81 +- packages/cli/src/commands/logs.ts | 5 +- packages/cli/src/commands/port-forward.ts | 7 +- packages/cli/src/config.ts | 2 +- packages/cli/src/types.ts | 9 + packages/cli/src/utils.ts | 22 +- packages/kubernetesjs/jest.config.js | 30 +- packages/kubernetesjs/scripts/codegen.ts | 3 +- packages/kubernetesjs/scripts/deploy.ts | 4 +- packages/kubernetesjs/scripts/teardown.ts | 4 +- packages/kubernetesjs/src/client.ts | 22 +- packages/kubernetesjs/src/index.ts | 16 +- packages/react/jest.config.js | 30 +- packages/react/scripts/codegen.ts | 3 +- packages/react/src/context.tsx | 30 +- packages/react/src/hooks.ts | 681 +++--- 421 files changed, 17633 insertions(+), 17528 deletions(-) create mode 100644 .eslintignore create mode 100644 apps/ops-dashboard/.eslintignore create mode 100644 apps/ops-dashboard/.eslintrc.js delete mode 100644 apps/ops-dashboard/eslint.config.js create mode 100644 packages/cli/.eslintignore create mode 100644 packages/cli/src/types.ts diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..9559ed9 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,5 @@ +node_modules/ +dist/ +**/dist/ +coverage/ + diff --git a/apps/ops-dashboard/.eslintignore b/apps/ops-dashboard/.eslintignore new file mode 100644 index 0000000..cfce2ad --- /dev/null +++ b/apps/ops-dashboard/.eslintignore @@ -0,0 +1,5 @@ +.next/ +node_modules/ +dist/ +coverage/ + diff --git a/apps/ops-dashboard/.eslintrc.js b/apps/ops-dashboard/.eslintrc.js new file mode 100644 index 0000000..5c2ff0f --- /dev/null +++ b/apps/ops-dashboard/.eslintrc.js @@ -0,0 +1,17 @@ +module.exports = { + root: false, + extends: [ + 'next', + 'next/core-web-vitals', + '../../.eslintrc.json', + ], + parser: '@typescript-eslint/parser', + parserOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + }, + rules: { + // Keep dashboard in sync with repo defaults; add overrides here if needed + }, +}; + diff --git a/apps/ops-dashboard/__mocks__/browser.ts b/apps/ops-dashboard/__mocks__/browser.ts index f804319..f1a0ea9 100644 --- a/apps/ops-dashboard/__mocks__/browser.ts +++ b/apps/ops-dashboard/__mocks__/browser.ts @@ -1,10 +1,11 @@ -import { setupWorker } from 'msw/browser' -import { baseHandlers } from './handlers' +import { setupWorker } from 'msw/browser'; + +import { baseHandlers } from './handlers'; // Create a test worker for browser environment -export const worker = setupWorker(...baseHandlers) +export const worker = setupWorker(...baseHandlers); // Export handlers for individual use -export { baseHandlers as handlers } +export { baseHandlers as handlers }; diff --git a/apps/ops-dashboard/__mocks__/handlers.ts b/apps/ops-dashboard/__mocks__/handlers.ts index a16c9b8..7616371 100644 --- a/apps/ops-dashboard/__mocks__/handlers.ts +++ b/apps/ops-dashboard/__mocks__/handlers.ts @@ -1,13 +1,13 @@ -import { http, HttpResponse, RequestHandler } from 'msw' +import { http, HttpResponse, RequestHandler } from 'msw'; // Base URL for API -const API_BASE = 'http://127.0.0.1:8001' +const API_BASE = 'http://127.0.0.1:8001'; // 基础 handlers - 总是包含的 export const baseHandlers: RequestHandler[] = [ // Simple test endpoint http.get(`${API_BASE}/api/test`, () => { - return HttpResponse.json({ message: 'Hello from MSW!' }) + return HttpResponse.json({ message: 'Hello from MSW!' }); }), // Health check endpoint @@ -15,7 +15,7 @@ export const baseHandlers: RequestHandler[] = [ return HttpResponse.json({ status: 'ok', timestamp: new Date().toISOString() - }) + }); }), // Error simulation endpoint @@ -23,18 +23,18 @@ export const baseHandlers: RequestHandler[] = [ return HttpResponse.json( { error: 'Test error' }, { status: 500 } - ) + ); }), // POST test endpoint http.post(`${API_BASE}/api/test`, async ({ request }) => { - const body = await request.json() + const body = await request.json(); return HttpResponse.json({ message: 'POST request received', receivedData: body - }) + }); }), -] +]; diff --git a/apps/ops-dashboard/__mocks__/handlers/backups.ts b/apps/ops-dashboard/__mocks__/handlers/backups.ts index 03f82eb..b458272 100644 --- a/apps/ops-dashboard/__mocks__/handlers/backups.ts +++ b/apps/ops-dashboard/__mocks__/handlers/backups.ts @@ -1,5 +1,6 @@ -import { http, HttpResponse } from "msw" -import { API_BASE } from "./common" +import { http, HttpResponse } from 'msw'; + +import { API_BASE } from './common'; export interface BackupInfo { name: string @@ -52,33 +53,33 @@ export const createBackupsListData = (): BackupInfo[] => { size: '0Gi', method: 'pg_dump' } - ] -} + ]; +}; export const createBackupsList = (backups: BackupInfo[] = createBackupsListData()) => { return http.get(`${API_BASE}/api/databases/:ns/:name/backups`, () => { - return HttpResponse.json({ backups }) - }) -} + return HttpResponse.json({ backups }); + }); +}; export const createBackupsListError = (status: number = 500, message: string = 'Internal Server Error') => { return http.get(`${API_BASE}/api/databases/:ns/:name/backups`, () => { return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; export const createBackupsListNetworkError = () => { return http.get(`${API_BASE}/api/databases/:ns/:name/backups`, () => { - return HttpResponse.error() - }) -} + return HttpResponse.error(); + }); +}; export const createCreateBackup = (ns: string, name: string) => { return http.post(`${API_BASE}/api/databases/${ns}/${name}/backups`, async ({ request }) => { - const body = await request.json() + const body = await request.json(); return HttpResponse.json({ success: true, message: `Backup created successfully for database ${name}`, @@ -93,50 +94,50 @@ export const createCreateBackup = (ns: string, name: string) => { createdAt: new Date().toISOString(), method: body.method || 'pg_dump' } - }) - }) -} + }); + }); +}; export const createCreateBackupError = (ns: string, name: string, status: number = 500, message: string = 'Backup creation failed') => { return http.post(`${API_BASE}/api/databases/${ns}/${name}/backups`, () => { return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; export const createDeleteBackup = (ns: string, name: string, backupName: string) => { return http.delete(`${API_BASE}/api/databases/${ns}/${name}/backups/${backupName}`, () => { return HttpResponse.json({ success: true, message: `Backup ${backupName} deleted successfully` - }) - }) -} + }); + }); +}; export const createDeleteBackupError = (ns: string, name: string, backupName: string, status: number = 500, message: string = 'Backup deletion failed') => { return http.delete(`${API_BASE}/api/databases/${ns}/${name}/backups/${backupName}`, () => { return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; export const createBackupLogs = (ns: string, name: string, backupName: string) => { return http.get(`${API_BASE}/api/databases/${ns}/${name}/backups/${backupName}/logs`, () => { return HttpResponse.json({ logs: `Backup logs for ${backupName}\nStarting backup...\nBackup completed successfully.` - }) - }) -} + }); + }); +}; export const createBackupLogsError = (ns: string, name: string, backupName: string, status: number = 500, message: string = 'Failed to fetch backup logs') => { return http.get(`${API_BASE}/api/databases/${ns}/${name}/backups/${backupName}/logs`, () => { return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; diff --git a/apps/ops-dashboard/__mocks__/handlers/cluster.ts b/apps/ops-dashboard/__mocks__/handlers/cluster.ts index d95e645..e15fd8d 100644 --- a/apps/ops-dashboard/__mocks__/handlers/cluster.ts +++ b/apps/ops-dashboard/__mocks__/handlers/cluster.ts @@ -1,4 +1,4 @@ -import { http, HttpResponse } from "msw" +import { http, HttpResponse } from 'msw'; export interface ClusterStatus { isConnected: boolean @@ -51,33 +51,33 @@ export const createClusterStatusData = (): ClusterStatus => { installed: 3, total: 5 } - } -} + }; +}; export const createClusterStatus = (status: ClusterStatus = createClusterStatusData()) => { return http.get('/api/cluster/status', () => { - return HttpResponse.json(status) - }) -} + return HttpResponse.json(status); + }); +}; export const createClusterStatusError = (status: number = 500, message: string = 'Failed to fetch cluster status') => { return http.get('/api/cluster/status', () => { return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; export const createClusterStatusNetworkError = () => { return http.get('/api/cluster/status', () => { - return HttpResponse.error() - }) -} + return HttpResponse.error(); + }); +}; export const createClusterStatusSlow = (delay: number = 2000) => { return http.get('/api/cluster/status', async () => { - await new Promise(resolve => setTimeout(resolve, delay)) - return HttpResponse.json(createClusterStatusData()) - }) -} + await new Promise(resolve => setTimeout(resolve, delay)); + return HttpResponse.json(createClusterStatusData()); + }); +}; diff --git a/apps/ops-dashboard/__mocks__/handlers/common.ts b/apps/ops-dashboard/__mocks__/handlers/common.ts index bb1550e..0f94761 100644 --- a/apps/ops-dashboard/__mocks__/handlers/common.ts +++ b/apps/ops-dashboard/__mocks__/handlers/common.ts @@ -1 +1 @@ -export const API_BASE = 'http://127.0.0.1:8001' +export const API_BASE = 'http://127.0.0.1:8001'; diff --git a/apps/ops-dashboard/__mocks__/handlers/configmaps.ts b/apps/ops-dashboard/__mocks__/handlers/configmaps.ts index 4c55f55..9a92391 100644 --- a/apps/ops-dashboard/__mocks__/handlers/configmaps.ts +++ b/apps/ops-dashboard/__mocks__/handlers/configmaps.ts @@ -1,6 +1,7 @@ -import { http, HttpResponse } from "msw" -import { API_BASE } from "./common" -import { V1ConfigMap } from "@kubernetesjs/ops" +import { V1ConfigMap } from '@kubernetesjs/ops'; +import { http, HttpResponse } from 'msw'; + +import { API_BASE } from './common'; export const createConfigMapsListData = (): V1ConfigMap[] => { return [ @@ -36,21 +37,21 @@ export const createConfigMapsListData = (): V1ConfigMap[] => { }, data: {} } - ] -} + ]; +}; export const createConfigMapsList = (configMaps: V1ConfigMap[] = createConfigMapsListData()) => { return http.get(`${API_BASE}/api/v1/namespaces/:namespace/configmaps`, ({ params }) => { - const namespace = params.namespace as string - const namespaceConfigMaps = configMaps.filter(cm => cm.metadata.namespace === namespace) + const namespace = params.namespace as string; + const namespaceConfigMaps = configMaps.filter(cm => cm.metadata.namespace === namespace); return HttpResponse.json({ apiVersion: 'v1', kind: 'ConfigMapList', items: namespaceConfigMaps - }) - }) -} + }); + }); +}; export const createAllConfigMapsList = (configMaps: V1ConfigMap[] = createConfigMapsListData()) => { return http.get(`${API_BASE}/api/v1/configmaps`, () => { @@ -58,9 +59,9 @@ export const createAllConfigMapsList = (configMaps: V1ConfigMap[] = createConfig apiVersion: 'v1', kind: 'ConfigMapList', items: configMaps - }) - }) -} + }); + }); +}; // Error handlers export const createConfigMapsListError = (status: number = 500, message: string = 'Internal Server Error') => { @@ -68,58 +69,58 @@ export const createConfigMapsListError = (status: number = 500, message: string return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; export const createAllConfigMapsListError = (status: number = 500, message: string = 'Internal Server Error') => { return http.get(`${API_BASE}/api/v1/configmaps`, () => { return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; // Network error handler export const createConfigMapsListNetworkError = () => { return http.get(`${API_BASE}/api/v1/namespaces/:namespace/configmaps`, () => { - return HttpResponse.error() - }) -} + return HttpResponse.error(); + }); +}; // Slow response handler for testing loading states export const createConfigMapsListSlow = (configMaps: V1ConfigMap[] = createConfigMapsListData(), delay: number = 1000) => { return http.get(`${API_BASE}/api/v1/namespaces/:namespace/configmaps`, async ({ params }) => { - await new Promise(resolve => setTimeout(resolve, delay)) - const namespace = params.namespace as string - const namespaceConfigMaps = configMaps.filter(cm => cm.metadata.namespace === namespace) + await new Promise(resolve => setTimeout(resolve, delay)); + const namespace = params.namespace as string; + const namespaceConfigMaps = configMaps.filter(cm => cm.metadata.namespace === namespace); return HttpResponse.json({ apiVersion: 'v1', kind: 'ConfigMapList', items: namespaceConfigMaps - }) - }) -} + }); + }); +}; // Get single configmap handler export const getConfigMap = (configMap: V1ConfigMap) => { return http.get(`${API_BASE}/api/v1/namespaces/:namespace/configmaps/:name`, ({ params }) => { - const name = params.name as string - const namespace = params.namespace as string + const name = params.name as string; + const namespace = params.namespace as string; if (name === configMap.metadata.name && namespace === configMap.metadata.namespace) { - return HttpResponse.json(configMap) + return HttpResponse.json(configMap); } - return HttpResponse.json({ error: 'ConfigMap not found' }, { status: 404 }) - }) -} + return HttpResponse.json({ error: 'ConfigMap not found' }, { status: 404 }); + }); +}; // Create configmap handler export const createConfigMap = () => { return http.post(`${API_BASE}/api/v1/namespaces/:namespace/configmaps`, async ({ request, params }) => { - const body = await request.json() as V1ConfigMap - const namespace = params.namespace as string + const body = await request.json() as V1ConfigMap; + const namespace = params.namespace as string; return HttpResponse.json({ ...body, @@ -130,16 +131,16 @@ export const createConfigMap = () => { uid: `cm-${body.metadata?.name || 'new-config'}`, creationTimestamp: new Date().toISOString() } - }, { status: 201 }) - }) -} + }, { status: 201 }); + }); +}; // Update configmap handler export const createConfigMapUpdate = () => { return http.put(`${API_BASE}/api/v1/namespaces/:namespace/configmaps/:name`, async ({ request, params }) => { - const body = await request.json() as V1ConfigMap - const name = params.name as string - const namespace = params.namespace as string + const body = await request.json() as V1ConfigMap; + const name = params.name as string; + const namespace = params.namespace as string; return HttpResponse.json({ ...body, @@ -150,9 +151,9 @@ export const createConfigMapUpdate = () => { resourceVersion: '12345', uid: `cm-${name}` } - }) - }) -} + }); + }); +}; // Update configmap error handler export const createConfigMapUpdateError = (status: number = 500, message: string = 'Update failed') => { @@ -160,16 +161,16 @@ export const createConfigMapUpdateError = (status: number = 500, message: string return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; // Delete configmap handler export const createConfigMapDelete = () => { return http.delete(`${API_BASE}/api/v1/namespaces/:namespace/configmaps/:name`, () => { - return HttpResponse.json({}) - }) -} + return HttpResponse.json({}); + }); +}; // Delete configmap error handler export const createConfigMapDeleteError = (status: number = 500, message: string = 'Delete failed') => { @@ -177,6 +178,6 @@ export const createConfigMapDeleteError = (status: number = 500, message: string return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; diff --git a/apps/ops-dashboard/__mocks__/handlers/cronjobs.ts b/apps/ops-dashboard/__mocks__/handlers/cronjobs.ts index 67d7939..6ed8c18 100644 --- a/apps/ops-dashboard/__mocks__/handlers/cronjobs.ts +++ b/apps/ops-dashboard/__mocks__/handlers/cronjobs.ts @@ -1,6 +1,7 @@ -import { http, HttpResponse } from "msw" -import { API_BASE } from "./common" -import { BatchV1CronJob } from "@kubernetesjs/ops" +import { BatchV1CronJob } from '@kubernetesjs/ops'; +import { http, HttpResponse } from 'msw'; + +import { API_BASE } from './common'; export const createCronJobsListData = (): BatchV1CronJob[] => { return [ @@ -111,21 +112,21 @@ export const createCronJobsListData = (): BatchV1CronJob[] => { active: [] } } - ] -} + ]; +}; export const createCronJobsList = (cronjobs: BatchV1CronJob[] = createCronJobsListData()) => { return http.get(`${API_BASE}/apis/batch/v1/namespaces/:namespace/cronjobs`, ({ params, request }) => { - const namespace = params.namespace as string - const namespaceCronJobs = cronjobs.filter(cj => cj.metadata.namespace === namespace) + const namespace = params.namespace as string; + const namespaceCronJobs = cronjobs.filter(cj => cj.metadata.namespace === namespace); return HttpResponse.json({ apiVersion: 'batch/v1', kind: 'CronJobList', items: namespaceCronJobs - }) - }) -} + }); + }); +}; export const createAllCronJobsList = (cronjobs: BatchV1CronJob[] = createCronJobsListData()) => { return http.get(`${API_BASE}/apis/batch/v1/cronjobs`, () => { @@ -133,9 +134,9 @@ export const createAllCronJobsList = (cronjobs: BatchV1CronJob[] = createCronJob apiVersion: 'batch/v1', kind: 'CronJobList', items: cronjobs - }) - }) -} + }); + }); +}; // Error handlers export const createCronJobsListError = (status: number = 500, message: string = 'Internal Server Error') => { @@ -143,79 +144,79 @@ export const createCronJobsListError = (status: number = 500, message: string = return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; export const createAllCronJobsListError = (status: number = 500, message: string = 'Internal Server Error') => { return http.get(`${API_BASE}/apis/batch/v1/cronjobs`, () => { return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; // Network error handler export const createCronJobsListNetworkError = () => { return http.get(`${API_BASE}/apis/batch/v1/namespaces/:namespace/cronjobs`, () => { - return HttpResponse.error() - }) -} + return HttpResponse.error(); + }); +}; // Slow response handler for testing loading states export const createCronJobsListSlow = (cronjobs: BatchV1CronJob[] = createCronJobsListData(), delay: number = 1000) => { return http.get(`${API_BASE}/apis/batch/v1/namespaces/:namespace/cronjobs`, async ({ params }) => { - await new Promise(resolve => setTimeout(resolve, delay)) - const namespace = params.namespace as string - const namespaceCronJobs = cronjobs.filter(cj => cj.metadata.namespace === namespace) + await new Promise(resolve => setTimeout(resolve, delay)); + const namespace = params.namespace as string; + const namespaceCronJobs = cronjobs.filter(cj => cj.metadata.namespace === namespace); return HttpResponse.json({ apiVersion: 'batch/v1', kind: 'CronJobList', items: namespaceCronJobs - }) - }) -} + }); + }); +}; // CronJob by name handler export const createCronJobByName = (cronjobs: BatchV1CronJob[] = createCronJobsListData()) => { return http.get(`${API_BASE}/apis/batch/v1/namespaces/:namespace/cronjobs/:name`, ({ params }) => { - const namespace = params.namespace as string - const name = params.name as string - const cronjob = cronjobs.find(cj => cj.metadata.namespace === namespace && cj.metadata.name === name) + const namespace = params.namespace as string; + const name = params.name as string; + const cronjob = cronjobs.find(cj => cj.metadata.namespace === namespace && cj.metadata.name === name); if (!cronjob) { return HttpResponse.json( { error: 'CronJob not found' }, { status: 404 } - ) + ); } - return HttpResponse.json(cronjob) - }) -} + return HttpResponse.json(cronjob); + }); +}; // CronJob details handler (alias for createCronJobByName) export const createCronJobDetails = (cronjob: BatchV1CronJob) => { return http.get(`${API_BASE}/apis/batch/v1/namespaces/:namespace/cronjobs/:name`, ({ params }) => { if (params.name === cronjob.metadata?.name && params.namespace === cronjob.metadata?.namespace) { - return HttpResponse.json(cronjob) + return HttpResponse.json(cronjob); } - return HttpResponse.json({ error: 'CronJob not found' }, { status: 404 }) - }) -} + return HttpResponse.json({ error: 'CronJob not found' }, { status: 404 }); + }); +}; // Delete CronJob handler export const createCronJobDelete = () => { return http.delete(`${API_BASE}/apis/batch/v1/namespaces/:namespace/cronjobs/:name`, () => { - return HttpResponse.json({}) - }) -} + return HttpResponse.json({}); + }); +}; // Patch CronJob handler (for suspend/unsuspend) export const createCronJobPatch = () => { return http.patch(`${API_BASE}/apis/batch/v1/namespaces/:namespace/cronjobs/:name`, () => { - return HttpResponse.json({}) - }) -} + return HttpResponse.json({}); + }); +}; diff --git a/apps/ops-dashboard/__mocks__/handlers/daemonsets.ts b/apps/ops-dashboard/__mocks__/handlers/daemonsets.ts index 537249a..83e6860 100644 --- a/apps/ops-dashboard/__mocks__/handlers/daemonsets.ts +++ b/apps/ops-dashboard/__mocks__/handlers/daemonsets.ts @@ -1,6 +1,7 @@ -import { http, HttpResponse } from "msw" -import { API_BASE } from "./common" -import { V1DaemonSet } from "@kubernetesjs/ops" +import { V1DaemonSet } from '@kubernetesjs/ops'; +import { http, HttpResponse } from 'msw'; + +import { API_BASE } from './common'; export const createDaemonSetsListData = (): V1DaemonSet[] => { return [ @@ -67,21 +68,21 @@ export const createDaemonSetsListData = (): V1DaemonSet[] => { numberAvailable: 0 } } - ] -} + ]; +}; export const createDaemonSetsList = (daemonSets: V1DaemonSet[] = createDaemonSetsListData()) => { return http.get(`${API_BASE}/apis/apps/v1/namespaces/:namespace/daemonsets`, ({ params }) => { - const namespace = params.namespace as string - const namespaceDaemonSets = daemonSets.filter(ds => ds.metadata.namespace === namespace) + const namespace = params.namespace as string; + const namespaceDaemonSets = daemonSets.filter(ds => ds.metadata.namespace === namespace); return HttpResponse.json({ apiVersion: 'apps/v1', kind: 'DaemonSetList', items: namespaceDaemonSets - }) - }) -} + }); + }); +}; export const createAllDaemonSetsList = (daemonSets: V1DaemonSet[] = createDaemonSetsListData()) => { return http.get(`${API_BASE}/apis/apps/v1/daemonsets`, () => { @@ -89,9 +90,9 @@ export const createAllDaemonSetsList = (daemonSets: V1DaemonSet[] = createDaemon apiVersion: 'apps/v1', kind: 'DaemonSetList', items: daemonSets - }) - }) -} + }); + }); +}; // Error handlers export const createDaemonSetsListError = (status: number = 500, message: string = 'Internal Server Error') => { @@ -99,75 +100,75 @@ export const createDaemonSetsListError = (status: number = 500, message: string return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; export const createAllDaemonSetsListError = (status: number = 500, message: string = 'Internal Server Error') => { return http.get(`${API_BASE}/apis/apps/v1/daemonsets`, () => { return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; // Network error handler export const createDaemonSetsListNetworkError = () => { return http.get(`${API_BASE}/apis/apps/v1/namespaces/:namespace/daemonsets`, () => { - return HttpResponse.error() - }) -} + return HttpResponse.error(); + }); +}; // Slow response handler for testing loading states export const createDaemonSetsListSlow = (daemonSets: V1DaemonSet[] = createDaemonSetsListData(), delay: number = 1000) => { return http.get(`${API_BASE}/apis/apps/v1/namespaces/:namespace/daemonsets`, async ({ params }) => { - await new Promise(resolve => setTimeout(resolve, delay)) - const namespace = params.namespace as string - const namespaceDaemonSets = daemonSets.filter(ds => ds.metadata.namespace === namespace) + await new Promise(resolve => setTimeout(resolve, delay)); + const namespace = params.namespace as string; + const namespaceDaemonSets = daemonSets.filter(ds => ds.metadata.namespace === namespace); return HttpResponse.json({ apiVersion: 'apps/v1', kind: 'DaemonSetList', items: namespaceDaemonSets - }) - }) -} + }); + }); +}; // DaemonSet by name handler export const createDaemonSetByName = (daemonSets: V1DaemonSet[] = createDaemonSetsListData()) => { return http.get(`${API_BASE}/apis/apps/v1/namespaces/:namespace/daemonsets/:name`, ({ params }) => { - const namespace = params.namespace as string - const name = params.name as string - const daemonSet = daemonSets.find(ds => ds.metadata.namespace === namespace && ds.metadata.name === name) + const namespace = params.namespace as string; + const name = params.name as string; + const daemonSet = daemonSets.find(ds => ds.metadata.namespace === namespace && ds.metadata.name === name); if (!daemonSet) { return HttpResponse.json( { error: 'DaemonSet not found' }, { status: 404 } - ) + ); } - return HttpResponse.json(daemonSet) - }) -} + return HttpResponse.json(daemonSet); + }); +}; // DaemonSet details handler (alias for createDaemonSetByName) export const createDaemonSetDetails = (daemonSet: V1DaemonSet) => { return http.get(`${API_BASE}/apis/apps/v1/namespaces/:namespace/daemonsets/:name`, ({ params }) => { if (params.name === daemonSet.metadata?.name && params.namespace === daemonSet.metadata?.namespace) { - return HttpResponse.json(daemonSet) + return HttpResponse.json(daemonSet); } - return HttpResponse.json({ error: 'DaemonSet not found' }, { status: 404 }) - }) -} + return HttpResponse.json({ error: 'DaemonSet not found' }, { status: 404 }); + }); +}; // Delete daemonset handler export const createDaemonSetDelete = () => { return http.delete(`${API_BASE}/apis/apps/v1/namespaces/:namespace/daemonsets/:name`, () => { - return HttpResponse.json({}) - }) -} + return HttpResponse.json({}); + }); +}; // Delete daemonset error handler export const createDaemonSetDeleteError = (status: number = 500, message: string = 'Delete failed') => { @@ -175,6 +176,6 @@ export const createDaemonSetDeleteError = (status: number = 500, message: string return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; diff --git a/apps/ops-dashboard/__mocks__/handlers/databases.ts b/apps/ops-dashboard/__mocks__/handlers/databases.ts index 48e9654..e59a398 100644 --- a/apps/ops-dashboard/__mocks__/handlers/databases.ts +++ b/apps/ops-dashboard/__mocks__/handlers/databases.ts @@ -1,5 +1,6 @@ -import { http, HttpResponse } from "msw" -import { API_BASE } from "./common" +import { http, HttpResponse } from 'msw'; + +import { API_BASE } from './common'; export interface DatabaseInfo { name: string @@ -64,29 +65,29 @@ export const createDatabasesListData = (): DatabaseInfo[] => { createdAt: '2024-01-05T10:00:00Z', description: 'Failed PostgreSQL database' } - ] -} + ]; +}; export const createDatabasesList = (databases: DatabaseInfo[] = createDatabasesListData()) => { return http.get('/api/databases', () => { - return HttpResponse.json(databases) - }) -} + return HttpResponse.json(databases); + }); +}; export const createDatabasesListError = (status: number = 500, message: string = 'Internal Server Error') => { return http.get(`${API_BASE}/api/databases`, () => { return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; export const createDatabasesListNetworkError = () => { return http.get(`${API_BASE}/api/databases`, () => { - return HttpResponse.error() - }) -} + return HttpResponse.error(); + }); +}; export const createCreateDatabase = (databaseName: string, namespace: string = 'default') => { return http.post(`${API_BASE}/api/databases`, ({ request }) => { @@ -103,54 +104,54 @@ export const createCreateDatabase = (databaseName: string, namespace: string = ' createdAt: new Date().toISOString(), description: `Database ${databaseName}` } - }) - }) -} + }); + }); +}; export const createCreateDatabaseError = (status: number = 500, message: string = 'Database creation failed') => { return http.post(`${API_BASE}/api/databases`, () => { return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; export const createDeleteDatabase = (databaseName: string, namespace: string = 'default') => { return http.delete(`${API_BASE}/api/databases/${namespace}/${databaseName}`, () => { return HttpResponse.json({ success: true, message: `Database ${databaseName} deleted successfully from namespace ${namespace}` - }) - }) -} + }); + }); +}; export const createDeleteDatabaseError = (databaseName: string, namespace: string = 'default', status: number = 500, message: string = 'Database deletion failed') => { return http.delete(`${API_BASE}/api/databases/${namespace}/${databaseName}`, () => { return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; export const createStartDatabase = (databaseName: string, namespace: string = 'default') => { return http.post(`${API_BASE}/api/databases/${namespace}/${databaseName}/start`, () => { return HttpResponse.json({ success: true, message: `Database ${databaseName} started successfully` - }) - }) -} + }); + }); +}; export const createStopDatabase = (databaseName: string, namespace: string = 'default') => { return http.post(`${API_BASE}/api/databases/${namespace}/${databaseName}/stop`, () => { return HttpResponse.json({ success: true, message: `Database ${databaseName} stopped successfully` - }) - }) -} + }); + }); +}; export const createScaleDatabase = (databaseName: string, namespace: string = 'default', replicas: number) => { return http.post(`${API_BASE}/api/databases/${namespace}/${databaseName}/scale`, ({ request }) => { @@ -158,13 +159,13 @@ export const createScaleDatabase = (databaseName: string, namespace: string = 'd success: true, message: `Database ${databaseName} scaled to ${replicas} replicas`, replicas - }) - }) -} + }); + }); +}; export const createCreateDatabaseSlow = (databaseName: string, namespace: string = 'default', delay: number = 2000) => { return http.post(`${API_BASE}/api/databases`, async () => { - await new Promise(resolve => setTimeout(resolve, delay)) + await new Promise(resolve => setTimeout(resolve, delay)); return HttpResponse.json({ success: true, message: `Database ${databaseName} created successfully in namespace ${namespace}`, @@ -178,9 +179,9 @@ export const createCreateDatabaseSlow = (databaseName: string, namespace: string createdAt: new Date().toISOString(), description: `Database ${databaseName}` } - }) - }) -} + }); + }); +}; // Database status handlers export interface DatabaseStatusSummary { @@ -267,26 +268,26 @@ export const createDatabaseStatusData = (): DatabaseStatusSummary => { restarts: 1 } ] - } -} + }; +}; export const createDatabaseStatus = (status: DatabaseStatusSummary = createDatabaseStatusData()) => { return http.get('/api/databases/:namespace/:name/status', () => { - return HttpResponse.json(status) - }) -} + return HttpResponse.json(status); + }); +}; export const createDatabaseStatusError = (status: number = 404, message: string = 'Database not found') => { return http.get('/api/databases/:namespace/:name/status', () => { - return HttpResponse.json({ error: message }, { status }) - }) -} + return HttpResponse.json({ error: message }, { status }); + }); +}; export const createDatabaseStatusNetworkError = () => { return http.get('/api/databases/:namespace/:name/status', () => { - return HttpResponse.error() - }) -} + return HttpResponse.error(); + }); +}; // Backup handlers export interface BackupInfo { @@ -320,20 +321,20 @@ export const createBackupsListData = (): BackupInfo[] => { status: 'completed', type: 'manual' } - ] -} + ]; +}; export const createBackupsList = (backups: BackupInfo[] = createBackupsListData()) => { return http.get('/api/databases/:namespace/:name/backups', () => { - return HttpResponse.json(backups) - }) -} + return HttpResponse.json(backups); + }); +}; export const createBackupsListError = (status: number = 500, message: string = 'Failed to fetch backups') => { return http.get('/api/databases/:namespace/:name/backups', () => { - return HttpResponse.json({ error: message }, { status }) - }) -} + return HttpResponse.json({ error: message }, { status }); + }); +}; export const createCreateBackup = (namespace: string, name: string, method: string = 'manual') => { return http.post('/api/databases/:namespace/:name/backups', () => { @@ -346,12 +347,12 @@ export const createCreateBackup = (namespace: string, name: string, method: stri status: 'in-progress', type: method } - }) - }) -} + }); + }); +}; export const createCreateBackupError = (status: number = 500, message: string = 'Failed to create backup') => { return http.post('/api/databases/:namespace/:name/backups', () => { - return HttpResponse.json({ error: message }, { status }) - }) -} + return HttpResponse.json({ error: message }, { status }); + }); +}; diff --git a/apps/ops-dashboard/__mocks__/handlers/deployments.ts b/apps/ops-dashboard/__mocks__/handlers/deployments.ts index 0b1e3c7..6ee2694 100644 --- a/apps/ops-dashboard/__mocks__/handlers/deployments.ts +++ b/apps/ops-dashboard/__mocks__/handlers/deployments.ts @@ -1,6 +1,7 @@ -import { http, HttpResponse } from "msw" -import { API_BASE } from "./common" -import { AppsV1Deployment } from "@kubernetesjs/ops" +import { AppsV1Deployment } from '@kubernetesjs/ops'; +import { http, HttpResponse } from 'msw'; + +import { API_BASE } from './common'; export const createDeploymentsListData = ():AppsV1Deployment[] => { return [ @@ -22,31 +23,31 @@ export const createDeploymentsListData = ():AppsV1Deployment[] => { spec: { replicas: 1, selector: { matchLabels: { app: 'redis' } }, template: { spec: { containers: [{ name: 'redis', image: 'redis:5.0.3-alpine' }] } } }, status: { readyReplicas: 1, replicas: 1 } } - ] -} + ]; +}; export const createAllDeploymentsList = (deployments: AppsV1Deployment[] = createDeploymentsListData()) =>{ - return http.get(`${API_BASE}/apis/apps/v1/deployments`, () => { - return HttpResponse.json({ - apiVersion: 'apps/v1', - kind: 'DeploymentList', - items: deployments - }) - }) -} + return http.get(`${API_BASE}/apis/apps/v1/deployments`, () => { + return HttpResponse.json({ + apiVersion: 'apps/v1', + kind: 'DeploymentList', + items: deployments + }); + }); +}; export const createDeploymentsList = (deployments: AppsV1Deployment[] = createDeploymentsListData()) =>{ - return http.get(`${API_BASE}/apis/apps/v1/namespaces/:namespace/deployments`, ({ params }) => { - const namespace = params.namespace as string - const namespaceDeployments = deployments.filter(deploy => deploy.metadata.namespace === namespace) + return http.get(`${API_BASE}/apis/apps/v1/namespaces/:namespace/deployments`, ({ params }) => { + const namespace = params.namespace as string; + const namespaceDeployments = deployments.filter(deploy => deploy.metadata.namespace === namespace); - return HttpResponse.json({ - apiVersion: 'apps/v1', - kind: 'DeploymentList', - items: namespaceDeployments - }) - }) -} + return HttpResponse.json({ + apiVersion: 'apps/v1', + kind: 'DeploymentList', + items: namespaceDeployments + }); + }); +}; // Error handlers export const createDeploymentsListError = (status: number = 500, message: string = 'Internal Server Error') => { @@ -54,40 +55,40 @@ export const createDeploymentsListError = (status: number = 500, message: string return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; export const createAllDeploymentsListError = (status: number = 500, message: string = 'Internal Server Error') => { return http.get(`${API_BASE}/apis/apps/v1/deployments`, () => { return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; // Network error handler export const createDeploymentsListNetworkError = () => { return http.get(`${API_BASE}/apis/apps/v1/namespaces/:namespace/deployments`, () => { - return HttpResponse.error() - }) -} + return HttpResponse.error(); + }); +}; // Slow response handler for testing loading states export const createDeploymentsListSlow = (deployments: AppsV1Deployment[] = createDeploymentsListData(), delay: number = 1000) => { return http.get(`${API_BASE}/apis/apps/v1/namespaces/:namespace/deployments`, async ({ params }) => { - await new Promise(resolve => setTimeout(resolve, delay)) - const namespace = params.namespace as string - const namespaceDeployments = deployments.filter(deploy => deploy.metadata.namespace === namespace) + await new Promise(resolve => setTimeout(resolve, delay)); + const namespace = params.namespace as string; + const namespaceDeployments = deployments.filter(deploy => deploy.metadata.namespace === namespace); return HttpResponse.json({ apiVersion: 'apps/v1', kind: 'DeploymentList', items: namespaceDeployments - }) - }) -} + }); + }); +}; // ============================================================================ // MUTATION HANDLERS @@ -96,44 +97,44 @@ export const createDeploymentsListSlow = (deployments: AppsV1Deployment[] = crea // Create deployment handler export const createDeploymentHandler = (deployment: AppsV1Deployment[] = createDeploymentsListData()) => { return http.post(`${API_BASE}/apis/apps/v1/namespaces/:namespace/deployments`, () => { - return HttpResponse.json(deployment, { status: 201 }) - }) -} + return HttpResponse.json(deployment, { status: 201 }); + }); +}; // Create deployment error handler export const createDeploymentErrorHandler = (status: number = 400, message: string = 'Creation failed') => { return http.post(`${API_BASE}/apis/apps/v1/namespaces/:namespace/deployments`, () => { - return HttpResponse.json({ error: message }, { status }) - }) -} + return HttpResponse.json({ error: message }, { status }); + }); +}; // Update deployment handler export const updateDeploymentHandler = (deployment: AppsV1Deployment = createDeploymentsListData()[0]) => { return http.put(`${API_BASE}/apis/apps/v1/namespaces/:namespace/deployments/:name`, () => { - return HttpResponse.json(deployment) - }) -} + return HttpResponse.json(deployment); + }); +}; // Update deployment error handler export const updateDeploymentErrorHandler = (status: number = 400, message: string = 'Update failed') => { return http.put(`${API_BASE}/apis/apps/v1/namespaces/:namespace/deployments/:name`, () => { - return HttpResponse.json({ error: message }, { status }) - }) -} + return HttpResponse.json({ error: message }, { status }); + }); +}; // Delete deployment handler export const deleteDeploymentHandler = () => { return http.delete(`${API_BASE}/apis/apps/v1/namespaces/:namespace/deployments/:name`, () => { - return HttpResponse.json({}, { status: 200 }) - }) -} + return HttpResponse.json({}, { status: 200 }); + }); +}; // Delete deployment error handler export const deleteDeploymentErrorHandler = (status: number = 404, message: string = 'Deletion failed') => { return http.delete(`${API_BASE}/apis/apps/v1/namespaces/:namespace/deployments/:name`, () => { - return HttpResponse.json({ error: message }, { status }) - }) -} + return HttpResponse.json({ error: message }, { status }); + }); +}; // Scale deployment handler export const scaleDeploymentHandler = (replicas: number = 3) => { @@ -143,44 +144,44 @@ export const scaleDeploymentHandler = (replicas: number = 3) => { kind: 'Scale', metadata: { name: 'test-deployment', namespace: 'default' }, spec: { replicas } - }) - }) -} + }); + }); +}; // Scale deployment error handler export const scaleDeploymentErrorHandler = (status: number = 400, message: string = 'Scaling failed') => { return http.put(`${API_BASE}/apis/apps/v1/namespaces/:namespace/deployments/:name/scale`, () => { - return HttpResponse.json({ error: message }, { status }) - }) -} + return HttpResponse.json({ error: message }, { status }); + }); +}; // Scale deployment with namespace validation handler export const scaleDeploymentWithNamespaceValidationHandler = (replicas: number, expectedNamespace: string = 'default') => { return http.put(`${API_BASE}/apis/apps/v1/namespaces/:namespace/deployments/:name/scale`, ({ params }) => { - expect(params.namespace).toBe(expectedNamespace) + expect(params.namespace).toBe(expectedNamespace); return HttpResponse.json({ apiVersion: 'autoscaling/v1', kind: 'Scale', metadata: { name: 'test-deployment', namespace: expectedNamespace }, spec: { replicas } - }) - }) -} + }); + }); +}; // Get single deployment by name handler export const createDeploymentByName = (deployment: AppsV1Deployment, delay: number = 0, errorStatus?: number, errorMessage?: string) => { return http.get(`${API_BASE}/apis/apps/v1/namespaces/:namespace/deployments/:name`, async ({ params }) => { if (delay > 0) { - await new Promise(resolve => setTimeout(resolve, delay)) + await new Promise(resolve => setTimeout(resolve, delay)); } if (errorStatus) { return HttpResponse.json( { error: errorMessage || 'Deployment not found' }, { status: errorStatus } - ) + ); } - return HttpResponse.json(deployment) - }) -} + return HttpResponse.json(deployment); + }); +}; diff --git a/apps/ops-dashboard/__mocks__/handlers/endpoints.ts b/apps/ops-dashboard/__mocks__/handlers/endpoints.ts index ca967c3..627fd7a 100644 --- a/apps/ops-dashboard/__mocks__/handlers/endpoints.ts +++ b/apps/ops-dashboard/__mocks__/handlers/endpoints.ts @@ -1,6 +1,7 @@ -import { http, HttpResponse } from "msw" -import { API_BASE } from "./common" -import { Endpoints } from "@kubernetesjs/ops" +import { Endpoints } from '@kubernetesjs/ops'; +import { http, HttpResponse } from 'msw'; + +import { API_BASE } from './common'; export const createEndpointsListData = (): Endpoints[] => { return [ @@ -75,21 +76,21 @@ export const createEndpointsListData = (): Endpoints[] => { } ] } - ] -} + ]; +}; export const createEndpointsList = (endpoints: Endpoints[] = createEndpointsListData()) => { return http.get(`${API_BASE}/api/v1/namespaces/:namespace/endpoints`, ({ params, request }) => { - const namespace = params.namespace as string - const namespaceEndpoints = endpoints.filter(ep => ep.metadata.namespace === namespace) + const namespace = params.namespace as string; + const namespaceEndpoints = endpoints.filter(ep => ep.metadata.namespace === namespace); return HttpResponse.json({ apiVersion: 'v1', kind: 'EndpointsList', items: namespaceEndpoints - }) - }) -} + }); + }); +}; export const createAllEndpointsList = (endpoints: Endpoints[] = createEndpointsListData()) => { return http.get(`${API_BASE}/api/v1/endpoints`, () => { @@ -97,9 +98,9 @@ export const createAllEndpointsList = (endpoints: Endpoints[] = createEndpointsL apiVersion: 'v1', kind: 'EndpointsList', items: endpoints - }) - }) -} + }); + }); +}; // Error handlers export const createEndpointsListError = (status: number = 500, message: string = 'Internal Server Error') => { @@ -107,72 +108,72 @@ export const createEndpointsListError = (status: number = 500, message: string = return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; export const createAllEndpointsListError = (status: number = 500, message: string = 'Internal Server Error') => { return http.get(`${API_BASE}/api/v1/endpoints`, () => { return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; // Network error handler export const createEndpointsListNetworkError = () => { return http.get(`${API_BASE}/api/v1/namespaces/:namespace/endpoints`, () => { - return HttpResponse.error() - }) -} + return HttpResponse.error(); + }); +}; // Slow response handler for testing loading states export const createEndpointsListSlow = (endpoints: Endpoints[] = createEndpointsListData(), delay: number = 1000) => { return http.get(`${API_BASE}/api/v1/namespaces/:namespace/endpoints`, async ({ params }) => { - await new Promise(resolve => setTimeout(resolve, delay)) - const namespace = params.namespace as string - const namespaceEndpoints = endpoints.filter(ep => ep.metadata.namespace === namespace) + await new Promise(resolve => setTimeout(resolve, delay)); + const namespace = params.namespace as string; + const namespaceEndpoints = endpoints.filter(ep => ep.metadata.namespace === namespace); return HttpResponse.json({ apiVersion: 'v1', kind: 'EndpointsList', items: namespaceEndpoints - }) - }) -} + }); + }); +}; // Endpoint by name handler export const createEndpointByName = (endpoints: Endpoints[] = createEndpointsListData()) => { return http.get(`${API_BASE}/api/v1/namespaces/:namespace/endpoints/:name`, ({ params }) => { - const namespace = params.namespace as string - const name = params.name as string - const endpoint = endpoints.find(ep => ep.metadata.namespace === namespace && ep.metadata.name === name) + const namespace = params.namespace as string; + const name = params.name as string; + const endpoint = endpoints.find(ep => ep.metadata.namespace === namespace && ep.metadata.name === name); if (!endpoint) { return HttpResponse.json( { error: 'Endpoints not found' }, { status: 404 } - ) + ); } - return HttpResponse.json(endpoint) - }) -} + return HttpResponse.json(endpoint); + }); +}; // Endpoint details handler (alias for createEndpointByName) export const createEndpointDetails = (endpoint: Endpoints) => { return http.get(`${API_BASE}/api/v1/namespaces/:namespace/endpoints/:name`, ({ params }) => { if (params.name === endpoint.metadata?.name && params.namespace === endpoint.metadata?.namespace) { - return HttpResponse.json(endpoint) + return HttpResponse.json(endpoint); } - return HttpResponse.json({ error: 'Endpoints not found' }, { status: 404 }) - }) -} + return HttpResponse.json({ error: 'Endpoints not found' }, { status: 404 }); + }); +}; // Delete Endpoint handler export const createEndpointDelete = () => { return http.delete(`${API_BASE}/api/v1/namespaces/:namespace/endpoints/:name`, () => { - return HttpResponse.json({}) - }) -} + return HttpResponse.json({}); + }); +}; diff --git a/apps/ops-dashboard/__mocks__/handlers/endpointslices.ts b/apps/ops-dashboard/__mocks__/handlers/endpointslices.ts index 8dc81df..273e2e5 100644 --- a/apps/ops-dashboard/__mocks__/handlers/endpointslices.ts +++ b/apps/ops-dashboard/__mocks__/handlers/endpointslices.ts @@ -1,5 +1,5 @@ -import { http, HttpResponse } from 'msw' -import { type DiscoveryK8sIoV1EndpointSlice as EndpointSlice } from '@kubernetesjs/ops' +import { type DiscoveryK8sIoV1EndpointSlice as EndpointSlice } from '@kubernetesjs/ops'; +import { http, HttpResponse } from 'msw'; export function createEndpointSlicesListData(): EndpointSlice[] { return [ @@ -74,26 +74,26 @@ export function createEndpointSlicesListData(): EndpointSlice[] { { name: 'mysql', port: 3306, protocol: 'TCP' } ] } - ] + ]; } export const createEndpointSliceDelete = () => http.delete('/apis/discovery.k8s.io/v1/namespaces/:namespace/endpointslices/:name', () => { - return HttpResponse.json({}) - }) + return HttpResponse.json({}); + }); export const createEndpointSlicesList = () => http.get('/apis/discovery.k8s.io/v1/namespaces/:namespace/endpointslices', ({ request, params }) => { - const namespace = params.namespace as string + const namespace = params.namespace as string; - const data = createEndpointSlicesListData().filter(slice => slice.metadata?.namespace === namespace) + const data = createEndpointSlicesListData().filter(slice => slice.metadata?.namespace === namespace); return HttpResponse.json({ apiVersion: 'discovery.k8s.io/v1', kind: 'EndpointSliceList', items: data - }) - }) + }); + }); export const createAllEndpointSlicesList = () => http.get('/apis/discovery.k8s.io/v1/endpointslices', () => { @@ -101,20 +101,20 @@ export const createAllEndpointSlicesList = () => apiVersion: 'discovery.k8s.io/v1', kind: 'EndpointSliceList', items: createEndpointSlicesListData() - }) - }) + }); + }); export const createEndpointSlicesListError = () => http.get('/apis/discovery.k8s.io/v1/namespaces/:namespace/endpointslices', () => { - return HttpResponse.error() - }) + return HttpResponse.error(); + }); export const createEndpointSlicesListSlow = () => http.get('/apis/discovery.k8s.io/v1/namespaces/:namespace/endpointslices', async () => { - await new Promise(resolve => setTimeout(resolve, 1000)) + await new Promise(resolve => setTimeout(resolve, 1000)); return HttpResponse.json({ apiVersion: 'discovery.k8s.io/v1', kind: 'EndpointSliceList', items: createEndpointSlicesListData() - }) - }) + }); + }); diff --git a/apps/ops-dashboard/__mocks__/handlers/hpas.ts b/apps/ops-dashboard/__mocks__/handlers/hpas.ts index a4eba8a..b968238 100644 --- a/apps/ops-dashboard/__mocks__/handlers/hpas.ts +++ b/apps/ops-dashboard/__mocks__/handlers/hpas.ts @@ -1,6 +1,7 @@ -import { http, HttpResponse } from "msw" -import { API_BASE } from "./common" -import { AutoscalingV2HorizontalPodAutoscaler } from "@kubernetesjs/ops" +import { AutoscalingV2HorizontalPodAutoscaler } from '@kubernetesjs/ops'; +import { http, HttpResponse } from 'msw'; + +import { API_BASE } from './common'; export const createHPAsListData = (): AutoscalingV2HorizontalPodAutoscaler[] => { return [ @@ -136,21 +137,21 @@ export const createHPAsListData = (): AutoscalingV2HorizontalPodAutoscaler[] => ] } } - ] -} + ]; +}; export const createHPAsList = (hpas: AutoscalingV2HorizontalPodAutoscaler[] = createHPAsListData()) => { return http.get(`${API_BASE}/apis/autoscaling/v2/namespaces/:namespace/horizontalpodautoscalers`, ({ params, request }) => { - const namespace = params.namespace as string - const namespaceHPAs = hpas.filter(hpa => hpa.metadata.namespace === namespace) + const namespace = params.namespace as string; + const namespaceHPAs = hpas.filter(hpa => hpa.metadata.namespace === namespace); return HttpResponse.json({ apiVersion: 'autoscaling/v2', kind: 'HorizontalPodAutoscalerList', items: namespaceHPAs - }) - }) -} + }); + }); +}; export const createAllHPAsList = (hpas: AutoscalingV2HorizontalPodAutoscaler[] = createHPAsListData()) => { return http.get(`${API_BASE}/apis/autoscaling/v2/horizontalpodautoscalers`, () => { @@ -158,9 +159,9 @@ export const createAllHPAsList = (hpas: AutoscalingV2HorizontalPodAutoscaler[] = apiVersion: 'autoscaling/v2', kind: 'HorizontalPodAutoscalerList', items: hpas - }) - }) -} + }); + }); +}; // Error handlers export const createHPAsListError = (status: number = 500, message: string = 'Internal Server Error') => { @@ -168,72 +169,72 @@ export const createHPAsListError = (status: number = 500, message: string = 'Int return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; export const createAllHPAsListError = (status: number = 500, message: string = 'Internal Server Error') => { return http.get(`${API_BASE}/apis/autoscaling/v2/horizontalpodautoscalers`, () => { return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; // Network error handler export const createHPAsListNetworkError = () => { return http.get(`${API_BASE}/apis/autoscaling/v2/namespaces/:namespace/horizontalpodautoscalers`, () => { - return HttpResponse.error() - }) -} + return HttpResponse.error(); + }); +}; // Slow response handler for testing loading states export const createHPAsListSlow = (hpas: AutoscalingV2HorizontalPodAutoscaler[] = createHPAsListData(), delay: number = 1000) => { return http.get(`${API_BASE}/apis/autoscaling/v2/namespaces/:namespace/horizontalpodautoscalers`, async ({ params }) => { - await new Promise(resolve => setTimeout(resolve, delay)) - const namespace = params.namespace as string - const namespaceHPAs = hpas.filter(hpa => hpa.metadata.namespace === namespace) + await new Promise(resolve => setTimeout(resolve, delay)); + const namespace = params.namespace as string; + const namespaceHPAs = hpas.filter(hpa => hpa.metadata.namespace === namespace); return HttpResponse.json({ apiVersion: 'autoscaling/v2', kind: 'HorizontalPodAutoscalerList', items: namespaceHPAs - }) - }) -} + }); + }); +}; // HPA by name handler export const createHPAByName = (hpas: AutoscalingV2HorizontalPodAutoscaler[] = createHPAsListData()) => { return http.get(`${API_BASE}/apis/autoscaling/v2/namespaces/:namespace/horizontalpodautoscalers/:name`, ({ params }) => { - const namespace = params.namespace as string - const name = params.name as string - const hpa = hpas.find(hpa => hpa.metadata.namespace === namespace && hpa.metadata.name === name) + const namespace = params.namespace as string; + const name = params.name as string; + const hpa = hpas.find(hpa => hpa.metadata.namespace === namespace && hpa.metadata.name === name); if (!hpa) { return HttpResponse.json( { error: 'HorizontalPodAutoscaler not found' }, { status: 404 } - ) + ); } - return HttpResponse.json(hpa) - }) -} + return HttpResponse.json(hpa); + }); +}; // HPA details handler (alias for createHPAByName) export const createHPADetails = (hpa: AutoscalingV2HorizontalPodAutoscaler) => { return http.get(`${API_BASE}/apis/autoscaling/v2/namespaces/:namespace/horizontalpodautoscalers/:name`, ({ params }) => { if (params.name === hpa.metadata?.name && params.namespace === hpa.metadata?.namespace) { - return HttpResponse.json(hpa) + return HttpResponse.json(hpa); } - return HttpResponse.json({ error: 'HorizontalPodAutoscaler not found' }, { status: 404 }) - }) -} + return HttpResponse.json({ error: 'HorizontalPodAutoscaler not found' }, { status: 404 }); + }); +}; // Delete HPA handler export const createHPADelete = () => { return http.delete(`${API_BASE}/apis/autoscaling/v2/namespaces/:namespace/horizontalpodautoscalers/:name`, () => { - return HttpResponse.json({}) - }) -} + return HttpResponse.json({}); + }); +}; diff --git a/apps/ops-dashboard/__mocks__/handlers/index.ts b/apps/ops-dashboard/__mocks__/handlers/index.ts index 4b5c068..cc71fe8 100644 --- a/apps/ops-dashboard/__mocks__/handlers/index.ts +++ b/apps/ops-dashboard/__mocks__/handlers/index.ts @@ -1,5 +1,5 @@ -import { handlers as deploymentHandlers } from './deployments' +import { handlers as deploymentHandlers } from './deployments'; export const handlers = [ ...deploymentHandlers, -] \ No newline at end of file +]; \ No newline at end of file diff --git a/apps/ops-dashboard/__mocks__/handlers/ingresses.ts b/apps/ops-dashboard/__mocks__/handlers/ingresses.ts index 6718149..68e7cbd 100644 --- a/apps/ops-dashboard/__mocks__/handlers/ingresses.ts +++ b/apps/ops-dashboard/__mocks__/handlers/ingresses.ts @@ -1,6 +1,7 @@ -import { http, HttpResponse } from "msw" -import { API_BASE } from "./common" -import { NetworkingK8sIoV1Ingress } from "@kubernetesjs/ops" +import { NetworkingK8sIoV1Ingress } from '@kubernetesjs/ops'; +import { http, HttpResponse } from 'msw'; + +import { API_BASE } from './common'; export const createIngressesListData = (): NetworkingK8sIoV1Ingress[] => { return [ @@ -145,21 +146,21 @@ export const createIngressesListData = (): NetworkingK8sIoV1Ingress[] => { } } } - ] -} + ]; +}; export const createIngressesList = (ingresses: NetworkingK8sIoV1Ingress[] = createIngressesListData()) => { return http.get(`${API_BASE}/apis/networking.k8s.io/v1/namespaces/:namespace/ingresses`, ({ params, request }) => { - const namespace = params.namespace as string - const namespaceIngresses = ingresses.filter(ing => ing.metadata.namespace === namespace) + const namespace = params.namespace as string; + const namespaceIngresses = ingresses.filter(ing => ing.metadata.namespace === namespace); return HttpResponse.json({ apiVersion: 'networking.k8s.io/v1', kind: 'IngressList', items: namespaceIngresses - }) - }) -} + }); + }); +}; export const createAllIngressesList = (ingresses: NetworkingK8sIoV1Ingress[] = createIngressesListData()) => { return http.get(`${API_BASE}/apis/networking.k8s.io/v1/ingresses`, () => { @@ -167,9 +168,9 @@ export const createAllIngressesList = (ingresses: NetworkingK8sIoV1Ingress[] = c apiVersion: 'networking.k8s.io/v1', kind: 'IngressList', items: ingresses - }) - }) -} + }); + }); +}; // Error handlers export const createIngressesListError = (status: number = 500, message: string = 'Internal Server Error') => { @@ -177,72 +178,72 @@ export const createIngressesListError = (status: number = 500, message: string = return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; export const createAllIngressesListError = (status: number = 500, message: string = 'Internal Server Error') => { return http.get(`${API_BASE}/apis/networking.k8s.io/v1/ingresses`, () => { return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; // Network error handler export const createIngressesListNetworkError = () => { return http.get(`${API_BASE}/apis/networking.k8s.io/v1/namespaces/:namespace/ingresses`, () => { - return HttpResponse.error() - }) -} + return HttpResponse.error(); + }); +}; // Slow response handler for testing loading states export const createIngressesListSlow = (ingresses: NetworkingK8sIoV1Ingress[] = createIngressesListData(), delay: number = 1000) => { return http.get(`${API_BASE}/apis/networking.k8s.io/v1/namespaces/:namespace/ingresses`, async ({ params }) => { - await new Promise(resolve => setTimeout(resolve, delay)) - const namespace = params.namespace as string - const namespaceIngresses = ingresses.filter(ing => ing.metadata.namespace === namespace) + await new Promise(resolve => setTimeout(resolve, delay)); + const namespace = params.namespace as string; + const namespaceIngresses = ingresses.filter(ing => ing.metadata.namespace === namespace); return HttpResponse.json({ apiVersion: 'networking.k8s.io/v1', kind: 'IngressList', items: namespaceIngresses - }) - }) -} + }); + }); +}; // Ingress by name handler export const createIngressByName = (ingresses: NetworkingK8sIoV1Ingress[] = createIngressesListData()) => { return http.get(`${API_BASE}/apis/networking.k8s.io/v1/namespaces/:namespace/ingresses/:name`, ({ params }) => { - const namespace = params.namespace as string - const name = params.name as string - const ingress = ingresses.find(ing => ing.metadata.namespace === namespace && ing.metadata.name === name) + const namespace = params.namespace as string; + const name = params.name as string; + const ingress = ingresses.find(ing => ing.metadata.namespace === namespace && ing.metadata.name === name); if (!ingress) { return HttpResponse.json( { error: 'Ingress not found' }, { status: 404 } - ) + ); } - return HttpResponse.json(ingress) - }) -} + return HttpResponse.json(ingress); + }); +}; // Ingress details handler (alias for createIngressByName) export const createIngressDetails = (ingress: NetworkingK8sIoV1Ingress) => { return http.get(`${API_BASE}/apis/networking.k8s.io/v1/namespaces/:namespace/ingresses/:name`, ({ params }) => { if (params.name === ingress.metadata?.name && params.namespace === ingress.metadata?.namespace) { - return HttpResponse.json(ingress) + return HttpResponse.json(ingress); } - return HttpResponse.json({ error: 'Ingress not found' }, { status: 404 }) - }) -} + return HttpResponse.json({ error: 'Ingress not found' }, { status: 404 }); + }); +}; // Delete Ingress handler export const createIngressDelete = () => { return http.delete(`${API_BASE}/apis/networking.k8s.io/v1/namespaces/:namespace/ingresses/:name`, () => { - return HttpResponse.json({}) - }) -} + return HttpResponse.json({}); + }); +}; diff --git a/apps/ops-dashboard/__mocks__/handlers/jobs.ts b/apps/ops-dashboard/__mocks__/handlers/jobs.ts index 0dad871..f71b3d4 100644 --- a/apps/ops-dashboard/__mocks__/handlers/jobs.ts +++ b/apps/ops-dashboard/__mocks__/handlers/jobs.ts @@ -1,6 +1,7 @@ -import { http, HttpResponse } from "msw" -import { API_BASE } from "./common" -import { BatchV1Job } from "@kubernetesjs/ops" +import { BatchV1Job } from '@kubernetesjs/ops'; +import { http, HttpResponse } from 'msw'; + +import { API_BASE } from './common'; export const createJobsListData = (): BatchV1Job[] => { return [ @@ -119,21 +120,21 @@ export const createJobsListData = (): BatchV1Job[] => { ] } } - ] -} + ]; +}; export const createJobsList = (jobs: BatchV1Job[] = createJobsListData()) => { return http.get(`${API_BASE}/apis/batch/v1/namespaces/:namespace/jobs`, ({ params, request }) => { - const namespace = params.namespace as string - const namespaceJobs = jobs.filter(job => job.metadata.namespace === namespace) + const namespace = params.namespace as string; + const namespaceJobs = jobs.filter(job => job.metadata.namespace === namespace); return HttpResponse.json({ apiVersion: 'batch/v1', kind: 'JobList', items: namespaceJobs - }) - }) -} + }); + }); +}; export const createAllJobsList = (jobs: BatchV1Job[] = createJobsListData()) => { return http.get(`${API_BASE}/apis/batch/v1/jobs`, () => { @@ -141,9 +142,9 @@ export const createAllJobsList = (jobs: BatchV1Job[] = createJobsListData()) => apiVersion: 'batch/v1', kind: 'JobList', items: jobs - }) - }) -} + }); + }); +}; // Error handlers export const createJobsListError = (status: number = 500, message: string = 'Internal Server Error') => { @@ -151,72 +152,72 @@ export const createJobsListError = (status: number = 500, message: string = 'Int return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; export const createAllJobsListError = (status: number = 500, message: string = 'Internal Server Error') => { return http.get(`${API_BASE}/apis/batch/v1/jobs`, () => { return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; // Network error handler export const createJobsListNetworkError = () => { return http.get(`${API_BASE}/apis/batch/v1/namespaces/:namespace/jobs`, () => { - return HttpResponse.error() - }) -} + return HttpResponse.error(); + }); +}; // Slow response handler for testing loading states export const createJobsListSlow = (jobs: BatchV1Job[] = createJobsListData(), delay: number = 1000) => { return http.get(`${API_BASE}/apis/batch/v1/namespaces/:namespace/jobs`, async ({ params }) => { - await new Promise(resolve => setTimeout(resolve, delay)) - const namespace = params.namespace as string - const namespaceJobs = jobs.filter(job => job.metadata.namespace === namespace) + await new Promise(resolve => setTimeout(resolve, delay)); + const namespace = params.namespace as string; + const namespaceJobs = jobs.filter(job => job.metadata.namespace === namespace); return HttpResponse.json({ apiVersion: 'batch/v1', kind: 'JobList', items: namespaceJobs - }) - }) -} + }); + }); +}; // Job by name handler export const createJobByName = (jobs: BatchV1Job[] = createJobsListData()) => { return http.get(`${API_BASE}/apis/batch/v1/namespaces/:namespace/jobs/:name`, ({ params }) => { - const namespace = params.namespace as string - const name = params.name as string - const job = jobs.find(job => job.metadata.namespace === namespace && job.metadata.name === name) + const namespace = params.namespace as string; + const name = params.name as string; + const job = jobs.find(job => job.metadata.namespace === namespace && job.metadata.name === name); if (!job) { return HttpResponse.json( { error: 'Job not found' }, { status: 404 } - ) + ); } - return HttpResponse.json(job) - }) -} + return HttpResponse.json(job); + }); +}; // Job details handler (alias for createJobByName) export const createJobDetails = (job: BatchV1Job) => { return http.get(`${API_BASE}/apis/batch/v1/namespaces/:namespace/jobs/:name`, ({ params }) => { if (params.name === job.metadata?.name && params.namespace === job.metadata?.namespace) { - return HttpResponse.json(job) + return HttpResponse.json(job); } - return HttpResponse.json({ error: 'Job not found' }, { status: 404 }) - }) -} + return HttpResponse.json({ error: 'Job not found' }, { status: 404 }); + }); +}; // Delete Job handler export const createJobDelete = () => { return http.delete(`${API_BASE}/apis/batch/v1/namespaces/:namespace/jobs/:name`, () => { - return HttpResponse.json({}) - }) -} + return HttpResponse.json({}); + }); +}; diff --git a/apps/ops-dashboard/__mocks__/handlers/namespaces.ts b/apps/ops-dashboard/__mocks__/handlers/namespaces.ts index 7e79e2b..a1cca79 100644 --- a/apps/ops-dashboard/__mocks__/handlers/namespaces.ts +++ b/apps/ops-dashboard/__mocks__/handlers/namespaces.ts @@ -1,6 +1,7 @@ -import { http, HttpResponse } from "msw" -import { API_BASE } from "./common" -import { V1Namespace } from "@kubernetesjs/ops" +import { V1Namespace } from '@kubernetesjs/ops'; +import { http, HttpResponse } from 'msw'; + +import { API_BASE } from './common'; export const createNamespacesListData = (): V1Namespace[] => { return [ @@ -38,14 +39,14 @@ export const createNamespacesListData = (): V1Namespace[] => { metadata: { name: 'test-namespace', uid: 'ns-4', - labels: { 'kubernetes.io/metadata.name': 'test-namespace', 'environment': 'test' }, + labels: { 'kubernetes.io/metadata.name': 'test-namespace', environment: 'test' }, creationTimestamp: new Date('2023-01-15T10:30:00Z') }, spec: {}, status: { phase: 'Active' } } - ] -} + ]; +}; export const createNamespacesList = (namespaces: V1Namespace[] = createNamespacesListData()) => { return http.get(`${API_BASE}/api/v1/namespaces`, () => { @@ -53,9 +54,9 @@ export const createNamespacesList = (namespaces: V1Namespace[] = createNamespace apiVersion: 'v1', kind: 'NamespaceList', items: namespaces - }) - }) -} + }); + }); +}; // Error handlers export const createNamespacesListError = (status: number = 500, message: string = 'Internal Server Error') => { @@ -63,33 +64,33 @@ export const createNamespacesListError = (status: number = 500, message: string return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; // Network error handler export const createNamespacesListNetworkError = () => { return http.get(`${API_BASE}/api/v1/namespaces`, () => { - return HttpResponse.error() - }) -} + return HttpResponse.error(); + }); +}; // Slow response handler for testing loading states export const createNamespacesListSlow = (namespaces: V1Namespace[] = createNamespacesListData(), delay: number = 1000) => { return http.get(`${API_BASE}/api/v1/namespaces`, async () => { - await new Promise(resolve => setTimeout(resolve, delay)) + await new Promise(resolve => setTimeout(resolve, delay)); return HttpResponse.json({ apiVersion: 'v1', kind: 'NamespaceList', items: namespaces - }) - }) -} + }); + }); +}; // Create namespace handler export const createNamespace = () => { return http.post(`${API_BASE}/api/v1/namespaces`, async ({ request }) => { - const body = await request.json() + const body = await request.json(); return HttpResponse.json({ apiVersion: 'v1', kind: 'Namespace', @@ -100,24 +101,24 @@ export const createNamespace = () => { }, spec: {}, status: { phase: 'Active' } - }, { status: 201 }) - }) -} + }, { status: 201 }); + }); +}; // Get single namespace handler export const getNamespace = (namespace: V1Namespace) => { return http.get(`${API_BASE}/api/v1/namespaces/:name`, ({ params }) => { - const name = params.name as string + const name = params.name as string; if (name === namespace.metadata.name) { - return HttpResponse.json(namespace) + return HttpResponse.json(namespace); } - return HttpResponse.json({ error: 'Namespace not found' }, { status: 404 }) - }) -} + return HttpResponse.json({ error: 'Namespace not found' }, { status: 404 }); + }); +}; // Delete namespace handler export const deleteNamespace = () => { return http.delete(`${API_BASE}/api/v1/namespaces/:name`, () => { - return HttpResponse.json({}, { status: 200 }) - }) -} + return HttpResponse.json({}, { status: 200 }); + }); +}; diff --git a/apps/ops-dashboard/__mocks__/handlers/networkpolicies.ts b/apps/ops-dashboard/__mocks__/handlers/networkpolicies.ts index d69f1ff..0b0ec53 100644 --- a/apps/ops-dashboard/__mocks__/handlers/networkpolicies.ts +++ b/apps/ops-dashboard/__mocks__/handlers/networkpolicies.ts @@ -1,6 +1,7 @@ -import { http, HttpResponse } from "msw" -import { API_BASE } from "./common" -import { NetworkingK8sIoV1NetworkPolicy } from "@kubernetesjs/ops" +import { NetworkingK8sIoV1NetworkPolicy } from '@kubernetesjs/ops'; +import { http, HttpResponse } from 'msw'; + +import { API_BASE } from './common'; export const createNetworkPoliciesListData = (): NetworkingK8sIoV1NetworkPolicy[] => { return [ @@ -108,21 +109,21 @@ export const createNetworkPoliciesListData = (): NetworkingK8sIoV1NetworkPolicy[ policyTypes: ['Ingress', 'Egress'] } } - ] -} + ]; +}; export const createNetworkPoliciesList = (policies: NetworkingK8sIoV1NetworkPolicy[] = createNetworkPoliciesListData()) => { return http.get(`${API_BASE}/apis/networking.k8s.io/v1/namespaces/:namespace/networkpolicies`, ({ params, request }) => { - const namespace = params.namespace as string - const namespacePolicies = policies.filter(pol => pol.metadata.namespace === namespace) + const namespace = params.namespace as string; + const namespacePolicies = policies.filter(pol => pol.metadata.namespace === namespace); return HttpResponse.json({ apiVersion: 'networking.k8s.io/v1', kind: 'NetworkPolicyList', items: namespacePolicies - }) - }) -} + }); + }); +}; export const createAllNetworkPoliciesList = (policies: NetworkingK8sIoV1NetworkPolicy[] = createNetworkPoliciesListData()) => { return http.get(`${API_BASE}/apis/networking.k8s.io/v1/networkpolicies`, () => { @@ -130,9 +131,9 @@ export const createAllNetworkPoliciesList = (policies: NetworkingK8sIoV1NetworkP apiVersion: 'networking.k8s.io/v1', kind: 'NetworkPolicyList', items: policies - }) - }) -} + }); + }); +}; // Error handlers export const createNetworkPoliciesListError = (status: number = 500, message: string = 'Internal Server Error') => { @@ -140,72 +141,72 @@ export const createNetworkPoliciesListError = (status: number = 500, message: st return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; export const createAllNetworkPoliciesListError = (status: number = 500, message: string = 'Internal Server Error') => { return http.get(`${API_BASE}/apis/networking.k8s.io/v1/networkpolicies`, () => { return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; // Network error handler export const createNetworkPoliciesListNetworkError = () => { return http.get(`${API_BASE}/apis/networking.k8s.io/v1/namespaces/:namespace/networkpolicies`, () => { - return HttpResponse.error() - }) -} + return HttpResponse.error(); + }); +}; // Slow response handler for testing loading states export const createNetworkPoliciesListSlow = (policies: NetworkingK8sIoV1NetworkPolicy[] = createNetworkPoliciesListData(), delay: number = 1000) => { return http.get(`${API_BASE}/apis/networking.k8s.io/v1/namespaces/:namespace/networkpolicies`, async ({ params }) => { - await new Promise(resolve => setTimeout(resolve, delay)) - const namespace = params.namespace as string - const namespacePolicies = policies.filter(pol => pol.metadata.namespace === namespace) + await new Promise(resolve => setTimeout(resolve, delay)); + const namespace = params.namespace as string; + const namespacePolicies = policies.filter(pol => pol.metadata.namespace === namespace); return HttpResponse.json({ apiVersion: 'networking.k8s.io/v1', kind: 'NetworkPolicyList', items: namespacePolicies - }) - }) -} + }); + }); +}; // NetworkPolicy by name handler export const createNetworkPolicyByName = (policies: NetworkingK8sIoV1NetworkPolicy[] = createNetworkPoliciesListData()) => { return http.get(`${API_BASE}/apis/networking.k8s.io/v1/namespaces/:namespace/networkpolicies/:name`, ({ params }) => { - const namespace = params.namespace as string - const name = params.name as string - const policy = policies.find(pol => pol.metadata.namespace === namespace && pol.metadata.name === name) + const namespace = params.namespace as string; + const name = params.name as string; + const policy = policies.find(pol => pol.metadata.namespace === namespace && pol.metadata.name === name); if (!policy) { return HttpResponse.json( { error: 'NetworkPolicy not found' }, { status: 404 } - ) + ); } - return HttpResponse.json(policy) - }) -} + return HttpResponse.json(policy); + }); +}; // NetworkPolicy details handler (alias for createNetworkPolicyByName) export const createNetworkPolicyDetails = (policy: NetworkingK8sIoV1NetworkPolicy) => { return http.get(`${API_BASE}/apis/networking.k8s.io/v1/namespaces/:namespace/networkpolicies/:name`, ({ params }) => { if (params.name === policy.metadata?.name && params.namespace === policy.metadata?.namespace) { - return HttpResponse.json(policy) + return HttpResponse.json(policy); } - return HttpResponse.json({ error: 'NetworkPolicy not found' }, { status: 404 }) - }) -} + return HttpResponse.json({ error: 'NetworkPolicy not found' }, { status: 404 }); + }); +}; // Delete NetworkPolicy handler export const createNetworkPolicyDelete = () => { return http.delete(`${API_BASE}/apis/networking.k8s.io/v1/namespaces/:namespace/networkpolicies/:name`, () => { - return HttpResponse.json({}) - }) -} + return HttpResponse.json({}); + }); +}; diff --git a/apps/ops-dashboard/__mocks__/handlers/operators.ts b/apps/ops-dashboard/__mocks__/handlers/operators.ts index 680252e..7a9098f 100644 --- a/apps/ops-dashboard/__mocks__/handlers/operators.ts +++ b/apps/ops-dashboard/__mocks__/handlers/operators.ts @@ -1,5 +1,5 @@ -import { http, HttpResponse } from "msw" -import { API_BASE } from "./common" +import { http, HttpResponse } from 'msw'; + export interface OperatorInfo { name: string @@ -50,72 +50,72 @@ export const createOperatorsListData = (): OperatorInfo[] => { version: 'v4.0.0', docsUrl: 'https://grafana.com/docs' } - ] -} + ]; +}; export const createOperatorsList = (operators: OperatorInfo[] = createOperatorsListData()) => { return http.get('/api/operators', () => { - return HttpResponse.json(operators) - }) -} + return HttpResponse.json(operators); + }); +}; export const createOperatorsListError = (status: number = 500, message: string = 'Internal Server Error') => { return http.get('/api/operators', () => { return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; export const createOperatorsListNetworkError = () => { return http.get('/api/operators', () => { - return HttpResponse.error() - }) -} + return HttpResponse.error(); + }); +}; export const createInstallOperator = (operatorName: string) => { return http.post(`/api/operators/${operatorName}/install`, () => { return HttpResponse.json({ success: true, message: `Operator ${operatorName} installed successfully` - }) - }) -} + }); + }); +}; export const createInstallOperatorError = (operatorName: string, status: number = 500, message: string = 'Installation failed') => { return http.post(`/api/operators/${operatorName}/install`, () => { return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; export const createUninstallOperator = (operatorName: string) => { return http.delete(`/api/operators/${operatorName}/install`, () => { return HttpResponse.json({ success: true, message: `Operator ${operatorName} uninstalled successfully` - }) - }) -} + }); + }); +}; export const createUninstallOperatorError = (operatorName: string, status: number = 500, message: string = 'Uninstallation failed') => { return http.delete(`/api/operators/${operatorName}/install`, () => { return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; export const createInstallOperatorSlow = (operatorName: string, delay: number = 2000) => { return http.post(`/api/operators/${operatorName}/install`, async () => { - await new Promise(resolve => setTimeout(resolve, delay)) + await new Promise(resolve => setTimeout(resolve, delay)); return HttpResponse.json({ success: true, message: `Operator ${operatorName} installed successfully` - }) - }) -} + }); + }); +}; diff --git a/apps/ops-dashboard/__mocks__/handlers/pdbs.ts b/apps/ops-dashboard/__mocks__/handlers/pdbs.ts index 877b946..323633b 100644 --- a/apps/ops-dashboard/__mocks__/handlers/pdbs.ts +++ b/apps/ops-dashboard/__mocks__/handlers/pdbs.ts @@ -1,6 +1,7 @@ -import { http, HttpResponse } from "msw" -import { API_BASE } from "./common" -import { PolicyV1PodDisruptionBudget } from "@kubernetesjs/ops" +import { PolicyV1PodDisruptionBudget } from '@kubernetesjs/ops'; +import { http, HttpResponse } from 'msw'; + +import { API_BASE } from './common'; export const createPDBsListData = (): PolicyV1PodDisruptionBudget[] => { return [ @@ -55,21 +56,21 @@ export const createPDBsListData = (): PolicyV1PodDisruptionBudget[] => { disruptionsAllowed: 0 } } - ] -} + ]; +}; export const createPDBsList = (pdbs: PolicyV1PodDisruptionBudget[] = createPDBsListData()) => { return http.get(`${API_BASE}/apis/policy/v1/namespaces/:namespace/poddisruptionbudgets`, ({ params }) => { - const namespace = params.namespace as string - const namespacePDBs = pdbs.filter(pdb => pdb.metadata.namespace === namespace) + const namespace = params.namespace as string; + const namespacePDBs = pdbs.filter(pdb => pdb.metadata.namespace === namespace); return HttpResponse.json({ apiVersion: 'policy/v1', kind: 'PodDisruptionBudgetList', items: namespacePDBs - }) - }) -} + }); + }); +}; export const createAllPDBsList = (pdbs: PolicyV1PodDisruptionBudget[] = createPDBsListData()) => { return http.get(`${API_BASE}/apis/policy/v1/poddisruptionbudgets`, () => { @@ -77,9 +78,9 @@ export const createAllPDBsList = (pdbs: PolicyV1PodDisruptionBudget[] = createPD apiVersion: 'policy/v1', kind: 'PodDisruptionBudgetList', items: pdbs - }) - }) -} + }); + }); +}; // Error handlers export const createPDBsListError = (status: number = 500, message: string = 'Internal Server Error') => { @@ -87,51 +88,51 @@ export const createPDBsListError = (status: number = 500, message: string = 'Int return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; export const createAllPDBsListError = (status: number = 500, message: string = 'Internal Server Error') => { return http.get(`${API_BASE}/apis/policy/v1/poddisruptionbudgets`, () => { return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; // Network error handler export const createPDBsListNetworkError = () => { return http.get(`${API_BASE}/apis/policy/v1/namespaces/:namespace/poddisruptionbudgets`, () => { - return HttpResponse.error() - }) -} + return HttpResponse.error(); + }); +}; // Slow response handler for testing loading states export const createPDBsListSlow = (pdbs: PolicyV1PodDisruptionBudget[] = createPDBsListData(), delay: number = 1000) => { return http.get(`${API_BASE}/apis/policy/v1/namespaces/:namespace/poddisruptionbudgets`, async ({ params }) => { - await new Promise(resolve => setTimeout(resolve, delay)) - const namespace = params.namespace as string - const namespacePDBs = pdbs.filter(pdb => pdb.metadata.namespace === namespace) + await new Promise(resolve => setTimeout(resolve, delay)); + const namespace = params.namespace as string; + const namespacePDBs = pdbs.filter(pdb => pdb.metadata.namespace === namespace); return HttpResponse.json({ apiVersion: 'policy/v1', kind: 'PodDisruptionBudgetList', items: namespacePDBs - }) - }) -} + }); + }); +}; // Delete PDB handler export const deletePDBHandler = () => { return http.delete(`${API_BASE}/apis/policy/v1/namespaces/:namespace/poddisruptionbudgets/:name`, () => { - return HttpResponse.json({}, { status: 200 }) - }) -} + return HttpResponse.json({}, { status: 200 }); + }); +}; // Delete PDB error handler export const deletePDBErrorHandler = (status: number = 404, message: string = 'Deletion failed') => { return http.delete(`${API_BASE}/apis/policy/v1/namespaces/:namespace/poddisruptionbudgets/:name`, () => { - return HttpResponse.json({ error: message }, { status }) - }) -} + return HttpResponse.json({ error: message }, { status }); + }); +}; diff --git a/apps/ops-dashboard/__mocks__/handlers/pods.ts b/apps/ops-dashboard/__mocks__/handlers/pods.ts index fe77c03..a4779e6 100644 --- a/apps/ops-dashboard/__mocks__/handlers/pods.ts +++ b/apps/ops-dashboard/__mocks__/handlers/pods.ts @@ -1,6 +1,7 @@ -import { http, HttpResponse } from "msw" -import { API_BASE } from "./common" -import { V1Pod } from "@kubernetesjs/ops" +import { V1Pod } from '@kubernetesjs/ops'; +import { http, HttpResponse } from 'msw'; + +import { API_BASE } from './common'; export const createPodsListData = (): V1Pod[] => { return [ @@ -100,21 +101,21 @@ export const createPodsListData = (): V1Pod[] => { ] } } - ] -} + ]; +}; export const createPodsList = (pods: V1Pod[] = createPodsListData()) => { return http.get(`${API_BASE}/api/v1/namespaces/:namespace/pods`, ({ params }) => { - const namespace = params.namespace as string - const namespacePods = pods.filter(pod => pod.metadata.namespace === namespace) + const namespace = params.namespace as string; + const namespacePods = pods.filter(pod => pod.metadata.namespace === namespace); return HttpResponse.json({ apiVersion: 'v1', kind: 'PodList', items: namespacePods - }) - }) -} + }); + }); +}; export const createAllPodsList = (pods: V1Pod[] = createPodsListData()) => { return http.get(`${API_BASE}/api/v1/pods`, () => { @@ -122,9 +123,9 @@ export const createAllPodsList = (pods: V1Pod[] = createPodsListData()) => { apiVersion: 'v1', kind: 'PodList', items: pods - }) - }) -} + }); + }); +}; // Error handlers export const createPodsListError = (status: number = 500, message: string = 'Internal Server Error') => { @@ -132,92 +133,92 @@ export const createPodsListError = (status: number = 500, message: string = 'Int return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; export const createAllPodsListError = (status: number = 500, message: string = 'Internal Server Error') => { return http.get(`${API_BASE}/api/v1/pods`, () => { return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; // Network error handler export const createPodsListNetworkError = () => { return http.get(`${API_BASE}/api/v1/namespaces/:namespace/pods`, () => { - return HttpResponse.error() - }) -} + return HttpResponse.error(); + }); +}; // Slow response handler for testing loading states export const createPodsListSlow = (pods: V1Pod[] = createPodsListData(), delay: number = 1000) => { return http.get(`${API_BASE}/api/v1/namespaces/:namespace/pods`, async ({ params }) => { - await new Promise(resolve => setTimeout(resolve, delay)) - const namespace = params.namespace as string - const namespacePods = pods.filter(pod => pod.metadata.namespace === namespace) + await new Promise(resolve => setTimeout(resolve, delay)); + const namespace = params.namespace as string; + const namespacePods = pods.filter(pod => pod.metadata.namespace === namespace); return HttpResponse.json({ apiVersion: 'v1', kind: 'PodList', items: namespacePods - }) - }) -} + }); + }); +}; // Pod by name handler export const createPodByName = (pods: V1Pod[] = createPodsListData()) => { return http.get(`${API_BASE}/api/v1/namespaces/:namespace/pods/:name`, ({ params }) => { - const namespace = params.namespace as string - const name = params.name as string - const pod = pods.find(p => p.metadata.namespace === namespace && p.metadata.name === name) + const namespace = params.namespace as string; + const name = params.name as string; + const pod = pods.find(p => p.metadata.namespace === namespace && p.metadata.name === name); if (!pod) { return HttpResponse.json( { error: 'Pod not found' }, { status: 404 } - ) + ); } - return HttpResponse.json(pod) - }) -} + return HttpResponse.json(pod); + }); +}; // Pod details handler (alias for createPodByName) export const createPodDetails = (pod: V1Pod) => { return http.get(`${API_BASE}/api/v1/namespaces/:namespace/pods/:name`, ({ params }) => { if (params.name === pod.metadata?.name && params.namespace === pod.metadata?.namespace) { - return HttpResponse.json(pod) + return HttpResponse.json(pod); } - return HttpResponse.json({ error: 'Pod not found' }, { status: 404 }) - }) -} + return HttpResponse.json({ error: 'Pod not found' }, { status: 404 }); + }); +}; // Pod logs handler export const createPodLogs = (name: string, namespace: string, logs: string) => { return http.get(`${API_BASE}/api/v1/namespaces/:namespace/pods/:name/log`, ({ params, request }) => { if (params.name === name && params.namespace === namespace) { // Check for container parameter in query string - const url = new URL(request.url) - const container = url.searchParams.get('container') + const url = new URL(request.url); + const container = url.searchParams.get('container'); return new HttpResponse(logs, { headers: { 'Content-Type': 'text/plain', 'Content-Length': logs.length.toString() } - }) + }); } - return HttpResponse.json({ error: 'Logs not found' }, { status: 404 }) - }) -} + return HttpResponse.json({ error: 'Logs not found' }, { status: 404 }); + }); +}; // Generic pod logs handler for any pod export const createPodLogsHandler = (logs: string) => { return http.get(`${API_BASE}/api/v1/namespaces/:namespace/pods/:name/log`, ({ params, request }) => { // Check for container parameter in query string - return HttpResponse.json(logs) - }) -} + return HttpResponse.json(logs); + }); +}; diff --git a/apps/ops-dashboard/__mocks__/handlers/priorityclasses.ts b/apps/ops-dashboard/__mocks__/handlers/priorityclasses.ts index 732196f..9401061 100644 --- a/apps/ops-dashboard/__mocks__/handlers/priorityclasses.ts +++ b/apps/ops-dashboard/__mocks__/handlers/priorityclasses.ts @@ -1,6 +1,7 @@ -import { http, HttpResponse } from "msw" -import { API_BASE } from "./common" -import { SchedulingK8sIoV1PriorityClass } from "@kubernetesjs/ops" +import { SchedulingK8sIoV1PriorityClass } from '@kubernetesjs/ops'; +import { http, HttpResponse } from 'msw'; + +import { API_BASE } from './common'; export const createPriorityClassesListData = (): SchedulingK8sIoV1PriorityClass[] => { return [ @@ -54,8 +55,8 @@ export const createPriorityClassesListData = (): SchedulingK8sIoV1PriorityClass[ description: 'Low priority class', preemptionPolicy: 'Never' } - ] -} + ]; +}; export const createPriorityClassesList = (priorityClasses: SchedulingK8sIoV1PriorityClass[] = createPriorityClassesListData()) => { return http.get(`${API_BASE}/apis/scheduling.k8s.io/v1/priorityclasses`, () => { @@ -63,44 +64,44 @@ export const createPriorityClassesList = (priorityClasses: SchedulingK8sIoV1Prio apiVersion: 'scheduling.k8s.io/v1', kind: 'PriorityClassList', items: priorityClasses - }) - }) -} + }); + }); +}; export const createPriorityClassesListError = (status: number = 500, message: string = 'Internal Server Error') => { return http.get(`${API_BASE}/apis/scheduling.k8s.io/v1/priorityclasses`, () => { return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; export const createPriorityClassesListSlow = (priorityClasses: SchedulingK8sIoV1PriorityClass[] = createPriorityClassesListData(), delay: number = 1000) => { return http.get(`${API_BASE}/apis/scheduling.k8s.io/v1/priorityclasses`, async () => { - await new Promise(resolve => setTimeout(resolve, delay)) + await new Promise(resolve => setTimeout(resolve, delay)); return HttpResponse.json({ apiVersion: 'scheduling.k8s.io/v1', kind: 'PriorityClassList', items: priorityClasses - }) - }) -} + }); + }); +}; export const deletePriorityClassHandler = (name: string) => { return http.delete(`${API_BASE}/apis/scheduling.k8s.io/v1/priorityclasses/:name`, ({ params }) => { if (params.name === name) { - return HttpResponse.json({}, { status: 200 }) + return HttpResponse.json({}, { status: 200 }); } - return HttpResponse.json({ error: 'Priority class not found' }, { status: 404 }) - }) -} + return HttpResponse.json({ error: 'Priority class not found' }, { status: 404 }); + }); +}; export const deletePriorityClassErrorHandler = (name: string, status: number = 500, message: string = 'Deletion failed') => { return http.delete(`${API_BASE}/apis/scheduling.k8s.io/v1/priorityclasses/:name`, ({ params }) => { if (params.name === name) { - return HttpResponse.json({ error: message }, { status }) + return HttpResponse.json({ error: message }, { status }); } - return HttpResponse.json({ error: 'Priority class not found' }, { status: 404 }) - }) -} \ No newline at end of file + return HttpResponse.json({ error: 'Priority class not found' }, { status: 404 }); + }); +}; \ No newline at end of file diff --git a/apps/ops-dashboard/__mocks__/handlers/pvcs.ts b/apps/ops-dashboard/__mocks__/handlers/pvcs.ts index ddc0c1d..c96c816 100644 --- a/apps/ops-dashboard/__mocks__/handlers/pvcs.ts +++ b/apps/ops-dashboard/__mocks__/handlers/pvcs.ts @@ -1,4 +1,4 @@ -import { http, HttpResponse } from 'msw' +import { http, HttpResponse } from 'msw'; export const createPVCsListData = () => [ { @@ -94,7 +94,7 @@ export const createPVCsListData = () => [ } } } -] +]; export const createPVCsList = () => { return http.get('/api/v1/namespaces/:namespace/persistentvolumeclaims', () => { @@ -102,9 +102,9 @@ export const createPVCsList = () => { apiVersion: 'v1', kind: 'PersistentVolumeClaimList', items: createPVCsListData() - }) - }) -} + }); + }); +}; export const createAllPVCsList = () => { return http.get('/api/v1/persistentvolumeclaims', () => { @@ -112,32 +112,32 @@ export const createAllPVCsList = () => { apiVersion: 'v1', kind: 'PersistentVolumeClaimList', items: createPVCsListData() - }) - }) -} + }); + }); +}; export const createPVCDelete = () => { return http.delete('/api/v1/namespaces/:namespace/persistentvolumeclaims/:name', () => { - return HttpResponse.json({}) - }) -} + return HttpResponse.json({}); + }); +}; export const createPVCsListError = () => { return http.get('/api/v1/namespaces/:namespace/persistentvolumeclaims', () => { return HttpResponse.json( { error: 'Server Error' }, { status: 500 } - ) - }) -} + ); + }); +}; export const createPVCsListSlow = () => { return http.get('/api/v1/namespaces/:namespace/persistentvolumeclaims', async () => { - await new Promise(resolve => setTimeout(resolve, 1000)) + await new Promise(resolve => setTimeout(resolve, 1000)); return HttpResponse.json({ apiVersion: 'v1', kind: 'PersistentVolumeClaimList', items: createPVCsListData() - }) - }) -} + }); + }); +}; diff --git a/apps/ops-dashboard/__mocks__/handlers/pvs.ts b/apps/ops-dashboard/__mocks__/handlers/pvs.ts index dfbd11b..0d05b0f 100644 --- a/apps/ops-dashboard/__mocks__/handlers/pvs.ts +++ b/apps/ops-dashboard/__mocks__/handlers/pvs.ts @@ -1,4 +1,4 @@ -import { http, HttpResponse } from 'msw' +import { http, HttpResponse } from 'msw'; export const createPVsListData = () => [ { @@ -77,7 +77,7 @@ export const createPVsListData = () => [ phase: 'Failed' } } -] +]; export const createPVsList = () => { return http.get('/api/v1/persistentvolumes', () => { @@ -85,32 +85,32 @@ export const createPVsList = () => { apiVersion: 'v1', kind: 'PersistentVolumeList', items: createPVsListData() - }) - }) -} + }); + }); +}; export const createPVDelete = () => { return http.delete('/api/v1/persistentvolumes/:name', () => { - return HttpResponse.json({}) - }) -} + return HttpResponse.json({}); + }); +}; export const createPVsListError = () => { return http.get('/api/v1/persistentvolumes', () => { return HttpResponse.json( { error: 'Server Error' }, { status: 500 } - ) - }) -} + ); + }); +}; export const createPVsListSlow = () => { return http.get('/api/v1/persistentvolumes', async () => { - await new Promise(resolve => setTimeout(resolve, 1000)) + await new Promise(resolve => setTimeout(resolve, 1000)); return HttpResponse.json({ apiVersion: 'v1', kind: 'PersistentVolumeList', items: createPVsListData() - }) - }) -} + }); + }); +}; diff --git a/apps/ops-dashboard/__mocks__/handlers/replicasets.ts b/apps/ops-dashboard/__mocks__/handlers/replicasets.ts index 73264cb..7f622c1 100644 --- a/apps/ops-dashboard/__mocks__/handlers/replicasets.ts +++ b/apps/ops-dashboard/__mocks__/handlers/replicasets.ts @@ -1,6 +1,7 @@ -import { http, HttpResponse } from "msw" -import { API_BASE } from "./common" -import { V1ReplicaSet } from "@kubernetesjs/ops" +import { V1ReplicaSet } from '@kubernetesjs/ops'; +import { http, HttpResponse } from 'msw'; + +import { API_BASE } from './common'; export const createReplicaSetsListData = (): V1ReplicaSet[] => { return [ @@ -94,21 +95,21 @@ export const createReplicaSetsListData = (): V1ReplicaSet[] => { observedGeneration: 1 } } - ] -} + ]; +}; export const createReplicaSetsList = (replicaSets: V1ReplicaSet[] = createReplicaSetsListData()) => { return http.get(`${API_BASE}/apis/apps/v1/namespaces/:namespace/replicasets`, ({ params }) => { - const namespace = params.namespace as string - const namespaceReplicaSets = replicaSets.filter(rs => rs.metadata.namespace === namespace) + const namespace = params.namespace as string; + const namespaceReplicaSets = replicaSets.filter(rs => rs.metadata.namespace === namespace); return HttpResponse.json({ apiVersion: 'apps/v1', kind: 'ReplicaSetList', items: namespaceReplicaSets - }) - }) -} + }); + }); +}; export const createAllReplicaSetsList = (replicaSets: V1ReplicaSet[] = createReplicaSetsListData()) => { return http.get(`${API_BASE}/apis/apps/v1/replicasets`, () => { @@ -116,9 +117,9 @@ export const createAllReplicaSetsList = (replicaSets: V1ReplicaSet[] = createRep apiVersion: 'apps/v1', kind: 'ReplicaSetList', items: replicaSets - }) - }) -} + }); + }); +}; // Error handlers export const createReplicaSetsListError = (status: number = 500, message: string = 'Internal Server Error') => { @@ -126,46 +127,46 @@ export const createReplicaSetsListError = (status: number = 500, message: string return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; export const createAllReplicaSetsListError = (status: number = 500, message: string = 'Internal Server Error') => { return http.get(`${API_BASE}/apis/apps/v1/replicasets`, () => { return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; // Network error handler export const createReplicaSetsListNetworkError = () => { return http.get(`${API_BASE}/apis/apps/v1/namespaces/:namespace/replicasets`, () => { - return HttpResponse.error() - }) -} + return HttpResponse.error(); + }); +}; // Slow response handler for testing loading states export const createReplicaSetsListSlow = (replicaSets: V1ReplicaSet[] = createReplicaSetsListData(), delay: number = 1000) => { return http.get(`${API_BASE}/apis/apps/v1/namespaces/:namespace/replicasets`, async ({ params }) => { - await new Promise(resolve => setTimeout(resolve, delay)) - const namespace = params.namespace as string - const namespaceReplicaSets = replicaSets.filter(rs => rs.metadata.namespace === namespace) + await new Promise(resolve => setTimeout(resolve, delay)); + const namespace = params.namespace as string; + const namespaceReplicaSets = replicaSets.filter(rs => rs.metadata.namespace === namespace); return HttpResponse.json({ apiVersion: 'apps/v1', kind: 'ReplicaSetList', items: namespaceReplicaSets - }) - }) -} + }); + }); +}; // Scale handlers export const createReplicaSetScale = () => { return http.put(`${API_BASE}/apis/apps/v1/namespaces/:namespace/replicasets/:name/scale`, ({ params, request }) => { - const namespace = params.namespace as string - const name = params.name as string + const namespace = params.namespace as string; + const name = params.name as string; return HttpResponse.json({ apiVersion: 'autoscaling/v1', @@ -181,24 +182,24 @@ export const createReplicaSetScale = () => { replicas: 5, selector: { app: 'nginx' } } - }) - }) -} + }); + }); +}; export const createReplicaSetScaleError = (status: number = 500, message: string = 'Scale failed') => { return http.put(`${API_BASE}/apis/apps/v1/namespaces/:namespace/replicasets/:name/scale`, () => { return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; // Delete handlers export const createReplicaSetDelete = () => { return http.delete(`${API_BASE}/apis/apps/v1/namespaces/:namespace/replicasets/:name`, ({ params }) => { - const namespace = params.namespace as string - const name = params.name as string + const namespace = params.namespace as string; + const name = params.name as string; return HttpResponse.json({ apiVersion: 'apps/v1', @@ -208,37 +209,37 @@ export const createReplicaSetDelete = () => { namespace, deletionTimestamp: new Date().toISOString() } - }) - }) -} + }); + }); +}; export const createReplicaSetDeleteError = (status: number = 500, message: string = 'Delete failed') => { return http.delete(`${API_BASE}/apis/apps/v1/namespaces/:namespace/replicasets/:name`, () => { return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; // Get single replicaset handler export const getReplicaSet = (replicaSet: V1ReplicaSet) => { return http.get(`${API_BASE}/apis/apps/v1/namespaces/:namespace/replicasets/:name`, ({ params }) => { - const name = params.name as string - const namespace = params.namespace as string + const name = params.name as string; + const namespace = params.namespace as string; if (name === replicaSet.metadata?.name && namespace === replicaSet.metadata?.namespace) { - return HttpResponse.json(replicaSet) + return HttpResponse.json(replicaSet); } - return HttpResponse.json({ error: 'ReplicaSet not found' }, { status: 404 }) - }) -} + return HttpResponse.json({ error: 'ReplicaSet not found' }, { status: 404 }); + }); +}; // Update replicaset handler export const updateReplicaSet = () => { return http.put(`${API_BASE}/apis/apps/v1/namespaces/:namespace/replicasets/:name`, async ({ request, params }) => { - const body = await request.json() as V1ReplicaSet - const name = params.name as string - const namespace = params.namespace as string + const body = await request.json() as V1ReplicaSet; + const name = params.name as string; + const namespace = params.namespace as string; return HttpResponse.json({ ...body, @@ -249,9 +250,9 @@ export const updateReplicaSet = () => { resourceVersion: '12345', uid: `rs-${name}` } - }) - }) -} + }); + }); +}; // Update replicaset error handler export const updateReplicaSetError = (status: number = 500, message: string = 'Update failed') => { @@ -259,6 +260,6 @@ export const updateReplicaSetError = (status: number = 500, message: string = 'U return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; diff --git a/apps/ops-dashboard/__mocks__/handlers/resourcequotas.ts b/apps/ops-dashboard/__mocks__/handlers/resourcequotas.ts index 7dc84e8..246294d 100644 --- a/apps/ops-dashboard/__mocks__/handlers/resourcequotas.ts +++ b/apps/ops-dashboard/__mocks__/handlers/resourcequotas.ts @@ -1,4 +1,4 @@ -import { http, HttpResponse } from 'msw' +import { http, HttpResponse } from 'msw'; export const createResourceQuotasListData = () => [ { @@ -14,7 +14,7 @@ export const createResourceQuotasListData = () => [ 'requests.memory': '4Gi', 'limits.cpu': '4', 'limits.memory': '8Gi', - 'pods': '10' + pods: '10' } }, status: { @@ -23,14 +23,14 @@ export const createResourceQuotasListData = () => [ 'requests.memory': '4Gi', 'limits.cpu': '4', 'limits.memory': '8Gi', - 'pods': '10' + pods: '10' }, used: { 'requests.cpu': '1', 'requests.memory': '2Gi', 'limits.cpu': '2', 'limits.memory': '4Gi', - 'pods': '5' + pods: '5' } } }, @@ -44,17 +44,17 @@ export const createResourceQuotasListData = () => [ spec: { hard: { 'requests.storage': '100Gi', - 'persistentvolumeclaims': '10' + persistentvolumeclaims: '10' } }, status: { hard: { 'requests.storage': '100Gi', - 'persistentvolumeclaims': '10' + persistentvolumeclaims: '10' }, used: { 'requests.storage': '80Gi', - 'persistentvolumeclaims': '8' + persistentvolumeclaims: '8' } } }, @@ -69,19 +69,19 @@ export const createResourceQuotasListData = () => [ hard: { 'requests.cpu': '1', 'requests.memory': '2Gi', - 'pods': '5' + pods: '5' } }, status: { hard: { 'requests.cpu': '1', 'requests.memory': '2Gi', - 'pods': '5' + pods: '5' }, used: { 'requests.cpu': '0.9', 'requests.memory': '1.8Gi', - 'pods': '4' + pods: '4' } } }, @@ -96,77 +96,77 @@ export const createResourceQuotasListData = () => [ hard: { 'requests.cpu': '2', 'requests.memory': '4Gi', - 'pods': '10' + pods: '10' } }, status: { hard: { 'requests.cpu': '2', 'requests.memory': '4Gi', - 'pods': '10' + pods: '10' }, used: { 'requests.cpu': '1.9', 'requests.memory': '3.8Gi', - 'pods': '9' + pods: '9' } } } -] +]; export const createResourceQuotaDelete = () => http.delete('/api/v1/namespaces/:namespace/resourcequotas/:name', ({ params }) => { - const { namespace, name } = params + const { namespace, name } = params; return HttpResponse.json({ metadata: { name, namespace, deletionTimestamp: new Date().toISOString() } - }) - }) + }); + }); export const createResourceQuotasList = () => http.get('/api/v1/namespaces/:namespace/resourcequotas', ({ request }) => { - const url = new URL(request.url) - const namespace = url.pathname.split('/')[4] + const url = new URL(request.url); + const namespace = url.pathname.split('/')[4]; const data = createResourceQuotasListData().filter(quota => quota.metadata.namespace === namespace - ) + ); return HttpResponse.json({ apiVersion: 'v1', kind: 'ResourceQuotaList', items: data - }) - }) + }); + }); export const createAllResourceQuotasList = () => http.get('/api/v1/resourcequotas', () => { - const data = createResourceQuotasListData() + const data = createResourceQuotasListData(); return HttpResponse.json({ apiVersion: 'v1', kind: 'ResourceQuotaList', items: data - }) - }) + }); + }); export const createResourceQuotasListError = () => http.get('/api/v1/namespaces/:namespace/resourcequotas', () => { return HttpResponse.json( { error: 'Network request failed' }, { status: 500 } - ) - }) + ); + }); export const createResourceQuotasListSlow = () => http.get('/api/v1/namespaces/:namespace/resourcequotas', async () => { - await new Promise(resolve => setTimeout(resolve, 2000)) + await new Promise(resolve => setTimeout(resolve, 2000)); return HttpResponse.json({ apiVersion: 'v1', kind: 'ResourceQuotaList', items: [] - }) - }) + }); + }); diff --git a/apps/ops-dashboard/__mocks__/handlers/rolebindings.ts b/apps/ops-dashboard/__mocks__/handlers/rolebindings.ts index c7c67af..a198767 100644 --- a/apps/ops-dashboard/__mocks__/handlers/rolebindings.ts +++ b/apps/ops-dashboard/__mocks__/handlers/rolebindings.ts @@ -1,4 +1,4 @@ -import { http, HttpResponse } from 'msw' +import { http, HttpResponse } from 'msw'; export const createRoleBindingsListData = () => [ { @@ -83,7 +83,7 @@ export const createRoleBindingsListData = () => [ } ] } -] +]; export const createClusterRoleBindingsListData = () => [ { @@ -142,101 +142,101 @@ export const createClusterRoleBindingsListData = () => [ } ] } -] +]; export const createRoleBindingDelete = () => http.delete('/apis/rbac.authorization.k8s.io/v1/namespaces/:namespace/rolebindings/:name', ({ params }) => { - const { namespace, name } = params + const { namespace, name } = params; return HttpResponse.json({ metadata: { name, namespace, deletionTimestamp: new Date().toISOString() } - }) - }) + }); + }); export const createClusterRoleBindingDelete = () => http.delete('/apis/rbac.authorization.k8s.io/v1/clusterrolebindings/:name', ({ params }) => { - const { name } = params + const { name } = params; return HttpResponse.json({ metadata: { name, deletionTimestamp: new Date().toISOString() } - }) - }) + }); + }); export const createRoleBindingsList = () => http.get('/apis/rbac.authorization.k8s.io/v1/namespaces/:namespace/rolebindings', ({ request }) => { - const url = new URL(request.url) - const namespace = url.pathname.split('/')[4] + const url = new URL(request.url); + const namespace = url.pathname.split('/')[4]; const data = createRoleBindingsListData().filter(binding => binding.metadata.namespace === namespace - ) + ); return HttpResponse.json({ apiVersion: 'rbac.authorization.k8s.io/v1', kind: 'RoleBindingList', items: data - }) - }) + }); + }); export const createAllRoleBindingsList = () => http.get('/apis/rbac.authorization.k8s.io/v1/rolebindings', () => { - const data = createRoleBindingsListData() + const data = createRoleBindingsListData(); return HttpResponse.json({ apiVersion: 'rbac.authorization.k8s.io/v1', kind: 'RoleBindingList', items: data - }) - }) + }); + }); export const createClusterRoleBindingsList = () => http.get('/apis/rbac.authorization.k8s.io/v1/clusterrolebindings', () => { - const data = createClusterRoleBindingsListData() + const data = createClusterRoleBindingsListData(); return HttpResponse.json({ apiVersion: 'rbac.authorization.k8s.io/v1', kind: 'ClusterRoleBindingList', items: data - }) - }) + }); + }); export const createRoleBindingsListError = () => http.get('/apis/rbac.authorization.k8s.io/v1/namespaces/:namespace/rolebindings', () => { return HttpResponse.json( { error: 'Network request failed' }, { status: 500 } - ) - }) + ); + }); export const createRoleBindingsListSlow = () => http.get('/apis/rbac.authorization.k8s.io/v1/namespaces/:namespace/rolebindings', async () => { - await new Promise(resolve => setTimeout(resolve, 2000)) + await new Promise(resolve => setTimeout(resolve, 2000)); return HttpResponse.json({ apiVersion: 'rbac.authorization.k8s.io/v1', kind: 'RoleBindingList', items: [] - }) - }) + }); + }); export const createClusterRoleBindingsListError = () => http.get('/apis/rbac.authorization.k8s.io/v1/clusterrolebindings', () => { return HttpResponse.json( { error: 'Network request failed' }, { status: 500 } - ) - }) + ); + }); export const createClusterRoleBindingsListSlow = () => http.get('/apis/rbac.authorization.k8s.io/v1/clusterrolebindings', async () => { - await new Promise(resolve => setTimeout(resolve, 2000)) + await new Promise(resolve => setTimeout(resolve, 2000)); return HttpResponse.json({ apiVersion: 'rbac.authorization.k8s.io/v1', kind: 'ClusterRoleBindingList', items: [] - }) - }) + }); + }); diff --git a/apps/ops-dashboard/__mocks__/handlers/roles.ts b/apps/ops-dashboard/__mocks__/handlers/roles.ts index b1c39db..12dd206 100644 --- a/apps/ops-dashboard/__mocks__/handlers/roles.ts +++ b/apps/ops-dashboard/__mocks__/handlers/roles.ts @@ -1,5 +1,5 @@ -import { http, HttpResponse } from 'msw' -import type { RbacAuthorizationK8sIoV1Role as Role, RbacAuthorizationK8sIoV1ClusterRole as ClusterRole } from '@kubernetesjs/ops' +import type { RbacAuthorizationK8sIoV1ClusterRole as ClusterRole,RbacAuthorizationK8sIoV1Role as Role } from '@kubernetesjs/ops'; +import { http, HttpResponse } from 'msw'; export function createRolesListData(): Role[] { return [ @@ -59,7 +59,7 @@ export function createRolesListData(): Role[] { } ] } - ] + ]; } export function createClusterRolesListData(): ClusterRole[] { @@ -109,40 +109,40 @@ export function createClusterRolesListData(): ClusterRole[] { } ] } - ] + ]; } export function createRoleDelete() { return http.delete('/apis/rbac.authorization.k8s.io/v1/namespaces/:namespace/roles/:name', () => { - return HttpResponse.json({}) - }) + return HttpResponse.json({}); + }); } export function createClusterRoleDelete() { return http.delete('/apis/rbac.authorization.k8s.io/v1/clusterroles/:name', () => { - return HttpResponse.json({}) - }) + return HttpResponse.json({}); + }); } export function createRolesList() { return http.get('/apis/rbac.authorization.k8s.io/v1/namespaces/:namespace/roles', ({ request }) => { - const url = new URL(request.url) - const namespace = url.pathname.split('/')[5] + const url = new URL(request.url); + const namespace = url.pathname.split('/')[5]; if (namespace === 'default') { return HttpResponse.json({ apiVersion: 'rbac.authorization.k8s.io/v1', kind: 'RoleList', items: createRolesListData().filter(role => role.metadata?.namespace === 'default') - }) + }); } return HttpResponse.json({ apiVersion: 'rbac.authorization.k8s.io/v1', kind: 'RoleList', items: createRolesListData() - }) - }) + }); + }); } export function createAllRolesList() { @@ -151,8 +151,8 @@ export function createAllRolesList() { apiVersion: 'rbac.authorization.k8s.io/v1', kind: 'RoleList', items: createRolesListData() - }) - }) + }); + }); } export function createClusterRolesList() { @@ -161,14 +161,14 @@ export function createClusterRolesList() { apiVersion: 'rbac.authorization.k8s.io/v1', kind: 'ClusterRoleList', items: createClusterRolesListData() - }) - }) + }); + }); } export function createRolesListError() { return http.get('/apis/rbac.authorization.k8s.io/v1/namespaces/:namespace/roles', () => { - return HttpResponse.error() - }) + return HttpResponse.error(); + }); } export function createRolesListSlow() { @@ -179,8 +179,8 @@ export function createRolesListSlow() { apiVersion: 'rbac.authorization.k8s.io/v1', kind: 'RoleList', items: createRolesListData() - })) - }, 2000) - }) - }) + })); + }, 2000); + }); + }); } diff --git a/apps/ops-dashboard/__mocks__/handlers/runtimeclasses.ts b/apps/ops-dashboard/__mocks__/handlers/runtimeclasses.ts index f5ac073..4b2828c 100644 --- a/apps/ops-dashboard/__mocks__/handlers/runtimeclasses.ts +++ b/apps/ops-dashboard/__mocks__/handlers/runtimeclasses.ts @@ -1,6 +1,7 @@ -import { http, HttpResponse } from "msw" -import { API_BASE } from "./common" -import { NodeK8sIoV1RuntimeClass } from "@kubernetesjs/ops" +import { NodeK8sIoV1RuntimeClass } from '@kubernetesjs/ops'; +import { http, HttpResponse } from 'msw'; + +import { API_BASE } from './common'; export const createRuntimeClassesListData = (): NodeK8sIoV1RuntimeClass[] => { return [ @@ -47,8 +48,8 @@ export const createRuntimeClassesListData = (): NodeK8sIoV1RuntimeClass[] => { }, overhead: { podFixed: { cpu: '50m', memory: '32Mi' } } } - ] -} + ]; +}; export const createRuntimeClassesList = (runtimeClasses: NodeK8sIoV1RuntimeClass[] = createRuntimeClassesListData()) => { return http.get(`${API_BASE}/apis/node.k8s.io/v1/runtimeclasses`, () => { @@ -56,44 +57,44 @@ export const createRuntimeClassesList = (runtimeClasses: NodeK8sIoV1RuntimeClass apiVersion: 'node.k8s.io/v1', kind: 'RuntimeClassList', items: runtimeClasses - }) - }) -} + }); + }); +}; export const createRuntimeClassesListError = (status: number = 500, message: string = 'Internal Server Error') => { return http.get(`${API_BASE}/apis/node.k8s.io/v1/runtimeclasses`, () => { return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; export const createRuntimeClassesListSlow = (runtimeClasses: NodeK8sIoV1RuntimeClass[] = createRuntimeClassesListData(), delay: number = 1000) => { return http.get(`${API_BASE}/apis/node.k8s.io/v1/runtimeclasses`, async () => { - await new Promise(resolve => setTimeout(resolve, delay)) + await new Promise(resolve => setTimeout(resolve, delay)); return HttpResponse.json({ apiVersion: 'node.k8s.io/v1', kind: 'RuntimeClassList', items: runtimeClasses - }) - }) -} + }); + }); +}; export const deleteRuntimeClassHandler = (name: string) => { return http.delete(`${API_BASE}/apis/node.k8s.io/v1/runtimeclasses/:name`, ({ params }) => { if (params.name === name) { - return HttpResponse.json({}, { status: 200 }) + return HttpResponse.json({}, { status: 200 }); } - return HttpResponse.json({ error: 'Runtime class not found' }, { status: 404 }) - }) -} + return HttpResponse.json({ error: 'Runtime class not found' }, { status: 404 }); + }); +}; export const deleteRuntimeClassErrorHandler = (name: string, status: number = 500, message: string = 'Deletion failed') => { return http.delete(`${API_BASE}/apis/node.k8s.io/v1/runtimeclasses/:name`, ({ params }) => { if (params.name === name) { - return HttpResponse.json({ error: message }, { status }) + return HttpResponse.json({ error: message }, { status }); } - return HttpResponse.json({ error: 'Runtime class not found' }, { status: 404 }) - }) -} \ No newline at end of file + return HttpResponse.json({ error: 'Runtime class not found' }, { status: 404 }); + }); +}; \ No newline at end of file diff --git a/apps/ops-dashboard/__mocks__/handlers/secrets.ts b/apps/ops-dashboard/__mocks__/handlers/secrets.ts index eb619b9..09fd346 100644 --- a/apps/ops-dashboard/__mocks__/handlers/secrets.ts +++ b/apps/ops-dashboard/__mocks__/handlers/secrets.ts @@ -1,6 +1,7 @@ -import { http, HttpResponse } from "msw" -import { API_BASE } from "./common" -import { V1Secret } from "@kubernetesjs/ops" +import { V1Secret } from '@kubernetesjs/ops'; +import { http, HttpResponse } from 'msw'; + +import { API_BASE } from './common'; export const createSecretsListData = (): V1Secret[] => { return [ @@ -12,8 +13,8 @@ export const createSecretsListData = (): V1Secret[] => { }, type: 'Opaque', data: { - 'username': 'dGVzdA==', // base64 encoded 'test' - 'password': 'cGFzc3dvcmQ=' // base64 encoded 'password' + username: 'dGVzdA==', // base64 encoded 'test' + password: 'cGFzc3dvcmQ=' // base64 encoded 'password' } }, { @@ -39,21 +40,21 @@ export const createSecretsListData = (): V1Secret[] => { 'tls.key': 'LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0t' // base64 encoded key } } - ] -} + ]; +}; export const createSecretsList = (secrets: V1Secret[] = createSecretsListData()) => { return http.get(`${API_BASE}/api/v1/namespaces/:namespace/secrets`, ({ params }) => { - const namespace = params.namespace as string - const namespaceSecrets = secrets.filter(secret => secret.metadata?.namespace === namespace) + const namespace = params.namespace as string; + const namespaceSecrets = secrets.filter(secret => secret.metadata?.namespace === namespace); return HttpResponse.json({ apiVersion: 'v1', kind: 'SecretList', items: namespaceSecrets - }) - }) -} + }); + }); +}; export const createAllSecretsList = (secrets: V1Secret[] = createSecretsListData()) => { return http.get(`${API_BASE}/api/v1/secrets`, () => { @@ -61,96 +62,96 @@ export const createAllSecretsList = (secrets: V1Secret[] = createSecretsListData apiVersion: 'v1', kind: 'SecretList', items: secrets - }) - }) -} + }); + }); +}; export const createSecretsListError = (status: number = 500, message: string = 'Internal Server Error') => { return http.get(`${API_BASE}/api/v1/namespaces/:namespace/secrets`, () => { return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; export const createAllSecretsListError = (status: number = 500, message: string = 'Internal Server Error') => { return http.get(`${API_BASE}/api/v1/secrets`, () => { return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; export const createSecretsListSlow = (secrets: V1Secret[] = createSecretsListData(), delay: number = 1000) => { return http.get(`${API_BASE}/api/v1/namespaces/:namespace/secrets`, async ({ params }) => { - await new Promise(resolve => setTimeout(resolve, delay)) - const namespace = params.namespace as string - const namespaceSecrets = secrets.filter(secret => secret.metadata?.namespace === namespace) + await new Promise(resolve => setTimeout(resolve, delay)); + const namespace = params.namespace as string; + const namespaceSecrets = secrets.filter(secret => secret.metadata?.namespace === namespace); return HttpResponse.json({ apiVersion: 'v1', kind: 'SecretList', items: namespaceSecrets - }) - }) -} + }); + }); +}; export const deleteSecretHandler = (name: string, namespace: string) => { return http.delete(`${API_BASE}/api/v1/namespaces/:namespace/secrets/:name`, ({ params }) => { if (params.name === name && params.namespace === namespace) { - return HttpResponse.json({}, { status: 200 }) + return HttpResponse.json({}, { status: 200 }); } - return HttpResponse.json({ error: 'Secret not found' }, { status: 404 }) - }) -} + return HttpResponse.json({ error: 'Secret not found' }, { status: 404 }); + }); +}; export const deleteSecretErrorHandler = (name: string, namespace: string, status: number = 500, message: string = 'Deletion failed') => { return http.delete(`${API_BASE}/api/v1/namespaces/:namespace/secrets/:name`, ({ params }) => { if (params.name === name && params.namespace === namespace) { - return HttpResponse.json({ error: message }, { status }) + return HttpResponse.json({ error: message }, { status }); } - return HttpResponse.json({ error: 'Secret not found' }, { status: 404 }) - }) -} + return HttpResponse.json({ error: 'Secret not found' }, { status: 404 }); + }); +}; export const createSecretHandler = (secret: V1Secret) => { return http.post(`${API_BASE}/api/v1/namespaces/:namespace/secrets`, () => { - return HttpResponse.json(secret, { status: 201 }) - }) -} + return HttpResponse.json(secret, { status: 201 }); + }); +}; export const createSecretErrorHandler = (status: number = 400, message: string = 'Creation failed') => { return http.post(`${API_BASE}/api/v1/namespaces/:namespace/secrets`, () => { - return HttpResponse.json({ error: message }, { status }) - }) -} + return HttpResponse.json({ error: message }, { status }); + }); +}; export const createSecretsListNetworkError = () => { return http.get(`${API_BASE}/api/v1/namespaces/:namespace/secrets`, () => { - return HttpResponse.error() - }) -} + return HttpResponse.error(); + }); +}; // Get single secret handler export const getSecret = (secret: V1Secret) => { return http.get(`${API_BASE}/api/v1/namespaces/:namespace/secrets/:name`, ({ params }) => { - const name = params.name as string - const namespace = params.namespace as string + const name = params.name as string; + const namespace = params.namespace as string; if (name === secret.metadata?.name && namespace === secret.metadata?.namespace) { - return HttpResponse.json(secret) + return HttpResponse.json(secret); } - return HttpResponse.json({ error: 'Secret not found' }, { status: 404 }) - }) -} + return HttpResponse.json({ error: 'Secret not found' }, { status: 404 }); + }); +}; // Update secret handler export const updateSecret = () => { return http.put(`${API_BASE}/api/v1/namespaces/:namespace/secrets/:name`, async ({ request, params }) => { - const body = await request.json() as V1Secret - const name = params.name as string - const namespace = params.namespace as string + const body = await request.json() as V1Secret; + const name = params.name as string; + const namespace = params.namespace as string; return HttpResponse.json({ ...body, @@ -161,9 +162,9 @@ export const updateSecret = () => { resourceVersion: '12345', uid: `secret-${name}` } - }) - }) -} + }); + }); +}; // Update secret error handler export const updateSecretError = (status: number = 500, message: string = 'Update failed') => { @@ -171,6 +172,6 @@ export const updateSecretError = (status: number = 500, message: string = 'Updat return HttpResponse.json( { error: message }, { status } - ) - }) -} \ No newline at end of file + ); + }); +}; \ No newline at end of file diff --git a/apps/ops-dashboard/__mocks__/handlers/serviceaccounts.ts b/apps/ops-dashboard/__mocks__/handlers/serviceaccounts.ts index 42f2ed1..74656ba 100644 --- a/apps/ops-dashboard/__mocks__/handlers/serviceaccounts.ts +++ b/apps/ops-dashboard/__mocks__/handlers/serviceaccounts.ts @@ -1,5 +1,5 @@ -import { http, HttpResponse } from 'msw' -import type { ServiceAccount } from '@kubernetesjs/ops' +import type { ServiceAccount } from '@kubernetesjs/ops'; +import { http, HttpResponse } from 'msw'; export function createServiceAccountsListData(): ServiceAccount[] { return [ @@ -76,34 +76,34 @@ export function createServiceAccountsListData(): ServiceAccount[] { ], automountServiceAccountToken: true } - ] + ]; } export function createServiceAccountDelete() { return http.delete('/api/v1/namespaces/:namespace/serviceaccounts/:name', () => { - return HttpResponse.json({}) - }) + return HttpResponse.json({}); + }); } export function createServiceAccountsList() { return http.get('/api/v1/namespaces/:namespace/serviceaccounts', ({ request }) => { - const url = new URL(request.url) - const namespace = url.pathname.split('/')[4] + const url = new URL(request.url); + const namespace = url.pathname.split('/')[4]; if (namespace === 'default') { return HttpResponse.json({ apiVersion: 'v1', kind: 'ServiceAccountList', items: createServiceAccountsListData().filter(sa => sa.metadata?.namespace === 'default') - }) + }); } return HttpResponse.json({ apiVersion: 'v1', kind: 'ServiceAccountList', items: createServiceAccountsListData() - }) - }) + }); + }); } export function createAllServiceAccountsList() { @@ -112,14 +112,14 @@ export function createAllServiceAccountsList() { apiVersion: 'v1', kind: 'ServiceAccountList', items: createServiceAccountsListData() - }) - }) + }); + }); } export function createServiceAccountsListError() { return http.get('/api/v1/namespaces/:namespace/serviceaccounts', () => { - return HttpResponse.error() - }) + return HttpResponse.error(); + }); } export function createServiceAccountsListSlow() { @@ -130,8 +130,8 @@ export function createServiceAccountsListSlow() { apiVersion: 'v1', kind: 'ServiceAccountList', items: createServiceAccountsListData() - })) - }, 2000) - }) - }) + })); + }, 2000); + }); + }); } diff --git a/apps/ops-dashboard/__mocks__/handlers/services.ts b/apps/ops-dashboard/__mocks__/handlers/services.ts index 79f3cf3..f1ccafe 100644 --- a/apps/ops-dashboard/__mocks__/handlers/services.ts +++ b/apps/ops-dashboard/__mocks__/handlers/services.ts @@ -1,6 +1,7 @@ -import { http, HttpResponse } from "msw" -import { API_BASE } from "./common" -import { V1Service } from "@kubernetesjs/ops" +import { V1Service } from '@kubernetesjs/ops'; +import { http, HttpResponse } from 'msw'; + +import { API_BASE } from './common'; export const createServicesListData = (): V1Service[] => { return [ @@ -80,21 +81,21 @@ export const createServicesListData = (): V1Service[] => { loadBalancer: {} } } - ] -} + ]; +}; export const createServicesList = (services: V1Service[] = createServicesListData()) => { return http.get(`${API_BASE}/api/v1/namespaces/:namespace/services`, ({ params }) => { - const namespace = params.namespace as string - const namespaceServices = services.filter(service => service.metadata?.namespace === namespace) + const namespace = params.namespace as string; + const namespaceServices = services.filter(service => service.metadata?.namespace === namespace); return HttpResponse.json({ apiVersion: 'v1', kind: 'ServiceList', items: namespaceServices - }) - }) -} + }); + }); +}; export const createAllServicesList = (services: V1Service[] = createServicesListData()) => { return http.get(`${API_BASE}/api/v1/services`, () => { @@ -102,96 +103,96 @@ export const createAllServicesList = (services: V1Service[] = createServicesList apiVersion: 'v1', kind: 'ServiceList', items: services - }) - }) -} + }); + }); +}; export const createServicesListError = (status: number = 500, message: string = 'Internal Server Error') => { return http.get(`${API_BASE}/api/v1/namespaces/:namespace/services`, () => { return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; export const createAllServicesListError = (status: number = 500, message: string = 'Internal Server Error') => { return http.get(`${API_BASE}/api/v1/services`, () => { return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; export const createServicesListSlow = (services: V1Service[] = createServicesListData(), delay: number = 1000) => { return http.get(`${API_BASE}/api/v1/namespaces/:namespace/services`, async ({ params }) => { - await new Promise(resolve => setTimeout(resolve, delay)) - const namespace = params.namespace as string - const namespaceServices = services.filter(service => service.metadata?.namespace === namespace) + await new Promise(resolve => setTimeout(resolve, delay)); + const namespace = params.namespace as string; + const namespaceServices = services.filter(service => service.metadata?.namespace === namespace); return HttpResponse.json({ apiVersion: 'v1', kind: 'ServiceList', items: namespaceServices - }) - }) -} + }); + }); +}; export const deleteServiceHandler = (name: string, namespace: string) => { return http.delete(`${API_BASE}/api/v1/namespaces/:namespace/services/:name`, ({ params }) => { if (params.name === name && params.namespace === namespace) { - return HttpResponse.json({}, { status: 200 }) + return HttpResponse.json({}, { status: 200 }); } - return HttpResponse.json({ error: 'Service not found' }, { status: 404 }) - }) -} + return HttpResponse.json({ error: 'Service not found' }, { status: 404 }); + }); +}; export const deleteServiceErrorHandler = (name: string, namespace: string, status: number = 500, message: string = 'Deletion failed') => { return http.delete(`${API_BASE}/api/v1/namespaces/:namespace/services/:name`, ({ params }) => { if (params.name === name && params.namespace === namespace) { - return HttpResponse.json({ error: message }, { status }) + return HttpResponse.json({ error: message }, { status }); } - return HttpResponse.json({ error: 'Service not found' }, { status: 404 }) - }) -} + return HttpResponse.json({ error: 'Service not found' }, { status: 404 }); + }); +}; export const createServiceHandler = (service: V1Service) => { return http.post(`${API_BASE}/api/v1/namespaces/:namespace/services`, () => { - return HttpResponse.json(service, { status: 201 }) - }) -} + return HttpResponse.json(service, { status: 201 }); + }); +}; export const createServiceErrorHandler = (status: number = 400, message: string = 'Creation failed') => { return http.post(`${API_BASE}/api/v1/namespaces/:namespace/services`, () => { - return HttpResponse.json({ error: message }, { status }) - }) -} + return HttpResponse.json({ error: message }, { status }); + }); +}; export const createServicesListNetworkError = () => { return http.get(`${API_BASE}/api/v1/namespaces/:namespace/services`, () => { - return HttpResponse.error() - }) -} + return HttpResponse.error(); + }); +}; // Get single service handler export const getService = (service: V1Service) => { return http.get(`${API_BASE}/api/v1/namespaces/:namespace/services/:name`, ({ params }) => { - const name = params.name as string - const namespace = params.namespace as string + const name = params.name as string; + const namespace = params.namespace as string; if (name === service.metadata.name && namespace === service.metadata.namespace) { - return HttpResponse.json(service) + return HttpResponse.json(service); } - return HttpResponse.json({ error: 'Service not found' }, { status: 404 }) - }) -} + return HttpResponse.json({ error: 'Service not found' }, { status: 404 }); + }); +}; // Update service handler export const updateService = () => { return http.put(`${API_BASE}/api/v1/namespaces/:namespace/services/:name`, async ({ request, params }) => { - const body = await request.json() as V1Service - const name = params.name as string - const namespace = params.namespace as string + const body = await request.json() as V1Service; + const name = params.name as string; + const namespace = params.namespace as string; return HttpResponse.json({ ...body, @@ -202,9 +203,9 @@ export const updateService = () => { resourceVersion: '12345', uid: `service-${name}` } - }) - }) -} + }); + }); +}; // Update service error handler export const updateServiceError = (status: number = 500, message: string = 'Update failed') => { @@ -212,6 +213,6 @@ export const updateServiceError = (status: number = 500, message: string = 'Upda return HttpResponse.json( { error: message }, { status } - ) - }) -} \ No newline at end of file + ); + }); +}; \ No newline at end of file diff --git a/apps/ops-dashboard/__mocks__/handlers/statefulsets.ts b/apps/ops-dashboard/__mocks__/handlers/statefulsets.ts index c81ad8f..be7545e 100644 --- a/apps/ops-dashboard/__mocks__/handlers/statefulsets.ts +++ b/apps/ops-dashboard/__mocks__/handlers/statefulsets.ts @@ -1,6 +1,7 @@ -import { http, HttpResponse } from "msw" -import { API_BASE } from "./common" -import { V1StatefulSet } from "@kubernetesjs/ops" +import { V1StatefulSet } from '@kubernetesjs/ops'; +import { http, HttpResponse } from 'msw'; + +import { API_BASE } from './common'; export const createStatefulSetsListData = (): V1StatefulSet[] => { return [ @@ -73,35 +74,35 @@ export const createStatefulSetsListData = (): V1StatefulSet[] => { updatedReplicas: 0 } } - ] -} + ]; +}; export const createStatefulSetsList = (statefulSets: V1StatefulSet[] = createStatefulSetsListData()) => { return http.get(`${API_BASE}/apis/apps/v1/namespaces/:namespace/statefulsets`, ({ params, request }) => { - const namespace = params.namespace as string - const namespaceStatefulSets = statefulSets.filter(ss => ss.metadata.namespace === namespace) + const namespace = params.namespace as string; + const namespaceStatefulSets = statefulSets.filter(ss => ss.metadata.namespace === namespace); return HttpResponse.json({ apiVersion: 'apps/v1', kind: 'StatefulSetList', items: namespaceStatefulSets - }) - }) -} + }); + }); +}; // Alternative handler that matches any statefulsets request export const createStatefulSetsListAny = (statefulSets: V1StatefulSet[] = createStatefulSetsListData()) => { return http.get(`${API_BASE}/apis/apps/v1/namespaces/:namespace/statefulsets`, ({ params, request }) => { - const namespace = params.namespace as string - const namespaceStatefulSets = statefulSets.filter(ss => ss.metadata.namespace === namespace) + const namespace = params.namespace as string; + const namespaceStatefulSets = statefulSets.filter(ss => ss.metadata.namespace === namespace); return HttpResponse.json({ apiVersion: 'apps/v1', kind: 'StatefulSetList', items: namespaceStatefulSets - }) - }) -} + }); + }); +}; export const createAllStatefulSetsList = (statefulSets: V1StatefulSet[] = createStatefulSetsListData()) => { return http.get(`${API_BASE}/apis/apps/v1/statefulsets`, () => { @@ -109,9 +110,9 @@ export const createAllStatefulSetsList = (statefulSets: V1StatefulSet[] = create apiVersion: 'apps/v1', kind: 'StatefulSetList', items: statefulSets - }) - }) -} + }); + }); +}; // Error handlers export const createStatefulSetsListError = (status: number = 500, message: string = 'Internal Server Error') => { @@ -119,68 +120,68 @@ export const createStatefulSetsListError = (status: number = 500, message: strin return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; export const createAllStatefulSetsListError = (status: number = 500, message: string = 'Internal Server Error') => { return http.get(`${API_BASE}/apis/apps/v1/statefulsets`, () => { return HttpResponse.json( { error: message }, { status } - ) - }) -} + ); + }); +}; // Network error handler export const createStatefulSetsListNetworkError = () => { return http.get(`${API_BASE}/apis/apps/v1/namespaces/:namespace/statefulsets`, () => { - return HttpResponse.error() - }) -} + return HttpResponse.error(); + }); +}; // Slow response handler for testing loading states export const createStatefulSetsListSlow = (statefulSets: V1StatefulSet[] = createStatefulSetsListData(), delay: number = 1000) => { return http.get(`${API_BASE}/apis/apps/v1/namespaces/:namespace/statefulsets`, async ({ params }) => { - await new Promise(resolve => setTimeout(resolve, delay)) - const namespace = params.namespace as string - const namespaceStatefulSets = statefulSets.filter(ss => ss.metadata.namespace === namespace) + await new Promise(resolve => setTimeout(resolve, delay)); + const namespace = params.namespace as string; + const namespaceStatefulSets = statefulSets.filter(ss => ss.metadata.namespace === namespace); return HttpResponse.json({ apiVersion: 'apps/v1', kind: 'StatefulSetList', items: namespaceStatefulSets - }) - }) -} + }); + }); +}; // StatefulSet by name handler export const createStatefulSetByName = (statefulSets: V1StatefulSet[] = createStatefulSetsListData()) => { return http.get(`${API_BASE}/apis/apps/v1/namespaces/:namespace/statefulsets/:name`, ({ params }) => { - const namespace = params.namespace as string - const name = params.name as string - const statefulSet = statefulSets.find(ss => ss.metadata.namespace === namespace && ss.metadata.name === name) + const namespace = params.namespace as string; + const name = params.name as string; + const statefulSet = statefulSets.find(ss => ss.metadata.namespace === namespace && ss.metadata.name === name); if (!statefulSet) { return HttpResponse.json( { error: 'StatefulSet not found' }, { status: 404 } - ) + ); } - return HttpResponse.json(statefulSet) - }) -} + return HttpResponse.json(statefulSet); + }); +}; // StatefulSet details handler (alias for createStatefulSetByName) export const createStatefulSetDetails = (statefulSet: V1StatefulSet) => { return http.get(`${API_BASE}/apis/apps/v1/namespaces/:namespace/statefulsets/:name`, ({ params }) => { if (params.name === statefulSet.metadata?.name && params.namespace === statefulSet.metadata?.namespace) { - return HttpResponse.json(statefulSet) + return HttpResponse.json(statefulSet); } - return HttpResponse.json({ error: 'StatefulSet not found' }, { status: 404 }) - }) -} + return HttpResponse.json({ error: 'StatefulSet not found' }, { status: 404 }); + }); +}; // Scale StatefulSet handler export const createStatefulSetScale = () => { @@ -190,13 +191,13 @@ export const createStatefulSetScale = () => { kind: 'Scale', metadata: { name: 'test', namespace: 'default' }, spec: { replicas: 1 } - }) - }) -} + }); + }); +}; // Delete StatefulSet handler export const createStatefulSetDelete = () => { return http.delete(`${API_BASE}/apis/apps/v1/namespaces/:namespace/statefulsets/:name`, () => { - return HttpResponse.json({}) - }) -} + return HttpResponse.json({}); + }); +}; diff --git a/apps/ops-dashboard/__mocks__/handlers/storageclasses.ts b/apps/ops-dashboard/__mocks__/handlers/storageclasses.ts index 570eaaf..e138b6a 100644 --- a/apps/ops-dashboard/__mocks__/handlers/storageclasses.ts +++ b/apps/ops-dashboard/__mocks__/handlers/storageclasses.ts @@ -1,4 +1,4 @@ -import { http, HttpResponse } from 'msw' +import { http, HttpResponse } from 'msw'; export const createStorageClassesListData = () => [ { @@ -67,17 +67,17 @@ export const createStorageClassesListData = () => [ type: 'ssd' } } -] +]; export const createStorageClassDelete = () => http.delete('/apis/storage.k8s.io/v1/storageclasses/:name', ({ params }) => { - const { name } = params + const { name } = params; return HttpResponse.json({ apiVersion: 'storage.k8s.io/v1', kind: 'StorageClass', metadata: { name } - }) - }) + }); + }); export const createStorageClassesList = () => http.get('/apis/storage.k8s.io/v1/storageclasses', () => { @@ -85,20 +85,20 @@ export const createStorageClassesList = () => apiVersion: 'v1', kind: 'StorageClassList', items: createStorageClassesListData() - }) - }) + }); + }); export const createStorageClassesListError = () => http.get('/apis/storage.k8s.io/v1/storageclasses', () => { - return HttpResponse.error() - }) + return HttpResponse.error(); + }); export const createStorageClassesListSlow = () => http.get('/apis/storage.k8s.io/v1/storageclasses', async () => { - await new Promise(resolve => setTimeout(resolve, 2000)) + await new Promise(resolve => setTimeout(resolve, 2000)); return HttpResponse.json({ apiVersion: 'v1', kind: 'StorageClassList', items: createStorageClassesListData() - }) - }) + }); + }); diff --git a/apps/ops-dashboard/__mocks__/handlers/volumeattachments.ts b/apps/ops-dashboard/__mocks__/handlers/volumeattachments.ts index c2973ad..c23ae5a 100644 --- a/apps/ops-dashboard/__mocks__/handlers/volumeattachments.ts +++ b/apps/ops-dashboard/__mocks__/handlers/volumeattachments.ts @@ -1,5 +1,5 @@ -import { http, HttpResponse } from 'msw' -import { type RequestHandler } from 'msw' +import { http, HttpResponse } from 'msw'; +import { type RequestHandler } from 'msw'; // Sample Volume Attachment data export const createVolumeAttachmentsListData = () => [ @@ -64,16 +64,16 @@ export const createVolumeAttachmentsListData = () => [ } } } -] +]; // Volume Attachment handlers export const createVolumeAttachmentDelete = (): RequestHandler => http.delete('/apis/storage.k8s.io/v1/volumeattachments/:name', ({ params }) => { - const { name } = params + const { name } = params; return HttpResponse.json({ message: `Volume attachment ${name} deleted successfully` - }) - }) + }); + }); export const createVolumeAttachmentsList = (): RequestHandler => http.get('/apis/storage.k8s.io/v1/volumeattachments', () => { @@ -81,8 +81,8 @@ export const createVolumeAttachmentsList = (): RequestHandler => apiVersion: 'storage.k8s.io/v1', kind: 'VolumeAttachmentList', items: createVolumeAttachmentsListData() - }) - }) + }); + }); // Error handlers export const createVolumeAttachmentsError = (): RequestHandler => @@ -90,15 +90,15 @@ export const createVolumeAttachmentsError = (): RequestHandler => return HttpResponse.json( { error: 'Failed to fetch volume attachments' }, { status: 500 } - ) - }) + ); + }); export const createVolumeAttachmentsSlow = (): RequestHandler => http.get('/apis/storage.k8s.io/v1/volumeattachments', async () => { - await new Promise(resolve => setTimeout(resolve, 2000)) + await new Promise(resolve => setTimeout(resolve, 2000)); return HttpResponse.json({ apiVersion: 'storage.k8s.io/v1', kind: 'VolumeAttachmentList', items: createVolumeAttachmentsListData() - }) - }) + }); + }); diff --git a/apps/ops-dashboard/__mocks__/server.ts b/apps/ops-dashboard/__mocks__/server.ts index ad131b6..9cd5641 100644 --- a/apps/ops-dashboard/__mocks__/server.ts +++ b/apps/ops-dashboard/__mocks__/server.ts @@ -1,8 +1,9 @@ -import { setupServer } from 'msw/node' -import { baseHandlers } from './handlers' +import { setupServer } from 'msw/node'; + +import { baseHandlers } from './handlers'; // Export handlers for individual use // Create a test server for Node.js environment with all handlers -export const server = setupServer(...baseHandlers) +export const server = setupServer(...baseHandlers); diff --git a/apps/ops-dashboard/__tests__/app/admin/backups/page.test.tsx b/apps/ops-dashboard/__tests__/app/admin/backups/page.test.tsx index 0d8fc58..f574588 100644 --- a/apps/ops-dashboard/__tests__/app/admin/backups/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/admin/backups/page.test.tsx @@ -1,10 +1,11 @@ -import React from 'react'; -import { render, screen, waitFor, act } from '@/__tests__/utils/test-utils'; import userEvent from '@testing-library/user-event'; -import { server } from '@/__mocks__/server'; import { http, HttpResponse } from 'msw'; +import React from 'react'; + +import { BackupInfo } from '@/__mocks__/handlers/backups'; +import { server } from '@/__mocks__/server'; +import {render, screen, waitFor } from '@/__tests__/utils/test-utils'; import AdminBackupView from '@/app/admin/backups/page'; -import { createBackupsList, createBackupsListError, createBackupsListNetworkError, createBackupsListData, BackupInfo } from '@/__mocks__/handlers/backups'; // Mock data factory const createMockBackup = (overrides: Partial = {}): BackupInfo => ({ diff --git a/apps/ops-dashboard/__tests__/app/admin/databases/page.test.tsx b/apps/ops-dashboard/__tests__/app/admin/databases/page.test.tsx index 644f6fa..0a6674c 100644 --- a/apps/ops-dashboard/__tests__/app/admin/databases/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/admin/databases/page.test.tsx @@ -1,16 +1,16 @@ import { screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { render } from '../../../utils/test-utils'; -import { server } from '@/__mocks__/server'; + import { - createDatabaseStatus, - createDatabaseStatusError, createBackupsList, - createCreateBackup -} from '@/__mocks__/handlers/databases'; + createDatabaseStatus, + createDatabaseStatusError} from '@/__mocks__/handlers/databases'; +import { server } from '@/__mocks__/server'; import DatabasesPage from '@/app/admin/databases/page'; import { DatabaseStatusSummary } from '@/hooks/use-database-status'; +import { render } from '../../../utils/test-utils'; + describe('DatabasesPage', () => { const mockDatabaseStatus: DatabaseStatusSummary = { name: 'postgres-cluster', diff --git a/apps/ops-dashboard/__tests__/app/admin/operators/page.test.tsx b/apps/ops-dashboard/__tests__/app/admin/operators/page.test.tsx index 44f1e16..e36086c 100644 --- a/apps/ops-dashboard/__tests__/app/admin/operators/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/admin/operators/page.test.tsx @@ -1,8 +1,9 @@ -import React from 'react'; -import { render, screen, waitFor } from '@/__tests__/utils/test-utils'; import userEvent from '@testing-library/user-event'; -import { server } from '@/__mocks__/server'; import { http, HttpResponse } from 'msw'; +import React from 'react'; + +import { server } from '@/__mocks__/server'; +import { render, screen, waitFor } from '@/__tests__/utils/test-utils'; import OperatorsPage from '@/app/admin/operators/page'; // Mock data diff --git a/apps/ops-dashboard/__tests__/app/admin/page.test.tsx b/apps/ops-dashboard/__tests__/app/admin/page.test.tsx index 2bd4342..7c1bb51 100644 --- a/apps/ops-dashboard/__tests__/app/admin/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/admin/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import DashboardPage from '@/app/admin/page'; diff --git a/apps/ops-dashboard/__tests__/app/admin/pods/page.test.tsx b/apps/ops-dashboard/__tests__/app/admin/pods/page.test.tsx index f86028e..4d81b7b 100644 --- a/apps/ops-dashboard/__tests__/app/admin/pods/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/admin/pods/page.test.tsx @@ -1,7 +1,8 @@ +import { http, HttpResponse } from 'msw'; import React from 'react'; -import { render, screen, waitFor } from '@/__tests__/utils/test-utils'; + import { server } from '@/__mocks__/server'; -import { http, HttpResponse } from 'msw'; +import { render, screen, waitFor } from '@/__tests__/utils/test-utils'; import AdminPodsPage from '@/app/admin/pods/page'; // Mock data diff --git a/apps/ops-dashboard/__tests__/app/admin/services/page.test.tsx b/apps/ops-dashboard/__tests__/app/admin/services/page.test.tsx index 94cb06b..8d77aab 100644 --- a/apps/ops-dashboard/__tests__/app/admin/services/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/admin/services/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import AdminServicesPage from '@/app/admin/services/page'; diff --git a/apps/ops-dashboard/__tests__/app/api/databases/[namespace]/[name]/backups.test.ts b/apps/ops-dashboard/__tests__/app/api/databases/[namespace]/[name]/backups.test.ts index 3dba203..90c8f98 100644 --- a/apps/ops-dashboard/__tests__/app/api/databases/[namespace]/[name]/backups.test.ts +++ b/apps/ops-dashboard/__tests__/app/api/databases/[namespace]/[name]/backups.test.ts @@ -1,4 +1,5 @@ import { NextRequest } from 'next/server'; + import { GET, POST } from '@/app/api/databases/[namespace]/[name]/backups/route'; // Mock the dependencies diff --git a/apps/ops-dashboard/__tests__/app/api/databases/[namespace]/[name]/deploy.test.ts b/apps/ops-dashboard/__tests__/app/api/databases/[namespace]/[name]/deploy.test.ts index 17d6285..f44661f 100644 --- a/apps/ops-dashboard/__tests__/app/api/databases/[namespace]/[name]/deploy.test.ts +++ b/apps/ops-dashboard/__tests__/app/api/databases/[namespace]/[name]/deploy.test.ts @@ -1,4 +1,5 @@ import { NextRequest } from 'next/server'; + import { POST } from '@/app/api/databases/[namespace]/[name]/deploy/route'; // Mock the dependencies diff --git a/apps/ops-dashboard/__tests__/app/api/databases/[namespace]/[name]/status.test.ts b/apps/ops-dashboard/__tests__/app/api/databases/[namespace]/[name]/status.test.ts index b8ba9f7..7e02c9c 100644 --- a/apps/ops-dashboard/__tests__/app/api/databases/[namespace]/[name]/status.test.ts +++ b/apps/ops-dashboard/__tests__/app/api/databases/[namespace]/[name]/status.test.ts @@ -1,4 +1,5 @@ import { NextRequest } from 'next/server'; + import { GET } from '@/app/api/databases/[namespace]/[name]/status/route'; // Mock the dependencies diff --git a/apps/ops-dashboard/__tests__/app/api/init.test.ts b/apps/ops-dashboard/__tests__/app/api/init.test.ts index 68ed2c0..5e1fe32 100644 --- a/apps/ops-dashboard/__tests__/app/api/init.test.ts +++ b/apps/ops-dashboard/__tests__/app/api/init.test.ts @@ -1,6 +1,7 @@ -import { POST } from '@/app/api/init/route'; import { NextRequest } from 'next/server'; +import { POST } from '@/app/api/init/route'; + // Mock crypto module jest.mock('crypto', () => ({ randomUUID: jest.fn(() => 'mock-uuid-123'), diff --git a/apps/ops-dashboard/__tests__/app/api/operators.test.ts b/apps/ops-dashboard/__tests__/app/api/operators.test.ts index a24a4f0..84c68b0 100644 --- a/apps/ops-dashboard/__tests__/app/api/operators.test.ts +++ b/apps/ops-dashboard/__tests__/app/api/operators.test.ts @@ -1,4 +1,5 @@ import { NextRequest } from 'next/server'; + import { GET } from '@/app/api/operators/route'; // Mock the dependencies diff --git a/apps/ops-dashboard/__tests__/app/api/operators/[operator]/debug.test.ts b/apps/ops-dashboard/__tests__/app/api/operators/[operator]/debug.test.ts index 629f927..b368fec 100644 --- a/apps/ops-dashboard/__tests__/app/api/operators/[operator]/debug.test.ts +++ b/apps/ops-dashboard/__tests__/app/api/operators/[operator]/debug.test.ts @@ -1,4 +1,5 @@ import { NextRequest } from 'next/server'; + import { GET } from '@/app/api/operators/[operator]/debug/route'; // Mock the dependencies diff --git a/apps/ops-dashboard/__tests__/app/api/operators/[operator]/install.test.ts b/apps/ops-dashboard/__tests__/app/api/operators/[operator]/install.test.ts index 4d82f0a..51fc1c6 100644 --- a/apps/ops-dashboard/__tests__/app/api/operators/[operator]/install.test.ts +++ b/apps/ops-dashboard/__tests__/app/api/operators/[operator]/install.test.ts @@ -1,5 +1,6 @@ import { NextRequest } from 'next/server'; -import { POST, DELETE } from '@/app/api/operators/[operator]/install/route'; + +import { DELETE,POST } from '@/app/api/operators/[operator]/install/route'; // Mock the dependencies jest.mock('@/k8s/client', () => ({ diff --git a/apps/ops-dashboard/__tests__/app/api/operators/[operator]/status.test.ts b/apps/ops-dashboard/__tests__/app/api/operators/[operator]/status.test.ts index 233d435..aff6e59 100644 --- a/apps/ops-dashboard/__tests__/app/api/operators/[operator]/status.test.ts +++ b/apps/ops-dashboard/__tests__/app/api/operators/[operator]/status.test.ts @@ -1,4 +1,5 @@ import { NextRequest } from 'next/server'; + import { GET } from '@/app/api/operators/[operator]/status/route'; // Mock the dependencies diff --git a/apps/ops-dashboard/__tests__/app/d/chains/page.test.tsx b/apps/ops-dashboard/__tests__/app/d/chains/page.test.tsx index 958b35d..a8df046 100644 --- a/apps/ops-dashboard/__tests__/app/d/chains/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/d/chains/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import ChainsPage from '@/app/d/chains/page'; diff --git a/apps/ops-dashboard/__tests__/app/d/databases/page.test.tsx b/apps/ops-dashboard/__tests__/app/d/databases/page.test.tsx index 54657e6..240d94d 100644 --- a/apps/ops-dashboard/__tests__/app/d/databases/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/d/databases/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import DatabasesPage from '@/app/d/databases/page'; diff --git a/apps/ops-dashboard/__tests__/app/d/functions/page.test.tsx b/apps/ops-dashboard/__tests__/app/d/functions/page.test.tsx index 4f86834..23a6745 100644 --- a/apps/ops-dashboard/__tests__/app/d/functions/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/d/functions/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import FunctionsPage from '@/app/d/functions/page'; diff --git a/apps/ops-dashboard/__tests__/app/d/page.test.tsx b/apps/ops-dashboard/__tests__/app/d/page.test.tsx index 584ae89..06e86c5 100644 --- a/apps/ops-dashboard/__tests__/app/d/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/d/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import SmartObjectsDashboard from '@/app/d/page'; diff --git a/apps/ops-dashboard/__tests__/app/d/registry/page.test.tsx b/apps/ops-dashboard/__tests__/app/d/registry/page.test.tsx index cb80b7a..92cf02a 100644 --- a/apps/ops-dashboard/__tests__/app/d/registry/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/d/registry/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import RegistryPage from '@/app/d/registry/page'; diff --git a/apps/ops-dashboard/__tests__/app/d/relayers/page.test.tsx b/apps/ops-dashboard/__tests__/app/d/relayers/page.test.tsx index 20895ce..0b67952 100644 --- a/apps/ops-dashboard/__tests__/app/d/relayers/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/d/relayers/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import RelayersPage from '@/app/d/relayers/page'; diff --git a/apps/ops-dashboard/__tests__/app/d/settings/page.test.tsx b/apps/ops-dashboard/__tests__/app/d/settings/page.test.tsx index c92695f..f99ffbc 100644 --- a/apps/ops-dashboard/__tests__/app/d/settings/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/d/settings/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import SettingsPage from '@/app/d/settings/page'; diff --git a/apps/ops-dashboard/__tests__/app/databases/page.test.tsx b/apps/ops-dashboard/__tests__/app/databases/page.test.tsx index 484b89f..1302e66 100644 --- a/apps/ops-dashboard/__tests__/app/databases/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/databases/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import DatabasesPage from '@/app/databases/page'; diff --git a/apps/ops-dashboard/__tests__/app/functions/page.test.tsx b/apps/ops-dashboard/__tests__/app/functions/page.test.tsx index cc0f39f..d0bcc2c 100644 --- a/apps/ops-dashboard/__tests__/app/functions/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/functions/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import FunctionsPage from '@/app/functions/page'; diff --git a/apps/ops-dashboard/__tests__/app/i/all/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/all/page.test.tsx index 5fa4797..6c48108 100644 --- a/apps/ops-dashboard/__tests__/app/i/all/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/i/all/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import AllResourcesPage from '@/app/i/all/page'; diff --git a/apps/ops-dashboard/__tests__/app/i/configmaps/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/configmaps/page.test.tsx index a3ff852..bf94744 100644 --- a/apps/ops-dashboard/__tests__/app/i/configmaps/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/i/configmaps/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import ConfigMapsPage from '@/app/i/configmaps/page'; diff --git a/apps/ops-dashboard/__tests__/app/i/cronjobs/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/cronjobs/page.test.tsx index daa8b33..679c1f6 100644 --- a/apps/ops-dashboard/__tests__/app/i/cronjobs/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/i/cronjobs/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import CronJobsPage from '@/app/i/cronjobs/page'; diff --git a/apps/ops-dashboard/__tests__/app/i/daemonsets/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/daemonsets/page.test.tsx index 18dfd50..a5d07e0 100644 --- a/apps/ops-dashboard/__tests__/app/i/daemonsets/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/i/daemonsets/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import DaemonSetsPage from '@/app/i/daemonsets/page'; diff --git a/apps/ops-dashboard/__tests__/app/i/deployments/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/deployments/page.test.tsx index e423ae8..5b7ce64 100644 --- a/apps/ops-dashboard/__tests__/app/i/deployments/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/i/deployments/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import DeploymentsPage from '@/app/i/deployments/page'; diff --git a/apps/ops-dashboard/__tests__/app/i/endpoints/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/endpoints/page.test.tsx index 14cdd37..abac8cb 100644 --- a/apps/ops-dashboard/__tests__/app/i/endpoints/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/i/endpoints/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import EndpointsPage from '@/app/i/endpoints/page'; diff --git a/apps/ops-dashboard/__tests__/app/i/endpointslices/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/endpointslices/page.test.tsx index 80c5ba4..42f743f 100644 --- a/apps/ops-dashboard/__tests__/app/i/endpointslices/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/i/endpointslices/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import EndpointSlicesPage from '@/app/i/endpointslices/page'; diff --git a/apps/ops-dashboard/__tests__/app/i/events/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/events/page.test.tsx index 897c8b9..2f3976b 100644 --- a/apps/ops-dashboard/__tests__/app/i/events/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/i/events/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import EventsPage from '@/app/i/events/page'; diff --git a/apps/ops-dashboard/__tests__/app/i/hpas/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/hpas/page.test.tsx index f2fae1c..daa8aab 100644 --- a/apps/ops-dashboard/__tests__/app/i/hpas/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/i/hpas/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import HPAsPage from '@/app/i/hpas/page'; diff --git a/apps/ops-dashboard/__tests__/app/i/ingresses/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/ingresses/page.test.tsx index f1cb613..d8e9b65 100644 --- a/apps/ops-dashboard/__tests__/app/i/ingresses/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/i/ingresses/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import IngressesPage from '@/app/i/ingresses/page'; diff --git a/apps/ops-dashboard/__tests__/app/i/jobs/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/jobs/page.test.tsx index 08300bf..ed1bd42 100644 --- a/apps/ops-dashboard/__tests__/app/i/jobs/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/i/jobs/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import JobsPage from '@/app/i/jobs/page'; diff --git a/apps/ops-dashboard/__tests__/app/i/networkpolicies/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/networkpolicies/page.test.tsx index 9cd34eb..1884f97 100644 --- a/apps/ops-dashboard/__tests__/app/i/networkpolicies/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/i/networkpolicies/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import NetworkPoliciesPage from '@/app/i/networkpolicies/page'; diff --git a/apps/ops-dashboard/__tests__/app/i/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/page.test.tsx index d6e088c..697f8f6 100644 --- a/apps/ops-dashboard/__tests__/app/i/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/i/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import InfrastructureOverviewPage from '@/app/i/page'; diff --git a/apps/ops-dashboard/__tests__/app/i/pdbs/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/pdbs/page.test.tsx index 43bb084..5178b67 100644 --- a/apps/ops-dashboard/__tests__/app/i/pdbs/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/i/pdbs/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import PDBsPage from '@/app/i/pdbs/page'; diff --git a/apps/ops-dashboard/__tests__/app/i/pods/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/pods/page.test.tsx index 559639f..735d16f 100644 --- a/apps/ops-dashboard/__tests__/app/i/pods/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/i/pods/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import PodsPage from '@/app/i/pods/page'; diff --git a/apps/ops-dashboard/__tests__/app/i/priorityclasses/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/priorityclasses/page.test.tsx index d71afc7..9253b55 100644 --- a/apps/ops-dashboard/__tests__/app/i/priorityclasses/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/i/priorityclasses/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import PriorityClassesPage from '@/app/i/priorityclasses/page'; diff --git a/apps/ops-dashboard/__tests__/app/i/pvcs/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/pvcs/page.test.tsx index 878f692..31fb554 100644 --- a/apps/ops-dashboard/__tests__/app/i/pvcs/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/i/pvcs/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import PVCsPage from '@/app/i/pvcs/page'; diff --git a/apps/ops-dashboard/__tests__/app/i/pvs/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/pvs/page.test.tsx index 1c45ed7..5de0679 100644 --- a/apps/ops-dashboard/__tests__/app/i/pvs/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/i/pvs/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import PVsPage from '@/app/i/pvs/page'; diff --git a/apps/ops-dashboard/__tests__/app/i/replicasets/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/replicasets/page.test.tsx index cd67134..aa4791b 100644 --- a/apps/ops-dashboard/__tests__/app/i/replicasets/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/i/replicasets/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import ReplicaSetsPage from '@/app/i/replicasets/page'; diff --git a/apps/ops-dashboard/__tests__/app/i/resourcequotas/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/resourcequotas/page.test.tsx index 116f6d5..853401c 100644 --- a/apps/ops-dashboard/__tests__/app/i/resourcequotas/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/i/resourcequotas/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import ResourceQuotasPage from '@/app/i/resourcequotas/page'; diff --git a/apps/ops-dashboard/__tests__/app/i/rolebindings/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/rolebindings/page.test.tsx index 8bbb7d6..c88ff88 100644 --- a/apps/ops-dashboard/__tests__/app/i/rolebindings/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/i/rolebindings/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import RoleBindingsPage from '@/app/i/rolebindings/page'; diff --git a/apps/ops-dashboard/__tests__/app/i/roles/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/roles/page.test.tsx index 70945cb..844da0a 100644 --- a/apps/ops-dashboard/__tests__/app/i/roles/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/i/roles/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import RolesPage from '@/app/i/roles/page'; diff --git a/apps/ops-dashboard/__tests__/app/i/runtimeclasses/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/runtimeclasses/page.test.tsx index 2ecf8c3..9052f52 100644 --- a/apps/ops-dashboard/__tests__/app/i/runtimeclasses/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/i/runtimeclasses/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import RuntimeClassesPage from '@/app/i/runtimeclasses/page'; diff --git a/apps/ops-dashboard/__tests__/app/i/secrets/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/secrets/page.test.tsx index 63d03b1..7f1224b 100644 --- a/apps/ops-dashboard/__tests__/app/i/secrets/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/i/secrets/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import SecretsPage from '@/app/i/secrets/page'; diff --git a/apps/ops-dashboard/__tests__/app/i/serviceaccounts/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/serviceaccounts/page.test.tsx index 508d645..03f1342 100644 --- a/apps/ops-dashboard/__tests__/app/i/serviceaccounts/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/i/serviceaccounts/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import ServiceAccountsPage from '@/app/i/serviceaccounts/page'; diff --git a/apps/ops-dashboard/__tests__/app/i/services/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/services/page.test.tsx index f95c6e2..7ef64c7 100644 --- a/apps/ops-dashboard/__tests__/app/i/services/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/i/services/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import ServicesPage from '@/app/i/services/page'; diff --git a/apps/ops-dashboard/__tests__/app/i/statefulsets/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/statefulsets/page.test.tsx index 6adb892..be4de88 100644 --- a/apps/ops-dashboard/__tests__/app/i/statefulsets/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/i/statefulsets/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import StatefulSetsPage from '@/app/i/statefulsets/page'; diff --git a/apps/ops-dashboard/__tests__/app/i/storageclasses/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/storageclasses/page.test.tsx index 5f059b2..a26fe1b 100644 --- a/apps/ops-dashboard/__tests__/app/i/storageclasses/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/i/storageclasses/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import StorageClassesPage from '@/app/i/storageclasses/page'; diff --git a/apps/ops-dashboard/__tests__/app/i/templates/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/templates/page.test.tsx index 8c34c40..187acb8 100644 --- a/apps/ops-dashboard/__tests__/app/i/templates/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/i/templates/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import TemplatesPage from '@/app/i/templates/page'; diff --git a/apps/ops-dashboard/__tests__/app/i/volumeattachments/page.test.tsx b/apps/ops-dashboard/__tests__/app/i/volumeattachments/page.test.tsx index b300cfe..f1592d2 100644 --- a/apps/ops-dashboard/__tests__/app/i/volumeattachments/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/i/volumeattachments/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import VolumeAttachmentsPage from '@/app/i/volumeattachments/page'; diff --git a/apps/ops-dashboard/__tests__/app/layout.test.tsx b/apps/ops-dashboard/__tests__/app/layout.test.tsx index 3aee64b..787ec16 100644 --- a/apps/ops-dashboard/__tests__/app/layout.test.tsx +++ b/apps/ops-dashboard/__tests__/app/layout.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render, screen } from '@/__tests__/utils/test-utils'; import RootLayout from '@/app/layout'; diff --git a/apps/ops-dashboard/__tests__/app/page.test.tsx b/apps/ops-dashboard/__tests__/app/page.test.tsx index 12ac9da..00cf7a2 100644 --- a/apps/ops-dashboard/__tests__/app/page.test.tsx +++ b/apps/ops-dashboard/__tests__/app/page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { render } from '@/__tests__/utils/test-utils'; import HomePage from '@/app/page'; diff --git a/apps/ops-dashboard/__tests__/app/providers.test.tsx b/apps/ops-dashboard/__tests__/app/providers.test.tsx index dc10bb5..37dc590 100644 --- a/apps/ops-dashboard/__tests__/app/providers.test.tsx +++ b/apps/ops-dashboard/__tests__/app/providers.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; +import React from 'react'; + import { Providers } from '@/app/providers'; // Mock the provider components diff --git a/apps/ops-dashboard/__tests__/components/adaptive-layout.test.tsx b/apps/ops-dashboard/__tests__/components/adaptive-layout.test.tsx index 2cd55ca..c85f6fc 100644 --- a/apps/ops-dashboard/__tests__/components/adaptive-layout.test.tsx +++ b/apps/ops-dashboard/__tests__/components/adaptive-layout.test.tsx @@ -1,6 +1,6 @@ import { render, screen } from '@testing-library/react'; + import { AdaptiveLayout } from '../../components/adaptive-layout'; -import { render as customRender } from '../utils/test-utils'; // Mock next/navigation jest.mock('next/navigation', () => ({ diff --git a/apps/ops-dashboard/__tests__/components/admin/cluster-overview.test.tsx b/apps/ops-dashboard/__tests__/components/admin/cluster-overview.test.tsx index 39784b6..ed9ac22 100644 --- a/apps/ops-dashboard/__tests__/components/admin/cluster-overview.test.tsx +++ b/apps/ops-dashboard/__tests__/components/admin/cluster-overview.test.tsx @@ -1,17 +1,18 @@ -import { render, screen, waitFor } from '../../utils/test-utils' -import { ClusterOverview } from '@/components/admin/cluster-overview' +import { ClusterOverview } from '@/components/admin/cluster-overview'; + +import { render, screen } from '../../utils/test-utils'; // Mock the hook jest.mock('../../../hooks/use-cluster-status', () => ({ useClusterStatus: jest.fn() -})) +})); describe('ClusterOverview', () => { - const mockUseClusterStatus = require('../../../hooks/use-cluster-status').useClusterStatus + const mockUseClusterStatus = require('../../../hooks/use-cluster-status').useClusterStatus; beforeEach(() => { - jest.clearAllMocks() - }) + jest.clearAllMocks(); + }); describe('Loading State', () => { it('should show loading spinner when loading', () => { @@ -19,27 +20,27 @@ describe('ClusterOverview', () => { data: null, isLoading: true, error: null - }) + }); - render() + render(); - expect(screen.getByText('Loading cluster status...')).toBeInTheDocument() - expect(screen.getByText('Loading cluster status...').previousElementSibling).toHaveClass('animate-spin') - }) + expect(screen.getByText('Loading cluster status...')).toBeInTheDocument(); + expect(screen.getByText('Loading cluster status...').previousElementSibling).toHaveClass('animate-spin'); + }); it('should show loading spinner with correct styling', () => { mockUseClusterStatus.mockReturnValue({ data: null, isLoading: true, error: null - }) + }); - render() + render(); - const spinner = screen.getByText('Loading cluster status...').previousElementSibling - expect(spinner).toHaveClass('animate-spin') - }) - }) + const spinner = screen.getByText('Loading cluster status...').previousElementSibling; + expect(spinner).toHaveClass('animate-spin'); + }); + }); describe('Error State', () => { it('should show error message when there is an error', () => { @@ -47,27 +48,27 @@ describe('ClusterOverview', () => { data: null, isLoading: false, error: new Error('Connection failed') - }) + }); - render() + render(); - expect(screen.getByText('Failed to load cluster status')).toBeInTheDocument() - expect(screen.getByText('Make sure kubectl proxy is running on port 8001')).toBeInTheDocument() - }) + expect(screen.getByText('Failed to load cluster status')).toBeInTheDocument(); + expect(screen.getByText('Make sure kubectl proxy is running on port 8001')).toBeInTheDocument(); + }); it('should show error message with correct styling', () => { mockUseClusterStatus.mockReturnValue({ data: null, isLoading: false, error: new Error('Connection failed') - }) + }); - render() + render(); - const errorMessage = screen.getByText('Failed to load cluster status') - expect(errorMessage).toHaveClass('text-red-600') - }) - }) + const errorMessage = screen.getByText('Failed to load cluster status'); + expect(errorMessage).toHaveClass('text-red-600'); + }); + }); describe('Success State', () => { const mockClusterData = { @@ -96,66 +97,66 @@ describe('ClusterOverview', () => { roles: ['worker'] } ] - } + }; beforeEach(() => { mockUseClusterStatus.mockReturnValue({ data: mockClusterData, isLoading: false, error: null - }) - }) + }); + }); it('should render cluster overview with header', () => { - render() + render(); - expect(screen.getByText('Cluster Status')).toBeInTheDocument() - }) + expect(screen.getByText('Cluster Status')).toBeInTheDocument(); + }); it('should display cluster statistics', () => { - render() + render(); - expect(screen.getByText('3')).toBeInTheDocument() // Nodes - expect(screen.getByText('15')).toBeInTheDocument() // Pods - expect(screen.getByText('8')).toBeInTheDocument() // Services - expect(screen.getByText('5')).toBeInTheDocument() // Operators - }) + expect(screen.getByText('3')).toBeInTheDocument(); // Nodes + expect(screen.getByText('15')).toBeInTheDocument(); // Pods + expect(screen.getByText('8')).toBeInTheDocument(); // Services + expect(screen.getByText('5')).toBeInTheDocument(); // Operators + }); it('should display statistics labels', () => { - render() + render(); - expect(screen.getByText('Nodes', { selector: '.text-sm.text-gray-500' })).toBeInTheDocument() - expect(screen.getByText('Pods', { selector: '.text-sm.text-gray-500' })).toBeInTheDocument() - expect(screen.getByText('Services', { selector: '.text-sm.text-gray-500' })).toBeInTheDocument() - expect(screen.getByText('Operators', { selector: '.text-sm.text-gray-500' })).toBeInTheDocument() - }) + expect(screen.getByText('Nodes', { selector: '.text-sm.text-gray-500' })).toBeInTheDocument(); + expect(screen.getByText('Pods', { selector: '.text-sm.text-gray-500' })).toBeInTheDocument(); + expect(screen.getByText('Services', { selector: '.text-sm.text-gray-500' })).toBeInTheDocument(); + expect(screen.getByText('Operators', { selector: '.text-sm.text-gray-500' })).toBeInTheDocument(); + }); it('should display nodes section when nodes are available', () => { - render() + render(); - expect(screen.getByText('Nodes', { selector: 'h4' })).toBeInTheDocument() - }) + expect(screen.getByText('Nodes', { selector: 'h4' })).toBeInTheDocument(); + }); it('should display node information', () => { - render() + render(); - expect(screen.getByText('master-node-1')).toBeInTheDocument() - expect(screen.getByText('worker-node-1')).toBeInTheDocument() - expect(screen.getByText('worker-node-2')).toBeInTheDocument() - }) + expect(screen.getByText('master-node-1')).toBeInTheDocument(); + expect(screen.getByText('worker-node-1')).toBeInTheDocument(); + expect(screen.getByText('worker-node-2')).toBeInTheDocument(); + }); it('should display node versions', () => { - render() + render(); - expect(screen.getAllByText('v1.28.0')).toHaveLength(3) - }) + expect(screen.getAllByText('v1.28.0')).toHaveLength(3); + }); it('should display node roles', () => { - render() + render(); - expect(screen.getByText('(master, control-plane)')).toBeInTheDocument() - expect(screen.getAllByText('(worker)')).toHaveLength(2) // Two worker nodes - }) + expect(screen.getByText('(master, control-plane)')).toBeInTheDocument(); + expect(screen.getAllByText('(worker)')).toHaveLength(2); // Two worker nodes + }); it('should not display nodes section when no nodes', () => { mockUseClusterStatus.mockReturnValue({ @@ -165,12 +166,12 @@ describe('ClusterOverview', () => { }, isLoading: false, error: null - }) + }); - render() + render(); - expect(screen.queryByText('Nodes', { selector: 'h4' })).not.toBeInTheDocument() - }) + expect(screen.queryByText('Nodes', { selector: 'h4' })).not.toBeInTheDocument(); + }); it('should not display nodes section when nodes is undefined', () => { mockUseClusterStatus.mockReturnValue({ @@ -180,13 +181,13 @@ describe('ClusterOverview', () => { }, isLoading: false, error: null - }) + }); - render() + render(); - expect(screen.queryByText('Nodes', { selector: 'h4' })).not.toBeInTheDocument() - }) - }) + expect(screen.queryByText('Nodes', { selector: 'h4' })).not.toBeInTheDocument(); + }); + }); describe('Status Indicators', () => { it('should show ready status indicator for healthy cluster', () => { @@ -200,13 +201,13 @@ describe('ClusterOverview', () => { }, isLoading: false, error: null - }) + }); - render() + render(); // StatusIndicator component should be rendered - expect(screen.getByText('Cluster Status')).toBeInTheDocument() - }) + expect(screen.getByText('Cluster Status')).toBeInTheDocument(); + }); it('should show error status indicator for unhealthy cluster', () => { mockUseClusterStatus.mockReturnValue({ @@ -219,13 +220,13 @@ describe('ClusterOverview', () => { }, isLoading: false, error: null - }) + }); - render() + render(); // StatusIndicator component should be rendered - expect(screen.getByText('Cluster Status')).toBeInTheDocument() - }) + expect(screen.getByText('Cluster Status')).toBeInTheDocument(); + }); it('should show status indicators for individual nodes', () => { mockUseClusterStatus.mockReturnValue({ @@ -252,14 +253,14 @@ describe('ClusterOverview', () => { }, isLoading: false, error: null - }) + }); - render() + render(); - expect(screen.getByText('ready-node')).toBeInTheDocument() - expect(screen.getByText('not-ready-node')).toBeInTheDocument() - }) - }) + expect(screen.getByText('ready-node')).toBeInTheDocument(); + expect(screen.getByText('not-ready-node')).toBeInTheDocument(); + }); + }); describe('Edge Cases', () => { it('should handle null cluster data', () => { @@ -267,24 +268,24 @@ describe('ClusterOverview', () => { data: null, isLoading: false, error: null - }) + }); - render() + render(); - expect(screen.getAllByText('0', { selector: '.text-2xl.font-semibold' })).toHaveLength(4) // All counts should be 0 - }) + expect(screen.getAllByText('0', { selector: '.text-2xl.font-semibold' })).toHaveLength(4); // All counts should be 0 + }); it('should handle undefined cluster properties', () => { mockUseClusterStatus.mockReturnValue({ data: {}, isLoading: false, error: null - }) + }); - render() + render(); - expect(screen.getAllByText('0')).toHaveLength(4) // All counts should be 0 - }) + expect(screen.getAllByText('0')).toHaveLength(4); // All counts should be 0 + }); it('should handle nodes with no roles', () => { mockUseClusterStatus.mockReturnValue({ @@ -305,14 +306,14 @@ describe('ClusterOverview', () => { }, isLoading: false, error: null - }) + }); - render() + render(); - expect(screen.getByText('node-without-roles')).toBeInTheDocument() - expect(screen.queryByText('()')).not.toBeInTheDocument() - }) - }) + expect(screen.getByText('node-without-roles')).toBeInTheDocument(); + expect(screen.queryByText('()')).not.toBeInTheDocument(); + }); + }); describe('Accessibility', () => { it('should have proper heading structure', () => { @@ -326,12 +327,12 @@ describe('ClusterOverview', () => { }, isLoading: false, error: null - }) + }); - render() + render(); - expect(screen.getByRole('heading', { name: 'Cluster Status' })).toBeInTheDocument() - }) + expect(screen.getByRole('heading', { name: 'Cluster Status' })).toBeInTheDocument(); + }); it('should be keyboard navigable', () => { mockUseClusterStatus.mockReturnValue({ @@ -344,12 +345,12 @@ describe('ClusterOverview', () => { }, isLoading: false, error: null - }) + }); - render() + render(); // The component should be accessible via keyboard - expect(screen.getByText('Cluster Status')).toBeInTheDocument() - }) - }) -}) \ No newline at end of file + expect(screen.getByText('Cluster Status')).toBeInTheDocument(); + }); + }); +}); \ No newline at end of file diff --git a/apps/ops-dashboard/__tests__/components/admin/operator-card.test.tsx b/apps/ops-dashboard/__tests__/components/admin/operator-card.test.tsx index e28e6a3..b6b8ef8 100644 --- a/apps/ops-dashboard/__tests__/components/admin/operator-card.test.tsx +++ b/apps/ops-dashboard/__tests__/components/admin/operator-card.test.tsx @@ -1,19 +1,20 @@ -import React from 'react' -import { render, screen, waitFor } from '../../utils/test-utils' -import userEvent from '@testing-library/user-event' -import { OperatorCard } from '../../../components/admin/operator-card' -import type { OperatorInfo } from '@kubernetesjs/client' +import type { OperatorInfo } from '@kubernetesjs/client'; +import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { OperatorCard } from '../../../components/admin/operator-card'; +import { render, screen, waitFor } from '../../utils/test-utils'; // Mock useOperatorMutation to control install/uninstall behavior -const installMock = jest.fn() -const uninstallMock = jest.fn() +const installMock = jest.fn(); +const uninstallMock = jest.fn(); jest.mock('../../../hooks/use-operators', () => ({ useOperatorMutation: () => ({ installOperator: { mutateAsync: installMock }, uninstallOperator: { mutateAsync: uninstallMock }, }), -})) +})); const baseOperator: OperatorInfo = { name: 'ingress-nginx', @@ -22,78 +23,78 @@ const baseOperator: OperatorInfo = { description: 'Kubernetes Ingress controller for NGINX', status: 'not-installed', docsUrl: 'https://kubernetes.github.io/ingress-nginx/', -} +}; describe('OperatorCard', () => { beforeEach(() => { - jest.clearAllMocks() - }) + jest.clearAllMocks(); + }); it('renders full card with title, version, description and status', () => { - render() + render(); - expect(screen.getByRole('heading', { name: 'Ingress NGINX' })).toBeInTheDocument() - expect(screen.getByText('v1.10.0')).toBeInTheDocument() - expect(screen.getByText('Kubernetes Ingress controller for NGINX')).toBeInTheDocument() + expect(screen.getByRole('heading', { name: 'Ingress NGINX' })).toBeInTheDocument(); + expect(screen.getByText('v1.10.0')).toBeInTheDocument(); + expect(screen.getByText('Kubernetes Ingress controller for NGINX')).toBeInTheDocument(); // StatusIndicator present (icon) - expect(document.querySelector('svg.lucide')).toBeInTheDocument() - }) + expect(document.querySelector('svg.lucide')).toBeInTheDocument(); + }); it('renders compact mode with icon, version and toggle', () => { - render() + render(); - expect(screen.getByText('Ingress NGINX')).toBeInTheDocument() - expect(screen.getByText('v1.10.0')).toBeInTheDocument() + expect(screen.getByText('Ingress NGINX')).toBeInTheDocument(); + expect(screen.getByText('v1.10.0')).toBeInTheDocument(); // Has switch (role switch comes from radix; fallback query by input[type=checkbox]) - const checkbox = document.querySelector('button[role="switch"], input[type="checkbox"]') - expect(checkbox).toBeTruthy() - }) + const checkbox = document.querySelector('button[role="switch"], input[type="checkbox"]'); + expect(checkbox).toBeTruthy(); + }); it('calls install when toggled on from not-installed', async () => { - const user = userEvent.setup() + const user = userEvent.setup(); // Delay install to observe loading state if needed - installMock.mockImplementation(() => new Promise(resolve => setTimeout(resolve, 50))) + installMock.mockImplementation(() => new Promise(resolve => setTimeout(resolve, 50))); - render() + render(); - const switchEl = document.querySelector('button[role="switch"], input[type="checkbox"]') as HTMLElement - expect(switchEl).toBeTruthy() - await user.click(switchEl) + const switchEl = document.querySelector('button[role="switch"], input[type="checkbox"]') as HTMLElement; + expect(switchEl).toBeTruthy(); + await user.click(switchEl); await waitFor(() => { - expect(installMock).toHaveBeenCalledWith('ingress-nginx') - }) - }) + expect(installMock).toHaveBeenCalledWith('ingress-nginx'); + }); + }); it('calls uninstall when toggled off from installed state', async () => { - const user = userEvent.setup() - uninstallMock.mockResolvedValue(undefined) + const user = userEvent.setup(); + uninstallMock.mockResolvedValue(undefined); - render() + render(); - const switchEl = document.querySelector('button[role="switch"], input[type="checkbox"]') as HTMLElement - expect(switchEl).toBeTruthy() - await user.click(switchEl) + const switchEl = document.querySelector('button[role="switch"], input[type="checkbox"]') as HTMLElement; + expect(switchEl).toBeTruthy(); + await user.click(switchEl); await waitFor(() => { - expect(uninstallMock).toHaveBeenCalledWith('ingress-nginx') - }) - }) + expect(uninstallMock).toHaveBeenCalledWith('ingress-nginx'); + }); + }); it('shows settings button only when installed', () => { - const { rerender } = render() + const { rerender } = render(); // Settings button is an anchor wrapped in button; look for Settings icon container - expect(document.querySelector('a[href="/operators/ingress-nginx"]')).not.toBeInTheDocument() + expect(document.querySelector('a[href="/operators/ingress-nginx"]')).not.toBeInTheDocument(); - rerender() - expect(document.querySelector('a[href="/operators/ingress-nginx"]')).toBeInTheDocument() - }) + rerender(); + expect(document.querySelector('a[href="/operators/ingress-nginx"]')).toBeInTheDocument(); + }); it('renders docs link when docsUrl provided', () => { - render() - const docs = document.querySelector(`a[href="${baseOperator.docsUrl}"]`) - expect(docs).toBeInTheDocument() - }) -}) + render(); + const docs = document.querySelector(`a[href="${baseOperator.docsUrl}"]`); + expect(docs).toBeInTheDocument(); + }); +}); diff --git a/apps/ops-dashboard/__tests__/components/admin/operator-filters.test.tsx b/apps/ops-dashboard/__tests__/components/admin/operator-filters.test.tsx index a9a5367..e3460da 100644 --- a/apps/ops-dashboard/__tests__/components/admin/operator-filters.test.tsx +++ b/apps/ops-dashboard/__tests__/components/admin/operator-filters.test.tsx @@ -1,318 +1,320 @@ -import { render, screen, fireEvent } from '../../utils/test-utils' -import userEvent from '@testing-library/user-event' -import { OperatorFilters } from '@/components/admin/operator-filters' +import userEvent from '@testing-library/user-event'; + +import { OperatorFilters } from '@/components/admin/operator-filters'; + +import {render, screen } from '../../utils/test-utils'; describe('OperatorFilters', () => { - const mockOnSearchChange = jest.fn() - const mockOnStatusFilterChange = jest.fn() + const mockOnSearchChange = jest.fn(); + const mockOnStatusFilterChange = jest.fn(); const defaultProps = { searchTerm: '', onSearchChange: mockOnSearchChange, statusFilter: 'all', onStatusFilterChange: mockOnStatusFilterChange, - } + }; beforeEach(() => { - jest.clearAllMocks() - }) + jest.clearAllMocks(); + }); describe('Basic Rendering', () => { it('should render search input with placeholder', () => { - render() + render(); - expect(screen.getByPlaceholderText('Search operators...')).toBeInTheDocument() - }) + expect(screen.getByPlaceholderText('Search operators...')).toBeInTheDocument(); + }); it('should render status filter select', () => { - render() + render(); - expect(screen.getByText('All Status')).toBeInTheDocument() - }) + expect(screen.getByText('All Status')).toBeInTheDocument(); + }); it('should render help text and documentation link', () => { - render() + render(); - expect(screen.getByText('Need help?')).toBeInTheDocument() - expect(screen.getByText('View operator docs')).toBeInTheDocument() - }) + expect(screen.getByText('Need help?')).toBeInTheDocument(); + expect(screen.getByText('View operator docs')).toBeInTheDocument(); + }); it('should render search icon', () => { - render() + render(); - const searchInput = screen.getByPlaceholderText('Search operators...') - const searchIcon = searchInput.parentElement?.querySelector('svg') - expect(searchIcon).toBeInTheDocument() - }) + const searchInput = screen.getByPlaceholderText('Search operators...'); + const searchIcon = searchInput.parentElement?.querySelector('svg'); + expect(searchIcon).toBeInTheDocument(); + }); it('should render filter icon', () => { - render() + render(); - const selectButton = screen.getByRole('combobox') - const filterIcon = selectButton.querySelector('svg') - expect(filterIcon).toBeInTheDocument() - }) - }) + const selectButton = screen.getByRole('combobox'); + const filterIcon = selectButton.querySelector('svg'); + expect(filterIcon).toBeInTheDocument(); + }); + }); describe('Search Functionality', () => { it('should display current search term', () => { - render() + render(); - const searchInput = screen.getByPlaceholderText('Search operators...') - expect(searchInput).toHaveValue('test search') - }) + const searchInput = screen.getByPlaceholderText('Search operators...'); + expect(searchInput).toHaveValue('test search'); + }); it('should call onSearchChange when typing in search input', async () => { - const user = userEvent.setup() - render() + const user = userEvent.setup(); + render(); - const searchInput = screen.getByPlaceholderText('Search operators...') - await user.type(searchInput, 'test') + const searchInput = screen.getByPlaceholderText('Search operators...'); + await user.type(searchInput, 'test'); - expect(mockOnSearchChange).toHaveBeenCalledTimes(4) // Called for each character - expect(mockOnSearchChange).toHaveBeenNthCalledWith(1, 't') - expect(mockOnSearchChange).toHaveBeenNthCalledWith(2, 'e') - expect(mockOnSearchChange).toHaveBeenNthCalledWith(3, 's') - expect(mockOnSearchChange).toHaveBeenNthCalledWith(4, 't') - }) + expect(mockOnSearchChange).toHaveBeenCalledTimes(4); // Called for each character + expect(mockOnSearchChange).toHaveBeenNthCalledWith(1, 't'); + expect(mockOnSearchChange).toHaveBeenNthCalledWith(2, 'e'); + expect(mockOnSearchChange).toHaveBeenNthCalledWith(3, 's'); + expect(mockOnSearchChange).toHaveBeenNthCalledWith(4, 't'); + }); it('should clear search input when cleared', async () => { - const user = userEvent.setup() - render() + const user = userEvent.setup(); + render(); - const searchInput = screen.getByPlaceholderText('Search operators...') - await user.clear(searchInput) + const searchInput = screen.getByPlaceholderText('Search operators...'); + await user.clear(searchInput); - expect(mockOnSearchChange).toHaveBeenCalledWith('') - }) + expect(mockOnSearchChange).toHaveBeenCalledWith(''); + }); it('should handle rapid typing', async () => { - const user = userEvent.setup() - render() - - const searchInput = screen.getByPlaceholderText('Search operators...') - await user.type(searchInput, 'kubernetes') - - expect(mockOnSearchChange).toHaveBeenCalledTimes(10) // Called for each character - expect(mockOnSearchChange).toHaveBeenNthCalledWith(1, 'k') - expect(mockOnSearchChange).toHaveBeenNthCalledWith(2, 'u') - expect(mockOnSearchChange).toHaveBeenNthCalledWith(3, 'b') - expect(mockOnSearchChange).toHaveBeenNthCalledWith(4, 'e') - expect(mockOnSearchChange).toHaveBeenNthCalledWith(5, 'r') - expect(mockOnSearchChange).toHaveBeenNthCalledWith(6, 'n') - expect(mockOnSearchChange).toHaveBeenNthCalledWith(7, 'e') - expect(mockOnSearchChange).toHaveBeenNthCalledWith(8, 't') - expect(mockOnSearchChange).toHaveBeenNthCalledWith(9, 'e') - expect(mockOnSearchChange).toHaveBeenNthCalledWith(10, 's') - }) - }) + const user = userEvent.setup(); + render(); + + const searchInput = screen.getByPlaceholderText('Search operators...'); + await user.type(searchInput, 'kubernetes'); + + expect(mockOnSearchChange).toHaveBeenCalledTimes(10); // Called for each character + expect(mockOnSearchChange).toHaveBeenNthCalledWith(1, 'k'); + expect(mockOnSearchChange).toHaveBeenNthCalledWith(2, 'u'); + expect(mockOnSearchChange).toHaveBeenNthCalledWith(3, 'b'); + expect(mockOnSearchChange).toHaveBeenNthCalledWith(4, 'e'); + expect(mockOnSearchChange).toHaveBeenNthCalledWith(5, 'r'); + expect(mockOnSearchChange).toHaveBeenNthCalledWith(6, 'n'); + expect(mockOnSearchChange).toHaveBeenNthCalledWith(7, 'e'); + expect(mockOnSearchChange).toHaveBeenNthCalledWith(8, 't'); + expect(mockOnSearchChange).toHaveBeenNthCalledWith(9, 'e'); + expect(mockOnSearchChange).toHaveBeenNthCalledWith(10, 's'); + }); + }); describe('Status Filter Functionality', () => { it('should display current status filter', () => { - render() + render(); - expect(screen.getByText('Installed')).toBeInTheDocument() - }) + expect(screen.getByText('Installed')).toBeInTheDocument(); + }); it('should show all status options when opened', async () => { - const user = userEvent.setup() - render() + const user = userEvent.setup(); + render(); - const selectTrigger = screen.getByRole('combobox') - await user.click(selectTrigger) + const selectTrigger = screen.getByRole('combobox'); + await user.click(selectTrigger); - expect(screen.getAllByText('All Status')).toHaveLength(2) // One in trigger, one in dropdown - expect(screen.getByText('Installed')).toBeInTheDocument() - expect(screen.getByText('Not Installed')).toBeInTheDocument() - expect(screen.getByText('Installing')).toBeInTheDocument() - expect(screen.getByText('Error')).toBeInTheDocument() - }) + expect(screen.getAllByText('All Status')).toHaveLength(2); // One in trigger, one in dropdown + expect(screen.getByText('Installed')).toBeInTheDocument(); + expect(screen.getByText('Not Installed')).toBeInTheDocument(); + expect(screen.getByText('Installing')).toBeInTheDocument(); + expect(screen.getByText('Error')).toBeInTheDocument(); + }); it('should call onStatusFilterChange when selecting a status', async () => { - const user = userEvent.setup() - render() + const user = userEvent.setup(); + render(); - const selectTrigger = screen.getByRole('combobox') - await user.click(selectTrigger) + const selectTrigger = screen.getByRole('combobox'); + await user.click(selectTrigger); - const installedOption = screen.getByText('Installed') - await user.click(installedOption) + const installedOption = screen.getByText('Installed'); + await user.click(installedOption); - expect(mockOnStatusFilterChange).toHaveBeenCalledWith('installed') - }) + expect(mockOnStatusFilterChange).toHaveBeenCalledWith('installed'); + }); it('should handle all status filter selection', async () => { - const user = userEvent.setup() - render() + const user = userEvent.setup(); + render(); - const selectTrigger = screen.getByRole('combobox') - await user.click(selectTrigger) + const selectTrigger = screen.getByRole('combobox'); + await user.click(selectTrigger); - const allStatusOption = screen.getByText('All Status') - await user.click(allStatusOption) + const allStatusOption = screen.getByText('All Status'); + await user.click(allStatusOption); - expect(mockOnStatusFilterChange).toHaveBeenCalledWith('all') - }) + expect(mockOnStatusFilterChange).toHaveBeenCalledWith('all'); + }); it('should handle error status filter selection', async () => { - const user = userEvent.setup() - render() + const user = userEvent.setup(); + render(); - const selectTrigger = screen.getByRole('combobox') - await user.click(selectTrigger) + const selectTrigger = screen.getByRole('combobox'); + await user.click(selectTrigger); - const errorOption = screen.getByText('Error') - await user.click(errorOption) + const errorOption = screen.getByText('Error'); + await user.click(errorOption); - expect(mockOnStatusFilterChange).toHaveBeenCalledWith('error') - }) - }) + expect(mockOnStatusFilterChange).toHaveBeenCalledWith('error'); + }); + }); describe('Documentation Link', () => { it('should have correct href and target attributes', () => { - render() + render(); - const docLink = screen.getByText('View operator docs') - expect(docLink).toHaveAttribute('href', 'https://docs.interweb.io/operators') - expect(docLink).toHaveAttribute('target', '_blank') - expect(docLink).toHaveAttribute('rel', 'noopener noreferrer') - }) + const docLink = screen.getByText('View operator docs'); + expect(docLink).toHaveAttribute('href', 'https://docs.interweb.io/operators'); + expect(docLink).toHaveAttribute('target', '_blank'); + expect(docLink).toHaveAttribute('rel', 'noopener noreferrer'); + }); it('should have correct styling classes', () => { - render() + render(); - const docLink = screen.getByText('View operator docs') - expect(docLink).toHaveClass('text-primary') - }) - }) + const docLink = screen.getByText('View operator docs'); + expect(docLink).toHaveClass('text-primary'); + }); + }); describe('Responsive Design', () => { it('should have responsive layout classes', () => { - render() + render(); - const searchInput = screen.getByPlaceholderText('Search operators...') - const container = searchInput.closest('.flex.flex-col.sm\\:flex-row') - expect(container).toBeInTheDocument() - }) + const searchInput = screen.getByPlaceholderText('Search operators...'); + const container = searchInput.closest('.flex.flex-col.sm\\:flex-row'); + expect(container).toBeInTheDocument(); + }); it('should have responsive width classes', () => { - render() + render(); - const searchInput = screen.getByPlaceholderText('Search operators...') - const searchContainer = searchInput.closest('.flex-1.max-w-sm') - expect(searchContainer).toBeInTheDocument() - }) - }) + const searchInput = screen.getByPlaceholderText('Search operators...'); + const searchContainer = searchInput.closest('.flex-1.max-w-sm'); + expect(searchContainer).toBeInTheDocument(); + }); + }); describe('Accessibility', () => { it('should have proper input attributes', () => { - render() + render(); - const searchInput = screen.getByPlaceholderText('Search operators...') - expect(searchInput).toHaveAttribute('placeholder', 'Search operators...') - }) + const searchInput = screen.getByPlaceholderText('Search operators...'); + expect(searchInput).toHaveAttribute('placeholder', 'Search operators...'); + }); it('should have proper select attributes', () => { - render() + render(); - const selectTrigger = screen.getByRole('combobox') - expect(selectTrigger).toBeInTheDocument() - }) + const selectTrigger = screen.getByRole('combobox'); + expect(selectTrigger).toBeInTheDocument(); + }); it('should be keyboard navigable', async () => { - const user = userEvent.setup() - render() + const user = userEvent.setup(); + render(); - const searchInput = screen.getByPlaceholderText('Search operators...') - await user.tab() + const searchInput = screen.getByPlaceholderText('Search operators...'); + await user.tab(); - expect(searchInput).toHaveFocus() - }) + expect(searchInput).toHaveFocus(); + }); it('should support keyboard navigation for select', async () => { - const user = userEvent.setup() - render() + const user = userEvent.setup(); + render(); - const selectTrigger = screen.getByRole('combobox') - await user.tab() - await user.tab() + const selectTrigger = screen.getByRole('combobox'); + await user.tab(); + await user.tab(); - expect(selectTrigger).toHaveFocus() - }) - }) + expect(selectTrigger).toHaveFocus(); + }); + }); describe('Edge Cases', () => { it('should handle empty search term', () => { - render() + render(); - const searchInput = screen.getByPlaceholderText('Search operators...') - expect(searchInput).toHaveValue('') - }) + const searchInput = screen.getByPlaceholderText('Search operators...'); + expect(searchInput).toHaveValue(''); + }); it('should handle special characters in search', async () => { - const user = userEvent.setup() - render() + const user = userEvent.setup(); + render(); - const searchInput = screen.getByPlaceholderText('Search operators...') - await user.type(searchInput, 'test@#$%^&*()') + const searchInput = screen.getByPlaceholderText('Search operators...'); + await user.type(searchInput, 'test@#$%^&*()'); - expect(mockOnSearchChange).toHaveBeenCalledTimes(13) // Called for each character - expect(mockOnSearchChange).toHaveBeenNthCalledWith(13, ')') - }) + expect(mockOnSearchChange).toHaveBeenCalledTimes(13); // Called for each character + expect(mockOnSearchChange).toHaveBeenNthCalledWith(13, ')'); + }); it('should handle very long search terms', async () => { - const user = userEvent.setup() - const longSearchTerm = 'a'.repeat(1000) - render() + const user = userEvent.setup(); + const longSearchTerm = 'a'.repeat(1000); + render(); - const searchInput = screen.getByPlaceholderText('Search operators...') - await user.type(searchInput, longSearchTerm) + const searchInput = screen.getByPlaceholderText('Search operators...'); + await user.type(searchInput, longSearchTerm); - expect(mockOnSearchChange).toHaveBeenCalledTimes(1000) // Called for each character - expect(mockOnSearchChange).toHaveBeenNthCalledWith(1000, 'a') - }) + expect(mockOnSearchChange).toHaveBeenCalledTimes(1000); // Called for each character + expect(mockOnSearchChange).toHaveBeenNthCalledWith(1000, 'a'); + }); it('should handle rapid status filter changes', async () => { - const user = userEvent.setup() - render() + const user = userEvent.setup(); + render(); - const selectTrigger = screen.getByRole('combobox') + const selectTrigger = screen.getByRole('combobox'); // Open select - await user.click(selectTrigger) - await user.click(screen.getByText('Installed')) + await user.click(selectTrigger); + await user.click(screen.getByText('Installed')); // Open select again - await user.click(selectTrigger) - await user.click(screen.getByText('Error')) + await user.click(selectTrigger); + await user.click(screen.getByText('Error')); - expect(mockOnStatusFilterChange).toHaveBeenCalledTimes(2) - expect(mockOnStatusFilterChange).toHaveBeenNthCalledWith(1, 'installed') - expect(mockOnStatusFilterChange).toHaveBeenNthCalledWith(2, 'error') - }) - }) + expect(mockOnStatusFilterChange).toHaveBeenCalledTimes(2); + expect(mockOnStatusFilterChange).toHaveBeenNthCalledWith(1, 'installed'); + expect(mockOnStatusFilterChange).toHaveBeenNthCalledWith(2, 'error'); + }); + }); describe('Integration', () => { it('should work with both search and filter simultaneously', async () => { - const user = userEvent.setup() - render() + const user = userEvent.setup(); + render(); // Verify initial state - expect(screen.getByDisplayValue('test')).toBeInTheDocument() - expect(screen.getByText('Installed')).toBeInTheDocument() + expect(screen.getByDisplayValue('test')).toBeInTheDocument(); + expect(screen.getByText('Installed')).toBeInTheDocument(); // Change search - const searchInput = screen.getByDisplayValue('test') - await user.clear(searchInput) - await user.type(searchInput, 'new search') + const searchInput = screen.getByDisplayValue('test'); + await user.clear(searchInput); + await user.type(searchInput, 'new search'); // Change filter - const selectTrigger = screen.getByRole('combobox') - await user.click(selectTrigger) - await user.click(screen.getByText('Error')) - - expect(mockOnSearchChange).toHaveBeenCalledTimes(11) // Called for clear + each character - expect(mockOnStatusFilterChange).toHaveBeenCalledWith('error') - }) - }) -}) \ No newline at end of file + const selectTrigger = screen.getByRole('combobox'); + await user.click(selectTrigger); + await user.click(screen.getByText('Error')); + + expect(mockOnSearchChange).toHaveBeenCalledTimes(11); // Called for clear + each character + expect(mockOnStatusFilterChange).toHaveBeenCalledWith('error'); + }); + }); +}); \ No newline at end of file diff --git a/apps/ops-dashboard/__tests__/components/admin/operator-grid.test.tsx b/apps/ops-dashboard/__tests__/components/admin/operator-grid.test.tsx index 22c2de1..07e58c7 100644 --- a/apps/ops-dashboard/__tests__/components/admin/operator-grid.test.tsx +++ b/apps/ops-dashboard/__tests__/components/admin/operator-grid.test.tsx @@ -1,13 +1,14 @@ -import React from 'react' -import { render, screen } from '../../utils/test-utils' -import { OperatorGrid } from '../../../components/admin/operator-grid' -import type { OperatorInfo } from '@kubernetesjs/client' +import type { OperatorInfo } from '@kubernetesjs/client'; +import React from 'react'; + +import { OperatorGrid } from '../../../components/admin/operator-grid'; +import { render, screen } from '../../utils/test-utils'; // Mock useOperators hook -const mockUseOperators = jest.fn() +const mockUseOperators = jest.fn(); jest.mock('../../../hooks/use-operators', () => ({ useOperators: () => mockUseOperators(), -})) +})); // Stub OperatorCard to avoid duplicating its logic; verify it receives props jest.mock('../../../components/admin/operator-card', () => ({ @@ -16,7 +17,7 @@ jest.mock('../../../components/admin/operator-card', () => ({ {operator.displayName} ) -})) +})); const makeOps = (n: number): OperatorInfo[] => Array.from({ length: n }).map((_, i) => ({ @@ -26,55 +27,55 @@ const makeOps = (n: number): OperatorInfo[] => description: 'desc', status: i % 2 === 0 ? 'installed' as const : 'not-installed' as const, docsUrl: 'https://example.com', - })) + })); describe('OperatorGrid', () => { afterEach(() => { - jest.clearAllMocks() - }) + jest.clearAllMocks(); + }); it('renders loading state', () => { - mockUseOperators.mockReturnValue({ data: undefined, isLoading: true, error: null }) - render() - expect(screen.getByText('Loading operators...')).toBeInTheDocument() - }) + mockUseOperators.mockReturnValue({ data: undefined, isLoading: true, error: null }); + render(); + expect(screen.getByText('Loading operators...')).toBeInTheDocument(); + }); it('renders error state', () => { - mockUseOperators.mockReturnValue({ data: undefined, isLoading: false, error: new Error('boom') }) - render() - expect(screen.getByText('Failed to load operators')).toBeInTheDocument() - expect(screen.getByText('Check your cluster connection')).toBeInTheDocument() - }) + mockUseOperators.mockReturnValue({ data: undefined, isLoading: false, error: new Error('boom') }); + render(); + expect(screen.getByText('Failed to load operators')).toBeInTheDocument(); + expect(screen.getByText('Check your cluster connection')).toBeInTheDocument(); + }); it('renders installed count and total', () => { - const ops = makeOps(5) - mockUseOperators.mockReturnValue({ data: ops, isLoading: false, error: null }) - render() + const ops = makeOps(5); + mockUseOperators.mockReturnValue({ data: ops, isLoading: false, error: null }); + render(); // Specific heading - expect(screen.getByRole('heading', { name: 'Operators' })).toBeInTheDocument() - expect(screen.getByText('3 of 5 operators installed')).toBeInTheDocument() - }) + expect(screen.getByRole('heading', { name: 'Operators' })).toBeInTheDocument(); + expect(screen.getByText('3 of 5 operators installed')).toBeInTheDocument(); + }); it('renders up to 6 compact OperatorCard items', () => { - const ops = makeOps(8) - mockUseOperators.mockReturnValue({ data: ops, isLoading: false, error: null }) - render() + const ops = makeOps(8); + mockUseOperators.mockReturnValue({ data: ops, isLoading: false, error: null }); + render(); // Should render only first 6 for (let i = 1; i <= 6; i++) { - expect(screen.getByTestId(`operator-card-op-${i}`)).toBeInTheDocument() - expect(screen.getByTestId(`operator-card-op-${i}`)).toHaveAttribute('data-compact', 'true') + expect(screen.getByTestId(`operator-card-op-${i}`)).toBeInTheDocument(); + expect(screen.getByTestId(`operator-card-op-${i}`)).toHaveAttribute('data-compact', 'true'); } - expect(screen.queryByTestId('operator-card-op-7')).not.toBeInTheDocument() - expect(screen.queryByTestId('operator-card-op-8')).not.toBeInTheDocument() - }) + expect(screen.queryByTestId('operator-card-op-7')).not.toBeInTheDocument(); + expect(screen.queryByTestId('operator-card-op-8')).not.toBeInTheDocument(); + }); it('renders "View all" links correctly when more than 6', () => { - const ops = makeOps(8) - mockUseOperators.mockReturnValue({ data: ops, isLoading: false, error: null }) - render() + const ops = makeOps(8); + mockUseOperators.mockReturnValue({ data: ops, isLoading: false, error: null }); + render(); - expect(screen.getByRole('link', { name: /^View all$/i })).toHaveAttribute('href', '/operators') - expect(screen.getByRole('link', { name: /View all 8 operators/i })).toHaveAttribute('href', '/operators') - }) -}) + expect(screen.getByRole('link', { name: /^View all$/i })).toHaveAttribute('href', '/operators'); + expect(screen.getByRole('link', { name: /View all 8 operators/i })).toHaveAttribute('href', '/operators'); + }); +}); diff --git a/apps/ops-dashboard/__tests__/components/admin/quick-actions.test.tsx b/apps/ops-dashboard/__tests__/components/admin/quick-actions.test.tsx index c009146..8730bca 100644 --- a/apps/ops-dashboard/__tests__/components/admin/quick-actions.test.tsx +++ b/apps/ops-dashboard/__tests__/components/admin/quick-actions.test.tsx @@ -1,42 +1,43 @@ -import React from 'react' -import { render, screen } from '../../utils/test-utils' -import { QuickActions } from '../../../components/admin/quick-actions' +import React from 'react'; + +import { QuickActions } from '../../../components/admin/quick-actions'; +import { render, screen } from '../../utils/test-utils'; describe('QuickActions', () => { it('renders header', () => { - render() - expect(screen.getByRole('heading', { name: 'Quick Actions' })).toBeInTheDocument() - }) + render(); + expect(screen.getByRole('heading', { name: 'Quick Actions' })).toBeInTheDocument(); + }); it('renders all action buttons with correct labels and descriptions', () => { - render() + render(); // Deploy Database - expect(screen.getByText('Deploy Database')).toBeInTheDocument() - expect(screen.getByText('Create a PostgreSQL cluster')).toBeInTheDocument() + expect(screen.getByText('Deploy Database')).toBeInTheDocument(); + expect(screen.getByText('Create a PostgreSQL cluster')).toBeInTheDocument(); // Deploy Application - expect(screen.getByText('Deploy Application')).toBeInTheDocument() - expect(screen.getByText('Deploy a new application')).toBeInTheDocument() + expect(screen.getByText('Deploy Application')).toBeInTheDocument(); + expect(screen.getByText('Deploy a new application')).toBeInTheDocument(); // Create Secret - expect(screen.getByText('Create Secret')).toBeInTheDocument() - expect(screen.getByText('Store credentials securely')).toBeInTheDocument() - }) + expect(screen.getByText('Create Secret')).toBeInTheDocument(); + expect(screen.getByText('Store credentials securely')).toBeInTheDocument(); + }); it('links point to correct destinations', () => { - render() + render(); - expect(screen.getByRole('link', { name: /deploy database/i })).toHaveAttribute('href', '/databases/create') - expect(screen.getByRole('link', { name: /deploy application/i })).toHaveAttribute('href', '/applications/create') - expect(screen.getByRole('link', { name: /create secret/i })).toHaveAttribute('href', '/secrets/create') - }) + expect(screen.getByRole('link', { name: /deploy database/i })).toHaveAttribute('href', '/databases/create'); + expect(screen.getByRole('link', { name: /deploy application/i })).toHaveAttribute('href', '/applications/create'); + expect(screen.getByRole('link', { name: /create secret/i })).toHaveAttribute('href', '/secrets/create'); + }); it('renders color badge and icon containers for each action', () => { - render() - const colorBadges = document.querySelectorAll('div.p-2.rounded-md') - expect(colorBadges.length).toBe(3) - const icons = document.querySelectorAll('svg.lucide') - expect(icons.length).toBeGreaterThanOrEqual(3) - }) -}) + render(); + const colorBadges = document.querySelectorAll('div.p-2.rounded-md'); + expect(colorBadges.length).toBe(3); + const icons = document.querySelectorAll('svg.lucide'); + expect(icons.length).toBeGreaterThanOrEqual(3); + }); +}); diff --git a/apps/ops-dashboard/__tests__/components/admin/recent-activity.test.tsx b/apps/ops-dashboard/__tests__/components/admin/recent-activity.test.tsx index 67d0655..bbd6f66 100644 --- a/apps/ops-dashboard/__tests__/components/admin/recent-activity.test.tsx +++ b/apps/ops-dashboard/__tests__/components/admin/recent-activity.test.tsx @@ -1,100 +1,101 @@ -import { render, screen } from '../../utils/test-utils' -import { RecentActivity } from '@/components/admin/recent-activity' +import { RecentActivity } from '@/components/admin/recent-activity'; + +import { render, screen } from '../../utils/test-utils'; // Mock the formatRelativeTime utility and cn function jest.mock('../../../lib/utils', () => ({ formatRelativeTime: jest.fn((timestamp: string) => { - const now = new Date() - const activityTime = new Date(timestamp) - const diffInMinutes = Math.floor((now.getTime() - activityTime.getTime()) / (1000 * 60)) + const now = new Date(); + const activityTime = new Date(timestamp); + const diffInMinutes = Math.floor((now.getTime() - activityTime.getTime()) / (1000 * 60)); - if (diffInMinutes < 1) return 'just now' - if (diffInMinutes < 60) return `${diffInMinutes} minutes ago` - if (diffInMinutes < 1440) return `${Math.floor(diffInMinutes / 60)} hours ago` - return `${Math.floor(diffInMinutes / 1440)} days ago` + if (diffInMinutes < 1) return 'just now'; + if (diffInMinutes < 60) return `${diffInMinutes} minutes ago`; + if (diffInMinutes < 1440) return `${Math.floor(diffInMinutes / 60)} hours ago`; + return `${Math.floor(diffInMinutes / 1440)} days ago`; }), cn: jest.fn((...classes) => classes.filter(Boolean).join(' ')) -})) +})); describe('RecentActivity', () => { it('should render recent activity card with header', () => { - render() + render(); - expect(screen.getByText('Recent Activity', { selector: 'h3' })).toBeInTheDocument() - }) + expect(screen.getByText('Recent Activity', { selector: 'h3' })).toBeInTheDocument(); + }); it('should render all activity items', () => { - render() + render(); // Check for all activity messages - expect(screen.getByText('CloudNativePG operator installed successfully')).toBeInTheDocument() - expect(screen.getByText('PostgreSQL cluster "main-db" created')).toBeInTheDocument() - expect(screen.getByText('cert-manager operator installation in progress')).toBeInTheDocument() - expect(screen.getByText('Database credentials secret created')).toBeInTheDocument() - expect(screen.getByText('Failed to scale deployment "api-server"')).toBeInTheDocument() - }) + expect(screen.getByText('CloudNativePG operator installed successfully')).toBeInTheDocument(); + expect(screen.getByText('PostgreSQL cluster "main-db" created')).toBeInTheDocument(); + expect(screen.getByText('cert-manager operator installation in progress')).toBeInTheDocument(); + expect(screen.getByText('Database credentials secret created')).toBeInTheDocument(); + expect(screen.getByText('Failed to scale deployment "api-server"')).toBeInTheDocument(); + }); it('should render status icons correctly', () => { - render() + render(); // Check for success icons (CheckCircle) - they have green color - const successIcons = screen.getAllByText('CloudNativePG operator installed successfully') - expect(successIcons).toHaveLength(1) + const successIcons = screen.getAllByText('CloudNativePG operator installed successfully'); + expect(successIcons).toHaveLength(1); // Check for pending icon (Clock) - has yellow color - const pendingIcons = screen.getAllByText('cert-manager operator installation in progress') - expect(pendingIcons).toHaveLength(1) + const pendingIcons = screen.getAllByText('cert-manager operator installation in progress'); + expect(pendingIcons).toHaveLength(1); // Check for error icon (XCircle) - has red color - const errorIcons = screen.getAllByText('Failed to scale deployment "api-server"') - expect(errorIcons).toHaveLength(1) - }) + const errorIcons = screen.getAllByText('Failed to scale deployment "api-server"'); + expect(errorIcons).toHaveLength(1); + }); it('should render status colors correctly', () => { - render() + render(); // Check for success color (green) - find the icon container with green color - const successActivity = screen.getByText('CloudNativePG operator installed successfully').closest('.flex') - const successIcon = successActivity?.querySelector('.text-green-600') - expect(successIcon).toBeInTheDocument() + const successActivity = screen.getByText('CloudNativePG operator installed successfully').closest('.flex'); + const successIcon = successActivity?.querySelector('.text-green-600'); + expect(successIcon).toBeInTheDocument(); // Check for pending color (yellow) - const pendingActivity = screen.getByText('cert-manager operator installation in progress').closest('.flex') - const pendingIcon = pendingActivity?.querySelector('.text-yellow-600') - expect(pendingIcon).toBeInTheDocument() + const pendingActivity = screen.getByText('cert-manager operator installation in progress').closest('.flex'); + const pendingIcon = pendingActivity?.querySelector('.text-yellow-600'); + expect(pendingIcon).toBeInTheDocument(); // Check for error color (red) - const errorActivity = screen.getByText('Failed to scale deployment "api-server"').closest('.flex') - const errorIcon = errorActivity?.querySelector('.text-red-600') - expect(errorIcon).toBeInTheDocument() - }) + const errorActivity = screen.getByText('Failed to scale deployment "api-server"').closest('.flex'); + const errorIcon = errorActivity?.querySelector('.text-red-600'); + expect(errorIcon).toBeInTheDocument(); + }); it('should render timestamps using formatRelativeTime', () => { - const { formatRelativeTime } = require('../../../lib/utils') - render() + const { formatRelativeTime } = require('../../../lib/utils'); + render(); // Verify formatRelativeTime was called for each activity (may be called multiple times due to re-renders) - expect(formatRelativeTime).toHaveBeenCalled() - }) + expect(formatRelativeTime).toHaveBeenCalled(); + }); it('should render view all activity button', () => { - render() + render(); - expect(screen.getByText('View all activity')).toBeInTheDocument() - }) + expect(screen.getByText('View all activity')).toBeInTheDocument(); + }); it('should have proper card structure', () => { - render() + render(); // Check for card header - expect(screen.getByText('Recent Activity', { selector: 'h3' })).toBeInTheDocument() + expect(screen.getByText('Recent Activity', { selector: 'h3' })).toBeInTheDocument(); // Check for card content - expect(screen.getByText('CloudNativePG operator installed successfully')).toBeInTheDocument() - }) + expect(screen.getByText('CloudNativePG operator installed successfully')).toBeInTheDocument(); + }); it('should display activity items in correct order', () => { - render() + render(); const activityMessages = [ 'CloudNativePG operator installed successfully', @@ -102,135 +103,135 @@ describe('RecentActivity', () => { 'cert-manager operator installation in progress', 'Database credentials secret created', 'Failed to scale deployment "api-server"' - ] + ]; - const renderedMessages = screen.getAllByText(/operator|cluster|secret|deployment/i) - expect(renderedMessages).toHaveLength(5) - }) + const renderedMessages = screen.getAllByText(/operator|cluster|secret|deployment/i); + expect(renderedMessages).toHaveLength(5); + }); it('should have proper spacing between activities', () => { - render() + render(); - const activityContainer = screen.getByText('CloudNativePG operator installed successfully').closest('.space-y-4') - expect(activityContainer).toBeInTheDocument() - }) + const activityContainer = screen.getByText('CloudNativePG operator installed successfully').closest('.space-y-4'); + expect(activityContainer).toBeInTheDocument(); + }); it('should have proper icon sizing', () => { - render() + render(); // Check that icons have proper sizing by looking for SVG elements with h-4 w-4 classes - const activityContainer = screen.getByText('CloudNativePG operator installed successfully').closest('.flex') - const icon = activityContainer?.querySelector('svg') - expect(icon).toHaveClass('h-4', 'w-4') - }) + const activityContainer = screen.getByText('CloudNativePG operator installed successfully').closest('.flex'); + const icon = activityContainer?.querySelector('svg'); + expect(icon).toHaveClass('h-4', 'w-4'); + }); it('should have proper text styling for messages', () => { - render() + render(); - const message = screen.getByText('CloudNativePG operator installed successfully') - expect(message).toHaveClass('text-sm', 'text-gray-900') - }) + const message = screen.getByText('CloudNativePG operator installed successfully'); + expect(message).toHaveClass('text-sm', 'text-gray-900'); + }); it('should have proper text styling for timestamps', () => { - render() + render(); - const timestamps = screen.getAllByText(/minutes ago|hours ago|days ago|just now/) + const timestamps = screen.getAllByText(/minutes ago|hours ago|days ago|just now/); timestamps.forEach(timestamp => { - expect(timestamp).toHaveClass('text-xs', 'text-gray-500') - }) - }) + expect(timestamp).toHaveClass('text-xs', 'text-gray-500'); + }); + }); it('should have proper border styling for separator', () => { - render() + render(); - const separator = screen.getByText('View all activity').closest('.border-t') - expect(separator).toHaveClass('border-gray-200') - }) + const separator = screen.getByText('View all activity').closest('.border-t'); + expect(separator).toHaveClass('border-gray-200'); + }); it('should have proper button styling', () => { - render() + render(); - const button = screen.getByText('View all activity') - expect(button).toHaveClass('text-sm', 'text-primary', 'hover:text-primary/80', 'font-medium') - }) + const button = screen.getByText('View all activity'); + expect(button).toHaveClass('text-sm', 'text-primary', 'hover:text-primary/80', 'font-medium'); + }); it('should be accessible with proper roles', () => { - render() + render(); // Check for heading - expect(screen.getByRole('heading', { name: 'Recent Activity' })).toBeInTheDocument() + expect(screen.getByRole('heading', { name: 'Recent Activity' })).toBeInTheDocument(); // Check for button - expect(screen.getByRole('button', { name: 'View all activity' })).toBeInTheDocument() - }) + expect(screen.getByRole('button', { name: 'View all activity' })).toBeInTheDocument(); + }); it('should handle different activity types', () => { - render() + render(); // Check for different activity types - expect(screen.getByText(/deployment/i)).toBeInTheDocument() - expect(screen.getByText(/database/i)).toBeInTheDocument() - expect(screen.getAllByText(/operator/i)).toHaveLength(2) // Two operator activities - expect(screen.getByText(/secret/i)).toBeInTheDocument() - expect(screen.getByText(/Failed/i)).toBeInTheDocument() // Error activity shows as "Failed" - }) + expect(screen.getByText(/deployment/i)).toBeInTheDocument(); + expect(screen.getByText(/database/i)).toBeInTheDocument(); + expect(screen.getAllByText(/operator/i)).toHaveLength(2); // Two operator activities + expect(screen.getByText(/secret/i)).toBeInTheDocument(); + expect(screen.getByText(/Failed/i)).toBeInTheDocument(); // Error activity shows as "Failed" + }); it('should display relative timestamps correctly', () => { - render() + render(); // Check that timestamps are displayed - const timestamps = screen.getAllByText(/minutes ago|hours ago|days ago|just now/) - expect(timestamps.length).toBeGreaterThan(0) - }) + const timestamps = screen.getAllByText(/minutes ago|hours ago|days ago|just now/); + expect(timestamps.length).toBeGreaterThan(0); + }); it('should have proper flex layout for activity items', () => { - render() + render(); - const activityItem = screen.getByText('CloudNativePG operator installed successfully').closest('.flex') - expect(activityItem).toHaveClass('items-start', 'gap-3') - }) + const activityItem = screen.getByText('CloudNativePG operator installed successfully').closest('.flex'); + expect(activityItem).toHaveClass('items-start', 'gap-3'); + }); it('should have proper icon container styling', () => { - render() + render(); - const activityContainer = screen.getByText('CloudNativePG operator installed successfully').closest('.flex') - const iconContainer = activityContainer?.querySelector('[class*="mt-0.5"]') - expect(iconContainer).toHaveClass('mt-0.5') - }) + const activityContainer = screen.getByText('CloudNativePG operator installed successfully').closest('.flex'); + const iconContainer = activityContainer?.querySelector('[class*="mt-0.5"]'); + expect(iconContainer).toHaveClass('mt-0.5'); + }); it('should have proper message container styling', () => { - render() + render(); - const messageContainer = screen.getByText('CloudNativePG operator installed successfully').parentElement - expect(messageContainer).toHaveClass('flex-1', 'min-w-0') - }) + const messageContainer = screen.getByText('CloudNativePG operator installed successfully').parentElement; + expect(messageContainer).toHaveClass('flex-1', 'min-w-0'); + }); it('should handle empty activity list gracefully', () => { // This test would require mocking the component with empty data // For now, we'll test the current implementation - render() + render(); - expect(screen.getByText('Recent Activity')).toBeInTheDocument() - expect(screen.getByText('View all activity')).toBeInTheDocument() - }) + expect(screen.getByText('Recent Activity')).toBeInTheDocument(); + expect(screen.getByText('View all activity')).toBeInTheDocument(); + }); it('should be keyboard navigable', () => { - render() + render(); - const button = screen.getByRole('button', { name: 'View all activity' }) - expect(button).toBeInTheDocument() - }) + const button = screen.getByRole('button', { name: 'View all activity' }); + expect(button).toBeInTheDocument(); + }); it('should have proper semantic structure', () => { - render() + render(); // Check for proper heading hierarchy - const heading = screen.getByRole('heading', { name: 'Recent Activity' }) - expect(heading.tagName).toBe('H3') - }) + const heading = screen.getByRole('heading', { name: 'Recent Activity' }); + expect(heading.tagName).toBe('H3'); + }); it('should display all required activity information', () => { - render() + render(); // Check that each activity has both message and timestamp const activities = [ @@ -239,10 +240,10 @@ describe('RecentActivity', () => { 'cert-manager operator installation in progress', 'Database credentials secret created', 'Failed to scale deployment "api-server"' - ] + ]; activities.forEach(activity => { - expect(screen.getByText(activity)).toBeInTheDocument() - }) - }) -}) \ No newline at end of file + expect(screen.getByText(activity)).toBeInTheDocument(); + }); + }); +}); \ No newline at end of file diff --git a/apps/ops-dashboard/__tests__/components/admin/resource-summary.test.tsx b/apps/ops-dashboard/__tests__/components/admin/resource-summary.test.tsx index 0cafcf2..dd5ed9b 100644 --- a/apps/ops-dashboard/__tests__/components/admin/resource-summary.test.tsx +++ b/apps/ops-dashboard/__tests__/components/admin/resource-summary.test.tsx @@ -1,48 +1,49 @@ -import React from 'react' -import { render, screen } from '../../utils/test-utils' -import { ResourceSummary } from '../../../components/admin/resource-summary' +import React from 'react'; + +import { ResourceSummary } from '../../../components/admin/resource-summary'; +import { render, screen } from '../../utils/test-utils'; // Mock useClusterStatus to control loading state -const mockUseClusterStatus = jest.fn() +const mockUseClusterStatus = jest.fn(); jest.mock('../../../hooks/use-cluster-status', () => ({ useClusterStatus: () => mockUseClusterStatus(), -})) +})); describe('ResourceSummary', () => { afterEach(() => { - jest.clearAllMocks() - }) + jest.clearAllMocks(); + }); it('renders loading skeleton when loading', () => { - mockUseClusterStatus.mockReturnValue({ data: undefined, isLoading: true }) - render() + mockUseClusterStatus.mockReturnValue({ data: undefined, isLoading: true }); + render(); - expect(screen.getByRole('heading', { name: 'Resource Summary' })).toBeInTheDocument() + expect(screen.getByRole('heading', { name: 'Resource Summary' })).toBeInTheDocument(); // Skeleton blocks present (based on animate-pulse class wrappers) - const skeletons = document.querySelectorAll('.animate-pulse') - expect(skeletons.length).toBeGreaterThanOrEqual(1) - }) + const skeletons = document.querySelectorAll('.animate-pulse'); + expect(skeletons.length).toBeGreaterThanOrEqual(1); + }); it('renders static resource summary when loaded', () => { - mockUseClusterStatus.mockReturnValue({ data: { ok: true }, isLoading: false }) - render() + mockUseClusterStatus.mockReturnValue({ data: { ok: true }, isLoading: false }); + render(); - expect(screen.getByRole('heading', { name: 'Resource Summary' })).toBeInTheDocument() + expect(screen.getByRole('heading', { name: 'Resource Summary' })).toBeInTheDocument(); // CPU - expect(screen.getByText('CPU Usage')).toBeInTheDocument() - expect(screen.getByText('2.4 / 8.0 cores')).toBeInTheDocument() + expect(screen.getByText('CPU Usage')).toBeInTheDocument(); + expect(screen.getByText('2.4 / 8.0 cores')).toBeInTheDocument(); // Memory - expect(screen.getByText('Memory Usage')).toBeInTheDocument() - expect(screen.getByText('4.2 / 16 GB')).toBeInTheDocument() + expect(screen.getByText('Memory Usage')).toBeInTheDocument(); + expect(screen.getByText('4.2 / 16 GB')).toBeInTheDocument(); // Storage - expect(screen.getByText('Storage Usage')).toBeInTheDocument() - expect(screen.getByText('45 / 100 GB')).toBeInTheDocument() + expect(screen.getByText('Storage Usage')).toBeInTheDocument(); + expect(screen.getByText('45 / 100 GB')).toBeInTheDocument(); // Progress bars exist - const bars = document.querySelectorAll('div.bg-gray-200.rounded-full.h-2') - expect(bars.length).toBe(3) - }) -}) + const bars = document.querySelectorAll('div.bg-gray-200.rounded-full.h-2'); + expect(bars.length).toBe(3); + }); +}); diff --git a/apps/ops-dashboard/__tests__/components/admin/status-indicator.test.tsx b/apps/ops-dashboard/__tests__/components/admin/status-indicator.test.tsx index de085e3..7c2b551 100644 --- a/apps/ops-dashboard/__tests__/components/admin/status-indicator.test.tsx +++ b/apps/ops-dashboard/__tests__/components/admin/status-indicator.test.tsx @@ -1,63 +1,64 @@ -import React from 'react' -import { render, screen } from '../../utils/test-utils' -import { StatusIndicator } from '../../../components/admin/status-indicator' +import React from 'react'; + +import { StatusIndicator } from '../../../components/admin/status-indicator'; +import { render, screen } from '../../utils/test-utils'; describe('StatusIndicator', () => { const getIconClass = () => { - const icon = document.querySelector('svg.lucide') as SVGElement | null - expect(icon).toBeTruthy() - return icon!.getAttribute('class') || '' - } + const icon = document.querySelector('svg.lucide') as SVGElement | null; + expect(icon).toBeTruthy(); + return icon!.getAttribute('class') || ''; + }; it('renders without text by default', () => { - render() + render(); // Icon exists - const icon = document.querySelector('svg.lucide') - expect(icon).toBeInTheDocument() + const icon = document.querySelector('svg.lucide'); + expect(icon).toBeInTheDocument(); // No text - expect(screen.queryByText('Ready')).not.toBeInTheDocument() - }) + expect(screen.queryByText('Ready')).not.toBeInTheDocument(); + }); it('shows text when showText is true', () => { - render() - expect(screen.getByText('Installed')).toBeInTheDocument() - }) + render(); + expect(screen.getByText('Installed')).toBeInTheDocument(); + }); it('applies correct icon color per status', () => { - const { rerender } = render() + const { rerender } = render(); // creating → yellow + animate-pulse - expect(getIconClass()).toMatch(/text-yellow-600/) + expect(getIconClass()).toMatch(/text-yellow-600/); - rerender() - expect(getIconClass()).toMatch(/text-yellow-600/) + rerender(); + expect(getIconClass()).toMatch(/text-yellow-600/); - rerender() - expect(getIconClass()).toMatch(/text-red-600/) + rerender(); + expect(getIconClass()).toMatch(/text-red-600/); - rerender() - expect(getIconClass()).toMatch(/text-gray-400/) + rerender(); + expect(getIconClass()).toMatch(/text-gray-400/); - rerender() - expect(getIconClass()).toMatch(/text-green-600/) + rerender(); + expect(getIconClass()).toMatch(/text-green-600/); - rerender() - expect(getIconClass()).toMatch(/text-green-600/) + rerender(); + expect(getIconClass()).toMatch(/text-green-600/); - rerender() - expect(getIconClass()).toMatch(/text-gray-400/) - }) + rerender(); + expect(getIconClass()).toMatch(/text-gray-400/); + }); it('shows matching text color when showText is true', () => { - render() - const text = screen.getByText('Creating') - expect(text).toBeInTheDocument() - expect(text.className).toMatch(/text-yellow-600/) - }) + render(); + const text = screen.getByText('Creating'); + expect(text).toBeInTheDocument(); + expect(text.className).toMatch(/text-yellow-600/); + }); it('merges custom className on root', () => { - render() - const root = document.querySelector('div.inline-flex') - expect(root).toBeInTheDocument() - expect(root!.className).toMatch(/data-test-class/) - }) -}) + render(); + const root = document.querySelector('div.inline-flex'); + expect(root).toBeInTheDocument(); + expect(root!.className).toMatch(/data-test-class/); + }); +}); diff --git a/apps/ops-dashboard/__tests__/components/app-layout.test.tsx b/apps/ops-dashboard/__tests__/components/app-layout.test.tsx index 2a11852..6d092a5 100644 --- a/apps/ops-dashboard/__tests__/components/app-layout.test.tsx +++ b/apps/ops-dashboard/__tests__/components/app-layout.test.tsx @@ -1,5 +1,6 @@ -import { render, screen, fireEvent } from '@testing-library/react'; +import { screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; + import { AppLayout } from '../../components/app-layout'; import { render as customRender } from '../utils/test-utils'; diff --git a/apps/ops-dashboard/__tests__/components/common/spinner.test.tsx b/apps/ops-dashboard/__tests__/components/common/spinner.test.tsx index 400a542..03d7330 100644 --- a/apps/ops-dashboard/__tests__/components/common/spinner.test.tsx +++ b/apps/ops-dashboard/__tests__/components/common/spinner.test.tsx @@ -1,4 +1,5 @@ import { render, screen } from '@testing-library/react'; + import { Spinner } from '@/components/common/spinner'; describe('Spinner', () => { diff --git a/apps/ops-dashboard/__tests__/components/context-switcher.test.tsx b/apps/ops-dashboard/__tests__/components/context-switcher.test.tsx index 2c27b2c..5674a0a 100644 --- a/apps/ops-dashboard/__tests__/components/context-switcher.test.tsx +++ b/apps/ops-dashboard/__tests__/components/context-switcher.test.tsx @@ -1,4 +1,3 @@ -import userEvent from '@testing-library/user-event'; import { ContextSwitcher } from '../../components/context-switcher'; import { render, screen } from '../utils/test-utils'; diff --git a/apps/ops-dashboard/__tests__/components/create-backup-dialog.test.tsx b/apps/ops-dashboard/__tests__/components/create-backup-dialog.test.tsx index 9023e6e..b84e045 100644 --- a/apps/ops-dashboard/__tests__/components/create-backup-dialog.test.tsx +++ b/apps/ops-dashboard/__tests__/components/create-backup-dialog.test.tsx @@ -1,17 +1,19 @@ -import React from 'react' -import { render, screen, waitFor } from '../utils/test-utils' -import userEvent from '@testing-library/user-event' -import { CreateBackupDialog } from '@/components/create-backup-dialog' +import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { CreateBackupDialog } from '@/components/create-backup-dialog'; + +import { render, screen, waitFor } from '../utils/test-utils'; // Mock AgentProvider jest.mock('agentic-kit', () => ({ AgentProvider: ({ children }: { children: React.ReactNode }) =>
{children}
-})) +})); describe('CreateBackupDialog', () => { - const user = userEvent.setup() - const mockOnOpenChange = jest.fn() - const mockOnSubmit = jest.fn() + const user = userEvent.setup(); + const mockOnOpenChange = jest.fn(); + const mockOnSubmit = jest.fn(); const mockBackups = { isFetched: true, @@ -20,7 +22,7 @@ describe('CreateBackupDialog', () => { methodConfigured: 'barmanObjectStore', snapshotSupported: true } - } + }; const mockDatabaseStatus = { backups: { @@ -32,11 +34,11 @@ describe('CreateBackupDialog', () => { configured: true, replicas: 2 } - } + }; beforeEach(() => { - jest.clearAllMocks() - }) + jest.clearAllMocks(); + }); describe('Basic Rendering', () => { it('should render dialog when open', () => { @@ -48,13 +50,13 @@ describe('CreateBackupDialog', () => { onOpenChange={mockOnOpenChange} onSubmit={mockOnSubmit} /> - ) + ); - expect(screen.getByRole('heading', { name: 'Create Backup' })).toBeInTheDocument() - expect(screen.getByText('Protection')).toBeInTheDocument() - expect(screen.getByText('Continuous Backup')).toBeInTheDocument() - expect(screen.getByText('Streaming Replication')).toBeInTheDocument() - }) + expect(screen.getByRole('heading', { name: 'Create Backup' })).toBeInTheDocument(); + expect(screen.getByText('Protection')).toBeInTheDocument(); + expect(screen.getByText('Continuous Backup')).toBeInTheDocument(); + expect(screen.getByText('Streaming Replication')).toBeInTheDocument(); + }); it('should not render when closed', () => { render( @@ -65,10 +67,10 @@ describe('CreateBackupDialog', () => { onOpenChange={mockOnOpenChange} onSubmit={mockOnSubmit} /> - ) + ); - expect(screen.queryByRole('heading', { name: 'Create Backup' })).not.toBeInTheDocument() - }) + expect(screen.queryByRole('heading', { name: 'Create Backup' })).not.toBeInTheDocument(); + }); it('should display backup status information', () => { render( @@ -79,17 +81,17 @@ describe('CreateBackupDialog', () => { onOpenChange={mockOnOpenChange} onSubmit={mockOnSubmit} /> - ) + ); - expect(screen.getByText('Scheduled: 3, last: 2024-01-01T10:00:00Z')).toBeInTheDocument() - expect(screen.getByText('2 replica(s)')).toBeInTheDocument() - }) + expect(screen.getByText('Scheduled: 3, last: 2024-01-01T10:00:00Z')).toBeInTheDocument(); + expect(screen.getByText('2 replica(s)')).toBeInTheDocument(); + }); it('should display not configured status when data is missing', () => { const emptyDatabaseStatus = { backups: { configured: false }, streaming: { configured: false } - } + }; render( { onOpenChange={mockOnOpenChange} onSubmit={mockOnSubmit} /> - ) + ); - expect(screen.getAllByText('Not configured')).toHaveLength(2) - }) - }) + expect(screen.getAllByText('Not configured')).toHaveLength(2); + }); + }); describe('Method Selection', () => { it('should render method selection dropdown', () => { @@ -115,10 +117,10 @@ describe('CreateBackupDialog', () => { onOpenChange={mockOnOpenChange} onSubmit={mockOnSubmit} /> - ) + ); - expect(screen.getByRole('combobox')).toBeInTheDocument() - }) + expect(screen.getByRole('combobox')).toBeInTheDocument(); + }); it('should show all method options', async () => { render( @@ -129,15 +131,15 @@ describe('CreateBackupDialog', () => { onOpenChange={mockOnOpenChange} onSubmit={mockOnSubmit} /> - ) + ); - const select = screen.getByRole('combobox') - await user.click(select) + const select = screen.getByRole('combobox'); + await user.click(select); - expect(screen.getAllByText('Auto')).toHaveLength(2) // Button and option - expect(screen.getByText('BarmanObjectStore')).toBeInTheDocument() - expect(screen.getByText('VolumeSnapshot')).toBeInTheDocument() - }) + expect(screen.getAllByText('Auto')).toHaveLength(2); // Button and option + expect(screen.getByText('BarmanObjectStore')).toBeInTheDocument(); + expect(screen.getByText('VolumeSnapshot')).toBeInTheDocument(); + }); it('should disable options based on backup configuration', async () => { const limitedBackups = { @@ -147,7 +149,7 @@ describe('CreateBackupDialog', () => { methodConfigured: 'volumeSnapshot', snapshotSupported: false } - } + }; render( { onOpenChange={mockOnOpenChange} onSubmit={mockOnSubmit} /> - ) + ); - const select = screen.getByRole('combobox') - await user.click(select) + const select = screen.getByRole('combobox'); + await user.click(select); // BarmanObjectStore should be disabled - const barmanOption = screen.getByText('BarmanObjectStore') - expect(barmanOption.closest('[data-disabled]')).toBeInTheDocument() + const barmanOption = screen.getByText('BarmanObjectStore'); + expect(barmanOption.closest('[data-disabled]')).toBeInTheDocument(); // VolumeSnapshot should be disabled - const volumeOption = screen.getByText('VolumeSnapshot') - expect(volumeOption.closest('[data-disabled]')).toBeInTheDocument() - }) - }) + const volumeOption = screen.getByText('VolumeSnapshot'); + expect(volumeOption.closest('[data-disabled]')).toBeInTheDocument(); + }); + }); describe('User Interactions', () => { it('should change method selection', async () => { @@ -182,19 +184,19 @@ describe('CreateBackupDialog', () => { onOpenChange={mockOnOpenChange} onSubmit={mockOnSubmit} /> - ) + ); - const select = screen.getByRole('combobox') - await user.click(select) + const select = screen.getByRole('combobox'); + await user.click(select); - const barmanOption = screen.getByText('BarmanObjectStore') - await user.click(barmanOption) + const barmanOption = screen.getByText('BarmanObjectStore'); + await user.click(barmanOption); - expect(select).toHaveTextContent('BarmanObjectStore') - }) + expect(select).toHaveTextContent('BarmanObjectStore'); + }); it('should submit with selected method', async () => { - mockOnSubmit.mockResolvedValue(undefined) + mockOnSubmit.mockResolvedValue(undefined); render( { onOpenChange={mockOnOpenChange} onSubmit={mockOnSubmit} /> - ) + ); - const select = screen.getByRole('combobox') - await user.click(select) + const select = screen.getByRole('combobox'); + await user.click(select); - const barmanOption = screen.getByText('BarmanObjectStore') - await user.click(barmanOption) + const barmanOption = screen.getByText('BarmanObjectStore'); + await user.click(barmanOption); - const createButton = screen.getByRole('button', { name: 'Create Backup' }) - await user.click(createButton) + const createButton = screen.getByRole('button', { name: 'Create Backup' }); + await user.click(createButton); - expect(mockOnSubmit).toHaveBeenCalledWith('barmanObjectStore') - expect(mockOnOpenChange).toHaveBeenCalledWith(false) - }) + expect(mockOnSubmit).toHaveBeenCalledWith('barmanObjectStore'); + expect(mockOnOpenChange).toHaveBeenCalledWith(false); + }); it('should submit with auto method (undefined)', async () => { - mockOnSubmit.mockResolvedValue(undefined) + mockOnSubmit.mockResolvedValue(undefined); render( { onOpenChange={mockOnOpenChange} onSubmit={mockOnSubmit} /> - ) + ); - const createButton = screen.getByRole('button', { name: 'Create Backup' }) - await user.click(createButton) + const createButton = screen.getByRole('button', { name: 'Create Backup' }); + await user.click(createButton); - expect(mockOnSubmit).toHaveBeenCalledWith(undefined) - expect(mockOnOpenChange).toHaveBeenCalledWith(false) - }) + expect(mockOnSubmit).toHaveBeenCalledWith(undefined); + expect(mockOnOpenChange).toHaveBeenCalledWith(false); + }); it('should cancel when cancel button is clicked', async () => { render( @@ -248,18 +250,18 @@ describe('CreateBackupDialog', () => { onOpenChange={mockOnOpenChange} onSubmit={mockOnSubmit} /> - ) + ); - const cancelButton = screen.getByRole('button', { name: 'Cancel' }) - await user.click(cancelButton) + const cancelButton = screen.getByRole('button', { name: 'Cancel' }); + await user.click(cancelButton); - expect(mockOnOpenChange).toHaveBeenCalledWith(false) - }) - }) + expect(mockOnOpenChange).toHaveBeenCalledWith(false); + }); + }); describe('Loading States', () => { it('should show loading state when submitting', async () => { - mockOnSubmit.mockImplementation(() => new Promise(resolve => setTimeout(resolve, 100))) + mockOnSubmit.mockImplementation(() => new Promise(resolve => setTimeout(resolve, 100))); render( { onOpenChange={mockOnOpenChange} onSubmit={mockOnSubmit} /> - ) + ); - const createButton = screen.getByRole('button', { name: 'Create Backup' }) - await user.click(createButton) + const createButton = screen.getByRole('button', { name: 'Create Backup' }); + await user.click(createButton); - expect(screen.getByText('Creating…')).toBeInTheDocument() - expect(createButton).toBeDisabled() - expect(screen.getByRole('button', { name: 'Cancel' })).toBeDisabled() - }) - }) + expect(screen.getByText('Creating…')).toBeInTheDocument(); + expect(createButton).toBeDisabled(); + expect(screen.getByRole('button', { name: 'Cancel' })).toBeDisabled(); + }); + }); describe('Error Handling', () => { it('should show error when submission fails', async () => { - const errorMessage = 'Failed to create backup' - mockOnSubmit.mockRejectedValue(new Error(errorMessage)) + const errorMessage = 'Failed to create backup'; + mockOnSubmit.mockRejectedValue(new Error(errorMessage)); render( { onOpenChange={mockOnOpenChange} onSubmit={mockOnSubmit} /> - ) + ); - const createButton = screen.getByRole('button', { name: 'Create Backup' }) - await user.click(createButton) + const createButton = screen.getByRole('button', { name: 'Create Backup' }); + await user.click(createButton); await waitFor(() => { - expect(screen.getByText(errorMessage)).toBeInTheDocument() - }) + expect(screen.getByText(errorMessage)).toBeInTheDocument(); + }); - expect(mockOnOpenChange).not.toHaveBeenCalled() - }) + expect(mockOnOpenChange).not.toHaveBeenCalled(); + }); it('should show generic error for non-Error exceptions', async () => { - mockOnSubmit.mockRejectedValue('String error') + mockOnSubmit.mockRejectedValue('String error'); render( { onOpenChange={mockOnOpenChange} onSubmit={mockOnSubmit} /> - ) + ); - const createButton = screen.getByRole('button', { name: 'Create Backup' }) - await user.click(createButton) + const createButton = screen.getByRole('button', { name: 'Create Backup' }); + await user.click(createButton); await waitFor(() => { - expect(screen.getByText('Failed to create backup')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('Failed to create backup')).toBeInTheDocument(); + }); + }); + }); describe('Button States', () => { it('should disable create button when no valid method is available', () => { @@ -336,7 +338,7 @@ describe('CreateBackupDialog', () => { methodConfigured: 'none', snapshotSupported: false } - } + }; render( { onOpenChange={mockOnOpenChange} onSubmit={mockOnSubmit} /> - ) + ); - const createButton = screen.getByRole('button', { name: 'Create Backup' }) - expect(createButton).toBeDisabled() - }) + const createButton = screen.getByRole('button', { name: 'Create Backup' }); + expect(createButton).toBeDisabled(); + }); it('should show appropriate tooltip for disabled button', () => { const noBackups = { @@ -360,7 +362,7 @@ describe('CreateBackupDialog', () => { methodConfigured: 'none', snapshotSupported: false } - } + }; render( { onOpenChange={mockOnOpenChange} onSubmit={mockOnSubmit} /> - ) + ); - const createButton = screen.getByRole('button', { name: 'Create Backup' }) - expect(createButton).toHaveAttribute('title', 'Configure backups (barman) or install VolumeSnapshot CRDs') - }) - }) + const createButton = screen.getByRole('button', { name: 'Create Backup' }); + expect(createButton).toHaveAttribute('title', 'Configure backups (barman) or install VolumeSnapshot CRDs'); + }); + }); describe('Accessibility', () => { it('should have proper labels and roles', () => { @@ -387,13 +389,13 @@ describe('CreateBackupDialog', () => { onOpenChange={mockOnOpenChange} onSubmit={mockOnSubmit} /> - ) + ); - expect(screen.getByRole('dialog')).toBeInTheDocument() - expect(screen.getByRole('combobox')).toBeInTheDocument() - expect(screen.getByRole('button', { name: 'Create Backup' })).toBeInTheDocument() - expect(screen.getByRole('button', { name: 'Cancel' })).toBeInTheDocument() - }) + expect(screen.getByRole('dialog')).toBeInTheDocument(); + expect(screen.getByRole('combobox')).toBeInTheDocument(); + expect(screen.getByRole('button', { name: 'Create Backup' })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: 'Cancel' })).toBeInTheDocument(); + }); it('should be keyboard navigable', async () => { render( @@ -404,15 +406,15 @@ describe('CreateBackupDialog', () => { onOpenChange={mockOnOpenChange} onSubmit={mockOnSubmit} /> - ) + ); - const select = screen.getByRole('combobox') - select.focus() + const select = screen.getByRole('combobox'); + select.focus(); - expect(document.activeElement).toBe(select) + expect(document.activeElement).toBe(select); - await user.keyboard('{Tab}') - expect(document.activeElement).not.toBe(select) - }) - }) -}) + await user.keyboard('{Tab}'); + expect(document.activeElement).not.toBe(select); + }); + }); +}); diff --git a/apps/ops-dashboard/__tests__/components/create-databases-dialog.test.tsx b/apps/ops-dashboard/__tests__/components/create-databases-dialog.test.tsx index 6237d49..8d410b5 100644 --- a/apps/ops-dashboard/__tests__/components/create-databases-dialog.test.tsx +++ b/apps/ops-dashboard/__tests__/components/create-databases-dialog.test.tsx @@ -1,133 +1,134 @@ -import React from 'react' -import { render, screen, waitFor } from '../utils/test-utils' -import userEvent from '@testing-library/user-event' -import { CreateDatabasesDialog } from '../../components/create-databases-dialog' +import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { CreateDatabasesDialog } from '../../components/create-databases-dialog'; +import { render, screen, waitFor } from '../utils/test-utils'; describe('CreateDatabasesDialog', () => { - const mockOnOpenChange = jest.fn() - const mockOnSubmit = jest.fn() + const mockOnOpenChange = jest.fn(); + const mockOnSubmit = jest.fn(); const defaultProps = { open: true, onOpenChange: mockOnOpenChange, onSubmit: mockOnSubmit, - } + }; beforeEach(() => { - jest.clearAllMocks() - }) + jest.clearAllMocks(); + }); describe('Basic Rendering', () => { it('should render dialog when open', () => { - render() + render(); - expect(screen.getByRole('dialog')).toBeInTheDocument() - expect(screen.getByRole('heading', { name: 'Create PostgreSQL (CloudNativePG)' })).toBeInTheDocument() - }) + expect(screen.getByRole('dialog')).toBeInTheDocument(); + expect(screen.getByRole('heading', { name: 'Create PostgreSQL (CloudNativePG)' })).toBeInTheDocument(); + }); it('should not render when closed', () => { - render() + render(); - expect(screen.queryByRole('dialog')).not.toBeInTheDocument() - }) + expect(screen.queryByRole('dialog')).not.toBeInTheDocument(); + }); it('should display all form fields with default values', () => { - render() + render(); // Check instances field - use getAllByRole and select first one - const instancesInputs = screen.getAllByRole('spinbutton') - const instancesInput = instancesInputs[0] // First one is "Instances" - expect(instancesInput).toBeInTheDocument() - expect(instancesInput).toHaveValue(1) + const instancesInputs = screen.getAllByRole('spinbutton'); + const instancesInput = instancesInputs[0]; // First one is "Instances" + expect(instancesInput).toBeInTheDocument(); + expect(instancesInput).toHaveValue(1); // Check storage field - const storageInput = screen.getByDisplayValue('1Gi') - expect(storageInput).toBeInTheDocument() + const storageInput = screen.getByDisplayValue('1Gi'); + expect(storageInput).toBeInTheDocument(); // Check app username field - const appUsernameInput = screen.getByDisplayValue('appuser') - expect(appUsernameInput).toBeInTheDocument() + const appUsernameInput = screen.getByDisplayValue('appuser'); + expect(appUsernameInput).toBeInTheDocument(); // Check app password field - const appPasswordInput = screen.getByDisplayValue('appuser123!') - expect(appPasswordInput).toBeInTheDocument() - expect(appPasswordInput).toHaveAttribute('type', 'password') + const appPasswordInput = screen.getByDisplayValue('appuser123!'); + expect(appPasswordInput).toBeInTheDocument(); + expect(appPasswordInput).toHaveAttribute('type', 'password'); // Check superuser password field - const superuserPasswordInput = screen.getByDisplayValue('postgres123!') - expect(superuserPasswordInput).toBeInTheDocument() - expect(superuserPasswordInput).toHaveAttribute('type', 'password') + const superuserPasswordInput = screen.getByDisplayValue('postgres123!'); + expect(superuserPasswordInput).toBeInTheDocument(); + expect(superuserPasswordInput).toHaveAttribute('type', 'password'); // Check pooler checkbox - const poolerCheckbox = screen.getByRole('checkbox', { name: /enable pgbouncer pooler/i }) - expect(poolerCheckbox).toBeInTheDocument() - expect(poolerCheckbox).toBeChecked() - }) + const poolerCheckbox = screen.getByRole('checkbox', { name: /enable pgbouncer pooler/i }); + expect(poolerCheckbox).toBeInTheDocument(); + expect(poolerCheckbox).toBeChecked(); + }); it('should show pooler fields when pooler is enabled', () => { - render() + render(); // Pooler fields should be visible when checkbox is checked - expect(screen.getByDisplayValue('postgres-pooler')).toBeInTheDocument() - const poolerInstancesInputs = screen.getAllByRole('spinbutton') - expect(poolerInstancesInputs[1]).toBeInTheDocument() // Second spinbutton is "Pooler Instances" - }) - }) + expect(screen.getByDisplayValue('postgres-pooler')).toBeInTheDocument(); + const poolerInstancesInputs = screen.getAllByRole('spinbutton'); + expect(poolerInstancesInputs[1]).toBeInTheDocument(); // Second spinbutton is "Pooler Instances" + }); + }); describe('Form Interactions', () => { it('should update instances field', async () => { - const user = userEvent.setup() - render() + const user = userEvent.setup(); + render(); - const instancesInputs = screen.getAllByRole('spinbutton') - const instancesInput = instancesInputs[0] // First one is "Instances" + const instancesInputs = screen.getAllByRole('spinbutton'); + const instancesInput = instancesInputs[0]; // First one is "Instances" // Triple click to select all, then type to replace - await user.tripleClick(instancesInput) - await user.keyboard('3') + await user.tripleClick(instancesInput); + await user.keyboard('3'); - expect(instancesInput).toHaveValue(3) - }) + expect(instancesInput).toHaveValue(3); + }); it('should update storage field', async () => { - const user = userEvent.setup() - render() + const user = userEvent.setup(); + render(); - const storageInput = screen.getByDisplayValue('1Gi') - await user.clear(storageInput) - await user.type(storageInput, '10Gi') + const storageInput = screen.getByDisplayValue('1Gi'); + await user.clear(storageInput); + await user.type(storageInput, '10Gi'); - expect(storageInput).toHaveValue('10Gi') - }) + expect(storageInput).toHaveValue('10Gi'); + }); it('should toggle pooler checkbox', async () => { - const user = userEvent.setup() - render() + const user = userEvent.setup(); + render(); - const poolerCheckbox = screen.getByRole('checkbox', { name: /enable pgbouncer pooler/i }) + const poolerCheckbox = screen.getByRole('checkbox', { name: /enable pgbouncer pooler/i }); // Initially checked - expect(poolerCheckbox).toBeChecked() + expect(poolerCheckbox).toBeChecked(); // Uncheck - await user.click(poolerCheckbox) - expect(poolerCheckbox).not.toBeChecked() + await user.click(poolerCheckbox); + expect(poolerCheckbox).not.toBeChecked(); // Check again - await user.click(poolerCheckbox) - expect(poolerCheckbox).toBeChecked() - }) - }) + await user.click(poolerCheckbox); + expect(poolerCheckbox).toBeChecked(); + }); + }); describe('Form Submission', () => { it('should submit with valid data', async () => { - const user = userEvent.setup() - mockOnSubmit.mockResolvedValue(undefined) + const user = userEvent.setup(); + mockOnSubmit.mockResolvedValue(undefined); - render() + render(); - const createButton = screen.getByRole('button', { name: /create/i }) - await user.click(createButton) + const createButton = screen.getByRole('button', { name: /create/i }); + await user.click(createButton); expect(mockOnSubmit).toHaveBeenCalledWith({ instances: 1, @@ -139,105 +140,105 @@ describe('CreateDatabasesDialog', () => { enablePooler: true, poolerName: 'postgres-pooler', poolerInstances: 1, - }) - }) + }); + }); it('should show loading state during submission', async () => { - const user = userEvent.setup() - mockOnSubmit.mockImplementation(() => new Promise(resolve => setTimeout(resolve, 100))) + const user = userEvent.setup(); + mockOnSubmit.mockImplementation(() => new Promise(resolve => setTimeout(resolve, 100))); - render() + render(); - const createButton = screen.getByRole('button', { name: /create/i }) - await user.click(createButton) + const createButton = screen.getByRole('button', { name: /create/i }); + await user.click(createButton); - expect(screen.getByRole('button', { name: /creating/i })).toBeInTheDocument() - expect(screen.getByRole('button', { name: /creating/i })).toBeDisabled() - expect(screen.getByRole('button', { name: /cancel/i })).toBeDisabled() - }) + expect(screen.getByRole('button', { name: /creating/i })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: /creating/i })).toBeDisabled(); + expect(screen.getByRole('button', { name: /cancel/i })).toBeDisabled(); + }); it('should close dialog after successful submission', async () => { - const user = userEvent.setup() - mockOnSubmit.mockResolvedValue(undefined) + const user = userEvent.setup(); + mockOnSubmit.mockResolvedValue(undefined); - render() + render(); - const createButton = screen.getByRole('button', { name: /create/i }) - await user.click(createButton) + const createButton = screen.getByRole('button', { name: /create/i }); + await user.click(createButton); await waitFor(() => { - expect(mockOnOpenChange).toHaveBeenCalledWith(false) - }) - }) - }) + expect(mockOnOpenChange).toHaveBeenCalledWith(false); + }); + }); + }); describe('Validation', () => { it('should show error for empty app username', async () => { - const user = userEvent.setup() - render() + const user = userEvent.setup(); + render(); - const appUsernameInput = screen.getByDisplayValue('appuser') - await user.clear(appUsernameInput) + const appUsernameInput = screen.getByDisplayValue('appuser'); + await user.clear(appUsernameInput); - const createButton = screen.getByRole('button', { name: /create/i }) - await user.click(createButton) + const createButton = screen.getByRole('button', { name: /create/i }); + await user.click(createButton); - expect(screen.getByText('App username is required')).toBeInTheDocument() - expect(mockOnSubmit).not.toHaveBeenCalled() - }) - }) + expect(screen.getByText('App username is required')).toBeInTheDocument(); + expect(mockOnSubmit).not.toHaveBeenCalled(); + }); + }); describe('Error Handling', () => { it('should show error when submission fails', async () => { - const user = userEvent.setup() - mockOnSubmit.mockRejectedValue(new Error('Database creation failed')) + const user = userEvent.setup(); + mockOnSubmit.mockRejectedValue(new Error('Database creation failed')); - render() + render(); - const createButton = screen.getByRole('button', { name: /create/i }) - await user.click(createButton) + const createButton = screen.getByRole('button', { name: /create/i }); + await user.click(createButton); await waitFor(() => { - expect(screen.getByText('Database creation failed')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Database creation failed')).toBeInTheDocument(); + }); + }); it('should show generic error for non-Error exceptions', async () => { - const user = userEvent.setup() - mockOnSubmit.mockRejectedValue('String error') + const user = userEvent.setup(); + mockOnSubmit.mockRejectedValue('String error'); - render() + render(); - const createButton = screen.getByRole('button', { name: /create/i }) - await user.click(createButton) + const createButton = screen.getByRole('button', { name: /create/i }); + await user.click(createButton); await waitFor(() => { - expect(screen.getByText('Failed to create database')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('Failed to create database')).toBeInTheDocument(); + }); + }); + }); describe('Cancel Functionality', () => { it('should close dialog when cancel is clicked', async () => { - const user = userEvent.setup() - render() + const user = userEvent.setup(); + render(); - const cancelButton = screen.getByRole('button', { name: /cancel/i }) - await user.click(cancelButton) + const cancelButton = screen.getByRole('button', { name: /cancel/i }); + await user.click(cancelButton); - expect(mockOnOpenChange).toHaveBeenCalledWith(false) - }) - }) + expect(mockOnOpenChange).toHaveBeenCalledWith(false); + }); + }); describe('Accessibility', () => { it('should have proper labels and roles', () => { - render() - - expect(screen.getByRole('dialog')).toBeInTheDocument() - expect(screen.getByRole('heading', { name: 'Create PostgreSQL (CloudNativePG)' })).toBeInTheDocument() - expect(screen.getByRole('checkbox', { name: /enable pgbouncer pooler/i })).toBeInTheDocument() - expect(screen.getByRole('button', { name: /cancel/i })).toBeInTheDocument() - expect(screen.getByRole('button', { name: /create/i })).toBeInTheDocument() - }) - }) -}) \ No newline at end of file + render(); + + expect(screen.getByRole('dialog')).toBeInTheDocument(); + expect(screen.getByRole('heading', { name: 'Create PostgreSQL (CloudNativePG)' })).toBeInTheDocument(); + expect(screen.getByRole('checkbox', { name: /enable pgbouncer pooler/i })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: /cancel/i })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: /create/i })).toBeInTheDocument(); + }); + }); +}); \ No newline at end of file diff --git a/apps/ops-dashboard/__tests__/components/create-deployment-dialog.test.tsx b/apps/ops-dashboard/__tests__/components/create-deployment-dialog.test.tsx index 082fa4b..79f77d1 100644 --- a/apps/ops-dashboard/__tests__/components/create-deployment-dialog.test.tsx +++ b/apps/ops-dashboard/__tests__/components/create-deployment-dialog.test.tsx @@ -1,7 +1,9 @@ -import React from 'react' -import { render, screen, waitFor, cleanup } from '../utils/test-utils' -import userEvent from '@testing-library/user-event' -import { CreateDeploymentDialog } from '@/components/create-deployment-dialog' +import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { CreateDeploymentDialog } from '@/components/create-deployment-dialog'; + +import { cleanup,render, screen, waitFor } from '../utils/test-utils'; // Mock the YAMLEditor component jest.mock('../../components/yaml-editor', () => ({ @@ -14,16 +16,16 @@ jest.mock('../../components/yaml-editor', () => ({ placeholder="YAML content" /> ) -})) +})); describe('CreateDeploymentDialog', () => { - const mockOnOpenChange = jest.fn() - const mockOnSubmit = jest.fn() + const mockOnOpenChange = jest.fn(); + const mockOnSubmit = jest.fn(); beforeEach(() => { - jest.clearAllMocks() - cleanup() - }) + jest.clearAllMocks(); + cleanup(); + }); describe('Basic Rendering', () => { it('should render dialog when open', () => { @@ -33,14 +35,14 @@ describe('CreateDeploymentDialog', () => { onOpenChange={mockOnOpenChange} onSubmit={mockOnSubmit} /> - ) + ); - expect(screen.getByText('Create Deployment')).toBeInTheDocument() - expect(screen.getByText('Define your deployment using YAML. The editor below provides a template to get you started.')).toBeInTheDocument() - expect(screen.getByTestId('yaml-editor')).toBeInTheDocument() - expect(screen.getByRole('button', { name: /cancel/i })).toBeInTheDocument() - expect(screen.getByRole('button', { name: /continue/i })).toBeInTheDocument() - }) + expect(screen.getByText('Create Deployment')).toBeInTheDocument(); + expect(screen.getByText('Define your deployment using YAML. The editor below provides a template to get you started.')).toBeInTheDocument(); + expect(screen.getByTestId('yaml-editor')).toBeInTheDocument(); + expect(screen.getByRole('button', { name: /cancel/i })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: /continue/i })).toBeInTheDocument(); + }); it('should not render dialog when closed', () => { render( @@ -49,10 +51,10 @@ describe('CreateDeploymentDialog', () => { onOpenChange={mockOnOpenChange} onSubmit={mockOnSubmit} /> - ) + ); - expect(screen.queryByText('Create Deployment')).not.toBeInTheDocument() - }) + expect(screen.queryByText('Create Deployment')).not.toBeInTheDocument(); + }); it('should display default YAML template', () => { render( @@ -61,52 +63,52 @@ describe('CreateDeploymentDialog', () => { onOpenChange={mockOnOpenChange} onSubmit={mockOnSubmit} /> - ) + ); - const yamlEditor = screen.getByTestId('yaml-editor') - expect(yamlEditor.value).toContain('apiVersion: apps/v1') - expect(yamlEditor.value).toContain('kind: Deployment') - expect(yamlEditor.value).toContain('name: my-app') - }) - }) + const yamlEditor = screen.getByTestId('yaml-editor'); + expect(yamlEditor.value).toContain('apiVersion: apps/v1'); + expect(yamlEditor.value).toContain('kind: Deployment'); + expect(yamlEditor.value).toContain('name: my-app'); + }); + }); describe('User Interactions', () => { it('should handle YAML content changes', async () => { - const user = userEvent.setup() + const user = userEvent.setup(); render( - ) + ); - const yamlEditor = screen.getByTestId('yaml-editor') - await user.clear(yamlEditor) - await user.type(yamlEditor, 'new yaml content') + const yamlEditor = screen.getByTestId('yaml-editor'); + await user.clear(yamlEditor); + await user.type(yamlEditor, 'new yaml content'); - expect(yamlEditor).toHaveValue('new yaml content') - }) + expect(yamlEditor).toHaveValue('new yaml content'); + }); it('should handle cancel button click', async () => { - const user = userEvent.setup() + const user = userEvent.setup(); render( - ) + ); - const cancelButton = screen.getByRole('button', { name: /cancel/i }) - await user.click(cancelButton) + const cancelButton = screen.getByRole('button', { name: /cancel/i }); + await user.click(cancelButton); - expect(mockOnOpenChange).toHaveBeenCalledWith(false) - }) + expect(mockOnOpenChange).toHaveBeenCalledWith(false); + }); it('should handle successful submission', async () => { - const user = userEvent.setup() - mockOnSubmit.mockResolvedValue(undefined) + const user = userEvent.setup(); + mockOnSubmit.mockResolvedValue(undefined); render( { onOpenChange={mockOnOpenChange} onSubmit={mockOnSubmit} /> - ) + ); - const continueButton = screen.getByRole('button', { name: /continue/i }) - await user.click(continueButton) + const continueButton = screen.getByRole('button', { name: /continue/i }); + await user.click(continueButton); await waitFor(() => { - expect(mockOnSubmit).toHaveBeenCalledWith(expect.stringContaining('apiVersion: apps/v1')) - expect(mockOnOpenChange).toHaveBeenCalledWith(false) - }) - }) + expect(mockOnSubmit).toHaveBeenCalledWith(expect.stringContaining('apiVersion: apps/v1')); + expect(mockOnOpenChange).toHaveBeenCalledWith(false); + }); + }); it('should show loading state during submission', async () => { - const user = userEvent.setup() - mockOnSubmit.mockImplementation(() => new Promise(resolve => setTimeout(resolve, 100))) + const user = userEvent.setup(); + mockOnSubmit.mockImplementation(() => new Promise(resolve => setTimeout(resolve, 100))); render( { onOpenChange={mockOnOpenChange} onSubmit={mockOnSubmit} /> - ) + ); - const continueButton = screen.getByRole('button', { name: /continue/i }) - await user.click(continueButton) + const continueButton = screen.getByRole('button', { name: /continue/i }); + await user.click(continueButton); - expect(screen.getByText('Creating...')).toBeInTheDocument() - expect(continueButton).toBeDisabled() - expect(screen.getByRole('button', { name: /cancel/i })).toBeDisabled() - }) - }) + expect(screen.getByText('Creating...')).toBeInTheDocument(); + expect(continueButton).toBeDisabled(); + expect(screen.getByRole('button', { name: /cancel/i })).toBeDisabled(); + }); + }); describe('Error Handling', () => { it('should display error message when submission fails', async () => { - const user = userEvent.setup() - const errorMessage = 'Failed to create deployment' - mockOnSubmit.mockRejectedValue(new Error(errorMessage)) + const user = userEvent.setup(); + const errorMessage = 'Failed to create deployment'; + mockOnSubmit.mockRejectedValue(new Error(errorMessage)); render( { onOpenChange={mockOnOpenChange} onSubmit={mockOnSubmit} /> - ) + ); - const continueButton = screen.getByRole('button', { name: /continue/i }) - await user.click(continueButton) + const continueButton = screen.getByRole('button', { name: /continue/i }); + await user.click(continueButton); await waitFor(() => { - expect(screen.getByText(errorMessage)).toBeInTheDocument() - }) + expect(screen.getByText(errorMessage)).toBeInTheDocument(); + }); - expect(mockOnOpenChange).not.toHaveBeenCalled() - }) + expect(mockOnOpenChange).not.toHaveBeenCalled(); + }); it('should display error for empty YAML content', async () => { - const user = userEvent.setup() + const user = userEvent.setup(); render( - ) + ); - const yamlEditor = screen.getByTestId('yaml-editor') - await user.clear(yamlEditor) + const yamlEditor = screen.getByTestId('yaml-editor'); + await user.clear(yamlEditor); - const continueButton = screen.getByRole('button', { name: /continue/i }) - await user.click(continueButton) + const continueButton = screen.getByRole('button', { name: /continue/i }); + await user.click(continueButton); await waitFor(() => { - expect(screen.getByText('YAML content cannot be empty')).toBeInTheDocument() - }) - }) + expect(screen.getByText('YAML content cannot be empty')).toBeInTheDocument(); + }); + }); it('should clear error when canceling', async () => { - const user = userEvent.setup() - mockOnSubmit.mockRejectedValue(new Error('Test error')) + const user = userEvent.setup(); + mockOnSubmit.mockRejectedValue(new Error('Test error')); render( { onOpenChange={mockOnOpenChange} onSubmit={mockOnSubmit} /> - ) + ); // Trigger an error first - const continueButton = screen.getByRole('button', { name: /continue/i }) - await user.click(continueButton) + const continueButton = screen.getByRole('button', { name: /continue/i }); + await user.click(continueButton); await waitFor(() => { - expect(screen.getByText('Test error')).toBeInTheDocument() - }) + expect(screen.getByText('Test error')).toBeInTheDocument(); + }); // Cancel should clear the error - const cancelButton = screen.getByRole('button', { name: /cancel/i }) - await user.click(cancelButton) + const cancelButton = screen.getByRole('button', { name: /cancel/i }); + await user.click(cancelButton); - expect(screen.queryByText('Test error')).not.toBeInTheDocument() - }) - }) + expect(screen.queryByText('Test error')).not.toBeInTheDocument(); + }); + }); describe('State Management', () => { it('should reset YAML to template after successful submission', async () => { - const user = userEvent.setup() - mockOnSubmit.mockResolvedValue(undefined) + const user = userEvent.setup(); + mockOnSubmit.mockResolvedValue(undefined); const { rerender } = render( { onOpenChange={mockOnOpenChange} onSubmit={mockOnSubmit} /> - ) + ); - const yamlEditor = screen.getByTestId('yaml-editor') - await user.clear(yamlEditor) - await user.type(yamlEditor, 'custom yaml') + const yamlEditor = screen.getByTestId('yaml-editor'); + await user.clear(yamlEditor); + await user.type(yamlEditor, 'custom yaml'); - const continueButton = screen.getByRole('button', { name: /continue/i }) - await user.click(continueButton) + const continueButton = screen.getByRole('button', { name: /continue/i }); + await user.click(continueButton); await waitFor(() => { - expect(mockOnOpenChange).toHaveBeenCalledWith(false) - }) + expect(mockOnOpenChange).toHaveBeenCalledWith(false); + }); // Re-open dialog should show template again rerender( @@ -250,28 +252,28 @@ describe('CreateDeploymentDialog', () => { onOpenChange={mockOnOpenChange} onSubmit={mockOnSubmit} /> - ) + ); - const newYamlEditor = screen.getByTestId('yaml-editor') - expect(newYamlEditor.value).toContain('apiVersion: apps/v1') - }) + const newYamlEditor = screen.getByTestId('yaml-editor'); + expect(newYamlEditor.value).toContain('apiVersion: apps/v1'); + }); it('should reset YAML to template when canceling', async () => { - const user = userEvent.setup() + const user = userEvent.setup(); const { rerender } = render( - ) + ); - const yamlEditor = screen.getByTestId('yaml-editor') - await user.clear(yamlEditor) - await user.type(yamlEditor, 'custom yaml') + const yamlEditor = screen.getByTestId('yaml-editor'); + await user.clear(yamlEditor); + await user.type(yamlEditor, 'custom yaml'); - const cancelButton = screen.getByRole('button', { name: /cancel/i }) - await user.click(cancelButton) + const cancelButton = screen.getByRole('button', { name: /cancel/i }); + await user.click(cancelButton); // Re-open dialog should show template again rerender( @@ -280,10 +282,10 @@ describe('CreateDeploymentDialog', () => { onOpenChange={mockOnOpenChange} onSubmit={mockOnSubmit} /> - ) + ); - const newYamlEditor = screen.getByTestId('yaml-editor') - expect(newYamlEditor.value).toContain('apiVersion: apps/v1') - }) - }) -}) + const newYamlEditor = screen.getByTestId('yaml-editor'); + expect(newYamlEditor.value).toContain('apiVersion: apps/v1'); + }); + }); +}); diff --git a/apps/ops-dashboard/__tests__/components/dashboard-layout.test.tsx b/apps/ops-dashboard/__tests__/components/dashboard-layout.test.tsx index 3acf5f3..66246fe 100644 --- a/apps/ops-dashboard/__tests__/components/dashboard-layout.test.tsx +++ b/apps/ops-dashboard/__tests__/components/dashboard-layout.test.tsx @@ -1,9 +1,11 @@ -import { screen, fireEvent, waitFor } from '@testing-library/react'; +import { fireEvent, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; + +import { createNamespacesList } from '@/__mocks__/handlers/namespaces'; +import { server } from '@/__mocks__/server'; import { DashboardLayout } from '@/components/dashboard-layout'; + import { render } from '../utils/test-utils'; -import { server } from '@/__mocks__/server'; -import { createNamespacesList } from '@/__mocks__/handlers/namespaces'; // Mock next/navigation jest.mock('next/navigation', () => ({ diff --git a/apps/ops-dashboard/__tests__/components/headers/admin-header.test.tsx b/apps/ops-dashboard/__tests__/components/headers/admin-header.test.tsx index aa3c9c4..53a6359 100644 --- a/apps/ops-dashboard/__tests__/components/headers/admin-header.test.tsx +++ b/apps/ops-dashboard/__tests__/components/headers/admin-header.test.tsx @@ -1,4 +1,5 @@ import userEvent from '@testing-library/user-event'; + import { AdminHeader } from '../../../components/headers/admin-header'; import { render, screen } from '../../utils/test-utils'; diff --git a/apps/ops-dashboard/__tests__/components/headers/infra-header.test.tsx b/apps/ops-dashboard/__tests__/components/headers/infra-header.test.tsx index 6c34358..6cc34c3 100644 --- a/apps/ops-dashboard/__tests__/components/headers/infra-header.test.tsx +++ b/apps/ops-dashboard/__tests__/components/headers/infra-header.test.tsx @@ -1,8 +1,10 @@ import userEvent from '@testing-library/user-event'; +import { http, HttpResponse } from 'msw'; + +import { server } from '@/__mocks__/server'; + import { InfraHeader } from '../../../components/headers/infra-header'; import { render, screen } from '../../utils/test-utils'; -import { server } from '@/__mocks__/server'; -import { http, HttpResponse } from 'msw'; describe('InfraHeader', () => { const defaultProps = { diff --git a/apps/ops-dashboard/__tests__/components/headers/smart-objects-header.test.tsx b/apps/ops-dashboard/__tests__/components/headers/smart-objects-header.test.tsx index 775266f..6a87fbf 100644 --- a/apps/ops-dashboard/__tests__/components/headers/smart-objects-header.test.tsx +++ b/apps/ops-dashboard/__tests__/components/headers/smart-objects-header.test.tsx @@ -1,4 +1,5 @@ import userEvent from '@testing-library/user-event'; + import { SmartObjectsHeader } from '../../../components/headers/smart-objects-header'; import { render, screen } from '../../utils/test-utils'; diff --git a/apps/ops-dashboard/__tests__/components/namespace-switcher.test.tsx b/apps/ops-dashboard/__tests__/components/namespace-switcher.test.tsx index fc4f6a1..1496cf4 100644 --- a/apps/ops-dashboard/__tests__/components/namespace-switcher.test.tsx +++ b/apps/ops-dashboard/__tests__/components/namespace-switcher.test.tsx @@ -1,9 +1,11 @@ import userEvent from '@testing-library/user-event'; +import { http, HttpResponse } from 'msw'; + +import { createNamespacesList } from '@/__mocks__/handlers/namespaces'; +import { server } from '@/__mocks__/server'; + import { NamespaceSwitcher } from '../../components/namespace-switcher'; import { render, screen, waitFor } from '../utils/test-utils'; -import { server } from '@/__mocks__/server'; -import { createNamespacesList } from '@/__mocks__/handlers/namespaces'; -import { http, HttpResponse } from 'msw'; // Mock usePreferredNamespace const mockSetNamespace = jest.fn(); @@ -151,7 +153,7 @@ describe('NamespaceSwitcher', () => { // Wait for data to load await waitFor(() => { - expect(screen.getByText('default')).toBeInTheDocument() + expect(screen.getByText('default')).toBeInTheDocument(); }); // Test calling setNamespace with 'kube-system' diff --git a/apps/ops-dashboard/__tests__/components/resources/all-resources.test.tsx b/apps/ops-dashboard/__tests__/components/resources/all-resources.test.tsx index c1361d3..21768b6 100644 --- a/apps/ops-dashboard/__tests__/components/resources/all-resources.test.tsx +++ b/apps/ops-dashboard/__tests__/components/resources/all-resources.test.tsx @@ -1,33 +1,20 @@ -import { render, screen, waitFor } from '@/__tests__/utils/test-utils' -import userEvent from '@testing-library/user-event' -import { AllResourcesView } from '@/components/resources/all-resources' -import { server } from '@/__mocks__/server' +import { AppsV1DaemonSet, AppsV1Deployment, AppsV1ReplicaSet,Pod, Service } from '@kubernetesjs/ops'; +import userEvent from '@testing-library/user-event'; + import { - createDeploymentsList, - createDeploymentsListError, - createDeploymentsListData -} from '@/__mocks__/handlers/deployments' + createDaemonSetsList} from '@/__mocks__/handlers/daemonsets'; import { - createServicesList, - createServicesListError, - createServicesListData -} from '@/__mocks__/handlers/services' + createDeploymentsList, + createDeploymentsListError} from '@/__mocks__/handlers/deployments'; import { - createPodsList, - createPodsListError, - createPodsListData -} from '@/__mocks__/handlers/pods' + createPodsList} from '@/__mocks__/handlers/pods'; import { - createDaemonSetsList, - createDaemonSetsListError, - createDaemonSetsListData -} from '@/__mocks__/handlers/daemonsets' + createReplicaSetsList} from '@/__mocks__/handlers/replicasets'; import { - createReplicaSetsList, - createReplicaSetsListError, - createReplicaSetsListData -} from '@/__mocks__/handlers/replicasets' -import { AppsV1Deployment, Service, Pod, AppsV1DaemonSet, AppsV1ReplicaSet } from '@kubernetesjs/ops' + createServicesList} from '@/__mocks__/handlers/services'; +import { server } from '@/__mocks__/server'; +import { render, screen, waitFor } from '@/__tests__/utils/test-utils'; +import { AllResourcesView } from '@/components/resources/all-resources'; // Helper functions to create custom test data const createCustomDeployment = (name: string, replicas: number, readyReplicas: number, image: string): AppsV1Deployment => ({ @@ -42,7 +29,7 @@ const createCustomDeployment = (name: string, replicas: number, readyReplicas: n } }, status: { readyReplicas, replicas } -}) +}); const createCustomService = (name: string, type: 'ClusterIP' | 'LoadBalancer' | 'NodePort' | 'ExternalName', ports: number[]): Service => ({ metadata: { name, uid: `${name}-uid`, namespace: 'default' }, @@ -52,7 +39,7 @@ const createCustomService = (name: string, type: 'ClusterIP' | 'LoadBalancer' | selector: { app: name } }, status: { loadBalancer: {} } -}) +}); const createCustomPod = (name: string, phase: 'Running' | 'Pending' | 'Succeeded' | 'Failed' | 'Unknown', readyContainers: number, totalContainers: number, nodeName: string): Pod => ({ metadata: { name, uid: `${name}-uid`, namespace: 'default' }, @@ -73,7 +60,7 @@ const createCustomPod = (name: string, phase: 'Running' | 'Pending' | 'Succeeded image: 'nginx:latest' })) } -}) +}); const createCustomDaemonSet = (name: string, desired: number, ready: number, image: string): AppsV1DaemonSet => ({ metadata: { name, uid: `${name}-uid`, namespace: 'default' }, @@ -93,7 +80,7 @@ const createCustomDaemonSet = (name: string, desired: number, ready: number, ima numberAvailable: ready, numberMisscheduled: 0 } -}) +}); const createCustomReplicaSet = (name: string, replicas: number, readyReplicas: number, image: string, ownerRef?: string): AppsV1ReplicaSet => ({ metadata: { @@ -127,12 +114,12 @@ const createCustomReplicaSet = (name: string, replicas: number, readyReplicas: n availableReplicas: readyReplicas, observedGeneration: 1 } -}) +}); describe('AllResourcesView', () => { beforeEach(() => { - server.resetHandlers() - }) + server.resetHandlers(); + }); describe('Resource Count Calculation Business Logic', () => { it('should calculate and display correct resource counts from API data', async () => { @@ -143,23 +130,23 @@ describe('AllResourcesView', () => { createPodsList(), createDaemonSetsList(), createReplicaSetsList() - ) + ); // Act: Render component - render() + render(); // Assert: Test the business logic - component should calculate counts from API response await waitFor(() => { // Check specific counts in summary cards (based on actual mock data for default namespace) - const summaryCards = screen.getAllByText(/\d+/, { selector: '.text-2xl.font-bold' }) - expect(summaryCards).toHaveLength(5) // Should have 5 summary cards + const summaryCards = screen.getAllByText(/\d+/, { selector: '.text-2xl.font-bold' }); + expect(summaryCards).toHaveLength(5); // Should have 5 summary cards // Check that we have the expected counts by looking for specific numbers - expect(screen.getAllByText('2', { selector: '.text-2xl.font-bold' })).toHaveLength(3) // Deployments, Services, DaemonSets - expect(screen.getByText('5', { selector: '.text-2xl.font-bold' })).toBeInTheDocument() // Pods count - expect(screen.getByText('3', { selector: '.text-2xl.font-bold' })).toBeInTheDocument() // ReplicaSets count - }) - }) + expect(screen.getAllByText('2', { selector: '.text-2xl.font-bold' })).toHaveLength(3); // Deployments, Services, DaemonSets + expect(screen.getByText('5', { selector: '.text-2xl.font-bold' })).toBeInTheDocument(); // Pods count + expect(screen.getByText('3', { selector: '.text-2xl.font-bold' })).toBeInTheDocument(); // ReplicaSets count + }); + }); it('should handle empty API responses and display zero counts', async () => { // Arrange: Test business logic with empty data @@ -169,18 +156,18 @@ describe('AllResourcesView', () => { createPodsList([]), createDaemonSetsList([]), createReplicaSetsList([]) - ) + ); // Act: Render component - render() + render(); // Assert: Test that the component correctly handles empty arrays await waitFor(() => { - const zeroCounts = screen.getAllByText('0', { selector: '.text-2xl.font-bold' }) - expect(zeroCounts).toHaveLength(5) // All 5 resource types should show 0 - }) - }) - }) + const zeroCounts = screen.getAllByText('0', { selector: '.text-2xl.font-bold' }); + expect(zeroCounts).toHaveLength(5); // All 5 resource types should show 0 + }); + }); + }); describe('Deployment Status Calculation Business Logic', () => { it('should calculate readiness status correctly when all replicas are ready', async () => { @@ -191,25 +178,25 @@ describe('AllResourcesView', () => { createPodsList([]), createDaemonSetsList([]), createReplicaSetsList([]) - ) + ); // Act: Render component - render() + render(); // Assert: Test the business logic - replicas === readyReplicas should show success badge await waitFor(() => { - expect(screen.getByText('3/3 Ready')).toBeInTheDocument() - expect(screen.getByText('1/1 Ready')).toBeInTheDocument() - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - expect(screen.getByText('redis-deployment')).toBeInTheDocument() - expect(screen.getByText('nginx:1.14.2')).toBeInTheDocument() - expect(screen.getByText('redis:5.0.3-alpine')).toBeInTheDocument() - }) - }) + expect(screen.getByText('3/3 Ready')).toBeInTheDocument(); + expect(screen.getByText('1/1 Ready')).toBeInTheDocument(); + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + expect(screen.getByText('redis-deployment')).toBeInTheDocument(); + expect(screen.getByText('nginx:1.14.2')).toBeInTheDocument(); + expect(screen.getByText('redis:5.0.3-alpine')).toBeInTheDocument(); + }); + }); it('should calculate warning status when not all replicas are ready', async () => { // Arrange: Test business logic with partial readiness - const notReadyDeployment = createCustomDeployment('not-ready-deployment', 3, 1, 'nginx:latest') + const notReadyDeployment = createCustomDeployment('not-ready-deployment', 3, 1, 'nginx:latest'); server.use( createDeploymentsList([notReadyDeployment]), @@ -217,18 +204,18 @@ describe('AllResourcesView', () => { createPodsList([]), createDaemonSetsList([]), createReplicaSetsList([]) - ) + ); // Act: Render component - render() + render(); // Assert: Test the business logic - when readyReplicas < replicas, should show warning await waitFor(() => { - expect(screen.getByText('1/3 Ready')).toBeInTheDocument() - expect(screen.getByText('not-ready-deployment')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('1/3 Ready')).toBeInTheDocument(); + expect(screen.getByText('not-ready-deployment')).toBeInTheDocument(); + }); + }); + }); describe('Service Data Processing Business Logic', () => { it('should process service type and port information correctly', async () => { @@ -239,26 +226,26 @@ describe('AllResourcesView', () => { createPodsList([]), createDaemonSetsList([]), createReplicaSetsList([]) - ) + ); // Act: Render component - render() + render(); // Assert: Test the business logic - service type extraction and display await waitFor(() => { - expect(screen.getByText('test-service-1')).toBeInTheDocument() - expect(screen.getByText('test-service-2')).toBeInTheDocument() + expect(screen.getByText('test-service-1')).toBeInTheDocument(); + expect(screen.getByText('test-service-2')).toBeInTheDocument(); // test-service-3 is in kube-system namespace, so won't appear in default namespace - expect(screen.getByText('ClusterIP')).toBeInTheDocument() - expect(screen.getByText('LoadBalancer')).toBeInTheDocument() - expect(screen.getByText('Ports: 80')).toBeInTheDocument() - expect(screen.getByText('Ports: 443')).toBeInTheDocument() - }) - }) + expect(screen.getByText('ClusterIP')).toBeInTheDocument(); + expect(screen.getByText('LoadBalancer')).toBeInTheDocument(); + expect(screen.getByText('Ports: 80')).toBeInTheDocument(); + expect(screen.getByText('Ports: 443')).toBeInTheDocument(); + }); + }); it('should handle multiple ports concatenation logic', async () => { // Arrange: Test business logic for port array processing - const multiPortService = createCustomService('multi-port-service', 'NodePort', [80, 443]) + const multiPortService = createCustomService('multi-port-service', 'NodePort', [80, 443]); server.use( createDeploymentsList([]), @@ -266,18 +253,18 @@ describe('AllResourcesView', () => { createPodsList([]), createDaemonSetsList([]), createReplicaSetsList([]) - ) + ); // Act: Render component - render() + render(); // Assert: Test the business logic - ports array should be joined with commas await waitFor(() => { - expect(screen.getByText('Ports: 80, 443')).toBeInTheDocument() - expect(screen.getByText('NodePort')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('Ports: 80, 443')).toBeInTheDocument(); + expect(screen.getByText('NodePort')).toBeInTheDocument(); + }); + }); + }); describe('Pod Status Processing Business Logic', () => { it('should calculate container readiness and phase status correctly', async () => { @@ -288,29 +275,29 @@ describe('AllResourcesView', () => { createPodsList(), createDaemonSetsList([]), createReplicaSetsList([]) - ) + ); // Act: Render component - render() + render(); // Assert: Test the business logic - pod phase and container status processing await waitFor(() => { - expect(screen.getByText('nginx-pod-1')).toBeInTheDocument() - expect(screen.getByText('redis-pod-1')).toBeInTheDocument() - expect(screen.getByText('pending-pod')).toBeInTheDocument() - expect(screen.getAllByText('Running')).toHaveLength(2) // Two running pods in mock data - expect(screen.getByText('Pending')).toBeInTheDocument() - expect(screen.getByText('Failed')).toBeInTheDocument() - expect(screen.getByText('Succeeded')).toBeInTheDocument() - expect(screen.getAllByText('1/1 Ready')).toHaveLength(2) // Two ready pods (2 Running) - expect(screen.getAllByText('Node: node-1')).toHaveLength(4) // Four pods on node-1 - expect(screen.getAllByText('Node: node-2')).toHaveLength(1) // One pod on node-2 - }) - }) + expect(screen.getByText('nginx-pod-1')).toBeInTheDocument(); + expect(screen.getByText('redis-pod-1')).toBeInTheDocument(); + expect(screen.getByText('pending-pod')).toBeInTheDocument(); + expect(screen.getAllByText('Running')).toHaveLength(2); // Two running pods in mock data + expect(screen.getByText('Pending')).toBeInTheDocument(); + expect(screen.getByText('Failed')).toBeInTheDocument(); + expect(screen.getByText('Succeeded')).toBeInTheDocument(); + expect(screen.getAllByText('1/1 Ready')).toHaveLength(2); // Two ready pods (2 Running) + expect(screen.getAllByText('Node: node-1')).toHaveLength(4); // Four pods on node-1 + expect(screen.getAllByText('Node: node-2')).toHaveLength(1); // One pod on node-2 + }); + }); it('should calculate readiness ratio for multiple containers', async () => { // Arrange: Test business logic for multi-container pods - const multiContainerPod = createCustomPod('multi-container-pod', 'Running', 1, 2, 'worker-2') + const multiContainerPod = createCustomPod('multi-container-pod', 'Running', 1, 2, 'worker-2'); server.use( createDeploymentsList([]), @@ -318,18 +305,18 @@ describe('AllResourcesView', () => { createPodsList([multiContainerPod]), createDaemonSetsList([]), createReplicaSetsList([]) - ) + ); // Act: Render component - render() + render(); // Assert: Test the business logic - ready containers / total containers await waitFor(() => { - expect(screen.getByText('1/2 Ready')).toBeInTheDocument() - expect(screen.getByText('Node: worker-2')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('1/2 Ready')).toBeInTheDocument(); + expect(screen.getByText('Node: worker-2')).toBeInTheDocument(); + }); + }); + }); describe('ReplicaSet Owner Reference Processing Business Logic', () => { it('should process and display owner reference information correctly', async () => { @@ -340,25 +327,25 @@ describe('AllResourcesView', () => { createPodsList([]), createDaemonSetsList([]), createReplicaSetsList() - ) + ); // Act: Render component - render() + render(); // Assert: Test the business logic - owner reference processing and display await waitFor(() => { - expect(screen.getByText('nginx-deployment-1234567890')).toBeInTheDocument() - expect(screen.getByText('redis-deployment-abcdefghij')).toBeInTheDocument() - expect(screen.getByText('3/3 Ready')).toBeInTheDocument() - expect(screen.getByText('1/1 Ready')).toBeInTheDocument() - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - expect(screen.getByText('redis-deployment')).toBeInTheDocument() - }) - }) + expect(screen.getByText('nginx-deployment-1234567890')).toBeInTheDocument(); + expect(screen.getByText('redis-deployment-abcdefghij')).toBeInTheDocument(); + expect(screen.getByText('3/3 Ready')).toBeInTheDocument(); + expect(screen.getByText('1/1 Ready')).toBeInTheDocument(); + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + expect(screen.getByText('redis-deployment')).toBeInTheDocument(); + }); + }); it('should handle ReplicaSets without owner references gracefully', async () => { // Arrange: Test business logic for missing owner references - const standaloneReplicaSet = createCustomReplicaSet('standalone-replicaset', 2, 2, 'nginx:latest') + const standaloneReplicaSet = createCustomReplicaSet('standalone-replicaset', 2, 2, 'nginx:latest'); server.use( createDeploymentsList([]), @@ -366,24 +353,24 @@ describe('AllResourcesView', () => { createPodsList([]), createDaemonSetsList([]), createReplicaSetsList([standaloneReplicaSet]) - ) + ); // Act: Render component - render() + render(); // Assert: Test the business logic - should not crash when ownerReferences is missing await waitFor(() => { - expect(screen.getByText('standalone-replicaset')).toBeInTheDocument() - expect(screen.getByText('2/2 Ready')).toBeInTheDocument() - expect(screen.queryByText('nginx-deployment')).not.toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('standalone-replicaset')).toBeInTheDocument(); + expect(screen.getByText('2/2 Ready')).toBeInTheDocument(); + expect(screen.queryByText('nginx-deployment')).not.toBeInTheDocument(); + }); + }); + }); describe('Refresh All Functionality', () => { it('should trigger API calls when refresh all is clicked', async () => { // Arrange: Setup user interaction and handlers - const user = userEvent.setup() + const user = userEvent.setup(); server.use( createDeploymentsList([]), @@ -391,28 +378,28 @@ describe('AllResourcesView', () => { createPodsList([]), createDaemonSetsList([]), createReplicaSetsList([]) - ) + ); // Act: Render component and trigger refresh - render() + render(); // Wait for initial load await waitFor(() => { - expect(screen.getAllByText('0', { selector: '.text-2xl.font-bold' })).toHaveLength(5) - }) + expect(screen.getAllByText('0', { selector: '.text-2xl.font-bold' })).toHaveLength(5); + }); // Click refresh all - const refreshAllButton = screen.getByRole('button', { name: /refresh all/i }) - await user.click(refreshAllButton) + const refreshAllButton = screen.getByRole('button', { name: /refresh all/i }); + await user.click(refreshAllButton); // Assert: Test that refresh button is clickable and component handles the action - expect(refreshAllButton).toBeInTheDocument() - }) + expect(refreshAllButton).toBeInTheDocument(); + }); it('should maintain data consistency after refresh all', async () => { // Arrange: Setup user interaction - const user = userEvent.setup() - const mockDeployments = [createCustomDeployment('nginx-deployment', 3, 3, 'nginx:1.14.2')] + const user = userEvent.setup(); + const mockDeployments = [createCustomDeployment('nginx-deployment', 3, 3, 'nginx:1.14.2')]; server.use( createDeploymentsList(mockDeployments), @@ -420,29 +407,29 @@ describe('AllResourcesView', () => { createPodsList([]), createDaemonSetsList([]), createReplicaSetsList([]) - ) + ); // Act: Render component and trigger refresh - render() + render(); // Verify initial data is displayed await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); // Click refresh all - const refreshAllButton = screen.getByRole('button', { name: /refresh all/i }) - await user.click(refreshAllButton) + const refreshAllButton = screen.getByRole('button', { name: /refresh all/i }); + await user.click(refreshAllButton); // Assert: Data should still be displayed after refresh - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); + }); describe('Individual Resource Section Refresh', () => { it('should refresh only the specific resource section when its refresh button is clicked', async () => { // Arrange: Setup user interaction - const user = userEvent.setup() + const user = userEvent.setup(); server.use( createDeploymentsList([]), @@ -450,37 +437,37 @@ describe('AllResourcesView', () => { createPodsList([]), createDaemonSetsList([]), createReplicaSetsList([]) - ) + ); // Act: Render component and trigger section refresh - render() + render(); // Wait for initial load await waitFor(() => { - expect(screen.getAllByText('0', { selector: '.text-2xl.font-bold' })).toHaveLength(5) - }) + expect(screen.getAllByText('0', { selector: '.text-2xl.font-bold' })).toHaveLength(5); + }); // Find and click a section refresh button - const refreshButtons = screen.getAllByRole('button') + const refreshButtons = screen.getAllByRole('button'); const sectionRefreshButton = refreshButtons.find(button => button.querySelector('.lucide-refresh-cw') && !button.textContent?.includes('Refresh All') - ) + ); if (sectionRefreshButton) { - await user.click(sectionRefreshButton) + await user.click(sectionRefreshButton); // Assert: Test that section refresh button is clickable - expect(sectionRefreshButton).toBeInTheDocument() + expect(sectionRefreshButton).toBeInTheDocument(); } - }) - }) + }); + }); describe('Resource Section Expansion', () => { it('should toggle section visibility when header is clicked', async () => { // Arrange: Setup user interaction - const user = userEvent.setup() - const mockDeployments = [createCustomDeployment('nginx-deployment', 3, 3, 'nginx:1.14.2')] + const user = userEvent.setup(); + const mockDeployments = [createCustomDeployment('nginx-deployment', 3, 3, 'nginx:1.14.2')]; server.use( createDeploymentsList(mockDeployments), @@ -488,26 +475,26 @@ describe('AllResourcesView', () => { createPodsList([]), createDaemonSetsList([]), createReplicaSetsList([]) - ) + ); // Act: Render component and toggle section - render() + render(); // Wait for data to load await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); // Find the deployments section header - const deploymentHeader = screen.getByText('Deployments', { selector: '.text-lg' }).closest('.cursor-pointer') + const deploymentHeader = screen.getByText('Deployments', { selector: '.text-lg' }).closest('.cursor-pointer'); // Click to toggle - await user.click(deploymentHeader!) + await user.click(deploymentHeader!); // Assert: Verify the click was handled (section should still be in DOM) - expect(deploymentHeader).toBeInTheDocument() - }) - }) + expect(deploymentHeader).toBeInTheDocument(); + }); + }); describe('Error Handling', () => { it('should display error message when API fails', async () => { @@ -518,18 +505,18 @@ describe('AllResourcesView', () => { createPodsList([]), createDaemonSetsList([]), createReplicaSetsList([]) - ) + ); // Act: Render component - render() + render(); // Assert: Test error handling await waitFor(() => { - expect(screen.getByText('Error loading data')).toBeInTheDocument() + expect(screen.getByText('Error loading data')).toBeInTheDocument(); // The error message might be displayed differently, let's check for the error state - expect(screen.getByText('Error loading data')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Error loading data')).toBeInTheDocument(); + }); + }); it('should handle network errors gracefully', async () => { // Arrange: Setup network error @@ -539,20 +526,20 @@ describe('AllResourcesView', () => { createPodsList([]), createDaemonSetsList([]), createReplicaSetsList([]) - ) + ); // Act: Render component - render() + render(); // Assert: Test network error handling await waitFor(() => { - expect(screen.getByText('Error loading data')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Error loading data')).toBeInTheDocument(); + }); + }); it('should handle partial API failures', async () => { // Arrange: Some APIs succeed, some fail - const testService = createCustomService('test-service', 'ClusterIP', [80]) + const testService = createCustomService('test-service', 'ClusterIP', [80]); server.use( createDeploymentsListError(500, 'Deployments API failed'), @@ -560,22 +547,22 @@ describe('AllResourcesView', () => { createPodsList([]), createDaemonSetsList([]), createReplicaSetsList([]) - ) + ); // Act: Render component - render() + render(); // Assert: Test partial failure handling await waitFor(() => { // Should show error for deployments - expect(screen.getByText('Error loading data')).toBeInTheDocument() + expect(screen.getByText('Error loading data')).toBeInTheDocument(); // But services should still work - expect(screen.getByText('test-service')).toBeInTheDocument() + expect(screen.getByText('test-service')).toBeInTheDocument(); // Services count should still be displayed - expect(screen.getByText('1', { selector: '.text-2xl.font-bold' })).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('1', { selector: '.text-2xl.font-bold' })).toBeInTheDocument(); + }); + }); + }); describe('Loading States', () => { it('should show loading state during API calls', async () => { @@ -586,20 +573,20 @@ describe('AllResourcesView', () => { createPodsList([]), createDaemonSetsList([]), createReplicaSetsList([]) - ) + ); // Act: Render component - render() + render(); // Assert: Test loading state - check for loading text in card descriptions - expect(screen.getAllByText('Loading...')).toHaveLength(5) // All 5 resource sections should show loading + expect(screen.getAllByText('Loading...')).toHaveLength(5); // All 5 resource sections should show loading // Wait for data to load await waitFor(() => { - expect(screen.getAllByText('0 items')).toHaveLength(5) // All sections should show "0 items" - }) - }) - }) + expect(screen.getAllByText('0 items')).toHaveLength(5); // All sections should show "0 items" + }); + }); + }); describe('Badge Status Logic', () => { it('should show correct badge variants based on resource status', async () => { @@ -608,7 +595,7 @@ describe('AllResourcesView', () => { createCustomPod('running-pod', 'Running', 1, 1, 'worker-1'), createCustomPod('pending-pod', 'Pending', 0, 1, 'worker-1'), createCustomPod('failed-pod', 'Failed', 0, 1, 'worker-1') - ] + ]; server.use( createDeploymentsList([]), @@ -616,19 +603,19 @@ describe('AllResourcesView', () => { createPodsList(mockPods), createDaemonSetsList([]), createReplicaSetsList([]) - ) + ); // Act: Render component - render() + render(); // Assert: Test different pod statuses await waitFor(() => { - expect(screen.getByText('Running')).toBeInTheDocument() - expect(screen.getByText('Pending')).toBeInTheDocument() - expect(screen.getByText('Failed')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('Running')).toBeInTheDocument(); + expect(screen.getByText('Pending')).toBeInTheDocument(); + expect(screen.getByText('Failed')).toBeInTheDocument(); + }); + }); + }); describe('Accessibility', () => { it('should have proper button roles and labels', async () => { @@ -639,22 +626,22 @@ describe('AllResourcesView', () => { createPodsList([]), createDaemonSetsList([]), createReplicaSetsList([]) - ) + ); // Act: Render component - render() + render(); // Assert: Test accessibility await waitFor(() => { - expect(screen.getByRole('button', { name: /refresh all/i })).toBeInTheDocument() - const refreshButtons = screen.getAllByRole('button') - expect(refreshButtons.length).toBeGreaterThan(0) - }) - }) + expect(screen.getByRole('button', { name: /refresh all/i })).toBeInTheDocument(); + const refreshButtons = screen.getAllByRole('button'); + expect(refreshButtons.length).toBeGreaterThan(0); + }); + }); it('should be keyboard navigable', async () => { // Arrange: Setup user interaction - const user = userEvent.setup() + const user = userEvent.setup(); server.use( createDeploymentsList([]), @@ -662,20 +649,20 @@ describe('AllResourcesView', () => { createPodsList([]), createDaemonSetsList([]), createReplicaSetsList([]) - ) + ); // Act: Render component and test keyboard navigation - render() + render(); await waitFor(() => { - expect(screen.getAllByText('0', { selector: '.text-2xl.font-bold' })).toHaveLength(5) - }) + expect(screen.getAllByText('0', { selector: '.text-2xl.font-bold' })).toHaveLength(5); + }); - const refreshAllButton = screen.getByRole('button', { name: /refresh all/i }) - await user.tab() + const refreshAllButton = screen.getByRole('button', { name: /refresh all/i }); + await user.tab(); // Assert: Test keyboard navigation - expect(refreshAllButton).toHaveFocus() - }) - }) -}) \ No newline at end of file + expect(refreshAllButton).toHaveFocus(); + }); + }); +}); \ No newline at end of file diff --git a/apps/ops-dashboard/__tests__/components/resources/configmaps.test.tsx b/apps/ops-dashboard/__tests__/components/resources/configmaps.test.tsx index b5e000e..a38a48b 100644 --- a/apps/ops-dashboard/__tests__/components/resources/configmaps.test.tsx +++ b/apps/ops-dashboard/__tests__/components/resources/configmaps.test.tsx @@ -1,21 +1,20 @@ -import { render, screen, waitFor, fireEvent, act } from '../../utils/test-utils'; import userEvent from '@testing-library/user-event'; -import { server } from '@/__mocks__/server'; +import { http, HttpResponse } from 'msw'; + import { - createConfigMapsList, + createConfigMapDelete, + createConfigMapDeleteError, + createConfigMapsList, createConfigMapsListError, createConfigMapsListSlow, - createConfigMapsListData, createConfigMapUpdate, - createConfigMapUpdateError, - createConfigMapDelete, - createConfigMapDeleteError -} from '@/__mocks__/handlers/configmaps'; -import { http, HttpResponse } from 'msw'; - + createConfigMapUpdateError} from '@/__mocks__/handlers/configmaps'; +import { server } from '@/__mocks__/server'; // Import the component import { ConfigMapsView } from '@/components/resources/configmaps'; +import {fireEvent, render, screen, waitFor } from '../../utils/test-utils'; + // Mock window.alert for testing error messages const mockAlert = jest.spyOn(window, 'alert').mockImplementation(() => {}); diff --git a/apps/ops-dashboard/__tests__/components/resources/cronjobs.test.tsx b/apps/ops-dashboard/__tests__/components/resources/cronjobs.test.tsx index d12639d..8484e13 100644 --- a/apps/ops-dashboard/__tests__/components/resources/cronjobs.test.tsx +++ b/apps/ops-dashboard/__tests__/components/resources/cronjobs.test.tsx @@ -1,396 +1,397 @@ -import React from 'react' -import { render, screen, waitFor } from '../../utils/test-utils' -import userEvent from '@testing-library/user-event' -import { CronJobsView } from '../../../components/resources/cronjobs' -import { server } from '@/__mocks__/server' +import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { server } from '@/__mocks__/server'; + import { - createCronJobsList, createAllCronJobsList, - createCronJobsListError, - createCronJobsListSlow, - createCronJobsListData, createCronJobDelete, - createCronJobPatch -} from '../../../__mocks__/handlers/cronjobs' + createCronJobPatch, + createCronJobsList, + createCronJobsListData, + createCronJobsListError, + createCronJobsListSlow} from '../../../__mocks__/handlers/cronjobs'; +import { CronJobsView } from '../../../components/resources/cronjobs'; +import { render, screen, waitFor } from '../../utils/test-utils'; // Mock the confirmDialog function jest.mock('../../../hooks/useConfirm', () => ({ ...jest.requireActual('../../../hooks/useConfirm'), confirmDialog: jest.fn() -})) +})); -const mockPrompt = jest.fn() -const mockAlert = jest.fn() +const mockPrompt = jest.fn(); +const mockAlert = jest.fn(); beforeAll(() => { - jest.spyOn(window, 'prompt').mockImplementation(mockPrompt) - jest.spyOn(window, 'alert').mockImplementation(mockAlert) -}) + jest.spyOn(window, 'prompt').mockImplementation(mockPrompt); + jest.spyOn(window, 'alert').mockImplementation(mockAlert); +}); afterEach(() => { - server.resetHandlers() - mockPrompt.mockClear() - mockAlert.mockClear() -}) + server.resetHandlers(); + mockPrompt.mockClear(); + mockAlert.mockClear(); +}); afterAll(() => { - jest.restoreAllMocks() -}) + jest.restoreAllMocks(); +}); describe('CronJobsView', () => { describe('Basic Rendering', () => { it('should render cronjobs view with header', () => { - server.use(createCronJobsList()) - render() + server.use(createCronJobsList()); + render(); - expect(screen.getByRole('heading', { name: 'CronJobs' })).toBeInTheDocument() - expect(screen.getByText('Manage your Kubernetes scheduled jobs')).toBeInTheDocument() - }) + expect(screen.getByRole('heading', { name: 'CronJobs' })).toBeInTheDocument(); + expect(screen.getByText('Manage your Kubernetes scheduled jobs')).toBeInTheDocument(); + }); it('should render refresh and create buttons', () => { - server.use(createCronJobsList()) - render() + server.use(createCronJobsList()); + render(); - expect(screen.getAllByRole('button', { name: '' })[0]).toBeInTheDocument() // Refresh button - expect(screen.getByRole('button', { name: /create cronjob/i })).toBeInTheDocument() - }) + expect(screen.getAllByRole('button', { name: '' })[0]).toBeInTheDocument(); // Refresh button + expect(screen.getByRole('button', { name: /create cronjob/i })).toBeInTheDocument(); + }); it('should render stats cards', () => { - server.use(createCronJobsList()) - render() + server.use(createCronJobsList()); + render(); - expect(screen.getByText('Total CronJobs')).toBeInTheDocument() - expect(screen.getByText('Active')).toBeInTheDocument() - expect(screen.getByText('Suspended')).toBeInTheDocument() - expect(screen.getByText('Running Jobs')).toBeInTheDocument() - }) + expect(screen.getByText('Total CronJobs')).toBeInTheDocument(); + expect(screen.getByText('Active')).toBeInTheDocument(); + expect(screen.getByText('Suspended')).toBeInTheDocument(); + expect(screen.getByText('Running Jobs')).toBeInTheDocument(); + }); it('should render table with correct headers', async () => { - server.use(createCronJobsList()) - render() + server.use(createCronJobsList()); + render(); await waitFor(() => { - expect(screen.getByRole('columnheader', { name: 'Name' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Namespace' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Status' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Schedule' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Last Run' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Next Run' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Image' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Actions' })).toBeInTheDocument() - }) - }) - }) + expect(screen.getByRole('columnheader', { name: 'Name' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Namespace' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Status' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Schedule' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Last Run' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Next Run' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Image' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Actions' })).toBeInTheDocument(); + }); + }); + }); describe('Data Loading and Display', () => { it('should display cronjobs data correctly', async () => { - server.use(createCronJobsList()) - render() + server.use(createCronJobsList()); + render(); await waitFor(() => { - expect(screen.getByText('backup-cronjob')).toBeInTheDocument() - expect(screen.getByText('cleanup-cronjob')).toBeInTheDocument() - expect(screen.getAllByText('default')).toHaveLength(2) // Two cronjobs in default namespace - expect(screen.getByText('postgres:13')).toBeInTheDocument() - expect(screen.getByText('alpine:latest')).toBeInTheDocument() - }) - }) + expect(screen.getByText('backup-cronjob')).toBeInTheDocument(); + expect(screen.getByText('cleanup-cronjob')).toBeInTheDocument(); + expect(screen.getAllByText('default')).toHaveLength(2); // Two cronjobs in default namespace + expect(screen.getByText('postgres:13')).toBeInTheDocument(); + expect(screen.getByText('alpine:latest')).toBeInTheDocument(); + }); + }); it('should display correct statistics', async () => { - server.use(createCronJobsList()) - render() + server.use(createCronJobsList()); + render(); await waitFor(() => { - expect(screen.getByText('2')).toBeInTheDocument() // Total CronJobs in default namespace - expect(screen.getAllByText('1')).toHaveLength(2) // Active count and Running Jobs count - expect(screen.getByText('0')).toBeInTheDocument() // Suspended count - }) - }) + expect(screen.getByText('2')).toBeInTheDocument(); // Total CronJobs in default namespace + expect(screen.getAllByText('1')).toHaveLength(2); // Active count and Running Jobs count + expect(screen.getByText('0')).toBeInTheDocument(); // Suspended count + }); + }); it('should display status badges correctly', async () => { - server.use(createCronJobsList()) - render() + server.use(createCronJobsList()); + render(); await waitFor(() => { - expect(screen.getAllByText('Active')).toHaveLength(2) // Header + badge - expect(screen.getByText('Idle')).toBeInTheDocument() - }) - }) + expect(screen.getAllByText('Active')).toHaveLength(2); // Header + badge + expect(screen.getByText('Idle')).toBeInTheDocument(); + }); + }); it('should display schedule correctly', async () => { - server.use(createCronJobsList()) - render() + server.use(createCronJobsList()); + render(); await waitFor(() => { - expect(screen.getByText('0 2 * * *')).toBeInTheDocument() // backup-cronjob schedule - expect(screen.getByText('0 0 * * 0')).toBeInTheDocument() // cleanup-cronjob schedule - }) - }) + expect(screen.getByText('0 2 * * *')).toBeInTheDocument(); // backup-cronjob schedule + expect(screen.getByText('0 0 * * 0')).toBeInTheDocument(); // cleanup-cronjob schedule + }); + }); it('should display last run time correctly', async () => { - server.use(createCronJobsList()) - render() + server.use(createCronJobsList()); + render(); await waitFor(() => { // Last run time should be displayed (either "ago" format or date) - expect(screen.getAllByText(/ago|Just now|\d+\/\d+\/\d+/)).toHaveLength(2) // Two cronjobs - }) - }) + expect(screen.getAllByText(/ago|Just now|\d+\/\d+\/\d+/)).toHaveLength(2); // Two cronjobs + }); + }); it('should display next run time correctly', async () => { - server.use(createCronJobsList()) - render() + server.use(createCronJobsList()); + render(); await waitFor(() => { - expect(screen.getAllByText('Calculating...')).toHaveLength(2) // Next run time for both cronjobs - }) - }) - }) + expect(screen.getAllByText('Calculating...')).toHaveLength(2); // Next run time for both cronjobs + }); + }); + }); describe('Loading States', () => { it('should show loading spinner when loading', () => { - server.use(createCronJobsListSlow()) - render() + server.use(createCronJobsListSlow()); + render(); - expect(document.querySelector('svg.lucide-refresh-cw.animate-spin')).toBeInTheDocument() - }) + expect(document.querySelector('svg.lucide-refresh-cw.animate-spin')).toBeInTheDocument(); + }); it('should disable refresh button when loading', () => { - server.use(createCronJobsListSlow()) - render() + server.use(createCronJobsListSlow()); + render(); - const refreshButton = screen.getAllByRole('button', { name: '' })[0] - expect(refreshButton).toBeDisabled() - }) - }) + const refreshButton = screen.getAllByRole('button', { name: '' })[0]; + expect(refreshButton).toBeDisabled(); + }); + }); describe('Error States', () => { it('should display error message when fetch fails', async () => { - server.use(createCronJobsListError(500, 'Server Error')) - render() + server.use(createCronJobsListError(500, 'Server Error')); + render(); await waitFor(() => { - expect(screen.getByText(/Server Error/)).toBeInTheDocument() - expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument() - }) - }) + expect(screen.getByText(/Server Error/)).toBeInTheDocument(); + expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument(); + }); + }); it('should show retry button in error state', async () => { - server.use(createCronJobsListError()) - render() + server.use(createCronJobsListError()); + render(); await waitFor(() => { - expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument() - }) - }) - }) + expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument(); + }); + }); + }); describe('Empty States', () => { it('should display empty state when no cronjobs', async () => { - server.use(createCronJobsList([])) - render() + server.use(createCronJobsList([])); + render(); await waitFor(() => { - expect(screen.getByText('No cronjobs found')).toBeInTheDocument() - expect(screen.getByRole('button', { name: /refresh/i })).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('No cronjobs found')).toBeInTheDocument(); + expect(screen.getByRole('button', { name: /refresh/i })).toBeInTheDocument(); + }); + }); + }); describe('User Interactions', () => { it('should refresh data when refresh button is clicked', async () => { - const user = userEvent.setup() - const cronjobs = createCronJobsListData() - server.use(createCronJobsList(cronjobs)) - render() + const user = userEvent.setup(); + const cronjobs = createCronJobsListData(); + server.use(createCronJobsList(cronjobs)); + render(); await waitFor(() => { - expect(screen.getByText('backup-cronjob')).toBeInTheDocument() - }) + expect(screen.getByText('backup-cronjob')).toBeInTheDocument(); + }); // Simulate new data after refresh const newCronJobs = [...cronjobs, { metadata: { name: 'new-cronjob', namespace: 'default', uid: 'cronjob-4', creationTimestamp: '2024-01-15T13:00:00Z' }, spec: { schedule: '0 0 * * *', suspend: false, jobTemplate: { spec: { template: { metadata: { labels: { app: 'new' } }, spec: { containers: [{ name: 'new', image: 'new:latest' }], restartPolicy: 'Never' } } } } }, status: { active: [] } - }] - server.use(createCronJobsList(newCronJobs)) + }]; + server.use(createCronJobsList(newCronJobs)); - const refreshButton = screen.getAllByRole('button', { name: '' })[0] - await user.click(refreshButton) + const refreshButton = screen.getAllByRole('button', { name: '' })[0]; + await user.click(refreshButton); await waitFor(() => { - expect(screen.getByText('new-cronjob')).toBeInTheDocument() - }) - }) + expect(screen.getByText('new-cronjob')).toBeInTheDocument(); + }); + }); it('should show create cronjob alert when create button is clicked', async () => { - const user = userEvent.setup() - server.use(createCronJobsList()) - render() + const user = userEvent.setup(); + server.use(createCronJobsList()); + render(); - const createButton = screen.getByRole('button', { name: /create cronjob/i }) - await user.click(createButton) + const createButton = screen.getByRole('button', { name: /create cronjob/i }); + await user.click(createButton); - expect(window.alert).toHaveBeenCalledWith('Create CronJob functionality not yet implemented') - }) + expect(window.alert).toHaveBeenCalledWith('Create CronJob functionality not yet implemented'); + }); it('should show delete confirmation when delete button is clicked', async () => { - const user = userEvent.setup() - const { confirmDialog } = require('../../../hooks/useConfirm') - confirmDialog.mockResolvedValue(true) + const user = userEvent.setup(); + const { confirmDialog } = require('../../../hooks/useConfirm'); + confirmDialog.mockResolvedValue(true); - server.use(createCronJobsList(), createCronJobDelete()) - render() + server.use(createCronJobsList(), createCronJobDelete()); + render(); await waitFor(() => { - expect(screen.getByText('backup-cronjob')).toBeInTheDocument() - }) + expect(screen.getByText('backup-cronjob')).toBeInTheDocument(); + }); const deleteButton = screen.getAllByRole('button').find(button => button.querySelector('svg.lucide-trash2') - ) - expect(deleteButton).toBeInTheDocument() + ); + expect(deleteButton).toBeInTheDocument(); if (deleteButton) { - await user.click(deleteButton) + await user.click(deleteButton); expect(confirmDialog).toHaveBeenCalledWith({ title: 'Delete CronJob', description: 'Are you sure you want to delete backup-cronjob?', confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); } - }) + }); it('should show view button when view button is clicked', async () => { - const user = userEvent.setup() - server.use(createCronJobsList()) - render() + const user = userEvent.setup(); + server.use(createCronJobsList()); + render(); await waitFor(() => { - expect(screen.getByText('backup-cronjob')).toBeInTheDocument() - }) + expect(screen.getByText('backup-cronjob')).toBeInTheDocument(); + }); const viewButton = screen.getAllByRole('button').find(button => button.querySelector('svg.lucide-eye') - ) - expect(viewButton).toBeInTheDocument() + ); + expect(viewButton).toBeInTheDocument(); if (viewButton) { - await user.click(viewButton) + await user.click(viewButton); // View functionality sets selectedCronJob state // This is tested indirectly through the component's internal state } - }) + }); it('should toggle suspend when suspend/unsuspend button is clicked', async () => { - const user = userEvent.setup() - server.use(createCronJobsList(), createCronJobPatch()) - render() + const user = userEvent.setup(); + server.use(createCronJobsList(), createCronJobPatch()); + render(); await waitFor(() => { - expect(screen.getByText('backup-cronjob')).toBeInTheDocument() - }) + expect(screen.getByText('backup-cronjob')).toBeInTheDocument(); + }); const suspendButton = screen.getAllByRole('button').find(button => button.querySelector('svg.lucide-pause') - ) - expect(suspendButton).toBeInTheDocument() + ); + expect(suspendButton).toBeInTheDocument(); if (suspendButton) { - await user.click(suspendButton) + await user.click(suspendButton); // Toggle suspend functionality // This is tested indirectly through the component's internal state } - }) - }) + }); + }); describe('Status Logic', () => { it('should show Active status when cronjob has active jobs', async () => { - server.use(createCronJobsList()) - render() + server.use(createCronJobsList()); + render(); await waitFor(() => { - expect(screen.getByText('Active')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Active')).toBeInTheDocument(); + }); + }); it('should show Idle status when cronjob has no active jobs', async () => { - server.use(createCronJobsList()) - render() + server.use(createCronJobsList()); + render(); await waitFor(() => { - expect(screen.getByText('Idle')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Idle')).toBeInTheDocument(); + }); + }); it('should show Suspended status when cronjob is suspended', async () => { - const cronjobs = createCronJobsListData() + const cronjobs = createCronJobsListData(); // Add a suspended cronjob to the list const suspendedCronJob = { metadata: { name: 'test-suspended-cronjob', namespace: 'default', uid: 'cronjob-suspended', creationTimestamp: '2024-01-15T14:00:00Z' }, spec: { schedule: '0 0 * * *', suspend: true, jobTemplate: { spec: { template: { metadata: { labels: { app: 'suspended' } }, spec: { containers: [{ name: 'suspended', image: 'suspended:latest' }], restartPolicy: 'Never' } } } } }, status: { active: [] } - } - server.use(createCronJobsList([...cronjobs, suspendedCronJob])) - render() + }; + server.use(createCronJobsList([...cronjobs, suspendedCronJob])); + render(); await waitFor(() => { - expect(screen.getByText('Suspended')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('Suspended')).toBeInTheDocument(); + }); + }); + }); describe('All Namespaces Mode', () => { it('should show all cronjobs when in all namespaces mode', async () => { // This test is simplified due to mock complexity // In a real scenario, the component would use useListBatchV1CronJobForAllNamespacesQuery - server.use(createAllCronJobsList()) - render() + server.use(createAllCronJobsList()); + render(); // The component will still use the default namespace context // This test verifies the handler works correctly await waitFor(() => { - expect(screen.getByText('Network request failed')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('Network request failed')).toBeInTheDocument(); + }); + }); + }); describe('Accessibility', () => { it('should have proper button roles and labels', () => { - server.use(createCronJobsList()) - render() + server.use(createCronJobsList()); + render(); - expect(screen.getByRole('button', { name: /create cronjob/i })).toBeInTheDocument() - expect(screen.getAllByRole('button', { name: '' })[0]).toBeInTheDocument() // Refresh button - }) + expect(screen.getByRole('button', { name: /create cronjob/i })).toBeInTheDocument(); + expect(screen.getAllByRole('button', { name: '' })[0]).toBeInTheDocument(); // Refresh button + }); it('should have proper table structure', async () => { - server.use(createCronJobsList()) - render() + server.use(createCronJobsList()); + render(); await waitFor(() => { - expect(screen.getByRole('table')).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Name' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Namespace' })).toBeInTheDocument() - }) - }) + expect(screen.getByRole('table')).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Name' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Namespace' })).toBeInTheDocument(); + }); + }); it('should be keyboard navigable', async () => { - const user = userEvent.setup() - server.use(createCronJobsList()) - render() + const user = userEvent.setup(); + server.use(createCronJobsList()); + render(); - const createButton = screen.getByRole('button', { name: /create cronjob/i }) - createButton.focus() + const createButton = screen.getByRole('button', { name: /create cronjob/i }); + createButton.focus(); - expect(document.activeElement).toBe(createButton) + expect(document.activeElement).toBe(createButton); // Test that tab navigation works - await user.tab() + await user.tab(); // The focus should move to the next focusable element - expect(document.activeElement).not.toBe(createButton) - }) - }) -}) + expect(document.activeElement).not.toBe(createButton); + }); + }); +}); diff --git a/apps/ops-dashboard/__tests__/components/resources/daemonsets.test.tsx b/apps/ops-dashboard/__tests__/components/resources/daemonsets.test.tsx index e6d5d29..87f3564 100644 --- a/apps/ops-dashboard/__tests__/components/resources/daemonsets.test.tsx +++ b/apps/ops-dashboard/__tests__/components/resources/daemonsets.test.tsx @@ -1,118 +1,119 @@ -import React from 'react' -import { render, screen, waitFor, fireEvent } from '../../utils/test-utils' -import userEvent from '@testing-library/user-event' -import { DaemonSetsView } from '@/components/resources/daemonsets' -import { server } from '../../../__mocks__/server' +import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { DaemonSetsView } from '@/components/resources/daemonsets'; + import { + createDaemonSetDelete, + createDaemonSetDeleteError, createDaemonSetsList, createDaemonSetsListError, - createDaemonSetsListSlow, - createDaemonSetDelete, - createDaemonSetDeleteError -} from '../../../__mocks__/handlers/daemonsets' + createDaemonSetsListSlow} from '../../../__mocks__/handlers/daemonsets'; +import { server } from '../../../__mocks__/server'; +import { fireEvent,render, screen, waitFor } from '../../utils/test-utils'; // Mock window.alert for testing error messages -const mockAlert = jest.spyOn(window, 'alert').mockImplementation(() => {}) +const mockAlert = jest.spyOn(window, 'alert').mockImplementation(() => {}); describe('DaemonSetsView', () => { beforeEach(() => { - jest.clearAllMocks() - server.use(createDaemonSetsList(), createDaemonSetDelete()) - }) + jest.clearAllMocks(); + server.use(createDaemonSetsList(), createDaemonSetDelete()); + }); afterEach(() => { - mockAlert.mockClear() - }) + mockAlert.mockClear(); + }); describe('Basic Rendering', () => { it('should render daemonsets view with header and controls', () => { - render() + render(); - expect(screen.getByText('DaemonSets')).toBeInTheDocument() - expect(screen.getByText('Manage your Kubernetes DaemonSets')).toBeInTheDocument() - expect(screen.getByRole('button', { name: /create daemonset/i })).toBeInTheDocument() - }) + expect(screen.getByText('DaemonSets')).toBeInTheDocument(); + expect(screen.getByText('Manage your Kubernetes DaemonSets')).toBeInTheDocument(); + expect(screen.getByRole('button', { name: /create daemonset/i })).toBeInTheDocument(); + }); it('should display daemonsets data when loaded', async () => { - render() + render(); await waitFor(() => { - expect(screen.getByText('nginx-daemonset')).toBeInTheDocument() - expect(screen.getByText('redis-daemonset')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-daemonset')).toBeInTheDocument(); + expect(screen.getByText('redis-daemonset')).toBeInTheDocument(); + }); // Check for total daemonsets count (only 2 in default namespace) - expect(screen.getByText('Total DaemonSets')).toBeInTheDocument() + expect(screen.getByText('Total DaemonSets')).toBeInTheDocument(); const totalCard = screen.getByText('Total DaemonSets').closest('.rounded-lg'); expect(totalCard).toBeInTheDocument(); expect(totalCard).toHaveTextContent('2'); - }) + }); it('should show loading state initially', () => { - render() + render(); - expect(screen.getByRole('button', { name: '' })).toBeInTheDocument() // Refresh button - expect(screen.getByRole('button', { name: /create daemonset/i })).toBeInTheDocument() - }) - }) + expect(screen.getByRole('button', { name: '' })).toBeInTheDocument(); // Refresh button + expect(screen.getByRole('button', { name: /create daemonset/i })).toBeInTheDocument(); + }); + }); describe('Data Loading', () => { it('should load daemonsets from API', async () => { - render() + render(); await waitFor(() => { - expect(screen.getByText('nginx-daemonset')).toBeInTheDocument() - expect(screen.getByText('redis-daemonset')).toBeInTheDocument() - }) - }) + expect(screen.getByText('nginx-daemonset')).toBeInTheDocument(); + expect(screen.getByText('redis-daemonset')).toBeInTheDocument(); + }); + }); it('should handle loading state with slow API response', async () => { - server.use(createDaemonSetsListSlow()) + server.use(createDaemonSetsListSlow()); - render() + render(); // Should show loading initially - expect(screen.getByRole('button', { name: '' })).toBeInTheDocument() // Refresh button - expect(screen.getByRole('button', { name: /create daemonset/i })).toBeInTheDocument() - expect(screen.getByText('Total DaemonSets')).toBeInTheDocument() - expect(screen.getByText('Ready')).toBeInTheDocument() - expect(screen.getByText('Total Pods')).toBeInTheDocument() - expect(screen.getAllByText('0')).toHaveLength(3) // Initial count before data loads + expect(screen.getByRole('button', { name: '' })).toBeInTheDocument(); // Refresh button + expect(screen.getByRole('button', { name: /create daemonset/i })).toBeInTheDocument(); + expect(screen.getByText('Total DaemonSets')).toBeInTheDocument(); + expect(screen.getByText('Ready')).toBeInTheDocument(); + expect(screen.getByText('Total Pods')).toBeInTheDocument(); + expect(screen.getAllByText('0')).toHaveLength(3); // Initial count before data loads await waitFor(() => { - expect(screen.getByText('nginx-daemonset')).toBeInTheDocument() - }, { timeout: 2000 }) - }) + expect(screen.getByText('nginx-daemonset')).toBeInTheDocument(); + }, { timeout: 2000 }); + }); it('should handle API errors gracefully', async () => { - server.use(createDaemonSetsListError(500, 'HTTP error! status: 500')) + server.use(createDaemonSetsListError(500, 'HTTP error! status: 500')); - render() + render(); await waitFor(() => { - expect(screen.getByText(/HTTP error! status: 500/)).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText(/HTTP error! status: 500/)).toBeInTheDocument(); + }); + }); + }); describe('DaemonSet Status Display', () => { it('should display daemonset status correctly', async () => { - render() + render(); await waitFor(() => { - expect(screen.getByText('nginx-daemonset')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-daemonset')).toBeInTheDocument(); + }); - expect(screen.getByText('nginx-daemonset').closest('tr')).toHaveTextContent('Ready') - expect(screen.getByText('redis-daemonset').closest('tr')).toHaveTextContent('Ready') - }) + expect(screen.getByText('nginx-daemonset').closest('tr')).toHaveTextContent('Ready'); + expect(screen.getByText('redis-daemonset').closest('tr')).toHaveTextContent('Ready'); + }); it('should show correct pod counts', async () => { - render() + render(); await waitFor(() => { - expect(screen.getByText('nginx-daemonset')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-daemonset')).toBeInTheDocument(); + }); // Find the Ready card by looking for the h3 element with "Ready" text const readyCard = screen.getByRole('heading', { name: 'Ready' }).closest('.rounded-lg'); @@ -122,40 +123,40 @@ describe('DaemonSetsView', () => { const totalPodsCard = screen.getByText('Total Pods').closest('.rounded-lg'); expect(totalPodsCard).toBeInTheDocument(); expect(totalPodsCard).toHaveTextContent('5'); // Total Pods: 5 (3+2) - }) - }) + }); + }); describe('Button Functionality', () => { it('should have create daemonset button', async () => { - render() + render(); - const createButton = screen.getByRole('button', { name: /create daemonset/i }) - expect(createButton).toBeInTheDocument() - }) + const createButton = screen.getByRole('button', { name: /create daemonset/i }); + expect(createButton).toBeInTheDocument(); + }); it('should have action buttons for each daemonset', async () => { - render() + render(); await waitFor(() => { - expect(screen.getByText('nginx-daemonset')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-daemonset')).toBeInTheDocument(); + }); - const viewButtons = screen.getAllByTitle('View details') - const deleteButtons = screen.getAllByTitle('Delete daemonset') + const viewButtons = screen.getAllByTitle('View details'); + const deleteButtons = screen.getAllByTitle('Delete daemonset'); - expect(viewButtons).toHaveLength(2) - expect(deleteButtons).toHaveLength(2) - }) - }) + expect(viewButtons).toHaveLength(2); + expect(deleteButtons).toHaveLength(2); + }); + }); describe('Refresh Functionality', () => { it('should refresh data when refresh button is clicked', async () => { - const user = userEvent.setup() - render() + const user = userEvent.setup(); + render(); await waitFor(() => { - expect(screen.getByText('nginx-daemonset')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-daemonset')).toBeInTheDocument(); + }); server.use(createDaemonSetsList([ { @@ -163,51 +164,51 @@ describe('DaemonSetsView', () => { spec: { selector: { matchLabels: { app: 'new' } }, template: { metadata: { labels: { app: 'new' } }, spec: { containers: [{ name: 'new', image: 'new:latest' }] } } }, status: { currentNumberScheduled: 1, numberReady: 1, desiredNumberScheduled: 1, numberAvailable: 1 } } - ])) + ])); - const refreshButton = screen.getAllByRole('button', { name: '' })[0] - await user.click(refreshButton) + const refreshButton = screen.getAllByRole('button', { name: '' })[0]; + await user.click(refreshButton); await waitFor(() => { - expect(screen.getByText('new-daemonset')).toBeInTheDocument() - expect(screen.queryByText('nginx-daemonset')).not.toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('new-daemonset')).toBeInTheDocument(); + expect(screen.queryByText('nginx-daemonset')).not.toBeInTheDocument(); + }); + }); + }); describe('Error Handling', () => { it('should show error message when API fails', async () => { - server.use(createDaemonSetsListError(500, 'HTTP error! status: 500')) + server.use(createDaemonSetsListError(500, 'HTTP error! status: 500')); - render() + render(); await waitFor(() => { - expect(screen.getByText(/HTTP error! status: 500/)).toBeInTheDocument() - }) - }) + expect(screen.getByText(/HTTP error! status: 500/)).toBeInTheDocument(); + }); + }); it('should show retry button when there is an error', async () => { - server.use(createDaemonSetsListError(500, 'HTTP error! status: 500')) + server.use(createDaemonSetsListError(500, 'HTTP error! status: 500')); - render() + render(); await waitFor(() => { - expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument() - }) - }) - }) + expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument(); + }); + }); + }); describe('Empty State', () => { it('should show empty state when no daemonsets exist', async () => { - server.use(createDaemonSetsList([])) + server.use(createDaemonSetsList([])); - render() + render(); await waitFor(() => { - expect(screen.getByText(/No daemonsets found in the default namespace/)).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText(/No daemonsets found in the default namespace/)).toBeInTheDocument(); + }); + }); + }); describe('Status Determination', () => { it('should determine daemonset status correctly for different states', async () => { @@ -526,4 +527,4 @@ describe('DaemonSetsView', () => { expect(refreshButton).not.toBeDisabled(); }); }); -}) \ No newline at end of file +}); \ No newline at end of file diff --git a/apps/ops-dashboard/__tests__/components/resources/deployments.test.tsx b/apps/ops-dashboard/__tests__/components/resources/deployments.test.tsx index 92a86aa..f46e849 100644 --- a/apps/ops-dashboard/__tests__/components/resources/deployments.test.tsx +++ b/apps/ops-dashboard/__tests__/components/resources/deployments.test.tsx @@ -1,38 +1,38 @@ -import React from 'react' -import { render, screen, waitFor, fireEvent } from '@/__tests__/utils/test-utils' -import userEvent from '@testing-library/user-event' -import { DeploymentsView } from '@/components/resources/deployments' -import { server } from '@/__mocks__/server' -import { confirmDialog } from '@/hooks/useConfirm' +import userEvent from '@testing-library/user-event'; +import React from 'react'; + import { + createDeploymentByName, + createDeploymentErrorHandler, + createDeploymentHandler, createDeploymentsList, + createDeploymentsListData, createDeploymentsListError, createDeploymentsListSlow, - createDeploymentHandler, - createDeploymentErrorHandler, - deleteDeploymentHandler, deleteDeploymentErrorHandler, - updateDeploymentHandler, - updateDeploymentErrorHandler, - scaleDeploymentHandler, + deleteDeploymentHandler, scaleDeploymentErrorHandler, - createDeploymentByName, - createDeploymentsListData -} from '@/__mocks__/handlers/deployments' + scaleDeploymentHandler, + updateDeploymentErrorHandler, + updateDeploymentHandler} from '@/__mocks__/handlers/deployments'; +import { server } from '@/__mocks__/server'; +import { fireEvent,render, screen, waitFor } from '@/__tests__/utils/test-utils'; +import { DeploymentsView } from '@/components/resources/deployments'; +import { confirmDialog } from '@/hooks/useConfirm'; // Mock window.alert for testing error messages -const mockAlert = jest.spyOn(window, 'alert').mockImplementation(() => {}) +const mockAlert = jest.spyOn(window, 'alert').mockImplementation(() => {}); // Mock confirmDialog function jest.mock('@/hooks/useConfirm', () => ({ ...jest.requireActual('@/hooks/useConfirm'), confirmDialog: jest.fn() -})) +})); describe('DeploymentsView', () => { beforeEach(() => { jest.clearAllMocks() - ;(confirmDialog as jest.Mock).mockClear() + ;(confirmDialog as jest.Mock).mockClear(); server.use( createDeploymentsList(), createDeploymentHandler(), @@ -40,93 +40,93 @@ describe('DeploymentsView', () => { updateDeploymentHandler(), scaleDeploymentHandler(), createDeploymentByName(createDeploymentsListData()[0]) - ) - }) + ); + }); afterEach(() => { - mockAlert.mockClear() - }) + mockAlert.mockClear(); + }); describe('Basic Rendering', () => { it('should render deployments view with header and controls', async () => { - render() + render(); - expect(screen.getByText('Deployments')).toBeInTheDocument() - expect(screen.getByText('Manage your Kubernetes deployments')).toBeInTheDocument() - expect(screen.getByRole('button', { name: '' })).toBeInTheDocument() // refresh button with no text - expect(screen.getByRole('button', { name: /create deployment/i })).toBeInTheDocument() - }) + expect(screen.getByText('Deployments')).toBeInTheDocument(); + expect(screen.getByText('Manage your Kubernetes deployments')).toBeInTheDocument(); + expect(screen.getByRole('button', { name: '' })).toBeInTheDocument(); // refresh button with no text + expect(screen.getByRole('button', { name: /create deployment/i })).toBeInTheDocument(); + }); it('should display deployments data when loaded', async () => { - render() + render(); await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - expect(screen.getByText('redis-deployment')).toBeInTheDocument() - }) - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + expect(screen.getByText('redis-deployment')).toBeInTheDocument(); + }); + }); it('should show loading state initially', () => { - render() + render(); - const refreshButton = screen.getByRole('button', { name: '' }) - expect(refreshButton).toBeDisabled() - }) - }) + const refreshButton = screen.getByRole('button', { name: '' }); + expect(refreshButton).toBeDisabled(); + }); + }); describe('Data Loading', () => { it('should load deployments from API', async () => { - render() + render(); await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - expect(screen.getByText('redis-deployment')).toBeInTheDocument() - }) - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + expect(screen.getByText('redis-deployment')).toBeInTheDocument(); + }); + }); it('should handle loading state with slow API response', async () => { - server.use(createDeploymentsListSlow()) + server.use(createDeploymentsListSlow()); - render() + render(); // Should show loading state - const refreshButton = screen.getByRole('button', { name: '' }) - expect(refreshButton).toBeDisabled() + const refreshButton = screen.getByRole('button', { name: '' }); + expect(refreshButton).toBeDisabled(); // Wait for data to load await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }, { timeout: 2000 }) - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }, { timeout: 2000 }); + }); it('should handle API errors gracefully', async () => { - server.use(createDeploymentsListError(500, 'Server Error')) + server.use(createDeploymentsListError(500, 'Server Error')); - render() + render(); await waitFor(() => { - expect(screen.getByText(/server error/i)).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText(/server error/i)).toBeInTheDocument(); + }); + }); + }); describe('Stats Display', () => { it('should display correct statistics', async () => { - render() + render(); await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); // Check for stats cards - expect(screen.getByText('Total Deployments')).toBeInTheDocument() - expect(screen.getByText('Running')).toBeInTheDocument() - expect(screen.getByText('Total Replicas')).toBeInTheDocument() + expect(screen.getByText('Total Deployments')).toBeInTheDocument(); + expect(screen.getByText('Running')).toBeInTheDocument(); + expect(screen.getByText('Total Replicas')).toBeInTheDocument(); // Check stats values - expect(screen.getByText('2')).toBeInTheDocument() // Total deployments - expect(screen.getByText('4')).toBeInTheDocument() // Total replicas (3 + 1) - }) + expect(screen.getByText('2')).toBeInTheDocument(); // Total deployments + expect(screen.getByText('4')).toBeInTheDocument(); // Total replicas (3 + 1) + }); it('should display status badges correctly', async () => { const deploymentsWithDifferentStatuses = [ @@ -166,168 +166,168 @@ describe('DeploymentsView', () => { ] } } - ] + ]; - server.use(createDeploymentsList(deploymentsWithDifferentStatuses)) + server.use(createDeploymentsList(deploymentsWithDifferentStatuses)); - render() + render(); await waitFor(() => { - expect(screen.getByText('running-deployment')).toBeInTheDocument() - expect(screen.getByText('pending-deployment')).toBeInTheDocument() - expect(screen.getByText('failed-deployment')).toBeInTheDocument() - }) + expect(screen.getByText('running-deployment')).toBeInTheDocument(); + expect(screen.getByText('pending-deployment')).toBeInTheDocument(); + expect(screen.getByText('failed-deployment')).toBeInTheDocument(); + }); // Check that status badges are displayed - expect(screen.getAllByText('Running')).toHaveLength(2) // Header and badge - expect(screen.getByText('Pending')).toBeInTheDocument() - expect(screen.getByText('Failed')).toBeInTheDocument() - }) - }) + expect(screen.getAllByText('Running')).toHaveLength(2); // Header and badge + expect(screen.getByText('Pending')).toBeInTheDocument(); + expect(screen.getByText('Failed')).toBeInTheDocument(); + }); + }); describe('User Interactions', () => { it('should refresh data when refresh button is clicked', async () => { - render() + render(); // Wait for initial load await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); - const refreshButtons = screen.getAllByRole('button', { name: '' }) + const refreshButtons = screen.getAllByRole('button', { name: '' }); const refreshButton = refreshButtons.find(button => button.querySelector('svg.lucide-refresh-cw') - ) + ); - expect(refreshButton).toBeInTheDocument() + expect(refreshButton).toBeInTheDocument(); if (refreshButton) { - fireEvent.click(refreshButton) + fireEvent.click(refreshButton); // Verify button is clickable and not disabled - expect(refreshButton).not.toBeDisabled() + expect(refreshButton).not.toBeDisabled(); } - }) + }); it('should open create dialog when create button is clicked', async () => { - render() + render(); - const createButton = screen.getByRole('button', { name: /create deployment/i }) - fireEvent.click(createButton) + const createButton = screen.getByRole('button', { name: /create deployment/i }); + fireEvent.click(createButton); // Check that create button is clickable - expect(createButton).toBeInTheDocument() - }) + expect(createButton).toBeInTheDocument(); + }); it('should handle view action', async () => { - const user = userEvent.setup() + const user = userEvent.setup(); - render() + render(); await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); // Find view button (eye icon) - const allButtons = screen.getAllByRole('button') + const allButtons = screen.getAllByRole('button'); const viewButton = allButtons.find(button => button.querySelector('svg.lucide-eye') - ) + ); - expect(viewButton).toBeInTheDocument() + expect(viewButton).toBeInTheDocument(); if (viewButton) { - fireEvent.click(viewButton) + fireEvent.click(viewButton); } - }) + }); it('should handle edit action', async () => { - const user = userEvent.setup() + const user = userEvent.setup(); - render() + render(); await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); // Find edit button (edit icon) - const allButtons = screen.getAllByRole('button') + const allButtons = screen.getAllByRole('button'); const editButton = allButtons.find(button => button.querySelector('svg.lucide-edit') - ) + ); if (editButton) { - expect(editButton).toBeInTheDocument() - fireEvent.click(editButton) + expect(editButton).toBeInTheDocument(); + fireEvent.click(editButton); } - }) + }); it('should call handleEdit when edit button is clicked', async () => { - render() + render(); await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); // Find edit button (edit icon) - const allButtons = screen.getAllByRole('button') + const allButtons = screen.getAllByRole('button'); const editButton = allButtons.find(button => button.querySelector('svg.lucide-edit') - ) + ); if (editButton) { - expect(editButton).toBeInTheDocument() - fireEvent.click(editButton) + expect(editButton).toBeInTheDocument(); + fireEvent.click(editButton); // Verify that the edit dialog opens await waitFor(() => { - expect(screen.getByText('Edit Deployment')).toBeInTheDocument() - }) + expect(screen.getByText('Edit Deployment')).toBeInTheDocument(); + }); } else { // If edit button is not found, that's also a valid test case - expect(editButton).toBeUndefined() + expect(editButton).toBeUndefined(); } - }) + }); it('should handle scale action', async () => { - const user = userEvent.setup() + const user = userEvent.setup(); - render() + render(); await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); // Find scale button (scale icon) - const allButtons = screen.getAllByRole('button') + const allButtons = screen.getAllByRole('button'); const scaleButton = allButtons.find(button => button.querySelector('svg.lucide-scale') - ) + ); - expect(scaleButton).toBeInTheDocument() + expect(scaleButton).toBeInTheDocument(); if (scaleButton) { - fireEvent.click(scaleButton) + fireEvent.click(scaleButton); } - }) - }) + }); + }); describe('Delete Functionality', () => { it('should handle delete action with confirmation', async () => { // Mock confirmDialog to return true (confirmation) - ;(confirmDialog as jest.Mock).mockResolvedValueOnce(true) + ;(confirmDialog as jest.Mock).mockResolvedValueOnce(true); - render() + render(); await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); // Find delete button (trash icon) - const allButtons = screen.getAllByRole('button') + const allButtons = screen.getAllByRole('button'); const deleteButton = allButtons.find(button => button.querySelector('svg.lucide-trash2') - ) + ); - expect(deleteButton).toBeInTheDocument() + expect(deleteButton).toBeInTheDocument(); if (deleteButton) { - fireEvent.click(deleteButton) + fireEvent.click(deleteButton); // Verify confirmDialog was called with correct parameters await waitFor(() => { @@ -336,30 +336,30 @@ describe('DeploymentsView', () => { description: 'Are you sure you want to delete nginx-deployment?', confirmText: 'Delete', confirmVariant: 'destructive' - }) - }) + }); + }); } - }) + }); it('should handle delete action with cancellation', async () => { // Mock confirmDialog to return false (cancellation) - ;(confirmDialog as jest.Mock).mockResolvedValueOnce(false) + ;(confirmDialog as jest.Mock).mockResolvedValueOnce(false); - render() + render(); await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); // Find delete button (trash icon) - const allButtons = screen.getAllByRole('button') + const allButtons = screen.getAllByRole('button'); const deleteButton = allButtons.find(button => button.querySelector('svg.lucide-trash2') - ) + ); - expect(deleteButton).toBeInTheDocument() + expect(deleteButton).toBeInTheDocument(); if (deleteButton) { - fireEvent.click(deleteButton) + fireEvent.click(deleteButton); // Verify confirmDialog was called with correct parameters await waitFor(() => { @@ -368,93 +368,93 @@ describe('DeploymentsView', () => { description: 'Are you sure you want to delete nginx-deployment?', confirmText: 'Delete', confirmVariant: 'destructive' - }) - }) + }); + }); // Verify that no deletion was attempted (no refetch should be called) // This is tested by ensuring the component doesn't crash and confirmDialog was called } - }) + }); it('should handle delete errors with alert', async () => { server.use(deleteDeploymentErrorHandler(500, 'Delete failed')) // Mock confirmDialog to return true (confirmation) - ;(confirmDialog as jest.Mock).mockResolvedValueOnce(true) + ;(confirmDialog as jest.Mock).mockResolvedValueOnce(true); - render() + render(); await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); // Find delete button (trash icon) - const allButtons = screen.getAllByRole('button') + const allButtons = screen.getAllByRole('button'); const deleteButton = allButtons.find(button => button.querySelector('svg.lucide-trash2') - ) + ); - expect(deleteButton).toBeInTheDocument() + expect(deleteButton).toBeInTheDocument(); if (deleteButton) { - fireEvent.click(deleteButton) + fireEvent.click(deleteButton); // Wait for error alert await waitFor(() => { expect(mockAlert).toHaveBeenCalledWith( expect.stringContaining('Failed to delete deployment') - ) - }) + ); + }); } - }) - }) + }); + }); describe('Create Deployment Dialog', () => { it('should handle create deployment with YAML parsing', async () => { - render() + render(); - const createButton = screen.getByRole('button', { name: /create deployment/i }) - fireEvent.click(createButton) + const createButton = screen.getByRole('button', { name: /create deployment/i }); + fireEvent.click(createButton); // Check that create button is clickable and dialog opens - expect(createButton).toBeInTheDocument() + expect(createButton).toBeInTheDocument(); // Wait for create dialog to appear await waitFor(() => { - expect(screen.getByRole('dialog')).toBeInTheDocument() - }) - }) + expect(screen.getByRole('dialog')).toBeInTheDocument(); + }); + }); it('should handle create deployment errors', async () => { - server.use(createDeploymentErrorHandler(400, 'Creation failed')) + server.use(createDeploymentErrorHandler(400, 'Creation failed')); - render() + render(); - const createButton = screen.getByRole('button', { name: /create deployment/i }) - fireEvent.click(createButton) + const createButton = screen.getByRole('button', { name: /create deployment/i }); + fireEvent.click(createButton); // Check that create button is clickable and dialog opens - expect(createButton).toBeInTheDocument() + expect(createButton).toBeInTheDocument(); // Wait for create dialog to appear await waitFor(() => { - expect(screen.getByRole('dialog')).toBeInTheDocument() - }) - }) + expect(screen.getByRole('dialog')).toBeInTheDocument(); + }); + }); it('should handle YAML input and submission', async () => { - render() + render(); - const createButton = screen.getByRole('button', { name: /create deployment/i }) - fireEvent.click(createButton) + const createButton = screen.getByRole('button', { name: /create deployment/i }); + fireEvent.click(createButton); // Wait for create dialog to appear await waitFor(() => { - expect(screen.getByRole('dialog')).toBeInTheDocument() - }) + expect(screen.getByRole('dialog')).toBeInTheDocument(); + }); // Find YAML editor textarea - const yamlEditor = screen.getByRole('textbox') - expect(yamlEditor).toBeInTheDocument() + const yamlEditor = screen.getByRole('textbox'); + expect(yamlEditor).toBeInTheDocument(); // Test YAML input const testYaml = `apiVersion: apps/v1 @@ -474,26 +474,26 @@ spec: spec: containers: - name: test - image: nginx:latest` + image: nginx:latest`; - fireEvent.change(yamlEditor, { target: { value: testYaml } }) - expect(yamlEditor).toHaveValue(testYaml) - }) + fireEvent.change(yamlEditor, { target: { value: testYaml } }); + expect(yamlEditor).toHaveValue(testYaml); + }); it('should handle create deployment with custom namespace parsing', async () => { - render() + render(); - const createButton = screen.getByRole('button', { name: /create deployment/i }) - fireEvent.click(createButton) + const createButton = screen.getByRole('button', { name: /create deployment/i }); + fireEvent.click(createButton); // Wait for create dialog to appear await waitFor(() => { - expect(screen.getByRole('dialog')).toBeInTheDocument() - }) + expect(screen.getByRole('dialog')).toBeInTheDocument(); + }); // Find YAML editor textarea - const yamlEditor = screen.getByRole('textbox') - expect(yamlEditor).toBeInTheDocument() + const yamlEditor = screen.getByRole('textbox'); + expect(yamlEditor).toBeInTheDocument(); // Test YAML with custom namespace const yamlWithCustomNamespace = `apiVersion: apps/v1 @@ -513,26 +513,26 @@ spec: spec: containers: - name: test - image: nginx:latest` + image: nginx:latest`; - fireEvent.change(yamlEditor, { target: { value: yamlWithCustomNamespace } }) - expect(yamlEditor).toHaveValue(yamlWithCustomNamespace) - }) + fireEvent.change(yamlEditor, { target: { value: yamlWithCustomNamespace } }); + expect(yamlEditor).toHaveValue(yamlWithCustomNamespace); + }); it('should handle create deployment with no metadata section', async () => { - render() + render(); - const createButton = screen.getByRole('button', { name: /create deployment/i }) - fireEvent.click(createButton) + const createButton = screen.getByRole('button', { name: /create deployment/i }); + fireEvent.click(createButton); // Wait for create dialog to appear await waitFor(() => { - expect(screen.getByRole('dialog')).toBeInTheDocument() - }) + expect(screen.getByRole('dialog')).toBeInTheDocument(); + }); // Find YAML editor textarea - const yamlEditor = screen.getByRole('textbox') - expect(yamlEditor).toBeInTheDocument() + const yamlEditor = screen.getByRole('textbox'); + expect(yamlEditor).toBeInTheDocument(); // Test YAML without metadata section const yamlWithoutMetadata = `apiVersion: apps/v1 @@ -549,86 +549,86 @@ spec: spec: containers: - name: test - image: nginx:latest` + image: nginx:latest`; - fireEvent.change(yamlEditor, { target: { value: yamlWithoutMetadata } }) - expect(yamlEditor).toHaveValue(yamlWithoutMetadata) - }) - }) + fireEvent.change(yamlEditor, { target: { value: yamlWithoutMetadata } }); + expect(yamlEditor).toHaveValue(yamlWithoutMetadata); + }); + }); describe('View/Edit Deployment Dialog', () => { it('should handle view deployment', async () => { - render() + render(); await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); // Find view button (eye icon) - const allButtons = screen.getAllByRole('button') + const allButtons = screen.getAllByRole('button'); const viewButton = allButtons.find(button => button.querySelector('svg.lucide-eye') - ) + ); - expect(viewButton).toBeInTheDocument() + expect(viewButton).toBeInTheDocument(); if (viewButton) { - fireEvent.click(viewButton) + fireEvent.click(viewButton); // Wait for view dialog to appear await waitFor(() => { - expect(screen.getByRole('dialog')).toBeInTheDocument() - }) + expect(screen.getByRole('dialog')).toBeInTheDocument(); + }); } - }) + }); it('should handle edit deployment', async () => { - render() + render(); await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); // Find edit button (edit icon) - const allButtons = screen.getAllByRole('button') + const allButtons = screen.getAllByRole('button'); const editButton = allButtons.find(button => button.querySelector('svg.lucide-edit') - ) + ); if (editButton) { - expect(editButton).toBeInTheDocument() - fireEvent.click(editButton) + expect(editButton).toBeInTheDocument(); + fireEvent.click(editButton); // Wait for edit dialog to appear await waitFor(() => { - expect(screen.getByRole('dialog')).toBeInTheDocument() - }) + expect(screen.getByRole('dialog')).toBeInTheDocument(); + }); } - }) + }); it('should handle YAML editing in edit mode', async () => { - render() + render(); await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); // Find edit button (edit icon) - const allButtons = screen.getAllByRole('button') + const allButtons = screen.getAllByRole('button'); const editButton = allButtons.find(button => button.querySelector('svg.lucide-edit') - ) + ); if (editButton) { - fireEvent.click(editButton) + fireEvent.click(editButton); // Wait for edit dialog to appear await waitFor(() => { - expect(screen.getByRole('dialog')).toBeInTheDocument() - }) + expect(screen.getByRole('dialog')).toBeInTheDocument(); + }); // Find YAML editor textarea - const yamlEditor = screen.getByRole('textbox') - expect(yamlEditor).toBeInTheDocument() + const yamlEditor = screen.getByRole('textbox'); + expect(yamlEditor).toBeInTheDocument(); // Test YAML editing const modifiedYaml = `apiVersion: apps/v1 @@ -648,76 +648,76 @@ spec: spec: containers: - name: nginx - image: nginx:1.15.0` + image: nginx:1.15.0`; - fireEvent.change(yamlEditor, { target: { value: modifiedYaml } }) - expect(yamlEditor).toHaveValue(modifiedYaml) + fireEvent.change(yamlEditor, { target: { value: modifiedYaml } }); + expect(yamlEditor).toHaveValue(modifiedYaml); } - }) + }); it('should handle update deployment errors', async () => { - server.use(updateDeploymentErrorHandler(400, 'Update failed')) + server.use(updateDeploymentErrorHandler(400, 'Update failed')); - render() + render(); await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); // Find edit button (edit icon) - const allButtons = screen.getAllByRole('button') + const allButtons = screen.getAllByRole('button'); const editButton = allButtons.find(button => button.querySelector('svg.lucide-edit') - ) + ); if (editButton) { - expect(editButton).toBeInTheDocument() - fireEvent.click(editButton) + expect(editButton).toBeInTheDocument(); + fireEvent.click(editButton); } - }) - }) + }); + }); describe('Scale Deployment Dialog', () => { it('should handle scale deployment', async () => { - render() + render(); await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); // Find scale button (scale icon) - const allButtons = screen.getAllByRole('button') + const allButtons = screen.getAllByRole('button'); const scaleButton = allButtons.find(button => button.querySelector('svg.lucide-scale') - ) + ); - expect(scaleButton).toBeInTheDocument() + expect(scaleButton).toBeInTheDocument(); if (scaleButton) { - fireEvent.click(scaleButton) + fireEvent.click(scaleButton); } - }) + }); it('should handle scale deployment errors', async () => { - server.use(scaleDeploymentErrorHandler(400, 'Scaling failed')) + server.use(scaleDeploymentErrorHandler(400, 'Scaling failed')); - render() + render(); await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); // Find scale button (scale icon) - const allButtons = screen.getAllByRole('button') + const allButtons = screen.getAllByRole('button'); const scaleButton = allButtons.find(button => button.querySelector('svg.lucide-scale') - ) + ); - expect(scaleButton).toBeInTheDocument() + expect(scaleButton).toBeInTheDocument(); if (scaleButton) { - fireEvent.click(scaleButton) + fireEvent.click(scaleButton); } - }) - }) + }); + }); describe('Status Determination', () => { it('should determine deployment status correctly', async () => { @@ -758,18 +758,18 @@ spec: ] } } - ] + ]; - server.use(createDeploymentsList(deploymentsWithStatus)) + server.use(createDeploymentsList(deploymentsWithStatus)); - render() + render(); await waitFor(() => { - expect(screen.getByText('running-deployment')).toBeInTheDocument() - expect(screen.getByText('pending-deployment')).toBeInTheDocument() - expect(screen.getByText('failed-deployment')).toBeInTheDocument() - }) - }) + expect(screen.getByText('running-deployment')).toBeInTheDocument(); + expect(screen.getByText('pending-deployment')).toBeInTheDocument(); + expect(screen.getByText('failed-deployment')).toBeInTheDocument(); + }); + }); it('should handle deployment with missing status', async () => { const deploymentsWithMissingStatus = [ @@ -778,17 +778,17 @@ spec: spec: { replicas: 1, selector: { matchLabels: { app: 'no-status' } }, template: { spec: { containers: [{ name: 'no-status', image: 'no-status:latest' }] } } } // Missing status } - ] + ]; - server.use(createDeploymentsList(deploymentsWithMissingStatus)) + server.use(createDeploymentsList(deploymentsWithMissingStatus)); - render() + render(); await waitFor(() => { // Check that the component renders without crashing - expect(screen.getByText('Deployments')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Deployments')).toBeInTheDocument(); + }); + }); it('should handle deployment with missing metadata', async () => { const deploymentsWithMissingMetadata = [ @@ -797,70 +797,70 @@ spec: spec: { replicas: 1, selector: { matchLabels: { app: 'missing' } }, template: { spec: { containers: [{ name: 'missing', image: 'missing:latest' }] } } }, status: { availableReplicas: 1, replicas: 1 } } - ] + ]; - server.use(createDeploymentsList(deploymentsWithMissingMetadata)) + server.use(createDeploymentsList(deploymentsWithMissingMetadata)); - render() + render(); await waitFor(() => { // Check that the component renders without crashing - expect(screen.getByText('Deployments')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('Deployments')).toBeInTheDocument(); + }); + }); + }); describe('Empty State', () => { it('should show empty state when no deployments exist', async () => { - server.use(createDeploymentsList([])) + server.use(createDeploymentsList([])); - render() + render(); await waitFor(() => { - expect(screen.getByText(/no deployments found/i)).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText(/no deployments found/i)).toBeInTheDocument(); + }); + }); + }); describe('Error Handling', () => { it('should show error message when API fails', async () => { - server.use(createDeploymentsListError(500, 'Internal Server Error')) + server.use(createDeploymentsListError(500, 'Internal Server Error')); - render() + render(); await waitFor(() => { - expect(screen.getByText(/internal server error/i)).toBeInTheDocument() - }) - }) + expect(screen.getByText(/internal server error/i)).toBeInTheDocument(); + }); + }); it('should show retry button when there is an error', async () => { - server.use(createDeploymentsListError(500, 'Internal Server Error')) + server.use(createDeploymentsListError(500, 'Internal Server Error')); - render() + render(); await waitFor(() => { - expect(screen.getByText(/internal server error/i)).toBeInTheDocument() - }) + expect(screen.getByText(/internal server error/i)).toBeInTheDocument(); + }); - expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument() - }) + expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument(); + }); it('should handle create deployment errors with proper error message', async () => { - server.use(createDeploymentErrorHandler(400, 'Invalid YAML')) + server.use(createDeploymentErrorHandler(400, 'Invalid YAML')); - render() + render(); - const createButton = screen.getByRole('button', { name: /create deployment/i }) - fireEvent.click(createButton) + const createButton = screen.getByRole('button', { name: /create deployment/i }); + fireEvent.click(createButton); // Wait for create dialog to appear await waitFor(() => { - expect(screen.getByRole('dialog')).toBeInTheDocument() - }) + expect(screen.getByRole('dialog')).toBeInTheDocument(); + }); // Find YAML editor textarea - const yamlEditor = screen.getByRole('textbox') - expect(yamlEditor).toBeInTheDocument() + const yamlEditor = screen.getByRole('textbox'); + expect(yamlEditor).toBeInTheDocument(); // Test YAML input const testYaml = `apiVersion: apps/v1 @@ -880,91 +880,91 @@ spec: spec: containers: - name: test - image: nginx:latest` + image: nginx:latest`; - fireEvent.change(yamlEditor, { target: { value: testYaml } }) - expect(yamlEditor).toHaveValue(testYaml) - }) + fireEvent.change(yamlEditor, { target: { value: testYaml } }); + expect(yamlEditor).toHaveValue(testYaml); + }); it('should handle update deployment errors', async () => { - server.use(updateDeploymentErrorHandler(400, 'Update failed')) + server.use(updateDeploymentErrorHandler(400, 'Update failed')); - render() + render(); await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); // Find edit button (edit icon) - const allButtons = screen.getAllByRole('button') + const allButtons = screen.getAllByRole('button'); const editButton = allButtons.find(button => button.querySelector('svg.lucide-edit') - ) + ); if (editButton) { - expect(editButton).toBeInTheDocument() - fireEvent.click(editButton) + expect(editButton).toBeInTheDocument(); + fireEvent.click(editButton); } else { // If edit button is not found, that's also a valid test case - expect(editButton).toBeUndefined() + expect(editButton).toBeUndefined(); } - }) + }); it('should handle scale deployment errors', async () => { - server.use(scaleDeploymentErrorHandler(400, 'Scaling failed')) + server.use(scaleDeploymentErrorHandler(400, 'Scaling failed')); - render() + render(); await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); // Find scale button (scale icon) - const allButtons = screen.getAllByRole('button') + const allButtons = screen.getAllByRole('button'); const scaleButton = allButtons.find(button => button.querySelector('svg.lucide-scale') - ) + ); - expect(scaleButton).toBeInTheDocument() + expect(scaleButton).toBeInTheDocument(); if (scaleButton) { - fireEvent.click(scaleButton) + fireEvent.click(scaleButton); } - }) - }) + }); + }); describe('YAML Parsing', () => { it('should handle YAML parsing for create deployment', async () => { - render() + render(); - const createButton = screen.getByRole('button', { name: /create deployment/i }) - fireEvent.click(createButton) + const createButton = screen.getByRole('button', { name: /create deployment/i }); + fireEvent.click(createButton); // Check that create button is clickable and dialog opens - expect(createButton).toBeInTheDocument() + expect(createButton).toBeInTheDocument(); // Wait for create dialog to appear await waitFor(() => { - expect(screen.getByRole('dialog')).toBeInTheDocument() - }) - }) + expect(screen.getByRole('dialog')).toBeInTheDocument(); + }); + }); it('should handle YAML parsing errors gracefully', async () => { - render() + render(); - const createButton = screen.getByRole('button', { name: /create deployment/i }) - fireEvent.click(createButton) + const createButton = screen.getByRole('button', { name: /create deployment/i }); + fireEvent.click(createButton); // Check that create button is clickable and dialog opens - expect(createButton).toBeInTheDocument() + expect(createButton).toBeInTheDocument(); // Wait for create dialog to appear await waitFor(() => { - expect(screen.getByRole('dialog')).toBeInTheDocument() - }) + expect(screen.getByRole('dialog')).toBeInTheDocument(); + }); // Find YAML editor textarea - const yamlEditor = screen.getByRole('textbox') - expect(yamlEditor).toBeInTheDocument() + const yamlEditor = screen.getByRole('textbox'); + expect(yamlEditor).toBeInTheDocument(); // Test invalid YAML input const invalidYaml = `apiVersion: apps/v1 @@ -985,26 +985,26 @@ spec: containers: - name: test image: nginx:latest - invalid: [unclosed array` + invalid: [unclosed array`; - fireEvent.change(yamlEditor, { target: { value: invalidYaml } }) - expect(yamlEditor).toHaveValue(invalidYaml) - }) + fireEvent.change(yamlEditor, { target: { value: invalidYaml } }); + expect(yamlEditor).toHaveValue(invalidYaml); + }); it('should parse namespace from YAML metadata', async () => { - render() + render(); - const createButton = screen.getByRole('button', { name: /create deployment/i }) - fireEvent.click(createButton) + const createButton = screen.getByRole('button', { name: /create deployment/i }); + fireEvent.click(createButton); // Wait for create dialog to appear await waitFor(() => { - expect(screen.getByRole('dialog')).toBeInTheDocument() - }) + expect(screen.getByRole('dialog')).toBeInTheDocument(); + }); // Find YAML editor textarea - const yamlEditor = screen.getByRole('textbox') - expect(yamlEditor).toBeInTheDocument() + const yamlEditor = screen.getByRole('textbox'); + expect(yamlEditor).toBeInTheDocument(); // Test YAML with custom namespace const yamlWithNamespace = `apiVersion: apps/v1 @@ -1024,26 +1024,26 @@ spec: spec: containers: - name: test - image: nginx:latest` + image: nginx:latest`; - fireEvent.change(yamlEditor, { target: { value: yamlWithNamespace } }) - expect(yamlEditor).toHaveValue(yamlWithNamespace) - }) + fireEvent.change(yamlEditor, { target: { value: yamlWithNamespace } }); + expect(yamlEditor).toHaveValue(yamlWithNamespace); + }); it('should handle YAML without namespace in metadata', async () => { - render() + render(); - const createButton = screen.getByRole('button', { name: /create deployment/i }) - fireEvent.click(createButton) + const createButton = screen.getByRole('button', { name: /create deployment/i }); + fireEvent.click(createButton); // Wait for create dialog to appear await waitFor(() => { - expect(screen.getByRole('dialog')).toBeInTheDocument() - }) + expect(screen.getByRole('dialog')).toBeInTheDocument(); + }); // Find YAML editor textarea - const yamlEditor = screen.getByRole('textbox') - expect(yamlEditor).toBeInTheDocument() + const yamlEditor = screen.getByRole('textbox'); + expect(yamlEditor).toBeInTheDocument(); // Test YAML without namespace (should default to 'default') const yamlWithoutNamespace = `apiVersion: apps/v1 @@ -1062,26 +1062,26 @@ spec: spec: containers: - name: test - image: nginx:latest` + image: nginx:latest`; - fireEvent.change(yamlEditor, { target: { value: yamlWithoutNamespace } }) - expect(yamlEditor).toHaveValue(yamlWithoutNamespace) - }) + fireEvent.change(yamlEditor, { target: { value: yamlWithoutNamespace } }); + expect(yamlEditor).toHaveValue(yamlWithoutNamespace); + }); it('should handle YAML with metadata but no namespace field', async () => { - render() + render(); - const createButton = screen.getByRole('button', { name: /create deployment/i }) - fireEvent.click(createButton) + const createButton = screen.getByRole('button', { name: /create deployment/i }); + fireEvent.click(createButton); // Wait for create dialog to appear await waitFor(() => { - expect(screen.getByRole('dialog')).toBeInTheDocument() - }) + expect(screen.getByRole('dialog')).toBeInTheDocument(); + }); // Find YAML editor textarea - const yamlEditor = screen.getByRole('textbox') - expect(yamlEditor).toBeInTheDocument() + const yamlEditor = screen.getByRole('textbox'); + expect(yamlEditor).toBeInTheDocument(); // Test YAML with metadata but no namespace field const yamlWithMetadataNoNamespace = `apiVersion: apps/v1 @@ -1102,47 +1102,47 @@ spec: spec: containers: - name: test - image: nginx:latest` + image: nginx:latest`; - fireEvent.change(yamlEditor, { target: { value: yamlWithMetadataNoNamespace } }) - expect(yamlEditor).toHaveValue(yamlWithMetadataNoNamespace) - }) - }) + fireEvent.change(yamlEditor, { target: { value: yamlWithMetadataNoNamespace } }); + expect(yamlEditor).toHaveValue(yamlWithMetadataNoNamespace); + }); + }); describe('Update Deployment with MSW', () => { it('should successfully update deployment with MSW', async () => { - const user = userEvent.setup() + const user = userEvent.setup(); // Setup MSW handlers for successful update server.use( createDeploymentsList(), updateDeploymentHandler() - ) + ); - render() + render(); // Wait for initial data to load await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); // Find edit button and click it - const editButtons = screen.getAllByRole('button', { name: /edit deployment/i }) - const editButton = editButtons[0] + const editButtons = screen.getAllByRole('button', { name: /edit deployment/i }); + const editButton = editButtons[0]; if (editButton) { - fireEvent.click(editButton) + fireEvent.click(editButton); // Wait for edit dialog to appear await waitFor(() => { - expect(screen.getByRole('dialog')).toBeInTheDocument() - }) + expect(screen.getByRole('dialog')).toBeInTheDocument(); + }); // Wait for YAML editor to appear and find it await waitFor(() => { - expect(screen.getByRole('textbox')).toBeInTheDocument() - }) - const yamlEditor = screen.getByRole('textbox') + expect(screen.getByRole('textbox')).toBeInTheDocument(); + }); + const yamlEditor = screen.getByRole('textbox'); const modifiedYaml = `apiVersion: apps/v1 kind: Deployment metadata: @@ -1160,57 +1160,57 @@ spec: spec: containers: - name: nginx - image: nginx:1.20.0` + image: nginx:1.20.0`; - await user.clear(yamlEditor) - await user.type(yamlEditor, modifiedYaml) + await user.clear(yamlEditor); + await user.type(yamlEditor, modifiedYaml); // Find and click save button - const saveButton = screen.getByRole('button', { name: /save changes/i }) - fireEvent.click(saveButton) + const saveButton = screen.getByRole('button', { name: /save changes/i }); + fireEvent.click(saveButton); // Verify the deployment was updated (this would trigger refetch) await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); } else { - throw new Error('Edit button not found') + throw new Error('Edit button not found'); } - }) + }); it('should handle update deployment error with MSW', async () => { - const user = userEvent.setup() + const user = userEvent.setup(); // Setup MSW handlers for update error server.use( createDeploymentsList(), updateDeploymentErrorHandler(400, 'Update failed') - ) + ); - render() + render(); // Wait for initial data to load await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); // Find edit button and click it - const editButtons = screen.getAllByRole('button', { name: /edit deployment/i }) - const editButton = editButtons[0] + const editButtons = screen.getAllByRole('button', { name: /edit deployment/i }); + const editButton = editButtons[0]; if (editButton) { - fireEvent.click(editButton) + fireEvent.click(editButton); // Wait for edit dialog to appear await waitFor(() => { - expect(screen.getByRole('dialog')).toBeInTheDocument() - }) + expect(screen.getByRole('dialog')).toBeInTheDocument(); + }); // Wait for YAML editor to appear and find it await waitFor(() => { - expect(screen.getByRole('textbox')).toBeInTheDocument() - }) - const yamlEditor = screen.getByRole('textbox') + expect(screen.getByRole('textbox')).toBeInTheDocument(); + }); + const yamlEditor = screen.getByRole('textbox'); const modifiedYaml = `apiVersion: apps/v1 kind: Deployment metadata: @@ -1228,199 +1228,199 @@ spec: spec: containers: - name: nginx - image: nginx:1.20.0` + image: nginx:1.20.0`; - await user.clear(yamlEditor) - await user.type(yamlEditor, modifiedYaml) + await user.clear(yamlEditor); + await user.type(yamlEditor, modifiedYaml); // Find and click save button - const saveButton = screen.getByRole('button', { name: /save changes/i }) - fireEvent.click(saveButton) + const saveButton = screen.getByRole('button', { name: /save changes/i }); + fireEvent.click(saveButton); // Verify error handling (the error should be caught and logged) await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); } else { - throw new Error('Edit button not found') + throw new Error('Edit button not found'); } - }) - }) + }); + }); describe('Scale Deployment with MSW', () => { it('should successfully scale deployment with MSW', async () => { - const user = userEvent.setup() + const user = userEvent.setup(); // Setup MSW handlers for successful scaling server.use( createDeploymentsList(), scaleDeploymentHandler(5) - ) + ); - render() + render(); // Wait for initial data to load await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); // Find scale button and click it - const allButtons = screen.getAllByRole('button') + const allButtons = screen.getAllByRole('button'); const scaleButton = allButtons.find(button => button.querySelector('svg.lucide-scale') - ) + ); if (scaleButton) { - fireEvent.click(scaleButton) + fireEvent.click(scaleButton); // Wait for scale dialog to appear await waitFor(() => { - expect(screen.getByText('Scale Deployment')).toBeInTheDocument() - }) + expect(screen.getByText('Scale Deployment')).toBeInTheDocument(); + }); // Find replicas input and change value - const replicasInput = screen.getByDisplayValue('3') - await user.clear(replicasInput) - await user.type(replicasInput, '5') + const replicasInput = screen.getByDisplayValue('3'); + await user.clear(replicasInput); + await user.type(replicasInput, '5'); // Find and click scale button - const confirmScaleButton = screen.getByRole('button', { name: /scale/i }) - fireEvent.click(confirmScaleButton) + const confirmScaleButton = screen.getByRole('button', { name: /scale/i }); + fireEvent.click(confirmScaleButton); // Verify the deployment was scaled (this would trigger refetch) await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); } else { - throw new Error('Scale button not found') + throw new Error('Scale button not found'); } - }) + }); it('should handle scale deployment error with MSW', async () => { - const user = userEvent.setup() + const user = userEvent.setup(); // Setup MSW handlers for scale error server.use( createDeploymentsList(), scaleDeploymentErrorHandler(400, 'Scaling failed') - ) + ); - render() + render(); // Wait for initial data to load await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); // Find scale button and click it - const allButtons = screen.getAllByRole('button') + const allButtons = screen.getAllByRole('button'); const scaleButton = allButtons.find(button => button.querySelector('svg.lucide-scale') - ) + ); if (scaleButton) { - fireEvent.click(scaleButton) + fireEvent.click(scaleButton); // Wait for scale dialog to appear await waitFor(() => { - expect(screen.getByText('Scale Deployment')).toBeInTheDocument() - }) + expect(screen.getByText('Scale Deployment')).toBeInTheDocument(); + }); // Find replicas input and change value - const replicasInput = screen.getByDisplayValue('3') - await user.clear(replicasInput) - await user.type(replicasInput, '5') + const replicasInput = screen.getByDisplayValue('3'); + await user.clear(replicasInput); + await user.type(replicasInput, '5'); // Find and click scale button - const confirmScaleButton = screen.getByRole('button', { name: /scale/i }) - fireEvent.click(confirmScaleButton) + const confirmScaleButton = screen.getByRole('button', { name: /scale/i }); + fireEvent.click(confirmScaleButton); // Verify error handling (the error should be caught and logged) await waitFor(() => { - expect(screen.getAllByText('nginx-deployment')[0]).toBeInTheDocument() - }) + expect(screen.getAllByText('nginx-deployment')[0]).toBeInTheDocument(); + }); } else { - throw new Error('Scale button not found') + throw new Error('Scale button not found'); } - }) + }); it('should validate namespace when scaling deployment', async () => { - const user = userEvent.setup() + const user = userEvent.setup(); // Setup MSW handlers with namespace validation server.use( createDeploymentsList(), scaleDeploymentHandler(5) - ) + ); - render() + render(); // Wait for initial data to load await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); // Find scale button and click it - const allButtons = screen.getAllByRole('button') + const allButtons = screen.getAllByRole('button'); const scaleButton = allButtons.find(button => button.querySelector('svg.lucide-scale') - ) + ); if (scaleButton) { - fireEvent.click(scaleButton) + fireEvent.click(scaleButton); // Wait for scale dialog to appear await waitFor(() => { - expect(screen.getByText('Scale Deployment')).toBeInTheDocument() - }) + expect(screen.getByText('Scale Deployment')).toBeInTheDocument(); + }); // Find replicas input and change value - const replicasInput = screen.getByDisplayValue('3') - await user.clear(replicasInput) - await user.type(replicasInput, '5') + const replicasInput = screen.getByDisplayValue('3'); + await user.clear(replicasInput); + await user.type(replicasInput, '5'); // Find and click scale button - const confirmScaleButton = screen.getByRole('button', { name: /scale/i }) - fireEvent.click(confirmScaleButton) + const confirmScaleButton = screen.getByRole('button', { name: /scale/i }); + fireEvent.click(confirmScaleButton); // Verify the deployment was scaled with correct namespace await waitFor(() => { - expect(screen.getAllByText('nginx-deployment')[0]).toBeInTheDocument() - }) + expect(screen.getAllByText('nginx-deployment')[0]).toBeInTheDocument(); + }); } else { - throw new Error('Scale button not found') + throw new Error('Scale button not found'); } - }) - }) + }); + }); describe('Create Deployment with MSW', () => { it('should successfully create deployment with MSW', async () => { - const user = userEvent.setup() + const user = userEvent.setup(); // Setup MSW handlers for successful creation server.use( createDeploymentsList(), createDeploymentHandler() - ) + ); - render() + render(); // Wait for initial data to load await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); // Click create button - const createButton = screen.getByRole('button', { name: /create deployment/i }) - fireEvent.click(createButton) + const createButton = screen.getByRole('button', { name: /create deployment/i }); + fireEvent.click(createButton); // Wait for create dialog to appear await waitFor(() => { - expect(screen.getByRole('dialog')).toBeInTheDocument() - }) + expect(screen.getByRole('dialog')).toBeInTheDocument(); + }); // Find YAML editor and enter deployment YAML - const yamlEditor = screen.getByRole('textbox') + const yamlEditor = screen.getByRole('textbox'); const deploymentYaml = `apiVersion: apps/v1 kind: Deployment metadata: @@ -1438,48 +1438,48 @@ spec: spec: containers: - name: test - image: nginx:latest` + image: nginx:latest`; - await user.clear(yamlEditor) - await user.type(yamlEditor, deploymentYaml) + await user.clear(yamlEditor); + await user.type(yamlEditor, deploymentYaml); // Find and click submit button - const submitButton = screen.getByRole('button', { name: /continue/i }) - fireEvent.click(submitButton) + const submitButton = screen.getByRole('button', { name: /continue/i }); + fireEvent.click(submitButton); // Verify the deployment was created (this would trigger refetch) await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); + }); it('should handle create deployment error with MSW', async () => { - const user = userEvent.setup() + const user = userEvent.setup(); // Setup MSW handlers for creation error server.use( createDeploymentsList(), createDeploymentErrorHandler(400, 'Creation failed') - ) + ); - render() + render(); // Wait for initial data to load await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); // Click create button - const createButton = screen.getByRole('button', { name: /create deployment/i }) - fireEvent.click(createButton) + const createButton = screen.getByRole('button', { name: /create deployment/i }); + fireEvent.click(createButton); // Wait for create dialog to appear await waitFor(() => { - expect(screen.getByRole('dialog')).toBeInTheDocument() - }) + expect(screen.getByRole('dialog')).toBeInTheDocument(); + }); // Find YAML editor and enter deployment YAML - const yamlEditor = screen.getByRole('textbox') + const yamlEditor = screen.getByRole('textbox'); const deploymentYaml = `apiVersion: apps/v1 kind: Deployment metadata: @@ -1497,48 +1497,48 @@ spec: spec: containers: - name: test - image: nginx:latest` + image: nginx:latest`; - await user.clear(yamlEditor) - await user.type(yamlEditor, deploymentYaml) + await user.clear(yamlEditor); + await user.type(yamlEditor, deploymentYaml); // Find and click submit button - const submitButton = screen.getByRole('button', { name: /continue/i }) - fireEvent.click(submitButton) + const submitButton = screen.getByRole('button', { name: /continue/i }); + fireEvent.click(submitButton); // Verify error handling (the error should be caught and logged) await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); + }); it('should handle YAML validation error with MSW', async () => { - const user = userEvent.setup() + const user = userEvent.setup(); // Setup MSW handlers for successful creation server.use( createDeploymentsList(), createDeploymentHandler() - ) + ); - render() + render(); // Wait for initial data to load await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); // Click create button - const createButton = screen.getByRole('button', { name: /create deployment/i }) - fireEvent.click(createButton) + const createButton = screen.getByRole('button', { name: /create deployment/i }); + fireEvent.click(createButton); // Wait for create dialog to appear await waitFor(() => { - expect(screen.getByRole('dialog')).toBeInTheDocument() - }) + expect(screen.getByRole('dialog')).toBeInTheDocument(); + }); // Find YAML editor and enter invalid YAML - const yamlEditor = screen.getByRole('textbox') + const yamlEditor = screen.getByRole('textbox'); const invalidYaml = `apiVersion: apps/v1 kind: Deployment metadata: @@ -1557,87 +1557,87 @@ spec: containers: - name: test image: nginx:latest - invalid: unclosed array` + invalid: unclosed array`; - await user.clear(yamlEditor) - fireEvent.change(yamlEditor, { target: { value: invalidYaml } }) + await user.clear(yamlEditor); + fireEvent.change(yamlEditor, { target: { value: invalidYaml } }); // Find and click submit button - const submitButton = screen.getByRole('button', { name: /continue/i }) - fireEvent.click(submitButton) + const submitButton = screen.getByRole('button', { name: /continue/i }); + fireEvent.click(submitButton); // Verify error handling (the error should be caught and logged) await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); + }); it('should handle empty YAML content with MSW', async () => { - const user = userEvent.setup() + const user = userEvent.setup(); // Setup MSW handlers for successful creation server.use( createDeploymentsList(), createDeploymentHandler() - ) + ); - render() + render(); // Wait for initial data to load await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); // Click create button - const createButton = screen.getByRole('button', { name: /create deployment/i }) - fireEvent.click(createButton) + const createButton = screen.getByRole('button', { name: /create deployment/i }); + fireEvent.click(createButton); // Wait for create dialog to appear await waitFor(() => { - expect(screen.getByRole('dialog')).toBeInTheDocument() - }) + expect(screen.getByRole('dialog')).toBeInTheDocument(); + }); // Find YAML editor and clear it - const yamlEditor = screen.getByRole('textbox') - await user.clear(yamlEditor) + const yamlEditor = screen.getByRole('textbox'); + await user.clear(yamlEditor); // Find and click submit button - const submitButton = screen.getByRole('button', { name: /continue/i }) - fireEvent.click(submitButton) + const submitButton = screen.getByRole('button', { name: /continue/i }); + fireEvent.click(submitButton); // Verify error handling (the error should be caught and logged) await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); + }); it('should handle create deployment with custom namespace with MSW', async () => { - const user = userEvent.setup() + const user = userEvent.setup(); // Setup MSW handlers for successful creation server.use( createDeploymentsList(), createDeploymentHandler() - ) + ); - render() + render(); // Wait for initial data to load await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); // Click create button - const createButton = screen.getByRole('button', { name: /create deployment/i }) - fireEvent.click(createButton) + const createButton = screen.getByRole('button', { name: /create deployment/i }); + fireEvent.click(createButton); // Wait for create dialog to appear await waitFor(() => { - expect(screen.getByRole('dialog')).toBeInTheDocument() - }) + expect(screen.getByRole('dialog')).toBeInTheDocument(); + }); // Find YAML editor and enter deployment YAML with custom namespace - const yamlEditor = screen.getByRole('textbox') + const yamlEditor = screen.getByRole('textbox'); const deploymentYaml = `apiVersion: apps/v1 kind: Deployment metadata: @@ -1655,19 +1655,19 @@ spec: spec: containers: - name: test - image: nginx:latest` + image: nginx:latest`; - await user.clear(yamlEditor) - await user.type(yamlEditor, deploymentYaml) + await user.clear(yamlEditor); + await user.type(yamlEditor, deploymentYaml); // Find and click submit button - const submitButton = screen.getByRole('button', { name: /continue/i }) - fireEvent.click(submitButton) + const submitButton = screen.getByRole('button', { name: /continue/i }); + fireEvent.click(submitButton); // Verify the deployment was created (this would trigger refetch) await waitFor(() => { - expect(screen.getByText('nginx-deployment')).toBeInTheDocument() - }) - }) - }) -}) \ No newline at end of file + expect(screen.getByText('nginx-deployment')).toBeInTheDocument(); + }); + }); + }); +}); \ No newline at end of file diff --git a/apps/ops-dashboard/__tests__/components/resources/endpoints.test.tsx b/apps/ops-dashboard/__tests__/components/resources/endpoints.test.tsx index 5774559..64325fd 100644 --- a/apps/ops-dashboard/__tests__/components/resources/endpoints.test.tsx +++ b/apps/ops-dashboard/__tests__/components/resources/endpoints.test.tsx @@ -1,205 +1,206 @@ -import React from 'react' -import { render, screen, waitFor } from '../../utils/test-utils' -import userEvent from '@testing-library/user-event' -import { EndpointsView } from '../../../components/resources/endpoints' -import { server } from '@/__mocks__/server' +import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { server } from '@/__mocks__/server'; + import { - createEndpointsList, createAllEndpointsList, - createEndpointsListError, - createEndpointsListSlow, + createEndpointDelete, + createEndpointsList, createEndpointsListData, - createEndpointDelete -} from '../../../__mocks__/handlers/endpoints' + createEndpointsListError, + createEndpointsListSlow} from '../../../__mocks__/handlers/endpoints'; +import { EndpointsView } from '../../../components/resources/endpoints'; +import { render, screen, waitFor } from '../../utils/test-utils'; // Mock the confirmDialog function jest.mock('../../../hooks/useConfirm', () => ({ ...jest.requireActual('../../../hooks/useConfirm'), confirmDialog: jest.fn() -})) +})); -const mockAlert = jest.fn() +const mockAlert = jest.fn(); beforeAll(() => { - jest.spyOn(window, 'alert').mockImplementation(mockAlert) -}) + jest.spyOn(window, 'alert').mockImplementation(mockAlert); +}); afterEach(() => { - server.resetHandlers() - mockAlert.mockClear() -}) + server.resetHandlers(); + mockAlert.mockClear(); +}); afterAll(() => { - jest.restoreAllMocks() -}) + jest.restoreAllMocks(); +}); describe('EndpointsView', () => { describe('Basic Rendering', () => { it('should render endpoints view with header', () => { - server.use(createEndpointsList()) - render() + server.use(createEndpointsList()); + render(); - expect(screen.getByRole('heading', { name: 'Endpoints', level: 2 })).toBeInTheDocument() - expect(screen.getByText('Network endpoints for services')).toBeInTheDocument() - }) + expect(screen.getByRole('heading', { name: 'Endpoints', level: 2 })).toBeInTheDocument(); + expect(screen.getByText('Network endpoints for services')).toBeInTheDocument(); + }); it('should render refresh button', () => { - server.use(createEndpointsList()) - render() + server.use(createEndpointsList()); + render(); - expect(screen.getAllByRole('button', { name: '' })[0]).toBeInTheDocument() // Refresh button - }) + expect(screen.getAllByRole('button', { name: '' })[0]).toBeInTheDocument(); // Refresh button + }); it('should render stats cards', () => { - server.use(createEndpointsList()) - render() + server.use(createEndpointsList()); + render(); - expect(screen.getByText('Total Endpoints')).toBeInTheDocument() - expect(screen.getByText('With Addresses')).toBeInTheDocument() - expect(screen.getByText('Total Addresses')).toBeInTheDocument() - expect(screen.getByText('Empty Endpoints')).toBeInTheDocument() - }) + expect(screen.getByText('Total Endpoints')).toBeInTheDocument(); + expect(screen.getByText('With Addresses')).toBeInTheDocument(); + expect(screen.getByText('Total Addresses')).toBeInTheDocument(); + expect(screen.getByText('Empty Endpoints')).toBeInTheDocument(); + }); it('should render table with correct headers', async () => { - server.use(createEndpointsList()) - render() + server.use(createEndpointsList()); + render(); await waitFor(() => { - expect(screen.getByRole('columnheader', { name: 'Name' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Namespace' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Status' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Addresses' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Ports' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Created' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Actions' })).toBeInTheDocument() - }) - }) - }) + expect(screen.getByRole('columnheader', { name: 'Name' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Namespace' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Status' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Addresses' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Ports' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Created' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Actions' })).toBeInTheDocument(); + }); + }); + }); describe('Data Loading and Display', () => { it('should display endpoints data correctly', async () => { - server.use(createEndpointsList()) - render() + server.use(createEndpointsList()); + render(); await waitFor(() => { - expect(screen.getByText('web-service')).toBeInTheDocument() - expect(screen.getByText('api-service')).toBeInTheDocument() - expect(screen.getAllByText('default')).toHaveLength(3) // Three endpoints in default namespace - expect(screen.getByText('kubernetes')).toBeInTheDocument() - }) - }) + expect(screen.getByText('web-service')).toBeInTheDocument(); + expect(screen.getByText('api-service')).toBeInTheDocument(); + expect(screen.getAllByText('default')).toHaveLength(3); // Three endpoints in default namespace + expect(screen.getByText('kubernetes')).toBeInTheDocument(); + }); + }); it('should display correct statistics', async () => { - server.use(createEndpointsList()) - render() + server.use(createEndpointsList()); + render(); await waitFor(() => { - expect(screen.getAllByText('3')).toHaveLength(2) // Total Endpoints and With Addresses - expect(screen.getByText('6')).toBeInTheDocument() // Total Addresses (2+3+1) - expect(screen.getByText('0')).toBeInTheDocument() // Empty Endpoints in default namespace - }) - }) + expect(screen.getAllByText('3')).toHaveLength(2); // Total Endpoints and With Addresses + expect(screen.getByText('6')).toBeInTheDocument(); // Total Addresses (2+3+1) + expect(screen.getByText('0')).toBeInTheDocument(); // Empty Endpoints in default namespace + }); + }); it('should display status badges correctly', async () => { - server.use(createEndpointsList()) - render() + server.use(createEndpointsList()); + render(); await waitFor(() => { - expect(screen.getAllByText('Ready')).toHaveLength(3) // Three ready endpoints - }) - }) + expect(screen.getAllByText('Ready')).toHaveLength(3); // Three ready endpoints + }); + }); it('should display addresses correctly', async () => { - server.use(createEndpointsList()) - render() + server.use(createEndpointsList()); + render(); await waitFor(() => { - expect(screen.getByText('10.244.1.10, 10.244.1.11')).toBeInTheDocument() - expect(screen.getByText('10.244.2.10, 10.244.2.11, 10.244.2.12')).toBeInTheDocument() - expect(screen.getByText('192.168.1.100')).toBeInTheDocument() - }) - }) + expect(screen.getByText('10.244.1.10, 10.244.1.11')).toBeInTheDocument(); + expect(screen.getByText('10.244.2.10, 10.244.2.11, 10.244.2.12')).toBeInTheDocument(); + expect(screen.getByText('192.168.1.100')).toBeInTheDocument(); + }); + }); it('should display port counts correctly', async () => { - server.use(createEndpointsList()) - render() + server.use(createEndpointsList()); + render(); await waitFor(() => { - expect(screen.getByText('2 port(s)')).toBeInTheDocument() // web-service - expect(screen.getAllByText('1 port(s)')).toHaveLength(2) // api-service and kubernetes - }) - }) + expect(screen.getByText('2 port(s)')).toBeInTheDocument(); // web-service + expect(screen.getAllByText('1 port(s)')).toHaveLength(2); // api-service and kubernetes + }); + }); it('should display creation date correctly', async () => { - server.use(createEndpointsList()) - render() + server.use(createEndpointsList()); + render(); await waitFor(() => { - expect(screen.getAllByText('1/15/2024')).toHaveLength(3) // Three endpoints with same date - }) - }) - }) + expect(screen.getAllByText('1/15/2024')).toHaveLength(3); // Three endpoints with same date + }); + }); + }); describe('Loading States', () => { it('should show loading spinner when loading', () => { - server.use(createEndpointsListSlow()) - render() + server.use(createEndpointsListSlow()); + render(); - expect(document.querySelector('svg.lucide-refresh-cw.animate-spin')).toBeInTheDocument() - }) + expect(document.querySelector('svg.lucide-refresh-cw.animate-spin')).toBeInTheDocument(); + }); it('should disable refresh button when loading', () => { - server.use(createEndpointsListSlow()) - render() + server.use(createEndpointsListSlow()); + render(); - const refreshButton = screen.getAllByRole('button', { name: '' })[0] - expect(refreshButton).toBeDisabled() - }) - }) + const refreshButton = screen.getAllByRole('button', { name: '' })[0]; + expect(refreshButton).toBeDisabled(); + }); + }); describe('Error States', () => { it('should display error message when fetch fails', async () => { - server.use(createEndpointsListError(500, 'Server Error')) - render() + server.use(createEndpointsListError(500, 'Server Error')); + render(); await waitFor(() => { - expect(screen.getByText(/Server Error/)).toBeInTheDocument() - expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument() - }) - }) + expect(screen.getByText(/Server Error/)).toBeInTheDocument(); + expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument(); + }); + }); it('should show retry button in error state', async () => { - server.use(createEndpointsListError()) - render() + server.use(createEndpointsListError()); + render(); await waitFor(() => { - expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument() - }) - }) - }) + expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument(); + }); + }); + }); describe('Empty States', () => { it('should display empty state when no endpoints', async () => { - server.use(createEndpointsList([])) - render() + server.use(createEndpointsList([])); + render(); await waitFor(() => { - expect(screen.getByText('No endpoints found')).toBeInTheDocument() - expect(screen.getByRole('button', { name: /refresh/i })).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('No endpoints found')).toBeInTheDocument(); + expect(screen.getByRole('button', { name: /refresh/i })).toBeInTheDocument(); + }); + }); + }); describe('User Interactions', () => { it('should refresh data when refresh button is clicked', async () => { - const user = userEvent.setup() - const endpoints = createEndpointsListData() - server.use(createEndpointsList(endpoints)) - render() + const user = userEvent.setup(); + const endpoints = createEndpointsListData(); + server.use(createEndpointsList(endpoints)); + render(); await waitFor(() => { - expect(screen.getByText('web-service')).toBeInTheDocument() - }) + expect(screen.getByText('web-service')).toBeInTheDocument(); + }); // Simulate new data after refresh const newEndpoints = [...endpoints, { @@ -210,114 +211,114 @@ describe('EndpointsView', () => { ports: [{ name: 'http', port: 8080, protocol: 'TCP' }] } ] - }] - server.use(createEndpointsList(newEndpoints)) + }]; + server.use(createEndpointsList(newEndpoints)); - const refreshButton = screen.getAllByRole('button', { name: '' })[0] - await user.click(refreshButton) + const refreshButton = screen.getAllByRole('button', { name: '' })[0]; + await user.click(refreshButton); await waitFor(() => { - expect(screen.getByText('new-service')).toBeInTheDocument() - }) - }) + expect(screen.getByText('new-service')).toBeInTheDocument(); + }); + }); it('should show delete confirmation when delete button is clicked', async () => { - const user = userEvent.setup() - const { confirmDialog } = require('../../../hooks/useConfirm') - confirmDialog.mockResolvedValue(true) + const user = userEvent.setup(); + const { confirmDialog } = require('../../../hooks/useConfirm'); + confirmDialog.mockResolvedValue(true); - server.use(createEndpointsList(), createEndpointDelete()) - render() + server.use(createEndpointsList(), createEndpointDelete()); + render(); await waitFor(() => { - expect(screen.getByText('web-service')).toBeInTheDocument() - }) + expect(screen.getByText('web-service')).toBeInTheDocument(); + }); const deleteButton = screen.getAllByRole('button').find(button => button.querySelector('svg.lucide-trash2') - ) - expect(deleteButton).toBeInTheDocument() + ); + expect(deleteButton).toBeInTheDocument(); if (deleteButton) { - await user.click(deleteButton) + await user.click(deleteButton); expect(confirmDialog).toHaveBeenCalledWith({ title: 'Delete Endpoint', description: 'Are you sure you want to delete web-service?', confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); } - }) + }); it('should show view button when view button is clicked', async () => { - const user = userEvent.setup() - server.use(createEndpointsList()) - render() + const user = userEvent.setup(); + server.use(createEndpointsList()); + render(); await waitFor(() => { - expect(screen.getByText('web-service')).toBeInTheDocument() - }) + expect(screen.getByText('web-service')).toBeInTheDocument(); + }); const viewButton = screen.getAllByRole('button').find(button => button.querySelector('svg.lucide-eye') - ) - expect(viewButton).toBeInTheDocument() + ); + expect(viewButton).toBeInTheDocument(); if (viewButton) { - await user.click(viewButton) + await user.click(viewButton); // View functionality sets selectedEndpoint state // This is tested indirectly through the component's internal state } - }) + }); it('should disable delete button for kubernetes endpoint', async () => { - server.use(createEndpointsList()) - render() + server.use(createEndpointsList()); + render(); await waitFor(() => { - expect(screen.getByText('kubernetes')).toBeInTheDocument() - }) + expect(screen.getByText('kubernetes')).toBeInTheDocument(); + }); - const kubernetesRow = screen.getByText('kubernetes').closest('tr') - const deleteButton = kubernetesRow?.querySelector('button[class*="text-destructive"]') - expect(deleteButton).toBeDisabled() - }) - }) + const kubernetesRow = screen.getByText('kubernetes').closest('tr'); + const deleteButton = kubernetesRow?.querySelector('button[class*="text-destructive"]'); + expect(deleteButton).toBeDisabled(); + }); + }); describe('Status Logic', () => { it('should show Ready status when endpoint has addresses', async () => { - server.use(createEndpointsList()) - render() + server.use(createEndpointsList()); + render(); await waitFor(() => { - expect(screen.getAllByText('Ready')).toHaveLength(3) // Three ready endpoints - }) - }) + expect(screen.getAllByText('Ready')).toHaveLength(3); // Three ready endpoints + }); + }); it('should show No Endpoints status when endpoint has no addresses', async () => { const endpoints = [{ metadata: { name: 'empty-service', namespace: 'default', uid: 'ep-empty', creationTimestamp: '2024-01-15T14:00:00Z' }, subsets: [] // Empty subsets - }] - server.use(createEndpointsList(endpoints)) - render() + }]; + server.use(createEndpointsList(endpoints)); + render(); await waitFor(() => { - expect(screen.getByText('No Endpoints')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('No Endpoints')).toBeInTheDocument(); + }); + }); + }); describe('Address Display Logic', () => { it('should display all addresses when 3 or fewer', async () => { - server.use(createEndpointsList()) - render() + server.use(createEndpointsList()); + render(); await waitFor(() => { - expect(screen.getByText('10.244.1.10, 10.244.1.11')).toBeInTheDocument() - expect(screen.getByText('10.244.2.10, 10.244.2.11, 10.244.2.12')).toBeInTheDocument() - }) - }) + expect(screen.getByText('10.244.1.10, 10.244.1.11')).toBeInTheDocument(); + expect(screen.getByText('10.244.2.10, 10.244.2.11, 10.244.2.12')).toBeInTheDocument(); + }); + }); it('should display truncated addresses when more than 3', async () => { const endpoints = [{ @@ -334,94 +335,94 @@ describe('EndpointsView', () => { ports: [{ name: 'http', port: 8080, protocol: 'TCP' }] } ] - }] - server.use(createEndpointsList(endpoints)) - render() + }]; + server.use(createEndpointsList(endpoints)); + render(); await waitFor(() => { - expect(screen.getByText('10.244.1.10, 10.244.1.11, 10.244.1.12 +2 more')).toBeInTheDocument() - }) - }) + expect(screen.getByText('10.244.1.10, 10.244.1.11, 10.244.1.12 +2 more')).toBeInTheDocument(); + }); + }); it('should display None when no addresses', async () => { const endpoints = [{ metadata: { name: 'no-addresses', namespace: 'default', uid: 'ep-none', creationTimestamp: '2024-01-15T16:00:00Z' }, subsets: [] // Empty subsets - }] - server.use(createEndpointsList(endpoints)) - render() + }]; + server.use(createEndpointsList(endpoints)); + render(); await waitFor(() => { - expect(screen.getByText('None')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('None')).toBeInTheDocument(); + }); + }); + }); describe('Port Count Logic', () => { it('should count unique ports correctly', async () => { - server.use(createEndpointsList()) - render() + server.use(createEndpointsList()); + render(); await waitFor(() => { - expect(screen.getByText('2 port(s)')).toBeInTheDocument() // web-service with 2 ports - expect(screen.getAllByText('1 port(s)')).toHaveLength(2) // api-service and kubernetes with 1 port each - }) - }) - }) + expect(screen.getByText('2 port(s)')).toBeInTheDocument(); // web-service with 2 ports + expect(screen.getAllByText('1 port(s)')).toHaveLength(2); // api-service and kubernetes with 1 port each + }); + }); + }); describe('All Namespaces Mode', () => { it('should show all endpoints when in all namespaces mode', async () => { // This test is simplified due to mock complexity // In a real scenario, the component would use useListCoreV1EndpointsForAllNamespacesQuery - server.use(createAllEndpointsList()) - render() + server.use(createAllEndpointsList()); + render(); // The component will still use the default namespace context // This test verifies the handler works correctly await waitFor(() => { - expect(screen.getByText('Network request failed')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('Network request failed')).toBeInTheDocument(); + }); + }); + }); describe('Accessibility', () => { it('should have proper button roles and labels', () => { - server.use(createEndpointsList()) - render() + server.use(createEndpointsList()); + render(); - expect(screen.getAllByRole('button', { name: '' })[0]).toBeInTheDocument() // Refresh button - }) + expect(screen.getAllByRole('button', { name: '' })[0]).toBeInTheDocument(); // Refresh button + }); it('should have proper table structure', async () => { - server.use(createEndpointsList()) - render() + server.use(createEndpointsList()); + render(); await waitFor(() => { - expect(screen.getByRole('table')).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Name' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Namespace' })).toBeInTheDocument() - }) - }) + expect(screen.getByRole('table')).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Name' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Namespace' })).toBeInTheDocument(); + }); + }); it('should be keyboard navigable', async () => { - const user = userEvent.setup() - server.use(createEndpointsList()) - render() + const user = userEvent.setup(); + server.use(createEndpointsList()); + render(); // Wait for data to load first await waitFor(() => { - expect(screen.getByText('web-service')).toBeInTheDocument() - }) + expect(screen.getByText('web-service')).toBeInTheDocument(); + }); - const refreshButton = screen.getAllByRole('button', { name: '' })[0] - refreshButton.focus() + const refreshButton = screen.getAllByRole('button', { name: '' })[0]; + refreshButton.focus(); - expect(document.activeElement).toBe(refreshButton) + expect(document.activeElement).toBe(refreshButton); // Test that tab navigation works - await user.tab() + await user.tab(); // The focus should move to the next focusable element - expect(document.activeElement).not.toBe(refreshButton) - }) - }) -}) + expect(document.activeElement).not.toBe(refreshButton); + }); + }); +}); diff --git a/apps/ops-dashboard/__tests__/components/resources/endpointslices.test.tsx b/apps/ops-dashboard/__tests__/components/resources/endpointslices.test.tsx index 1d927fa..7173cba 100644 --- a/apps/ops-dashboard/__tests__/components/resources/endpointslices.test.tsx +++ b/apps/ops-dashboard/__tests__/components/resources/endpointslices.test.tsx @@ -1,16 +1,17 @@ -import { render, screen, waitFor } from '@testing-library/react' -import userEvent from '@testing-library/user-event' -import { EndpointSlicesView } from '@/components/resources/endpointslices' +import { render, screen, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; + +import { EndpointSlicesView } from '@/components/resources/endpointslices'; // Mock the confirm dialog jest.mock('../../../hooks/useConfirm', () => ({ confirmDialog: jest.fn().mockResolvedValue(true) -})) +})); // Mock the Kubernetes hooks jest.mock('../../../contexts/NamespaceContext', () => ({ usePreferredNamespace: () => ({ namespace: 'default' }) -})) +})); jest.mock('../../../k8s', () => ({ useListDiscoveryV1NamespacedEndpointSliceQuery: jest.fn(() => ({ @@ -87,100 +88,100 @@ jest.mock('../../../k8s', () => ({ mutate: jest.fn(), isPending: false })) -})) +})); describe('EndpointSlicesView', () => { describe('Basic Rendering', () => { it('should render endpoint slices view with header', () => { - render() + render(); - expect(screen.getByRole('heading', { name: 'Endpoint Slices', level: 2 })).toBeInTheDocument() - expect(screen.getByText('Scalable network endpoint groupings')).toBeInTheDocument() - }) + expect(screen.getByRole('heading', { name: 'Endpoint Slices', level: 2 })).toBeInTheDocument(); + expect(screen.getByText('Scalable network endpoint groupings')).toBeInTheDocument(); + }); it('should render refresh button', () => { - render() + render(); // The refresh button is an icon button without accessible name - const refreshButtons = screen.getAllByRole('button') + const refreshButtons = screen.getAllByRole('button'); const headerRefreshButton = refreshButtons.find(button => button.querySelector('svg.lucide-refresh-cw') && button.classList.contains('h-10') // Header refresh button has h-10 class - ) - expect(headerRefreshButton).toBeInTheDocument() - }) + ); + expect(headerRefreshButton).toBeInTheDocument(); + }); it('should render stats cards', () => { - render() + render(); - expect(screen.getByText('Total Slices')).toBeInTheDocument() - expect(screen.getByText('Total Endpoints')).toBeInTheDocument() - expect(screen.getByText('Ready Endpoints')).toBeInTheDocument() - expect(screen.getByText('Services')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Total Slices')).toBeInTheDocument(); + expect(screen.getByText('Total Endpoints')).toBeInTheDocument(); + expect(screen.getByText('Ready Endpoints')).toBeInTheDocument(); + expect(screen.getByText('Services')).toBeInTheDocument(); + }); + }); describe('Data Display', () => { it('should display endpoint slice data', async () => { - render() + render(); await waitFor(() => { - expect(screen.getByText('web-service-slice-1')).toBeInTheDocument() - expect(screen.getByText('api-service-slice-1')).toBeInTheDocument() - }) - }) + expect(screen.getByText('web-service-slice-1')).toBeInTheDocument(); + expect(screen.getByText('api-service-slice-1')).toBeInTheDocument(); + }); + }); it('should display correct statistics', async () => { - render() + render(); await waitFor(() => { - expect(screen.getAllByText('2')).toHaveLength(2) // Total Slices and Services - expect(screen.getAllByText('3')).toHaveLength(2) // Total Endpoints and Ready Endpoints - }) - }) + expect(screen.getAllByText('2')).toHaveLength(2); // Total Slices and Services + expect(screen.getAllByText('3')).toHaveLength(2); // Total Endpoints and Ready Endpoints + }); + }); it('should display status badges correctly', async () => { - render() + render(); await waitFor(() => { - expect(screen.getAllByText('All Ready')).toHaveLength(2) - }) - }) + expect(screen.getAllByText('All Ready')).toHaveLength(2); + }); + }); it('should display endpoint counts correctly', async () => { - render() + render(); await waitFor(() => { - expect(screen.getAllByText('2/2')).toHaveLength(1) // web-service-slice-1 - expect(screen.getByText('1/1')).toBeInTheDocument() // api-service-slice-1 - }) - }) + expect(screen.getAllByText('2/2')).toHaveLength(1); // web-service-slice-1 + expect(screen.getByText('1/1')).toBeInTheDocument(); // api-service-slice-1 + }); + }); it('should display address type correctly', async () => { - render() + render(); await waitFor(() => { - expect(screen.getAllByText('IPv4')).toHaveLength(2) - }) - }) + expect(screen.getAllByText('IPv4')).toHaveLength(2); + }); + }); it('should display ports correctly', async () => { - render() + render(); await waitFor(() => { - expect(screen.getByText('http:80/TCP, https:443/TCP')).toBeInTheDocument() - expect(screen.getByText('api:8080/TCP')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('http:80/TCP, https:443/TCP')).toBeInTheDocument(); + expect(screen.getByText('api:8080/TCP')).toBeInTheDocument(); + }); + }); + }); describe('User Interactions', () => { it('should refresh data when refresh button is clicked', async () => { - const user = userEvent.setup() - const mockRefetch = jest.fn() + const user = userEvent.setup(); + const mockRefetch = jest.fn(); // Mock the hook to return a refetch function - const { useListDiscoveryV1NamespacedEndpointSliceQuery } = require('../../../k8s') + const { useListDiscoveryV1NamespacedEndpointSliceQuery } = require('../../../k8s'); useListDiscoveryV1NamespacedEndpointSliceQuery.mockReturnValue({ data: { apiVersion: 'discovery.k8s.io/v1', @@ -190,25 +191,25 @@ describe('EndpointSlicesView', () => { isLoading: false, error: null, refetch: mockRefetch - }) + }); - render() + render(); - const refreshButtons = screen.getAllByRole('button') + const refreshButtons = screen.getAllByRole('button'); const refreshButton = refreshButtons.find(button => button.querySelector('svg.lucide-refresh-cw') && button.classList.contains('h-10') - ) - await user.click(refreshButton) + ); + await user.click(refreshButton); - expect(mockRefetch).toHaveBeenCalled() - }) + expect(mockRefetch).toHaveBeenCalled(); + }); it('should show delete confirmation when delete button is clicked', async () => { - const user = userEvent.setup() + const user = userEvent.setup(); // Mock the hook to return data - const { useListDiscoveryV1NamespacedEndpointSliceQuery } = require('../../../k8s') + const { useListDiscoveryV1NamespacedEndpointSliceQuery } = require('../../../k8s'); useListDiscoveryV1NamespacedEndpointSliceQuery.mockReturnValue({ data: { apiVersion: 'discovery.k8s.io/v1', @@ -232,31 +233,31 @@ describe('EndpointSlicesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('web-service-slice-1')).toBeInTheDocument() - }) + expect(screen.getByText('web-service-slice-1')).toBeInTheDocument(); + }); - const deleteButtons = screen.getAllByRole('button') + const deleteButtons = screen.getAllByRole('button'); const deleteButton = deleteButtons.find(button => button.querySelector('svg.lucide-trash-2') - ) + ); if (deleteButton) { - await user.click(deleteButton) + await user.click(deleteButton); // The confirm dialog is mocked to return true - expect(deleteButton).toBeInTheDocument() + expect(deleteButton).toBeInTheDocument(); } - }) + }); it('should show view button when view button is clicked', async () => { - const user = userEvent.setup() + const user = userEvent.setup(); // Mock the hook to return data - const { useListDiscoveryV1NamespacedEndpointSliceQuery } = require('../../../k8s') + const { useListDiscoveryV1NamespacedEndpointSliceQuery } = require('../../../k8s'); useListDiscoveryV1NamespacedEndpointSliceQuery.mockReturnValue({ data: { apiVersion: 'discovery.k8s.io/v1', @@ -280,28 +281,28 @@ describe('EndpointSlicesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('web-service-slice-1')).toBeInTheDocument() - }) + expect(screen.getByText('web-service-slice-1')).toBeInTheDocument(); + }); - const viewButtons = screen.getAllByRole('button') + const viewButtons = screen.getAllByRole('button'); const viewButton = viewButtons.find(button => button.querySelector('svg.lucide-eye') - ) + ); if (viewButton) { - await user.click(viewButton) - expect(viewButton).toBeInTheDocument() + await user.click(viewButton); + expect(viewButton).toBeInTheDocument(); } - }) + }); it('should disable delete button for kubernetes slice', async () => { // Mock data with kubernetes slice - const { useListDiscoveryV1NamespacedEndpointSliceQuery } = require('../../../k8s') + const { useListDiscoveryV1NamespacedEndpointSliceQuery } = require('../../../k8s'); useListDiscoveryV1NamespacedEndpointSliceQuery.mockReturnValue({ data: { apiVersion: 'discovery.k8s.io/v1', @@ -323,37 +324,37 @@ describe('EndpointSlicesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('kubernetes-slice')).toBeInTheDocument() - }) + expect(screen.getByText('kubernetes-slice')).toBeInTheDocument(); + }); // Check if the kubernetes slice is rendered - expect(screen.getByText('kubernetes-slice')).toBeInTheDocument() + expect(screen.getByText('kubernetes-slice')).toBeInTheDocument(); // Find all buttons and check if any contain trash icon - const allButtons = screen.getAllByRole('button') + const allButtons = screen.getAllByRole('button'); const deleteButton = allButtons.find(button => button.querySelector('svg[class*="trash"]') || button.querySelector('svg[class*="Trash"]') - ) + ); if (deleteButton) { - expect(deleteButton).toBeDisabled() + expect(deleteButton).toBeDisabled(); } else { // If no delete button found, that's also acceptable for kubernetes slices - expect(allButtons.length).toBeGreaterThan(0) + expect(allButtons.length).toBeGreaterThan(0); } - }) - }) + }); + }); describe('Status Logic', () => { it('should show All Ready status when all endpoints are ready', async () => { // Mock the hook to return data with all ready endpoints - const { useListDiscoveryV1NamespacedEndpointSliceQuery } = require('../../../k8s') + const { useListDiscoveryV1NamespacedEndpointSliceQuery } = require('../../../k8s'); useListDiscoveryV1NamespacedEndpointSliceQuery.mockReturnValue({ data: { apiVersion: 'discovery.k8s.io/v1', @@ -380,17 +381,17 @@ describe('EndpointSlicesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('All Ready')).toBeInTheDocument() - }) - }) + expect(screen.getByText('All Ready')).toBeInTheDocument(); + }); + }); it('should show None Ready status when no endpoints are ready', async () => { - const { useListDiscoveryV1NamespacedEndpointSliceQuery } = require('../../../k8s') + const { useListDiscoveryV1NamespacedEndpointSliceQuery } = require('../../../k8s'); useListDiscoveryV1NamespacedEndpointSliceQuery.mockReturnValue({ data: { apiVersion: 'discovery.k8s.io/v1', @@ -413,17 +414,17 @@ describe('EndpointSlicesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('None Ready')).toBeInTheDocument() - }) - }) + expect(screen.getByText('None Ready')).toBeInTheDocument(); + }); + }); it('should show Partial Ready status when some endpoints are ready', async () => { - const { useListDiscoveryV1NamespacedEndpointSliceQuery } = require('../../../k8s') + const { useListDiscoveryV1NamespacedEndpointSliceQuery } = require('../../../k8s'); useListDiscoveryV1NamespacedEndpointSliceQuery.mockReturnValue({ data: { apiVersion: 'discovery.k8s.io/v1', @@ -447,17 +448,17 @@ describe('EndpointSlicesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('Partial Ready')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Partial Ready')).toBeInTheDocument(); + }); + }); it('should show Empty status when no endpoints', async () => { - const { useListDiscoveryV1NamespacedEndpointSliceQuery } = require('../../../k8s') + const { useListDiscoveryV1NamespacedEndpointSliceQuery } = require('../../../k8s'); useListDiscoveryV1NamespacedEndpointSliceQuery.mockReturnValue({ data: { apiVersion: 'discovery.k8s.io/v1', @@ -478,66 +479,66 @@ describe('EndpointSlicesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('Empty')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('Empty')).toBeInTheDocument(); + }); + }); + }); describe('Loading States', () => { it('should show loading spinner when loading', () => { - const { useListDiscoveryV1NamespacedEndpointSliceQuery } = require('../../../k8s') + const { useListDiscoveryV1NamespacedEndpointSliceQuery } = require('../../../k8s'); useListDiscoveryV1NamespacedEndpointSliceQuery.mockReturnValue({ data: null, isLoading: true, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('button', { name: '' })).toBeDisabled() - expect(screen.getByRole('button', { name: '' }).querySelector('svg')).toHaveClass('animate-spin') - }) - }) + expect(screen.getByRole('button', { name: '' })).toBeDisabled(); + expect(screen.getByRole('button', { name: '' }).querySelector('svg')).toHaveClass('animate-spin'); + }); + }); describe('Error States', () => { it('should display error message when fetch fails', () => { - const { useListDiscoveryV1NamespacedEndpointSliceQuery } = require('../../../k8s') + const { useListDiscoveryV1NamespacedEndpointSliceQuery } = require('../../../k8s'); useListDiscoveryV1NamespacedEndpointSliceQuery.mockReturnValue({ data: null, isLoading: false, error: new Error('Network request failed'), refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByText(/Network request failed/)).toBeInTheDocument() - }) + expect(screen.getByText(/Network request failed/)).toBeInTheDocument(); + }); it('should show retry button in error state', () => { - const { useListDiscoveryV1NamespacedEndpointSliceQuery } = require('../../../k8s') + const { useListDiscoveryV1NamespacedEndpointSliceQuery } = require('../../../k8s'); useListDiscoveryV1NamespacedEndpointSliceQuery.mockReturnValue({ data: null, isLoading: false, error: new Error('Network request failed'), refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument() - }) - }) + expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument(); + }); + }); describe('Empty States', () => { it('should display empty state when no endpoint slices', () => { - const { useListDiscoveryV1NamespacedEndpointSliceQuery } = require('../../../k8s') + const { useListDiscoveryV1NamespacedEndpointSliceQuery } = require('../../../k8s'); useListDiscoveryV1NamespacedEndpointSliceQuery.mockReturnValue({ data: { apiVersion: 'discovery.k8s.io/v1', @@ -547,27 +548,27 @@ describe('EndpointSlicesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByText('No endpoint slices found')).toBeInTheDocument() - expect(screen.getByRole('button', { name: /refresh/i })).toBeInTheDocument() - }) - }) + expect(screen.getByText('No endpoint slices found')).toBeInTheDocument(); + expect(screen.getByRole('button', { name: /refresh/i })).toBeInTheDocument(); + }); + }); describe('Accessibility', () => { it('should have proper button roles and labels', () => { - render() + render(); - expect(screen.getAllByRole('button', { name: '' })[0]).toBeInTheDocument() // Refresh button - }) + expect(screen.getAllByRole('button', { name: '' })[0]).toBeInTheDocument(); // Refresh button + }); it('should be keyboard navigable', async () => { - const user = userEvent.setup() + const user = userEvent.setup(); // Mock the hook to return data - const { useListDiscoveryV1NamespacedEndpointSliceQuery } = require('../../../k8s') + const { useListDiscoveryV1NamespacedEndpointSliceQuery } = require('../../../k8s'); useListDiscoveryV1NamespacedEndpointSliceQuery.mockReturnValue({ data: { apiVersion: 'discovery.k8s.io/v1', @@ -591,28 +592,28 @@ describe('EndpointSlicesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); // Wait for data to load first await waitFor(() => { - expect(screen.getByText('web-service-slice-1')).toBeInTheDocument() - }) + expect(screen.getByText('web-service-slice-1')).toBeInTheDocument(); + }); - const refreshButtons = screen.getAllByRole('button') + const refreshButtons = screen.getAllByRole('button'); const refreshButton = refreshButtons.find(button => button.querySelector('svg.lucide-refresh-cw') && button.classList.contains('h-10') - ) - refreshButton.focus() + ); + refreshButton.focus(); - expect(document.activeElement).toBe(refreshButton) + expect(document.activeElement).toBe(refreshButton); // Test that tab navigation works - await user.tab() + await user.tab(); // The focus should move to the next focusable element - expect(document.activeElement).not.toBe(refreshButton) - }) - }) -}) \ No newline at end of file + expect(document.activeElement).not.toBe(refreshButton); + }); + }); +}); \ No newline at end of file diff --git a/apps/ops-dashboard/__tests__/components/resources/events.test.tsx b/apps/ops-dashboard/__tests__/components/resources/events.test.tsx index 9be42f6..71d4973 100644 --- a/apps/ops-dashboard/__tests__/components/resources/events.test.tsx +++ b/apps/ops-dashboard/__tests__/components/resources/events.test.tsx @@ -1,6 +1,7 @@ -import { render, screen, waitFor } from '@testing-library/react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { render, screen, waitFor } from '@testing-library/react'; import { ThemeProvider } from 'next-themes'; + import { EventsView } from '@/components/resources/events'; // Mock the Kubernetes hooks diff --git a/apps/ops-dashboard/__tests__/components/resources/hpas.test.tsx b/apps/ops-dashboard/__tests__/components/resources/hpas.test.tsx index 234e459..24bd12d 100644 --- a/apps/ops-dashboard/__tests__/components/resources/hpas.test.tsx +++ b/apps/ops-dashboard/__tests__/components/resources/hpas.test.tsx @@ -1,220 +1,221 @@ -import React from 'react' -import { render, screen, waitFor } from '../../utils/test-utils' -import userEvent from '@testing-library/user-event' -import { HPAsView } from '../../../components/resources/hpas' -import { server } from '@/__mocks__/server' +import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { server } from '@/__mocks__/server'; + import { - createHPAsList, createAllHPAsList, - createHPAsListError, - createHPAsListSlow, + createHPADelete, + createHPAsList, createHPAsListData, - createHPADelete -} from '../../../__mocks__/handlers/hpas' + createHPAsListError, + createHPAsListSlow} from '../../../__mocks__/handlers/hpas'; +import { HPAsView } from '../../../components/resources/hpas'; +import { render, screen, waitFor } from '../../utils/test-utils'; // Mock the confirmDialog function jest.mock('../../../hooks/useConfirm', () => ({ ...jest.requireActual('../../../hooks/useConfirm'), confirmDialog: jest.fn() -})) +})); -const mockAlert = jest.fn() +const mockAlert = jest.fn(); beforeAll(() => { - jest.spyOn(window, 'alert').mockImplementation(mockAlert) -}) + jest.spyOn(window, 'alert').mockImplementation(mockAlert); +}); afterEach(() => { - server.resetHandlers() - mockAlert.mockClear() -}) + server.resetHandlers(); + mockAlert.mockClear(); +}); afterAll(() => { - jest.restoreAllMocks() -}) + jest.restoreAllMocks(); +}); describe('HPAsView', () => { describe('Basic Rendering', () => { it('should render HPAs view with header', () => { - server.use(createHPAsList()) - render() + server.use(createHPAsList()); + render(); - expect(screen.getByRole('heading', { name: 'Horizontal Pod Autoscalers', level: 2 })).toBeInTheDocument() - expect(screen.getByText('Automatically scale your workloads based on metrics')).toBeInTheDocument() - }) + expect(screen.getByRole('heading', { name: 'Horizontal Pod Autoscalers', level: 2 })).toBeInTheDocument(); + expect(screen.getByText('Automatically scale your workloads based on metrics')).toBeInTheDocument(); + }); it('should render refresh and create buttons', () => { - server.use(createHPAsList()) - render() + server.use(createHPAsList()); + render(); - expect(screen.getAllByRole('button', { name: '' })[0]).toBeInTheDocument() // Refresh button - expect(screen.getByRole('button', { name: /create hpa/i })).toBeInTheDocument() - }) + expect(screen.getAllByRole('button', { name: '' })[0]).toBeInTheDocument(); // Refresh button + expect(screen.getByRole('button', { name: /create hpa/i })).toBeInTheDocument(); + }); it('should render stats cards', () => { - server.use(createHPAsList()) - render() + server.use(createHPAsList()); + render(); - expect(screen.getByText('Total HPAs')).toBeInTheDocument() - expect(screen.getByText('Active')).toBeInTheDocument() - expect(screen.getByText('Scaling Up')).toBeInTheDocument() - expect(screen.getByText('Total Replicas')).toBeInTheDocument() - }) + expect(screen.getByText('Total HPAs')).toBeInTheDocument(); + expect(screen.getByText('Active')).toBeInTheDocument(); + expect(screen.getByText('Scaling Up')).toBeInTheDocument(); + expect(screen.getByText('Total Replicas')).toBeInTheDocument(); + }); it('should render table with correct headers', async () => { - server.use(createHPAsList()) - render() + server.use(createHPAsList()); + render(); await waitFor(() => { - expect(screen.getByRole('columnheader', { name: 'Name' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Namespace' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Target' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Status' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Min/Max' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Current' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Metrics' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Actions' })).toBeInTheDocument() - }) - }) - }) + expect(screen.getByRole('columnheader', { name: 'Name' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Namespace' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Target' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Status' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Min/Max' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Current' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Metrics' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Actions' })).toBeInTheDocument(); + }); + }); + }); describe('Data Loading and Display', () => { it('should display HPAs data correctly', async () => { - server.use(createHPAsList()) - render() + server.use(createHPAsList()); + render(); await waitFor(() => { - expect(screen.getByText('web-hpa')).toBeInTheDocument() - expect(screen.getByText('api-hpa')).toBeInTheDocument() - expect(screen.getAllByText('default')).toHaveLength(2) // Two HPAs in default namespace - expect(screen.getByText('web-deployment')).toBeInTheDocument() - expect(screen.getByText('api-deployment')).toBeInTheDocument() - }) - }) + expect(screen.getByText('web-hpa')).toBeInTheDocument(); + expect(screen.getByText('api-hpa')).toBeInTheDocument(); + expect(screen.getAllByText('default')).toHaveLength(2); // Two HPAs in default namespace + expect(screen.getByText('web-deployment')).toBeInTheDocument(); + expect(screen.getByText('api-deployment')).toBeInTheDocument(); + }); + }); it('should display correct statistics', async () => { - server.use(createHPAsList()) - render() + server.use(createHPAsList()); + render(); await waitFor(() => { - expect(screen.getAllByText('2')).toHaveLength(2) // Total HPAs and current replicas - expect(screen.getAllByText('1')).toHaveLength(2) // Active and Scaling Up - expect(screen.getByText('5')).toBeInTheDocument() // Total Replicas (3 + 2) - }) - }) + expect(screen.getAllByText('2')).toHaveLength(2); // Total HPAs and current replicas + expect(screen.getAllByText('1')).toHaveLength(2); // Active and Scaling Up + expect(screen.getByText('5')).toBeInTheDocument(); // Total Replicas (3 + 2) + }); + }); it('should display target correctly', async () => { - server.use(createHPAsList()) - render() + server.use(createHPAsList()); + render(); await waitFor(() => { - expect(screen.getByText('web-deployment')).toBeInTheDocument() - expect(screen.getByText('api-deployment')).toBeInTheDocument() - }) - }) + expect(screen.getByText('web-deployment')).toBeInTheDocument(); + expect(screen.getByText('api-deployment')).toBeInTheDocument(); + }); + }); it('should display status badges correctly', async () => { - server.use(createHPAsList()) - render() + server.use(createHPAsList()); + render(); await waitFor(() => { - expect(screen.getAllByText('Active')).toHaveLength(2) // Card title and badge - expect(screen.getByText('Idle')).toBeInTheDocument() - }) - }) + expect(screen.getAllByText('Active')).toHaveLength(2); // Card title and badge + expect(screen.getByText('Idle')).toBeInTheDocument(); + }); + }); it('should display min/max replicas correctly', async () => { - server.use(createHPAsList()) - render() + server.use(createHPAsList()); + render(); await waitFor(() => { - expect(screen.getByText('2/10')).toBeInTheDocument() // web-hpa min/max - expect(screen.getByText('1/5')).toBeInTheDocument() // api-hpa min/max - }) - }) + expect(screen.getByText('2/10')).toBeInTheDocument(); // web-hpa min/max + expect(screen.getByText('1/5')).toBeInTheDocument(); // api-hpa min/max + }); + }); it('should display current replicas with scaling direction', async () => { - server.use(createHPAsList()) - render() + server.use(createHPAsList()); + render(); await waitFor(() => { - expect(screen.getByText('3')).toBeInTheDocument() // web-hpa current replicas - expect(screen.getAllByText('2')).toHaveLength(2) // Total HPAs and api-hpa current replicas - expect(screen.getByText('→ 5')).toBeInTheDocument() // web-hpa scaling to desired - }) - }) + expect(screen.getByText('3')).toBeInTheDocument(); // web-hpa current replicas + expect(screen.getAllByText('2')).toHaveLength(2); // Total HPAs and api-hpa current replicas + expect(screen.getByText('→ 5')).toBeInTheDocument(); // web-hpa scaling to desired + }); + }); it('should display metrics correctly', async () => { - server.use(createHPAsList()) - render() + server.use(createHPAsList()); + render(); await waitFor(() => { - expect(screen.getByText('cpu (70%)')).toBeInTheDocument() - expect(screen.getByText('memory (80%)')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('cpu (70%)')).toBeInTheDocument(); + expect(screen.getByText('memory (80%)')).toBeInTheDocument(); + }); + }); + }); describe('Loading States', () => { it('should show loading spinner when loading', () => { - server.use(createHPAsListSlow()) - render() + server.use(createHPAsListSlow()); + render(); - expect(document.querySelector('svg.lucide-refresh-cw.animate-spin')).toBeInTheDocument() - }) + expect(document.querySelector('svg.lucide-refresh-cw.animate-spin')).toBeInTheDocument(); + }); it('should disable refresh button when loading', () => { - server.use(createHPAsListSlow()) - render() + server.use(createHPAsListSlow()); + render(); - const refreshButton = screen.getAllByRole('button', { name: '' })[0] - expect(refreshButton).toBeDisabled() - }) - }) + const refreshButton = screen.getAllByRole('button', { name: '' })[0]; + expect(refreshButton).toBeDisabled(); + }); + }); describe('Error States', () => { it('should display error message when fetch fails', async () => { - server.use(createHPAsListError(500, 'Server Error')) - render() + server.use(createHPAsListError(500, 'Server Error')); + render(); await waitFor(() => { - expect(screen.getByText(/Server Error/)).toBeInTheDocument() - expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument() - }) - }) + expect(screen.getByText(/Server Error/)).toBeInTheDocument(); + expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument(); + }); + }); it('should show retry button in error state', async () => { - server.use(createHPAsListError()) - render() + server.use(createHPAsListError()); + render(); await waitFor(() => { - expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument() - }) - }) - }) + expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument(); + }); + }); + }); describe('Empty States', () => { it('should display empty state when no HPAs', async () => { - server.use(createHPAsList([])) - render() + server.use(createHPAsList([])); + render(); await waitFor(() => { - expect(screen.getByText('No horizontal pod autoscalers found')).toBeInTheDocument() - expect(screen.getByRole('button', { name: /refresh/i })).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('No horizontal pod autoscalers found')).toBeInTheDocument(); + expect(screen.getByRole('button', { name: /refresh/i })).toBeInTheDocument(); + }); + }); + }); describe('User Interactions', () => { it('should refresh data when refresh button is clicked', async () => { - const user = userEvent.setup() - const hpas = createHPAsListData() - server.use(createHPAsList(hpas)) - render() + const user = userEvent.setup(); + const hpas = createHPAsListData(); + server.use(createHPAsList(hpas)); + render(); await waitFor(() => { - expect(screen.getByText('web-hpa')).toBeInTheDocument() - }) + expect(screen.getByText('web-hpa')).toBeInTheDocument(); + }); // Simulate new data after refresh const newHPAs = [...hpas, { @@ -230,96 +231,96 @@ describe('HPAsView', () => { desiredReplicas: 1, conditions: [] } - }] - server.use(createHPAsList(newHPAs)) + }]; + server.use(createHPAsList(newHPAs)); - const refreshButton = screen.getAllByRole('button', { name: '' })[0] - await user.click(refreshButton) + const refreshButton = screen.getAllByRole('button', { name: '' })[0]; + await user.click(refreshButton); await waitFor(() => { - expect(screen.getByText('new-hpa')).toBeInTheDocument() - }) - }) + expect(screen.getByText('new-hpa')).toBeInTheDocument(); + }); + }); it('should show create HPA alert when create button is clicked', async () => { - const user = userEvent.setup() - server.use(createHPAsList()) - render() + const user = userEvent.setup(); + server.use(createHPAsList()); + render(); - const createButton = screen.getByRole('button', { name: /create hpa/i }) - await user.click(createButton) + const createButton = screen.getByRole('button', { name: /create hpa/i }); + await user.click(createButton); - expect(window.alert).toHaveBeenCalledWith('Create HPA functionality not yet implemented') - }) + expect(window.alert).toHaveBeenCalledWith('Create HPA functionality not yet implemented'); + }); it('should show delete confirmation when delete button is clicked', async () => { - const user = userEvent.setup() - const { confirmDialog } = require('../../../hooks/useConfirm') - confirmDialog.mockResolvedValue(true) + const user = userEvent.setup(); + const { confirmDialog } = require('../../../hooks/useConfirm'); + confirmDialog.mockResolvedValue(true); - server.use(createHPAsList(), createHPADelete()) - render() + server.use(createHPAsList(), createHPADelete()); + render(); await waitFor(() => { - expect(screen.getByText('web-hpa')).toBeInTheDocument() - }) + expect(screen.getByText('web-hpa')).toBeInTheDocument(); + }); const deleteButton = screen.getAllByRole('button').find(button => button.querySelector('svg.lucide-trash2') - ) - expect(deleteButton).toBeInTheDocument() + ); + expect(deleteButton).toBeInTheDocument(); if (deleteButton) { - await user.click(deleteButton) + await user.click(deleteButton); expect(confirmDialog).toHaveBeenCalledWith({ title: 'Delete Horizontal Pod Autoscaler', description: 'Are you sure you want to delete web-hpa?', confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); } - }) + }); it('should show view button when view button is clicked', async () => { - const user = userEvent.setup() - server.use(createHPAsList()) - render() + const user = userEvent.setup(); + server.use(createHPAsList()); + render(); await waitFor(() => { - expect(screen.getByText('web-hpa')).toBeInTheDocument() - }) + expect(screen.getByText('web-hpa')).toBeInTheDocument(); + }); const viewButton = screen.getAllByRole('button').find(button => button.querySelector('svg.lucide-eye') - ) - expect(viewButton).toBeInTheDocument() + ); + expect(viewButton).toBeInTheDocument(); if (viewButton) { - await user.click(viewButton) + await user.click(viewButton); // View functionality sets selectedHPA state // This is tested indirectly through the component's internal state } - }) - }) + }); + }); describe('Status Logic', () => { it('should show Active status when scaling is active', async () => { - server.use(createHPAsList()) - render() + server.use(createHPAsList()); + render(); await waitFor(() => { - expect(screen.getByText('Active')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Active')).toBeInTheDocument(); + }); + }); it('should show Idle status when not scaling', async () => { - server.use(createHPAsList()) - render() + server.use(createHPAsList()); + render(); await waitFor(() => { - expect(screen.getByText('Idle')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Idle')).toBeInTheDocument(); + }); + }); it('should show Unable to Scale status when conditions indicate failure', async () => { const hpas = [{ @@ -343,46 +344,46 @@ describe('HPAsView', () => { } ] } - }] - server.use(createHPAsList(hpas)) - render() + }]; + server.use(createHPAsList(hpas)); + render(); await waitFor(() => { - expect(screen.getByText('Unable to Scale')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('Unable to Scale')).toBeInTheDocument(); + }); + }); + }); describe('Scaling Direction Logic', () => { it('should show scaling up icon when current < desired', async () => { - server.use(createHPAsList()) - render() + server.use(createHPAsList()); + render(); await waitFor(() => { - expect(document.querySelector('svg.lucide-trending-up')).toBeInTheDocument() - }) - }) + expect(document.querySelector('svg.lucide-trending-up')).toBeInTheDocument(); + }); + }); it('should show stable icon when current = desired', async () => { - server.use(createHPAsList()) - render() + server.use(createHPAsList()); + render(); await waitFor(() => { - expect(document.querySelector('svg.lucide-minus')).toBeInTheDocument() - }) - }) - }) + expect(document.querySelector('svg.lucide-minus')).toBeInTheDocument(); + }); + }); + }); describe('Metrics Logic', () => { it('should display resource metrics correctly', async () => { - server.use(createHPAsList()) - render() + server.use(createHPAsList()); + render(); await waitFor(() => { - expect(screen.getByText('cpu (70%)')).toBeInTheDocument() - expect(screen.getByText('memory (80%)')).toBeInTheDocument() - }) - }) + expect(screen.getByText('cpu (70%)')).toBeInTheDocument(); + expect(screen.getByText('memory (80%)')).toBeInTheDocument(); + }); + }); it('should display No metrics when no metrics configured', async () => { const hpas = [{ @@ -398,65 +399,65 @@ describe('HPAsView', () => { desiredReplicas: 1, conditions: [] } - }] - server.use(createHPAsList(hpas)) - render() + }]; + server.use(createHPAsList(hpas)); + render(); await waitFor(() => { - expect(screen.getByText('No metrics')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('No metrics')).toBeInTheDocument(); + }); + }); + }); describe('All Namespaces Mode', () => { it('should show all HPAs when in all namespaces mode', async () => { // This test is simplified due to mock complexity // In a real scenario, the component would use useListAutoscalingV2HorizontalPodAutoscalerForAllNamespacesQuery - server.use(createAllHPAsList()) - render() + server.use(createAllHPAsList()); + render(); // The component will still use the default namespace context // This test verifies the handler works correctly await waitFor(() => { - expect(screen.getByText('Network request failed')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('Network request failed')).toBeInTheDocument(); + }); + }); + }); describe('Accessibility', () => { it('should have proper button roles and labels', () => { - server.use(createHPAsList()) - render() + server.use(createHPAsList()); + render(); - expect(screen.getByRole('button', { name: /create hpa/i })).toBeInTheDocument() - expect(screen.getAllByRole('button', { name: '' })[0]).toBeInTheDocument() // Refresh button - }) + expect(screen.getByRole('button', { name: /create hpa/i })).toBeInTheDocument(); + expect(screen.getAllByRole('button', { name: '' })[0]).toBeInTheDocument(); // Refresh button + }); it('should have proper table structure', async () => { - server.use(createHPAsList()) - render() + server.use(createHPAsList()); + render(); await waitFor(() => { - expect(screen.getByRole('table')).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Name' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Namespace' })).toBeInTheDocument() - }) - }) + expect(screen.getByRole('table')).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Name' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Namespace' })).toBeInTheDocument(); + }); + }); it('should be keyboard navigable', async () => { - const user = userEvent.setup() - server.use(createHPAsList()) - render() + const user = userEvent.setup(); + server.use(createHPAsList()); + render(); - const createButton = screen.getByRole('button', { name: /create hpa/i }) - createButton.focus() + const createButton = screen.getByRole('button', { name: /create hpa/i }); + createButton.focus(); - expect(document.activeElement).toBe(createButton) + expect(document.activeElement).toBe(createButton); // Test that tab navigation works - await user.tab() + await user.tab(); // The focus should move to the next focusable element - expect(document.activeElement).not.toBe(createButton) - }) - }) -}) + expect(document.activeElement).not.toBe(createButton); + }); + }); +}); diff --git a/apps/ops-dashboard/__tests__/components/resources/ingresses.test.tsx b/apps/ops-dashboard/__tests__/components/resources/ingresses.test.tsx index 2fc91c8..481073f 100644 --- a/apps/ops-dashboard/__tests__/components/resources/ingresses.test.tsx +++ b/apps/ops-dashboard/__tests__/components/resources/ingresses.test.tsx @@ -1,219 +1,220 @@ -import React from 'react' -import { render, screen, waitFor } from '../../utils/test-utils' -import userEvent from '@testing-library/user-event' -import { IngressesView } from '../../../components/resources/ingresses' -import { server } from '@/__mocks__/server' +import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { server } from '@/__mocks__/server'; + import { - createIngressesList, createAllIngressesList, - createIngressesListError, - createIngressesListSlow, + createIngressDelete, + createIngressesList, createIngressesListData, - createIngressDelete -} from '../../../__mocks__/handlers/ingresses' + createIngressesListError, + createIngressesListSlow} from '../../../__mocks__/handlers/ingresses'; +import { IngressesView } from '../../../components/resources/ingresses'; +import { render, screen, waitFor } from '../../utils/test-utils'; // Mock the confirmDialog function jest.mock('../../../hooks/useConfirm', () => ({ ...jest.requireActual('../../../hooks/useConfirm'), confirmDialog: jest.fn() -})) +})); -const mockAlert = jest.fn() +const mockAlert = jest.fn(); beforeAll(() => { - jest.spyOn(window, 'alert').mockImplementation(mockAlert) -}) + jest.spyOn(window, 'alert').mockImplementation(mockAlert); +}); afterEach(() => { - server.resetHandlers() - mockAlert.mockClear() -}) + server.resetHandlers(); + mockAlert.mockClear(); +}); afterAll(() => { - jest.restoreAllMocks() -}) + jest.restoreAllMocks(); +}); describe('IngressesView', () => { describe('Basic Rendering', () => { it('should render ingresses view with header', () => { - server.use(createIngressesList()) - render() + server.use(createIngressesList()); + render(); - expect(screen.getByRole('heading', { name: 'Ingresses', level: 2 })).toBeInTheDocument() - expect(screen.getByText('Manage external access to services')).toBeInTheDocument() - }) + expect(screen.getByRole('heading', { name: 'Ingresses', level: 2 })).toBeInTheDocument(); + expect(screen.getByText('Manage external access to services')).toBeInTheDocument(); + }); it('should render refresh and create buttons', () => { - server.use(createIngressesList()) - render() + server.use(createIngressesList()); + render(); - expect(screen.getAllByRole('button', { name: '' })[0]).toBeInTheDocument() // Refresh button - expect(screen.getByRole('button', { name: /create ingress/i })).toBeInTheDocument() - }) + expect(screen.getAllByRole('button', { name: '' })[0]).toBeInTheDocument(); // Refresh button + expect(screen.getByRole('button', { name: /create ingress/i })).toBeInTheDocument(); + }); it('should render stats cards', () => { - server.use(createIngressesList()) - render() + server.use(createIngressesList()); + render(); - expect(screen.getByText('Total Ingresses')).toBeInTheDocument() - expect(screen.getByText('With TLS')).toBeInTheDocument() - expect(screen.getByText('Total Hosts')).toBeInTheDocument() - expect(screen.getByText('Total Paths')).toBeInTheDocument() - }) + expect(screen.getByText('Total Ingresses')).toBeInTheDocument(); + expect(screen.getByText('With TLS')).toBeInTheDocument(); + expect(screen.getByText('Total Hosts')).toBeInTheDocument(); + expect(screen.getByText('Total Paths')).toBeInTheDocument(); + }); it('should render table with correct headers', async () => { - server.use(createIngressesList()) - render() + server.use(createIngressesList()); + render(); await waitFor(() => { - expect(screen.getByRole('columnheader', { name: 'Name' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Namespace' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Class' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Hosts' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Status' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'TLS' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Load Balancer' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Actions' })).toBeInTheDocument() - }) - }) - }) + expect(screen.getByRole('columnheader', { name: 'Name' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Namespace' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Class' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Hosts' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Status' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'TLS' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Load Balancer' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Actions' })).toBeInTheDocument(); + }); + }); + }); describe('Data Loading and Display', () => { it('should display ingresses data correctly', async () => { - server.use(createIngressesList()) - render() + server.use(createIngressesList()); + render(); await waitFor(() => { - expect(screen.getByText('web-ingress')).toBeInTheDocument() - expect(screen.getByText('api-ingress')).toBeInTheDocument() - expect(screen.getAllByText('default')).toHaveLength(2) // Two ingresses in default namespace - expect(screen.getByText('example.com')).toBeInTheDocument() - expect(screen.getByText('api.example.com')).toBeInTheDocument() - }) - }) + expect(screen.getByText('web-ingress')).toBeInTheDocument(); + expect(screen.getByText('api-ingress')).toBeInTheDocument(); + expect(screen.getAllByText('default')).toHaveLength(2); // Two ingresses in default namespace + expect(screen.getByText('example.com')).toBeInTheDocument(); + expect(screen.getByText('api.example.com')).toBeInTheDocument(); + }); + }); it('should display correct statistics', async () => { - server.use(createIngressesList()) - render() + server.use(createIngressesList()); + render(); await waitFor(() => { - expect(screen.getAllByText('2')).toHaveLength(2) // Total Ingresses and Total Hosts - expect(screen.getByText('1')).toBeInTheDocument() // With TLS count - expect(screen.getByText('3')).toBeInTheDocument() // Total Paths count - }) - }) + expect(screen.getAllByText('2')).toHaveLength(2); // Total Ingresses and Total Hosts + expect(screen.getByText('1')).toBeInTheDocument(); // With TLS count + expect(screen.getByText('3')).toBeInTheDocument(); // Total Paths count + }); + }); it('should display ingress class correctly', async () => { - server.use(createIngressesList()) - render() + server.use(createIngressesList()); + render(); await waitFor(() => { - expect(screen.getByText('nginx')).toBeInTheDocument() - expect(screen.getByText('traefik')).toBeInTheDocument() - }) - }) + expect(screen.getByText('nginx')).toBeInTheDocument(); + expect(screen.getByText('traefik')).toBeInTheDocument(); + }); + }); it('should display hosts correctly', async () => { - server.use(createIngressesList()) - render() + server.use(createIngressesList()); + render(); await waitFor(() => { - expect(screen.getByText('example.com')).toBeInTheDocument() - expect(screen.getByText('api.example.com')).toBeInTheDocument() - }) - }) + expect(screen.getByText('example.com')).toBeInTheDocument(); + expect(screen.getByText('api.example.com')).toBeInTheDocument(); + }); + }); it('should display status badges correctly', async () => { - server.use(createIngressesList()) - render() + server.use(createIngressesList()); + render(); await waitFor(() => { - expect(screen.getByText('Active')).toBeInTheDocument() - expect(screen.getByText('Pending')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Active')).toBeInTheDocument(); + expect(screen.getByText('Pending')).toBeInTheDocument(); + }); + }); it('should display TLS status correctly', async () => { - server.use(createIngressesList()) - render() + server.use(createIngressesList()); + render(); await waitFor(() => { - expect(screen.getByText('Enabled')).toBeInTheDocument() - expect(screen.getByText('Disabled')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Enabled')).toBeInTheDocument(); + expect(screen.getByText('Disabled')).toBeInTheDocument(); + }); + }); it('should display load balancer information correctly', async () => { - server.use(createIngressesList()) - render() + server.use(createIngressesList()); + render(); await waitFor(() => { - expect(screen.getByText('192.168.1.100')).toBeInTheDocument() - expect(screen.getByText('None')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('192.168.1.100')).toBeInTheDocument(); + expect(screen.getByText('None')).toBeInTheDocument(); + }); + }); + }); describe('Loading States', () => { it('should show loading spinner when loading', () => { - server.use(createIngressesListSlow()) - render() + server.use(createIngressesListSlow()); + render(); - expect(document.querySelector('svg.lucide-refresh-cw.animate-spin')).toBeInTheDocument() - }) + expect(document.querySelector('svg.lucide-refresh-cw.animate-spin')).toBeInTheDocument(); + }); it('should disable refresh button when loading', () => { - server.use(createIngressesListSlow()) - render() + server.use(createIngressesListSlow()); + render(); - const refreshButton = screen.getAllByRole('button', { name: '' })[0] - expect(refreshButton).toBeDisabled() - }) - }) + const refreshButton = screen.getAllByRole('button', { name: '' })[0]; + expect(refreshButton).toBeDisabled(); + }); + }); describe('Error States', () => { it('should display error message when fetch fails', async () => { - server.use(createIngressesListError(500, 'Server Error')) - render() + server.use(createIngressesListError(500, 'Server Error')); + render(); await waitFor(() => { - expect(screen.getByText(/Server Error/)).toBeInTheDocument() - expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument() - }) - }) + expect(screen.getByText(/Server Error/)).toBeInTheDocument(); + expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument(); + }); + }); it('should show retry button in error state', async () => { - server.use(createIngressesListError()) - render() + server.use(createIngressesListError()); + render(); await waitFor(() => { - expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument() - }) - }) - }) + expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument(); + }); + }); + }); describe('Empty States', () => { it('should display empty state when no ingresses', async () => { - server.use(createIngressesList([])) - render() + server.use(createIngressesList([])); + render(); await waitFor(() => { - expect(screen.getByText('No ingresses found')).toBeInTheDocument() - expect(screen.getByRole('button', { name: /refresh/i })).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('No ingresses found')).toBeInTheDocument(); + expect(screen.getByRole('button', { name: /refresh/i })).toBeInTheDocument(); + }); + }); + }); describe('User Interactions', () => { it('should refresh data when refresh button is clicked', async () => { - const user = userEvent.setup() - const ingresses = createIngressesListData() - server.use(createIngressesList(ingresses)) - render() + const user = userEvent.setup(); + const ingresses = createIngressesListData(); + server.use(createIngressesList(ingresses)); + render(); await waitFor(() => { - expect(screen.getByText('web-ingress')).toBeInTheDocument() - }) + expect(screen.getByText('web-ingress')).toBeInTheDocument(); + }); // Simulate new data after refresh const newIngresses = [...ingresses, { @@ -223,128 +224,128 @@ describe('IngressesView', () => { rules: [{ host: 'new.example.com', http: { paths: [{ path: '/', pathType: 'Prefix', backend: { service: { name: 'new-service', port: { number: 80 } } } }] } }] }, status: { loadBalancer: { ingress: [] } } - }] - server.use(createIngressesList(newIngresses)) + }]; + server.use(createIngressesList(newIngresses)); - const refreshButton = screen.getAllByRole('button', { name: '' })[0] - await user.click(refreshButton) + const refreshButton = screen.getAllByRole('button', { name: '' })[0]; + await user.click(refreshButton); await waitFor(() => { - expect(screen.getByText('new-ingress')).toBeInTheDocument() - }) - }) + expect(screen.getByText('new-ingress')).toBeInTheDocument(); + }); + }); it('should show create ingress alert when create button is clicked', async () => { - const user = userEvent.setup() - server.use(createIngressesList()) - render() + const user = userEvent.setup(); + server.use(createIngressesList()); + render(); - const createButton = screen.getByRole('button', { name: /create ingress/i }) - await user.click(createButton) + const createButton = screen.getByRole('button', { name: /create ingress/i }); + await user.click(createButton); - expect(window.alert).toHaveBeenCalledWith('Create Ingress functionality not yet implemented') - }) + expect(window.alert).toHaveBeenCalledWith('Create Ingress functionality not yet implemented'); + }); it('should show delete confirmation when delete button is clicked', async () => { - const user = userEvent.setup() - const { confirmDialog } = require('../../../hooks/useConfirm') - confirmDialog.mockResolvedValue(true) + const user = userEvent.setup(); + const { confirmDialog } = require('../../../hooks/useConfirm'); + confirmDialog.mockResolvedValue(true); - server.use(createIngressesList(), createIngressDelete()) - render() + server.use(createIngressesList(), createIngressDelete()); + render(); await waitFor(() => { - expect(screen.getByText('web-ingress')).toBeInTheDocument() - }) + expect(screen.getByText('web-ingress')).toBeInTheDocument(); + }); const deleteButton = screen.getAllByRole('button').find(button => button.querySelector('svg.lucide-trash2') - ) - expect(deleteButton).toBeInTheDocument() + ); + expect(deleteButton).toBeInTheDocument(); if (deleteButton) { - await user.click(deleteButton) + await user.click(deleteButton); expect(confirmDialog).toHaveBeenCalledWith({ title: 'Delete Ingress', description: 'Are you sure you want to delete web-ingress?', confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); } - }) + }); it('should show view button when view button is clicked', async () => { - const user = userEvent.setup() - server.use(createIngressesList()) - render() + const user = userEvent.setup(); + server.use(createIngressesList()); + render(); await waitFor(() => { - expect(screen.getByText('web-ingress')).toBeInTheDocument() - }) + expect(screen.getByText('web-ingress')).toBeInTheDocument(); + }); const viewButton = screen.getAllByRole('button').find(button => button.querySelector('svg.lucide-eye') - ) - expect(viewButton).toBeInTheDocument() + ); + expect(viewButton).toBeInTheDocument(); if (viewButton) { - await user.click(viewButton) + await user.click(viewButton); // View functionality sets selectedIngress state // This is tested indirectly through the component's internal state } - }) - }) + }); + }); describe('Status Logic', () => { it('should show Active status when ingress has load balancer', async () => { - server.use(createIngressesList()) - render() + server.use(createIngressesList()); + render(); await waitFor(() => { - expect(screen.getByText('Active')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Active')).toBeInTheDocument(); + }); + }); it('should show Pending status when ingress has no load balancer', async () => { - server.use(createIngressesList()) - render() + server.use(createIngressesList()); + render(); await waitFor(() => { - expect(screen.getByText('Pending')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('Pending')).toBeInTheDocument(); + }); + }); + }); describe('TLS Logic', () => { it('should show Enabled when ingress has TLS', async () => { - server.use(createIngressesList()) - render() + server.use(createIngressesList()); + render(); await waitFor(() => { - expect(screen.getByText('Enabled')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Enabled')).toBeInTheDocument(); + }); + }); it('should show Disabled when ingress has no TLS', async () => { - server.use(createIngressesList()) - render() + server.use(createIngressesList()); + render(); await waitFor(() => { - expect(screen.getByText('Disabled')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('Disabled')).toBeInTheDocument(); + }); + }); + }); describe('Host Display Logic', () => { it('should display hosts with globe icon', async () => { - server.use(createIngressesList()) - render() + server.use(createIngressesList()); + render(); await waitFor(() => { - expect(screen.getByText('example.com')).toBeInTheDocument() - expect(screen.getByText('api.example.com')).toBeInTheDocument() - }) - }) + expect(screen.getByText('example.com')).toBeInTheDocument(); + expect(screen.getByText('api.example.com')).toBeInTheDocument(); + }); + }); it('should show more hosts indicator when there are many hosts', async () => { // Create an ingress with many hosts @@ -359,65 +360,65 @@ describe('IngressesView', () => { ] }, status: { loadBalancer: { ingress: [] } } - }] - server.use(createIngressesList(ingresses)) - render() + }]; + server.use(createIngressesList(ingresses)); + render(); await waitFor(() => { - expect(screen.getByText('+1 more')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('+1 more')).toBeInTheDocument(); + }); + }); + }); describe('All Namespaces Mode', () => { it('should show all ingresses when in all namespaces mode', async () => { // This test is simplified due to mock complexity // In a real scenario, the component would use useListNetworkingV1IngressForAllNamespacesQuery - server.use(createAllIngressesList()) - render() + server.use(createAllIngressesList()); + render(); // The component will still use the default namespace context // This test verifies the handler works correctly await waitFor(() => { - expect(screen.getByText('Network request failed')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('Network request failed')).toBeInTheDocument(); + }); + }); + }); describe('Accessibility', () => { it('should have proper button roles and labels', () => { - server.use(createIngressesList()) - render() + server.use(createIngressesList()); + render(); - expect(screen.getByRole('button', { name: /create ingress/i })).toBeInTheDocument() - expect(screen.getAllByRole('button', { name: '' })[0]).toBeInTheDocument() // Refresh button - }) + expect(screen.getByRole('button', { name: /create ingress/i })).toBeInTheDocument(); + expect(screen.getAllByRole('button', { name: '' })[0]).toBeInTheDocument(); // Refresh button + }); it('should have proper table structure', async () => { - server.use(createIngressesList()) - render() + server.use(createIngressesList()); + render(); await waitFor(() => { - expect(screen.getByRole('table')).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Name' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Namespace' })).toBeInTheDocument() - }) - }) + expect(screen.getByRole('table')).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Name' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Namespace' })).toBeInTheDocument(); + }); + }); it('should be keyboard navigable', async () => { - const user = userEvent.setup() - server.use(createIngressesList()) - render() + const user = userEvent.setup(); + server.use(createIngressesList()); + render(); - const createButton = screen.getByRole('button', { name: /create ingress/i }) - createButton.focus() + const createButton = screen.getByRole('button', { name: /create ingress/i }); + createButton.focus(); - expect(document.activeElement).toBe(createButton) + expect(document.activeElement).toBe(createButton); // Test that tab navigation works - await user.tab() + await user.tab(); // The focus should move to the next focusable element - expect(document.activeElement).not.toBe(createButton) - }) - }) -}) + expect(document.activeElement).not.toBe(createButton); + }); + }); +}); diff --git a/apps/ops-dashboard/__tests__/components/resources/jobs.test.tsx b/apps/ops-dashboard/__tests__/components/resources/jobs.test.tsx index ddee625..5197b5e 100644 --- a/apps/ops-dashboard/__tests__/components/resources/jobs.test.tsx +++ b/apps/ops-dashboard/__tests__/components/resources/jobs.test.tsx @@ -1,366 +1,367 @@ -import React from 'react' -import { render, screen, waitFor } from '../../utils/test-utils' -import userEvent from '@testing-library/user-event' -import { JobsView } from '../../../components/resources/jobs' -import { server } from '@/__mocks__/server' +import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { server } from '@/__mocks__/server'; + import { - createJobsList, createAllJobsList, - createJobsListError, - createJobsListSlow, + createJobDelete, + createJobsList, createJobsListData, - createJobDelete -} from '../../../__mocks__/handlers/jobs' + createJobsListError, + createJobsListSlow} from '../../../__mocks__/handlers/jobs'; +import { JobsView } from '../../../components/resources/jobs'; +import { render, screen, waitFor } from '../../utils/test-utils'; // Mock the confirmDialog function jest.mock('../../../hooks/useConfirm', () => ({ ...jest.requireActual('../../../hooks/useConfirm'), confirmDialog: jest.fn() -})) +})); -const mockPrompt = jest.fn() -const mockAlert = jest.fn() +const mockPrompt = jest.fn(); +const mockAlert = jest.fn(); beforeAll(() => { - jest.spyOn(window, 'prompt').mockImplementation(mockPrompt) - jest.spyOn(window, 'alert').mockImplementation(mockAlert) -}) + jest.spyOn(window, 'prompt').mockImplementation(mockPrompt); + jest.spyOn(window, 'alert').mockImplementation(mockAlert); +}); afterEach(() => { - server.resetHandlers() - mockPrompt.mockClear() - mockAlert.mockClear() -}) + server.resetHandlers(); + mockPrompt.mockClear(); + mockAlert.mockClear(); +}); afterAll(() => { - jest.restoreAllMocks() -}) + jest.restoreAllMocks(); +}); describe('JobsView', () => { describe('Basic Rendering', () => { it('should render jobs view with header', () => { - server.use(createJobsList()) - render() + server.use(createJobsList()); + render(); - expect(screen.getByRole('heading', { name: 'Jobs' })).toBeInTheDocument() - expect(screen.getByText('Manage your Kubernetes batch jobs')).toBeInTheDocument() - }) + expect(screen.getByRole('heading', { name: 'Jobs' })).toBeInTheDocument(); + expect(screen.getByText('Manage your Kubernetes batch jobs')).toBeInTheDocument(); + }); it('should render refresh and create buttons', () => { - server.use(createJobsList()) - render() + server.use(createJobsList()); + render(); - expect(screen.getAllByRole('button', { name: '' })[0]).toBeInTheDocument() // Refresh button - expect(screen.getByRole('button', { name: /create job/i })).toBeInTheDocument() - }) + expect(screen.getAllByRole('button', { name: '' })[0]).toBeInTheDocument(); // Refresh button + expect(screen.getByRole('button', { name: /create job/i })).toBeInTheDocument(); + }); it('should render stats cards', () => { - server.use(createJobsList()) - render() + server.use(createJobsList()); + render(); - expect(screen.getByText('Total Jobs')).toBeInTheDocument() - expect(screen.getByText('Running')).toBeInTheDocument() - expect(screen.getByText('Completed')).toBeInTheDocument() - expect(screen.getByText('Failed')).toBeInTheDocument() - }) + expect(screen.getByText('Total Jobs')).toBeInTheDocument(); + expect(screen.getByText('Running')).toBeInTheDocument(); + expect(screen.getByText('Completed')).toBeInTheDocument(); + expect(screen.getByText('Failed')).toBeInTheDocument(); + }); it('should render table with correct headers', async () => { - server.use(createJobsList()) - render() + server.use(createJobsList()); + render(); await waitFor(() => { - expect(screen.getByRole('columnheader', { name: 'Name' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Namespace' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Status' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Completions' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Duration' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Image' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Created' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Actions' })).toBeInTheDocument() - }) - }) - }) + expect(screen.getByRole('columnheader', { name: 'Name' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Namespace' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Status' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Completions' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Duration' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Image' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Created' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Actions' })).toBeInTheDocument(); + }); + }); + }); describe('Data Loading and Display', () => { it('should display jobs data correctly', async () => { - server.use(createJobsList()) - render() + server.use(createJobsList()); + render(); await waitFor(() => { - expect(screen.getByText('data-processing-job')).toBeInTheDocument() - expect(screen.getByText('backup-job')).toBeInTheDocument() - expect(screen.getAllByText('default')).toHaveLength(2) // Two jobs in default namespace - expect(screen.getByText('python:3.9')).toBeInTheDocument() - expect(screen.getByText('postgres:13')).toBeInTheDocument() - }) - }) + expect(screen.getByText('data-processing-job')).toBeInTheDocument(); + expect(screen.getByText('backup-job')).toBeInTheDocument(); + expect(screen.getAllByText('default')).toHaveLength(2); // Two jobs in default namespace + expect(screen.getByText('python:3.9')).toBeInTheDocument(); + expect(screen.getByText('postgres:13')).toBeInTheDocument(); + }); + }); it('should display correct statistics', async () => { - server.use(createJobsList()) - render() + server.use(createJobsList()); + render(); await waitFor(() => { - expect(screen.getByText('2')).toBeInTheDocument() // Total Jobs in default namespace - expect(screen.getAllByText('1')).toHaveLength(2) // Running count and Completed count - expect(screen.getByText('0')).toBeInTheDocument() // Failed count - }) - }) + expect(screen.getByText('2')).toBeInTheDocument(); // Total Jobs in default namespace + expect(screen.getAllByText('1')).toHaveLength(2); // Running count and Completed count + expect(screen.getByText('0')).toBeInTheDocument(); // Failed count + }); + }); it('should display status badges correctly', async () => { - server.use(createJobsList()) - render() + server.use(createJobsList()); + render(); await waitFor(() => { - expect(screen.getByText('Completed')).toBeInTheDocument() - expect(screen.getByText('Running')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Completed')).toBeInTheDocument(); + expect(screen.getByText('Running')).toBeInTheDocument(); + }); + }); it('should display completions correctly', async () => { - server.use(createJobsList()) - render() + server.use(createJobsList()); + render(); await waitFor(() => { - expect(screen.getByText('1/1')).toBeInTheDocument() // data-processing-job - expect(screen.getByText('2/3')).toBeInTheDocument() // backup-job - }) - }) + expect(screen.getByText('1/1')).toBeInTheDocument(); // data-processing-job + expect(screen.getByText('2/3')).toBeInTheDocument(); // backup-job + }); + }); it('should display duration correctly', async () => { - server.use(createJobsList()) - render() + server.use(createJobsList()); + render(); await waitFor(() => { - expect(screen.getByText('5m 0s')).toBeInTheDocument() // data-processing-job duration + expect(screen.getByText('5m 0s')).toBeInTheDocument(); // data-processing-job duration // backup-job has startTime but no completionTime, so it shows running duration - expect(screen.getAllByText(/^\d+[smh]/)).toHaveLength(2) // Both jobs have duration - }) - }) - }) + expect(screen.getAllByText(/^\d+[smh]/)).toHaveLength(2); // Both jobs have duration + }); + }); + }); describe('Loading States', () => { it('should show loading spinner when loading', () => { - server.use(createJobsListSlow()) - render() + server.use(createJobsListSlow()); + render(); - expect(document.querySelector('svg.lucide-refresh-cw.animate-spin')).toBeInTheDocument() - }) + expect(document.querySelector('svg.lucide-refresh-cw.animate-spin')).toBeInTheDocument(); + }); it('should disable refresh button when loading', () => { - server.use(createJobsListSlow()) - render() + server.use(createJobsListSlow()); + render(); - const refreshButton = screen.getAllByRole('button', { name: '' })[0] - expect(refreshButton).toBeDisabled() - }) - }) + const refreshButton = screen.getAllByRole('button', { name: '' })[0]; + expect(refreshButton).toBeDisabled(); + }); + }); describe('Error States', () => { it('should display error message when fetch fails', async () => { - server.use(createJobsListError(500, 'Server Error')) - render() + server.use(createJobsListError(500, 'Server Error')); + render(); await waitFor(() => { - expect(screen.getByText(/Server Error/)).toBeInTheDocument() - expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument() - }) - }) + expect(screen.getByText(/Server Error/)).toBeInTheDocument(); + expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument(); + }); + }); it('should show retry button in error state', async () => { - server.use(createJobsListError()) - render() + server.use(createJobsListError()); + render(); await waitFor(() => { - expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument() - }) - }) - }) + expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument(); + }); + }); + }); describe('Empty States', () => { it('should display empty state when no jobs', async () => { - server.use(createJobsList([])) - render() + server.use(createJobsList([])); + render(); await waitFor(() => { - expect(screen.getByText('No jobs found')).toBeInTheDocument() - expect(screen.getByRole('button', { name: /refresh/i })).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('No jobs found')).toBeInTheDocument(); + expect(screen.getByRole('button', { name: /refresh/i })).toBeInTheDocument(); + }); + }); + }); describe('User Interactions', () => { it('should refresh data when refresh button is clicked', async () => { - const user = userEvent.setup() - const jobs = createJobsListData() - server.use(createJobsList(jobs)) - render() + const user = userEvent.setup(); + const jobs = createJobsListData(); + server.use(createJobsList(jobs)); + render(); await waitFor(() => { - expect(screen.getByText('data-processing-job')).toBeInTheDocument() - }) + expect(screen.getByText('data-processing-job')).toBeInTheDocument(); + }); // Simulate new data after refresh const newJobs = [...jobs, { metadata: { name: 'new-job', namespace: 'default', uid: 'job-4', creationTimestamp: '2024-01-15T13:00:00Z' }, spec: { completions: 1, template: { metadata: { labels: { app: 'new' } }, spec: { containers: [{ name: 'new', image: 'new:latest' }], restartPolicy: 'Never' } } }, status: { active: 0, succeeded: 1, failed: 0, startTime: '2024-01-15T13:00:00Z', completionTime: '2024-01-15T13:05:00Z', conditions: [{ type: 'Complete', status: 'True', lastProbeTime: '2024-01-15T13:05:00Z', lastTransitionTime: '2024-01-15T13:05:00Z' }] } - }] - server.use(createJobsList(newJobs)) + }]; + server.use(createJobsList(newJobs)); - const refreshButton = screen.getAllByRole('button', { name: '' })[0] - await user.click(refreshButton) + const refreshButton = screen.getAllByRole('button', { name: '' })[0]; + await user.click(refreshButton); await waitFor(() => { - expect(screen.getByText('new-job')).toBeInTheDocument() - }) - }) + expect(screen.getByText('new-job')).toBeInTheDocument(); + }); + }); it('should show create job alert when create button is clicked', async () => { - const user = userEvent.setup() - server.use(createJobsList()) - render() + const user = userEvent.setup(); + server.use(createJobsList()); + render(); - const createButton = screen.getByRole('button', { name: /create job/i }) - await user.click(createButton) + const createButton = screen.getByRole('button', { name: /create job/i }); + await user.click(createButton); - expect(window.alert).toHaveBeenCalledWith('Create Job functionality not yet implemented') - }) + expect(window.alert).toHaveBeenCalledWith('Create Job functionality not yet implemented'); + }); it('should show delete confirmation when delete button is clicked', async () => { - const user = userEvent.setup() - const { confirmDialog } = require('../../../hooks/useConfirm') - confirmDialog.mockResolvedValue(true) + const user = userEvent.setup(); + const { confirmDialog } = require('../../../hooks/useConfirm'); + confirmDialog.mockResolvedValue(true); - server.use(createJobsList(), createJobDelete()) - render() + server.use(createJobsList(), createJobDelete()); + render(); await waitFor(() => { - expect(screen.getByText('data-processing-job')).toBeInTheDocument() - }) + expect(screen.getByText('data-processing-job')).toBeInTheDocument(); + }); const deleteButton = screen.getAllByRole('button').find(button => button.querySelector('svg.lucide-trash2') - ) - expect(deleteButton).toBeInTheDocument() + ); + expect(deleteButton).toBeInTheDocument(); if (deleteButton) { - await user.click(deleteButton) + await user.click(deleteButton); expect(confirmDialog).toHaveBeenCalledWith({ title: 'Delete Job', description: 'Are you sure you want to delete data-processing-job?', confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); } - }) + }); it('should show view button when view button is clicked', async () => { - const user = userEvent.setup() - server.use(createJobsList()) - render() + const user = userEvent.setup(); + server.use(createJobsList()); + render(); await waitFor(() => { - expect(screen.getByText('data-processing-job')).toBeInTheDocument() - }) + expect(screen.getByText('data-processing-job')).toBeInTheDocument(); + }); const viewButton = screen.getAllByRole('button').find(button => button.querySelector('svg.lucide-eye') - ) - expect(viewButton).toBeInTheDocument() + ); + expect(viewButton).toBeInTheDocument(); if (viewButton) { - await user.click(viewButton) + await user.click(viewButton); // View functionality sets selectedJob state // This is tested indirectly through the component's internal state } - }) - }) + }); + }); describe('Status Logic', () => { it('should show Completed status when job is complete', async () => { - server.use(createJobsList()) - render() + server.use(createJobsList()); + render(); await waitFor(() => { - expect(screen.getByText('Completed')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Completed')).toBeInTheDocument(); + }); + }); it('should show Running status when job is active', async () => { - server.use(createJobsList()) - render() + server.use(createJobsList()); + render(); await waitFor(() => { - expect(screen.getByText('Running')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Running')).toBeInTheDocument(); + }); + }); it('should show Failed status when job has failed condition', async () => { - const jobs = createJobsListData() + const jobs = createJobsListData(); // Add a failed job to the list const failedJob = { metadata: { name: 'test-failed-job', namespace: 'default', uid: 'job-failed', creationTimestamp: '2024-01-15T14:00:00Z' }, spec: { completions: 1, template: { metadata: { labels: { app: 'failed' } }, spec: { containers: [{ name: 'failed', image: 'failed:latest' }], restartPolicy: 'Never' } } }, status: { active: 0, succeeded: 0, failed: 1, startTime: '2024-01-15T14:00:00Z', conditions: [{ type: 'Failed', status: 'True', lastProbeTime: '2024-01-15T14:05:00Z', lastTransitionTime: '2024-01-15T14:05:00Z' }] } - } - server.use(createJobsList([...jobs, failedJob])) - render() + }; + server.use(createJobsList([...jobs, failedJob])); + render(); await waitFor(() => { - expect(screen.getByText('Failed')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('Failed')).toBeInTheDocument(); + }); + }); + }); describe('All Namespaces Mode', () => { it('should show all jobs when in all namespaces mode', async () => { // This test is simplified due to mock complexity // In a real scenario, the component would use useListBatchV1JobForAllNamespacesQuery - server.use(createAllJobsList()) - render() + server.use(createAllJobsList()); + render(); // The component will still use the default namespace context // This test verifies the handler works correctly await waitFor(() => { - expect(screen.getByText('Network request failed')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('Network request failed')).toBeInTheDocument(); + }); + }); + }); describe('Accessibility', () => { it('should have proper button roles and labels', () => { - server.use(createJobsList()) - render() + server.use(createJobsList()); + render(); - expect(screen.getByRole('button', { name: /create job/i })).toBeInTheDocument() - expect(screen.getAllByRole('button', { name: '' })[0]).toBeInTheDocument() // Refresh button - }) + expect(screen.getByRole('button', { name: /create job/i })).toBeInTheDocument(); + expect(screen.getAllByRole('button', { name: '' })[0]).toBeInTheDocument(); // Refresh button + }); it('should have proper table structure', async () => { - server.use(createJobsList()) - render() + server.use(createJobsList()); + render(); await waitFor(() => { - expect(screen.getByRole('table')).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Name' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Namespace' })).toBeInTheDocument() - }) - }) + expect(screen.getByRole('table')).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Name' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Namespace' })).toBeInTheDocument(); + }); + }); it('should be keyboard navigable', async () => { - const user = userEvent.setup() - server.use(createJobsList()) - render() + const user = userEvent.setup(); + server.use(createJobsList()); + render(); - const createButton = screen.getByRole('button', { name: /create job/i }) - createButton.focus() + const createButton = screen.getByRole('button', { name: /create job/i }); + createButton.focus(); - expect(document.activeElement).toBe(createButton) + expect(document.activeElement).toBe(createButton); // Test that tab navigation works - await user.tab() + await user.tab(); // The focus should move to the next focusable element - expect(document.activeElement).not.toBe(createButton) - }) - }) -}) + expect(document.activeElement).not.toBe(createButton); + }); + }); +}); diff --git a/apps/ops-dashboard/__tests__/components/resources/networkpolicies.test.tsx b/apps/ops-dashboard/__tests__/components/resources/networkpolicies.test.tsx index d36fd59..e0e0e62 100644 --- a/apps/ops-dashboard/__tests__/components/resources/networkpolicies.test.tsx +++ b/apps/ops-dashboard/__tests__/components/resources/networkpolicies.test.tsx @@ -1,207 +1,209 @@ -import React from 'react' -import { render, screen, waitFor } from '../../utils/test-utils' -import userEvent from '@testing-library/user-event' -import { NetworkPoliciesView } from '../../../components/resources/networkpolicies' -import { server } from '@/__mocks__/server' +import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { server } from '@/__mocks__/server'; + import { - createNetworkPoliciesList, createAllNetworkPoliciesList, + createNetworkPoliciesList, + createNetworkPoliciesListData, createNetworkPoliciesListError, createNetworkPoliciesListSlow, - createNetworkPoliciesListData, createNetworkPolicyDelete -} from '../../../__mocks__/handlers/networkpolicies' +} from '../../../__mocks__/handlers/networkpolicies'; +import { NetworkPoliciesView } from '../../../components/resources/networkpolicies'; +import { render, screen, waitFor } from '../../utils/test-utils'; // Mock the confirmDialog function jest.mock('../../../hooks/useConfirm', () => ({ ...jest.requireActual('../../../hooks/useConfirm'), confirmDialog: jest.fn() -})) +})); -const mockAlert = jest.fn() +const mockAlert = jest.fn(); beforeAll(() => { - jest.spyOn(window, 'alert').mockImplementation(mockAlert) -}) + jest.spyOn(window, 'alert').mockImplementation(mockAlert); +}); afterEach(() => { - server.resetHandlers() - mockAlert.mockClear() -}) + server.resetHandlers(); + mockAlert.mockClear(); +}); afterAll(() => { - jest.restoreAllMocks() -}) + jest.restoreAllMocks(); +}); describe('NetworkPoliciesView', () => { describe('Basic Rendering', () => { it('should render network policies view with header', () => { - server.use(createNetworkPoliciesList()) - render() + server.use(createNetworkPoliciesList()); + render(); - expect(screen.getByRole('heading', { name: 'Network Policies', level: 2 })).toBeInTheDocument() - expect(screen.getByText('Control traffic flow between pods')).toBeInTheDocument() - }) + expect(screen.getByRole('heading', { name: 'Network Policies', level: 2 })).toBeInTheDocument(); + expect(screen.getByText('Control traffic flow between pods')).toBeInTheDocument(); + }); it('should render refresh and create buttons', () => { - server.use(createNetworkPoliciesList()) - render() + server.use(createNetworkPoliciesList()); + render(); - expect(screen.getAllByRole('button', { name: '' })[0]).toBeInTheDocument() // Refresh button - expect(screen.getByRole('button', { name: /create policy/i })).toBeInTheDocument() - }) + expect(screen.getAllByRole('button', { name: '' })[0]).toBeInTheDocument(); // Refresh button + expect(screen.getByRole('button', { name: /create policy/i })).toBeInTheDocument(); + }); it('should render stats cards', () => { - server.use(createNetworkPoliciesList()) - render() + server.use(createNetworkPoliciesList()); + render(); - expect(screen.getByText('Total Policies')).toBeInTheDocument() - expect(screen.getByText('Ingress Rules')).toBeInTheDocument() - expect(screen.getByText('Egress Rules')).toBeInTheDocument() - expect(screen.getByText('Namespaces')).toBeInTheDocument() - }) + expect(screen.getByText('Total Policies')).toBeInTheDocument(); + expect(screen.getByText('Ingress Rules')).toBeInTheDocument(); + expect(screen.getByText('Egress Rules')).toBeInTheDocument(); + expect(screen.getByText('Namespaces')).toBeInTheDocument(); + }); it('should render table with correct headers', async () => { - server.use(createNetworkPoliciesList()) - render() + server.use(createNetworkPoliciesList()); + render(); await waitFor(() => { - expect(screen.getByRole('columnheader', { name: 'Name' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Namespace' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Pod Selector' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Policy Types' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Ingress Rules' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Egress Rules' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Created' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Actions' })).toBeInTheDocument() - }) - }) - }) + expect(screen.getByRole('columnheader', { name: 'Name' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Namespace' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Pod Selector' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Policy Types' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Ingress Rules' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Egress Rules' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Created' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Actions' })).toBeInTheDocument(); + }); + }); + }); describe('Data Loading and Display', () => { it('should display network policies data correctly', async () => { - server.use(createNetworkPoliciesList()) - render() + server.use(createNetworkPoliciesList()); + render(); await waitFor(() => { - expect(screen.getByText('web-policy')).toBeInTheDocument() - expect(screen.getByText('api-policy')).toBeInTheDocument() - expect(screen.getAllByText('default')).toHaveLength(2) // Two policies in default namespace - expect(screen.getByText('app=web')).toBeInTheDocument() - expect(screen.getByText('app=api')).toBeInTheDocument() - }) - }) + expect(screen.getByText('web-policy')).toBeInTheDocument(); + expect(screen.getByText('api-policy')).toBeInTheDocument(); + expect(screen.getAllByText('default')).toHaveLength(2); // Two policies in default namespace + expect(screen.getByText('app=web')).toBeInTheDocument(); + expect(screen.getByText('app=api')).toBeInTheDocument(); + }); + }); it('should display correct statistics', async () => { - server.use(createNetworkPoliciesList()) - render() + server.use(createNetworkPoliciesList()); + render(); await waitFor(() => { - expect(screen.getAllByText('2')).toHaveLength(2) // Total Policies and Ingress Rules - expect(screen.getAllByText('1')).toHaveLength(5) // Multiple 1s in stats and table - }) - }) + expect(screen.getAllByText('2')).toHaveLength(2); // Total Policies and Ingress Rules + expect(screen.getAllByText('1')).toHaveLength(5); // Multiple 1s in stats and table + }); + }); it('should display pod selector correctly', async () => { - server.use(createNetworkPoliciesList()) - render() + server.use(createNetworkPoliciesList()); + render(); await waitFor(() => { - expect(screen.getByText('app=web')).toBeInTheDocument() - expect(screen.getByText('app=api')).toBeInTheDocument() - }) - }) + expect(screen.getByText('app=web')).toBeInTheDocument(); + expect(screen.getByText('app=api')).toBeInTheDocument(); + }); + }); it('should display policy types correctly', async () => { - server.use(createNetworkPoliciesList()) - render() + server.use(createNetworkPoliciesList()); + render(); await waitFor(() => { - expect(screen.getByText('Ingress')).toBeInTheDocument() - expect(screen.getByText('Both')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Ingress')).toBeInTheDocument(); + expect(screen.getByText('Both')).toBeInTheDocument(); + }); + }); it('should display ingress and egress rules correctly', async () => { - server.use(createNetworkPoliciesList()) - render() + server.use(createNetworkPoliciesList()); + render(); await waitFor(() => { - expect(screen.getAllByText('1')).toHaveLength(5) // Multiple 1s in stats and table - expect(screen.getByText('0')).toBeInTheDocument() // Egress rules for web-policy - }) - }) + expect(screen.getAllByText('1')).toHaveLength(5); // Multiple 1s in stats and table + expect(screen.getByText('0')).toBeInTheDocument(); // Egress rules for web-policy + }); + }); it('should display creation date correctly', async () => { - server.use(createNetworkPoliciesList()) - render() + server.use(createNetworkPoliciesList()); + render(); await waitFor(() => { - expect(screen.getAllByText('1/15/2024')).toHaveLength(2) // Two policies with same date - }) - }) - }) + expect(screen.getAllByText('1/15/2024')).toHaveLength(2); // Two policies with same date + }); + }); + }); describe('Loading States', () => { it('should show loading spinner when loading', () => { - server.use(createNetworkPoliciesListSlow()) - render() + server.use(createNetworkPoliciesListSlow()); + render(); - expect(document.querySelector('svg.lucide-refresh-cw.animate-spin')).toBeInTheDocument() - }) + expect(document.querySelector('svg.lucide-refresh-cw.animate-spin')).toBeInTheDocument(); + }); it('should disable refresh button when loading', () => { - server.use(createNetworkPoliciesListSlow()) - render() + server.use(createNetworkPoliciesListSlow()); + render(); - const refreshButton = screen.getAllByRole('button', { name: '' })[0] - expect(refreshButton).toBeDisabled() - }) - }) + const refreshButton = screen.getAllByRole('button', { name: '' })[0]; + expect(refreshButton).toBeDisabled(); + }); + }); describe('Error States', () => { it('should display error message when fetch fails', async () => { - server.use(createNetworkPoliciesListError(500, 'Server Error')) - render() + server.use(createNetworkPoliciesListError(500, 'Server Error')); + render(); await waitFor(() => { - expect(screen.getByText(/Server Error/)).toBeInTheDocument() - expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument() - }) - }) + expect(screen.getByText(/Server Error/)).toBeInTheDocument(); + expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument(); + }); + }); it('should show retry button in error state', async () => { - server.use(createNetworkPoliciesListError()) - render() + server.use(createNetworkPoliciesListError()); + render(); await waitFor(() => { - expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument() - }) - }) - }) + expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument(); + }); + }); + }); describe('Empty States', () => { it('should display empty state when no network policies', async () => { - server.use(createNetworkPoliciesList([])) - render() + server.use(createNetworkPoliciesList([])); + render(); await waitFor(() => { - expect(screen.getByText('No network policies found')).toBeInTheDocument() - expect(screen.getByRole('button', { name: /refresh/i })).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('No network policies found')).toBeInTheDocument(); + expect(screen.getByRole('button', { name: /refresh/i })).toBeInTheDocument(); + }); + }); + }); describe('User Interactions', () => { it('should refresh data when refresh button is clicked', async () => { - const user = userEvent.setup() - const policies = createNetworkPoliciesListData() - server.use(createNetworkPoliciesList(policies)) - render() + const user = userEvent.setup(); + const policies = createNetworkPoliciesListData(); + server.use(createNetworkPoliciesList(policies)); + render(); await waitFor(() => { - expect(screen.getByText('web-policy')).toBeInTheDocument() - }) + expect(screen.getByText('web-policy')).toBeInTheDocument(); + }); // Simulate new data after refresh const newPolicies = [...policies, { @@ -211,108 +213,108 @@ describe('NetworkPoliciesView', () => { policyTypes: ['Ingress'], ingress: [] } - }] - server.use(createNetworkPoliciesList(newPolicies)) + }]; + server.use(createNetworkPoliciesList(newPolicies)); - const refreshButton = screen.getAllByRole('button', { name: '' })[0] - await user.click(refreshButton) + const refreshButton = screen.getAllByRole('button', { name: '' })[0]; + await user.click(refreshButton); await waitFor(() => { - expect(screen.getByText('new-policy')).toBeInTheDocument() - }) - }) + expect(screen.getByText('new-policy')).toBeInTheDocument(); + }); + }); it('should show create policy alert when create button is clicked', async () => { - const user = userEvent.setup() - server.use(createNetworkPoliciesList()) - render() + const user = userEvent.setup(); + server.use(createNetworkPoliciesList()); + render(); - const createButton = screen.getByRole('button', { name: /create policy/i }) - await user.click(createButton) + const createButton = screen.getByRole('button', { name: /create policy/i }); + await user.click(createButton); - expect(window.alert).toHaveBeenCalledWith('Create Network Policy functionality not yet implemented') - }) + expect(window.alert).toHaveBeenCalledWith('Create Network Policy functionality not yet implemented'); + }); it('should show delete confirmation when delete button is clicked', async () => { - const user = userEvent.setup() - const { confirmDialog } = require('../../../hooks/useConfirm') - confirmDialog.mockResolvedValue(true) + const user = userEvent.setup(); + const { confirmDialog } = require('../../../hooks/useConfirm'); + confirmDialog.mockResolvedValue(true); - server.use(createNetworkPoliciesList(), createNetworkPolicyDelete()) - render() + server.use(createNetworkPoliciesList(), createNetworkPolicyDelete()); + render(); await waitFor(() => { - expect(screen.getByText('web-policy')).toBeInTheDocument() - }) + expect(screen.getByText('web-policy')).toBeInTheDocument(); + }); const deleteButton = screen.getAllByRole('button').find(button => button.querySelector('svg.lucide-trash2') - ) - expect(deleteButton).toBeInTheDocument() + ); + expect(deleteButton).toBeInTheDocument(); if (deleteButton) { - await user.click(deleteButton) + await user.click(deleteButton); expect(confirmDialog).toHaveBeenCalledWith({ title: 'Delete Network Policy', description: 'Are you sure you want to delete web-policy?', confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); } - }) + }); it('should show view button when view button is clicked', async () => { - const user = userEvent.setup() - server.use(createNetworkPoliciesList()) - render() + const user = userEvent.setup(); + server.use(createNetworkPoliciesList()); + render(); await waitFor(() => { - expect(screen.getByText('web-policy')).toBeInTheDocument() - }) + expect(screen.getByText('web-policy')).toBeInTheDocument(); + }); const viewButton = screen.getAllByRole('button').find(button => button.querySelector('svg.lucide-eye') - ) - expect(viewButton).toBeInTheDocument() + ); + expect(viewButton).toBeInTheDocument(); if (viewButton) { - await user.click(viewButton) + await user.click(viewButton); // View functionality sets selectedPolicy state // This is tested indirectly through the component's internal state } - }) - }) + }); + }); describe('Policy Type Logic', () => { it('should show Ingress type when policy has only ingress', async () => { - server.use(createNetworkPoliciesList()) - render() + server.use(createNetworkPoliciesList()); + render(); await waitFor(() => { - expect(screen.getByText('Ingress')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Ingress')).toBeInTheDocument(); + }); + }); it('should show Both type when policy has ingress and egress', async () => { - server.use(createNetworkPoliciesList()) - render() + server.use(createNetworkPoliciesList()); + render(); await waitFor(() => { - expect(screen.getByText('Both')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('Both')).toBeInTheDocument(); + }); + }); + }); describe('Pod Selector Logic', () => { it('should display specific pod selector when policy has matchLabels', async () => { - server.use(createNetworkPoliciesList()) - render() + server.use(createNetworkPoliciesList()); + render(); await waitFor(() => { - expect(screen.getByText('app=web')).toBeInTheDocument() - expect(screen.getByText('app=api')).toBeInTheDocument() - }) - }) + expect(screen.getByText('app=web')).toBeInTheDocument(); + expect(screen.getByText('app=api')).toBeInTheDocument(); + }); + }); it('should display All pods when policy has empty selector', async () => { const policies = [{ @@ -321,87 +323,87 @@ describe('NetworkPoliciesView', () => { podSelector: {}, policyTypes: ['Ingress'] } - }] - server.use(createNetworkPoliciesList(policies)) - render() + }]; + server.use(createNetworkPoliciesList(policies)); + render(); await waitFor(() => { - expect(screen.getByText('All pods')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('All pods')).toBeInTheDocument(); + }); + }); + }); describe('Rules Count Logic', () => { it('should display correct ingress rules count', async () => { - server.use(createNetworkPoliciesList()) - render() + server.use(createNetworkPoliciesList()); + render(); await waitFor(() => { - expect(screen.getAllByText('1')).toHaveLength(5) // Multiple 1s in stats and table - expect(screen.getByText('0')).toBeInTheDocument() // One egress rule count - }) - }) + expect(screen.getAllByText('1')).toHaveLength(5); // Multiple 1s in stats and table + expect(screen.getByText('0')).toBeInTheDocument(); // One egress rule count + }); + }); it('should display correct egress rules count', async () => { - server.use(createNetworkPoliciesList()) - render() + server.use(createNetworkPoliciesList()); + render(); await waitFor(() => { - expect(screen.getByText('0')).toBeInTheDocument() // web-policy egress rules - expect(screen.getAllByText('1')).toHaveLength(5) // Multiple 1s in stats and table - }) - }) - }) + expect(screen.getByText('0')).toBeInTheDocument(); // web-policy egress rules + expect(screen.getAllByText('1')).toHaveLength(5); // Multiple 1s in stats and table + }); + }); + }); describe('All Namespaces Mode', () => { it('should show all network policies when in all namespaces mode', async () => { // This test is simplified due to mock complexity // In a real scenario, the component would use useListNetworkingV1NetworkPolicyForAllNamespacesQuery - server.use(createAllNetworkPoliciesList()) - render() + server.use(createAllNetworkPoliciesList()); + render(); // The component will still use the default namespace context // This test verifies the handler works correctly await waitFor(() => { - expect(screen.getByText('Network request failed')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('Network request failed')).toBeInTheDocument(); + }); + }); + }); describe('Accessibility', () => { it('should have proper button roles and labels', () => { - server.use(createNetworkPoliciesList()) - render() + server.use(createNetworkPoliciesList()); + render(); - expect(screen.getByRole('button', { name: /create policy/i })).toBeInTheDocument() - expect(screen.getAllByRole('button', { name: '' })[0]).toBeInTheDocument() // Refresh button - }) + expect(screen.getByRole('button', { name: /create policy/i })).toBeInTheDocument(); + expect(screen.getAllByRole('button', { name: '' })[0]).toBeInTheDocument(); // Refresh button + }); it('should have proper table structure', async () => { - server.use(createNetworkPoliciesList()) - render() + server.use(createNetworkPoliciesList()); + render(); await waitFor(() => { - expect(screen.getByRole('table')).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Name' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Namespace' })).toBeInTheDocument() - }) - }) + expect(screen.getByRole('table')).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Name' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Namespace' })).toBeInTheDocument(); + }); + }); it('should be keyboard navigable', async () => { - const user = userEvent.setup() - server.use(createNetworkPoliciesList()) - render() + const user = userEvent.setup(); + server.use(createNetworkPoliciesList()); + render(); - const createButton = screen.getByRole('button', { name: /create policy/i }) - createButton.focus() + const createButton = screen.getByRole('button', { name: /create policy/i }); + createButton.focus(); - expect(document.activeElement).toBe(createButton) + expect(document.activeElement).toBe(createButton); // Test that tab navigation works - await user.tab() + await user.tab(); // The focus should move to the next focusable element - expect(document.activeElement).not.toBe(createButton) - }) - }) -}) + expect(document.activeElement).not.toBe(createButton); + }); + }); +}); diff --git a/apps/ops-dashboard/__tests__/components/resources/pdbs.test.tsx b/apps/ops-dashboard/__tests__/components/resources/pdbs.test.tsx index febada7..d6bfc34 100644 --- a/apps/ops-dashboard/__tests__/components/resources/pdbs.test.tsx +++ b/apps/ops-dashboard/__tests__/components/resources/pdbs.test.tsx @@ -1,16 +1,15 @@ -import { screen, waitFor, fireEvent } from '@testing-library/react'; +import { fireEvent,screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { render } from '../../utils/test-utils'; -import { server } from '@/__mocks__/server'; +import { http, HttpResponse } from 'msw'; + +import { API_BASE } from '@/__mocks__/handlers/common'; import { createPDBsList, createPDBsListError, - createPDBsListSlow, - deletePDBHandler, - deletePDBErrorHandler -} from '@/__mocks__/handlers/pdbs'; -import { http, HttpResponse } from 'msw'; -import { API_BASE } from '@/__mocks__/handlers/common'; + createPDBsListSlow} from '@/__mocks__/handlers/pdbs'; +import { server } from '@/__mocks__/server'; + +import { render } from '../../utils/test-utils'; // Mock window.alert for testing const mockAlert = jest.spyOn(window, 'alert').mockImplementation(() => {}); diff --git a/apps/ops-dashboard/__tests__/components/resources/pods.test.tsx b/apps/ops-dashboard/__tests__/components/resources/pods.test.tsx index 483f95d..fe4f6e2 100644 --- a/apps/ops-dashboard/__tests__/components/resources/pods.test.tsx +++ b/apps/ops-dashboard/__tests__/components/resources/pods.test.tsx @@ -1,14 +1,14 @@ -import { screen, waitFor, fireEvent } from '@testing-library/react'; +import { fireEvent,screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { render } from '../../utils/test-utils'; -import { server } from '@/__mocks__/server'; + import { createPodsList, createPodsListError, createPodsListSlow } from '@/__mocks__/handlers/pods'; -import { http, HttpResponse } from 'msw'; -import { API_BASE } from '@/__mocks__/handlers/common'; +import { server } from '@/__mocks__/server'; + +import { render } from '../../utils/test-utils'; // Mock window.alert for testing const mockAlert = jest.spyOn(window, 'alert').mockImplementation(() => {}); @@ -281,21 +281,21 @@ describe('PodsView', () => { }); }); - describe('Stats Display', () => { - it('should display correct statistics', async () => { - render(); + describe('Stats Display', () => { + it('should display correct statistics', async () => { + render(); - await waitFor(() => { - expect(screen.getByText('nginx-pod-1')).toBeInTheDocument(); - }); + await waitFor(() => { + expect(screen.getByText('nginx-pod-1')).toBeInTheDocument(); + }); - // Check for stats cards - expect(screen.getByText('Total Pods')).toBeInTheDocument(); - expect(screen.getByRole('heading', { name: 'Running' })).toBeInTheDocument(); - expect(screen.getByRole('heading', { name: 'Pending' })).toBeInTheDocument(); - expect(screen.getByRole('heading', { name: 'Failed' })).toBeInTheDocument(); - }); - }); + // Check for stats cards + expect(screen.getByText('Total Pods')).toBeInTheDocument(); + expect(screen.getByRole('heading', { name: 'Running' })).toBeInTheDocument(); + expect(screen.getByRole('heading', { name: 'Pending' })).toBeInTheDocument(); + expect(screen.getByRole('heading', { name: 'Failed' })).toBeInTheDocument(); + }); + }); describe('Namespace Handling', () => { it('should handle namespace prop', async () => { diff --git a/apps/ops-dashboard/__tests__/components/resources/priorityclasses.test.tsx b/apps/ops-dashboard/__tests__/components/resources/priorityclasses.test.tsx index bcd4967..ecce20b 100644 --- a/apps/ops-dashboard/__tests__/components/resources/priorityclasses.test.tsx +++ b/apps/ops-dashboard/__tests__/components/resources/priorityclasses.test.tsx @@ -1,17 +1,17 @@ -import { screen, waitFor, fireEvent } from '@testing-library/react'; +import { fireEvent,screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { render } from '../../utils/test-utils'; -import { server } from '@/__mocks__/server'; +import { http, HttpResponse } from 'msw'; + +import { API_BASE } from '@/__mocks__/handlers/common'; import { - createPriorityClassesList, + createPriorityClassesList, createPriorityClassesListError, createPriorityClassesListSlow, - deletePriorityClassHandler, deletePriorityClassErrorHandler, - createPriorityClassesListData -} from '@/__mocks__/handlers/priorityclasses'; -import { http, HttpResponse } from 'msw'; -import { API_BASE } from '@/__mocks__/handlers/common'; + deletePriorityClassHandler} from '@/__mocks__/handlers/priorityclasses'; +import { server } from '@/__mocks__/server'; + +import { render } from '../../utils/test-utils'; // Mock window.alert for testing const mockAlert = jest.spyOn(window, 'alert').mockImplementation(() => {}); diff --git a/apps/ops-dashboard/__tests__/components/resources/pvcs.test.tsx b/apps/ops-dashboard/__tests__/components/resources/pvcs.test.tsx index e546c64..d9d734d 100644 --- a/apps/ops-dashboard/__tests__/components/resources/pvcs.test.tsx +++ b/apps/ops-dashboard/__tests__/components/resources/pvcs.test.tsx @@ -1,97 +1,96 @@ -import { render, screen, waitFor } from '@testing-library/react' -import userEvent from '@testing-library/user-event' -import { PVCsView } from '@/components/resources/pvcs' -import { server } from '@/__mocks__/server' -import { http, HttpResponse } from 'msw' +import { render, screen, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; + +import { PVCsView } from '@/components/resources/pvcs'; // Mock the confirm dialog jest.mock('../../../hooks/useConfirm', () => ({ confirmDialog: jest.fn().mockResolvedValue(true) -})) +})); // Mock the Kubernetes hooks jest.mock('../../../k8s', () => ({ useListCoreV1NamespacedPersistentVolumeClaimQuery: jest.fn(), useListCoreV1PersistentVolumeClaimForAllNamespacesQuery: jest.fn(), useDeleteCoreV1NamespacedPersistentVolumeClaim: jest.fn() -})) +})); // Mock the namespace context jest.mock('../../../contexts/NamespaceContext', () => ({ usePreferredNamespace: () => ({ namespace: 'default' }) -})) +})); describe('PVCsView', () => { beforeEach(() => { - jest.clearAllMocks() - }) + jest.clearAllMocks(); + }); describe('Basic Rendering', () => { it('should render PVCs view with header', () => { - const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s') + const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s'); useListCoreV1NamespacedPersistentVolumeClaimQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('heading', { name: 'Persistent Volume Claims', level: 2 })).toBeInTheDocument() - expect(screen.getByText('Storage requests by pods')).toBeInTheDocument() - }) + expect(screen.getByRole('heading', { name: 'Persistent Volume Claims', level: 2 })).toBeInTheDocument(); + expect(screen.getByText('Storage requests by pods')).toBeInTheDocument(); + }); it('should render refresh button', () => { - const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s') + const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s'); useListCoreV1NamespacedPersistentVolumeClaimQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - const refreshButton = screen.getByRole('button', { name: '' }) - expect(refreshButton).toBeInTheDocument() - }) + const refreshButton = screen.getByRole('button', { name: '' }); + expect(refreshButton).toBeInTheDocument(); + }); it('should render create PVC button', () => { - const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s') + const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s'); useListCoreV1NamespacedPersistentVolumeClaimQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('button', { name: 'Create PVC' })).toBeInTheDocument() - }) + expect(screen.getByRole('button', { name: 'Create PVC' })).toBeInTheDocument(); + }); it('should render stats cards', () => { - const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s') + const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s'); useListCoreV1NamespacedPersistentVolumeClaimQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByText('Total PVCs')).toBeInTheDocument() - expect(screen.getByText('Bound')).toBeInTheDocument() - expect(screen.getByText('Pending')).toBeInTheDocument() - expect(screen.getByText('Total Storage')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Total PVCs')).toBeInTheDocument(); + expect(screen.getByText('Bound')).toBeInTheDocument(); + expect(screen.getByText('Pending')).toBeInTheDocument(); + expect(screen.getByText('Total Storage')).toBeInTheDocument(); + }); + }); describe('Data Display', () => { it('should display PVC data', async () => { - const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s') + const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s'); useListCoreV1NamespacedPersistentVolumeClaimQuery.mockReturnValue({ data: { items: [ @@ -105,17 +104,17 @@ describe('PVCsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('pvc-1')).toBeInTheDocument() - }) - }) + expect(screen.getByText('pvc-1')).toBeInTheDocument(); + }); + }); it('should display correct statistics', async () => { - const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s') + const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s'); useListCoreV1NamespacedPersistentVolumeClaimQuery.mockReturnValue({ data: { items: [ @@ -128,20 +127,20 @@ describe('PVCsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('4')).toBeInTheDocument() // Total PVCs - expect(screen.getByText('2', { selector: '.text-green-600' })).toBeInTheDocument() // Bound - expect(screen.getByText('1', { selector: '.text-yellow-600' })).toBeInTheDocument() // Pending - expect(screen.getByText('0.0 GB')).toBeInTheDocument() // Total Storage - }) - }) + expect(screen.getByText('4')).toBeInTheDocument(); // Total PVCs + expect(screen.getByText('2', { selector: '.text-green-600' })).toBeInTheDocument(); // Bound + expect(screen.getByText('1', { selector: '.text-yellow-600' })).toBeInTheDocument(); // Pending + expect(screen.getByText('0.0 GB')).toBeInTheDocument(); // Total Storage + }); + }); it('should display status badges correctly', async () => { - const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s') + const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s'); useListCoreV1NamespacedPersistentVolumeClaimQuery.mockReturnValue({ data: { items: [ @@ -153,19 +152,19 @@ describe('PVCsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('Bound', { selector: '.rounded-full' })).toBeInTheDocument() - expect(screen.getByText('Pending', { selector: '.rounded-full' })).toBeInTheDocument() - expect(screen.getByText('Lost', { selector: '.rounded-full' })).toBeInTheDocument() - }) - }) + expect(screen.getByText('Bound', { selector: '.rounded-full' })).toBeInTheDocument(); + expect(screen.getByText('Pending', { selector: '.rounded-full' })).toBeInTheDocument(); + expect(screen.getByText('Lost', { selector: '.rounded-full' })).toBeInTheDocument(); + }); + }); it('should display storage size correctly', async () => { - const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s') + const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s'); useListCoreV1NamespacedPersistentVolumeClaimQuery.mockReturnValue({ data: { items: [ @@ -183,18 +182,18 @@ describe('PVCsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('10Gi')).toBeInTheDocument() - expect(screen.getByText('20Gi')).toBeInTheDocument() - }) - }) + expect(screen.getByText('10Gi')).toBeInTheDocument(); + expect(screen.getByText('20Gi')).toBeInTheDocument(); + }); + }); it('should display access modes correctly', async () => { - const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s') + const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s'); useListCoreV1NamespacedPersistentVolumeClaimQuery.mockReturnValue({ data: { items: [ @@ -211,18 +210,18 @@ describe('PVCsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('RWO')).toBeInTheDocument() - expect(screen.getByText('RWX, ROX')).toBeInTheDocument() - }) - }) + expect(screen.getByText('RWO')).toBeInTheDocument(); + expect(screen.getByText('RWX, ROX')).toBeInTheDocument(); + }); + }); it('should display storage class correctly', async () => { - const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s') + const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s'); useListCoreV1NamespacedPersistentVolumeClaimQuery.mockReturnValue({ data: { items: [ @@ -239,18 +238,18 @@ describe('PVCsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('fast-ssd')).toBeInTheDocument() - expect(screen.getByText('default')).toBeInTheDocument() - }) - }) + expect(screen.getByText('fast-ssd')).toBeInTheDocument(); + expect(screen.getByText('default')).toBeInTheDocument(); + }); + }); it('should display volume name correctly', async () => { - const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s') + const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s'); useListCoreV1NamespacedPersistentVolumeClaimQuery.mockReturnValue({ data: { items: [ @@ -267,64 +266,64 @@ describe('PVCsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('pv-1')).toBeInTheDocument() - expect(screen.getByText('Not bound')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('pv-1')).toBeInTheDocument(); + expect(screen.getByText('Not bound')).toBeInTheDocument(); + }); + }); + }); describe('User Interactions', () => { it('should refresh data when refresh button is clicked', async () => { - const user = userEvent.setup() - const mockRefetch = jest.fn() - const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s') + const user = userEvent.setup(); + const mockRefetch = jest.fn(); + const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s'); useListCoreV1NamespacedPersistentVolumeClaimQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: mockRefetch - }) + }); - render() + render(); - const refreshButton = screen.getByRole('button', { name: '' }) - await user.click(refreshButton) + const refreshButton = screen.getByRole('button', { name: '' }); + await user.click(refreshButton); - expect(mockRefetch).toHaveBeenCalled() - }) + expect(mockRefetch).toHaveBeenCalled(); + }); it('should show create PVC alert when create button is clicked', async () => { - const user = userEvent.setup() - const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s') + const user = userEvent.setup(); + const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s'); useListCoreV1NamespacedPersistentVolumeClaimQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); // Mock alert - const alertSpy = jest.spyOn(window, 'alert').mockImplementation(() => {}) + const alertSpy = jest.spyOn(window, 'alert').mockImplementation(() => {}); - render() + render(); - const createButton = screen.getByRole('button', { name: 'Create PVC' }) - await user.click(createButton) + const createButton = screen.getByRole('button', { name: 'Create PVC' }); + await user.click(createButton); - expect(alertSpy).toHaveBeenCalledWith('Create PVC functionality not yet implemented') + expect(alertSpy).toHaveBeenCalledWith('Create PVC functionality not yet implemented'); - alertSpy.mockRestore() - }) + alertSpy.mockRestore(); + }); it('should show delete confirmation when delete button is clicked', async () => { - const user = userEvent.setup() - const { useListCoreV1NamespacedPersistentVolumeClaimQuery, useDeleteCoreV1NamespacedPersistentVolumeClaim } = require('../../../k8s') - const mockDelete = jest.fn().mockResolvedValue({}) + const user = userEvent.setup(); + const { useListCoreV1NamespacedPersistentVolumeClaimQuery, useDeleteCoreV1NamespacedPersistentVolumeClaim } = require('../../../k8s'); + const mockDelete = jest.fn().mockResolvedValue({}); useListCoreV1NamespacedPersistentVolumeClaimQuery.mockReturnValue({ data: { @@ -339,31 +338,31 @@ describe('PVCsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); useDeleteCoreV1NamespacedPersistentVolumeClaim.mockReturnValue({ mutateAsync: mockDelete - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('pvc-1')).toBeInTheDocument() - }) + expect(screen.getByText('pvc-1')).toBeInTheDocument(); + }); - const deleteButtons = screen.getAllByRole('button') + const deleteButtons = screen.getAllByRole('button'); const deleteButton = deleteButtons.find(button => button.querySelector('svg.lucide-trash-2') - ) + ); if (deleteButton) { - await user.click(deleteButton) - expect(deleteButton).toBeInTheDocument() + await user.click(deleteButton); + expect(deleteButton).toBeInTheDocument(); } - }) + }); it('should show view button when view button is clicked', async () => { - const user = userEvent.setup() - const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s') + const user = userEvent.setup(); + const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s'); useListCoreV1NamespacedPersistentVolumeClaimQuery.mockReturnValue({ data: { items: [ @@ -377,27 +376,27 @@ describe('PVCsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('pvc-1')).toBeInTheDocument() - }) + expect(screen.getByText('pvc-1')).toBeInTheDocument(); + }); - const viewButtons = screen.getAllByRole('button') + const viewButtons = screen.getAllByRole('button'); const viewButton = viewButtons.find(button => button.querySelector('svg.lucide-eye') - ) + ); if (viewButton) { - await user.click(viewButton) - expect(viewButton).toBeInTheDocument() + await user.click(viewButton); + expect(viewButton).toBeInTheDocument(); } - }) + }); it('should disable delete button for bound PVCs', async () => { - const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s') + const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s'); useListCoreV1NamespacedPersistentVolumeClaimQuery.mockReturnValue({ data: { items: [ @@ -411,28 +410,28 @@ describe('PVCsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('pvc-1')).toBeInTheDocument() - }) + expect(screen.getByText('pvc-1')).toBeInTheDocument(); + }); - const deleteButtons = screen.getAllByRole('button') + const deleteButtons = screen.getAllByRole('button'); const deleteButton = deleteButtons.find(button => button.querySelector('svg.lucide-trash-2') - ) + ); if (deleteButton) { - expect(deleteButton).toBeDisabled() + expect(deleteButton).toBeDisabled(); } - }) - }) + }); + }); describe('Status Logic', () => { it('should show Bound status correctly', async () => { - const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s') + const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s'); useListCoreV1NamespacedPersistentVolumeClaimQuery.mockReturnValue({ data: { items: [ @@ -445,17 +444,17 @@ describe('PVCsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('Bound', { selector: '.rounded-full' })).toBeInTheDocument() - }) - }) + expect(screen.getByText('Bound', { selector: '.rounded-full' })).toBeInTheDocument(); + }); + }); it('should show Pending status correctly', async () => { - const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s') + const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s'); useListCoreV1NamespacedPersistentVolumeClaimQuery.mockReturnValue({ data: { items: [ @@ -468,17 +467,17 @@ describe('PVCsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('Pending', { selector: '.rounded-full' })).toBeInTheDocument() - }) - }) + expect(screen.getByText('Pending', { selector: '.rounded-full' })).toBeInTheDocument(); + }); + }); it('should show Lost status correctly', async () => { - const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s') + const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s'); useListCoreV1NamespacedPersistentVolumeClaimQuery.mockReturnValue({ data: { items: [ @@ -491,84 +490,84 @@ describe('PVCsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('Lost', { selector: '.rounded-full' })).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('Lost', { selector: '.rounded-full' })).toBeInTheDocument(); + }); + }); + }); describe('Loading States', () => { it('should show loading spinner when loading', () => { - const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s') + const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s'); useListCoreV1NamespacedPersistentVolumeClaimQuery.mockReturnValue({ data: undefined, isLoading: true, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('button', { name: '' })).toBeDisabled() // Refresh button - }) - }) + expect(screen.getByRole('button', { name: '' })).toBeDisabled(); // Refresh button + }); + }); describe('Error States', () => { it('should display error message when fetch fails', () => { - const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s') + const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s'); useListCoreV1NamespacedPersistentVolumeClaimQuery.mockReturnValue({ data: undefined, isLoading: false, error: new Error('Network request failed'), refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByText('Network request failed')).toBeInTheDocument() - }) + expect(screen.getByText('Network request failed')).toBeInTheDocument(); + }); it('should show retry button in error state', () => { - const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s') + const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s'); useListCoreV1NamespacedPersistentVolumeClaimQuery.mockReturnValue({ data: undefined, isLoading: false, error: new Error('Network request failed'), refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('button', { name: 'Retry' })).toBeInTheDocument() - }) - }) + expect(screen.getByRole('button', { name: 'Retry' })).toBeInTheDocument(); + }); + }); describe('Empty States', () => { it('should display empty state when no PVCs', () => { - const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s') + const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s'); useListCoreV1NamespacedPersistentVolumeClaimQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByText('No persistent volume claims found')).toBeInTheDocument() - }) - }) + expect(screen.getByText('No persistent volume claims found')).toBeInTheDocument(); + }); + }); describe('Delete Functionality', () => { it('should handle delete action with confirmation', async () => { - const user = userEvent.setup() - const { useListCoreV1NamespacedPersistentVolumeClaimQuery, useDeleteCoreV1NamespacedPersistentVolumeClaim } = require('../../../k8s') - const mockDelete = jest.fn().mockResolvedValue({}) - const mockRefetch = jest.fn() + const user = userEvent.setup(); + const { useListCoreV1NamespacedPersistentVolumeClaimQuery, useDeleteCoreV1NamespacedPersistentVolumeClaim } = require('../../../k8s'); + const mockDelete = jest.fn().mockResolvedValue({}); + const mockRefetch = jest.fn(); useListCoreV1NamespacedPersistentVolumeClaimQuery.mockReturnValue({ data: { @@ -583,26 +582,26 @@ describe('PVCsView', () => { isLoading: false, error: null, refetch: mockRefetch - }) + }); useDeleteCoreV1NamespacedPersistentVolumeClaim.mockReturnValue({ mutateAsync: mockDelete - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('pvc-1')).toBeInTheDocument() - }) + expect(screen.getByText('pvc-1')).toBeInTheDocument(); + }); // Check that component renders without errors - expect(screen.getByRole('heading', { name: 'Persistent Volume Claims', level: 2 })).toBeInTheDocument() - }) + expect(screen.getByRole('heading', { name: 'Persistent Volume Claims', level: 2 })).toBeInTheDocument(); + }); it('should handle delete action error', async () => { - const user = userEvent.setup() - const { useListCoreV1NamespacedPersistentVolumeClaimQuery, useDeleteCoreV1NamespacedPersistentVolumeClaim } = require('../../../k8s') - const mockDelete = jest.fn().mockRejectedValue(new Error('Delete failed')) - const mockRefetch = jest.fn() + const user = userEvent.setup(); + const { useListCoreV1NamespacedPersistentVolumeClaimQuery, useDeleteCoreV1NamespacedPersistentVolumeClaim } = require('../../../k8s'); + const mockDelete = jest.fn().mockRejectedValue(new Error('Delete failed')); + const mockRefetch = jest.fn(); useListCoreV1NamespacedPersistentVolumeClaimQuery.mockReturnValue({ data: { @@ -617,30 +616,30 @@ describe('PVCsView', () => { isLoading: false, error: null, refetch: mockRefetch - }) + }); useDeleteCoreV1NamespacedPersistentVolumeClaim.mockReturnValue({ mutateAsync: mockDelete - }) + }); // Mock alert - const alertSpy = jest.spyOn(window, 'alert').mockImplementation(() => {}) + const alertSpy = jest.spyOn(window, 'alert').mockImplementation(() => {}); - render() + render(); await waitFor(() => { - expect(screen.getByText('pvc-1')).toBeInTheDocument() - }) + expect(screen.getByText('pvc-1')).toBeInTheDocument(); + }); // Check that component renders without errors - expect(screen.getByRole('heading', { name: 'Persistent Volume Claims', level: 2 })).toBeInTheDocument() + expect(screen.getByRole('heading', { name: 'Persistent Volume Claims', level: 2 })).toBeInTheDocument(); - alertSpy.mockRestore() - }) - }) + alertSpy.mockRestore(); + }); + }); describe('Storage Calculation', () => { it('should calculate storage correctly with different units', async () => { - const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s') + const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s'); useListCoreV1NamespacedPersistentVolumeClaimQuery.mockReturnValue({ data: { items: [ @@ -661,40 +660,40 @@ describe('PVCsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('pvc-1')).toBeInTheDocument() - expect(screen.getByText('pvc-2')).toBeInTheDocument() - expect(screen.getByText('pvc-3')).toBeInTheDocument() - }) + expect(screen.getByText('pvc-1')).toBeInTheDocument(); + expect(screen.getByText('pvc-2')).toBeInTheDocument(); + expect(screen.getByText('pvc-3')).toBeInTheDocument(); + }); // Check that storage calculation is displayed - expect(screen.getByText('Total Storage')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Total Storage')).toBeInTheDocument(); + }); + }); describe('Accessibility', () => { it('should have proper button roles and labels', () => { - const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s') + const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s'); useListCoreV1NamespacedPersistentVolumeClaimQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('button', { name: '' })).toBeInTheDocument() // Refresh button - expect(screen.getByRole('button', { name: 'Create PVC' })).toBeInTheDocument() - }) + expect(screen.getByRole('button', { name: '' })).toBeInTheDocument(); // Refresh button + expect(screen.getByRole('button', { name: 'Create PVC' })).toBeInTheDocument(); + }); it('should be keyboard navigable', async () => { - const user = userEvent.setup() - const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s') + const user = userEvent.setup(); + const { useListCoreV1NamespacedPersistentVolumeClaimQuery } = require('../../../k8s'); useListCoreV1NamespacedPersistentVolumeClaimQuery.mockReturnValue({ data: { items: [ @@ -708,28 +707,28 @@ describe('PVCsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); // Wait for data to load first await waitFor(() => { - expect(screen.getByText('pvc-1')).toBeInTheDocument() - }) + expect(screen.getByText('pvc-1')).toBeInTheDocument(); + }); - const refreshButtons = screen.getAllByRole('button') + const refreshButtons = screen.getAllByRole('button'); const refreshButton = refreshButtons.find(button => button.querySelector('svg.lucide-refresh-cw') && button.classList.contains('h-10') - ) - refreshButton.focus() + ); + refreshButton.focus(); - expect(document.activeElement).toBe(refreshButton) + expect(document.activeElement).toBe(refreshButton); // Test that tab navigation works - await user.tab() + await user.tab(); // The focus should move to the next focusable element - expect(document.activeElement).not.toBe(refreshButton) - }) - }) -}) + expect(document.activeElement).not.toBe(refreshButton); + }); + }); +}); diff --git a/apps/ops-dashboard/__tests__/components/resources/pvs.test.tsx b/apps/ops-dashboard/__tests__/components/resources/pvs.test.tsx index 981c2d8..9e21642 100644 --- a/apps/ops-dashboard/__tests__/components/resources/pvs.test.tsx +++ b/apps/ops-dashboard/__tests__/components/resources/pvs.test.tsx @@ -1,91 +1,90 @@ -import { render, screen, waitFor } from '@testing-library/react' -import userEvent from '@testing-library/user-event' -import { PVsView } from '@/components/resources/pvs' -import { server } from '@/__mocks__/server' -import { http, HttpResponse } from 'msw' +import { render, screen, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; + +import { PVsView } from '@/components/resources/pvs'; // Mock the confirm dialog jest.mock('../../../hooks/useConfirm', () => ({ confirmDialog: jest.fn().mockResolvedValue(true) -})) +})); // Mock the Kubernetes hooks jest.mock('../../../k8s', () => ({ useListCoreV1PersistentVolumeQuery: jest.fn(), useDeleteCoreV1PersistentVolume: jest.fn() -})) +})); describe('PVsView', () => { beforeEach(() => { - jest.clearAllMocks() - }) + jest.clearAllMocks(); + }); describe('Basic Rendering', () => { it('should render PVs view with header', () => { - const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s') + const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s'); useListCoreV1PersistentVolumeQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('heading', { name: 'Persistent Volumes', level: 2 })).toBeInTheDocument() - expect(screen.getByText('Cluster-wide storage resources')).toBeInTheDocument() - }) + expect(screen.getByRole('heading', { name: 'Persistent Volumes', level: 2 })).toBeInTheDocument(); + expect(screen.getByText('Cluster-wide storage resources')).toBeInTheDocument(); + }); it('should render refresh button', () => { - const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s') + const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s'); useListCoreV1PersistentVolumeQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - const refreshButton = screen.getByRole('button', { name: '' }) - expect(refreshButton).toBeInTheDocument() - }) + const refreshButton = screen.getByRole('button', { name: '' }); + expect(refreshButton).toBeInTheDocument(); + }); it('should render create PV button', () => { - const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s') + const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s'); useListCoreV1PersistentVolumeQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('button', { name: 'Create PV' })).toBeInTheDocument() - }) + expect(screen.getByRole('button', { name: 'Create PV' })).toBeInTheDocument(); + }); it('should render stats cards', () => { - const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s') + const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s'); useListCoreV1PersistentVolumeQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByText('Total PVs')).toBeInTheDocument() - expect(screen.getByText('Available')).toBeInTheDocument() - expect(screen.getByText('Bound')).toBeInTheDocument() - expect(screen.getByText('Total Capacity')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Total PVs')).toBeInTheDocument(); + expect(screen.getByText('Available')).toBeInTheDocument(); + expect(screen.getByText('Bound')).toBeInTheDocument(); + expect(screen.getByText('Total Capacity')).toBeInTheDocument(); + }); + }); describe('Data Display', () => { it('should display PV data', async () => { - const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s') + const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s'); useListCoreV1PersistentVolumeQuery.mockReturnValue({ data: { items: [ @@ -99,17 +98,17 @@ describe('PVsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('pv-1')).toBeInTheDocument() - }) - }) + expect(screen.getByText('pv-1')).toBeInTheDocument(); + }); + }); it('should display correct statistics', async () => { - const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s') + const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s'); useListCoreV1PersistentVolumeQuery.mockReturnValue({ data: { items: [ @@ -122,20 +121,20 @@ describe('PVsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('4')).toBeInTheDocument() // Total PVs - expect(screen.getByText('1', { selector: '.text-green-600' })).toBeInTheDocument() // Available - expect(screen.getByText('1', { selector: '.text-blue-600' })).toBeInTheDocument() // Bound - expect(screen.getByText('0.0 GB')).toBeInTheDocument() // Total Capacity - }) - }) + expect(screen.getByText('4')).toBeInTheDocument(); // Total PVs + expect(screen.getByText('1', { selector: '.text-green-600' })).toBeInTheDocument(); // Available + expect(screen.getByText('1', { selector: '.text-blue-600' })).toBeInTheDocument(); // Bound + expect(screen.getByText('0.0 GB')).toBeInTheDocument(); // Total Capacity + }); + }); it('should display status badges correctly', async () => { - const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s') + const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s'); useListCoreV1PersistentVolumeQuery.mockReturnValue({ data: { items: [ @@ -148,21 +147,21 @@ describe('PVsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('Available', { selector: 'h3' })).toBeInTheDocument() // Card title - expect(screen.getByText('Available', { selector: '.rounded-full' })).toBeInTheDocument() // Badge - expect(screen.getByText('Bound', { selector: '.rounded-full' })).toBeInTheDocument() - expect(screen.getByText('Released', { selector: '.rounded-full' })).toBeInTheDocument() - expect(screen.getByText('Failed', { selector: '.rounded-full' })).toBeInTheDocument() - }) - }) + expect(screen.getByText('Available', { selector: 'h3' })).toBeInTheDocument(); // Card title + expect(screen.getByText('Available', { selector: '.rounded-full' })).toBeInTheDocument(); // Badge + expect(screen.getByText('Bound', { selector: '.rounded-full' })).toBeInTheDocument(); + expect(screen.getByText('Released', { selector: '.rounded-full' })).toBeInTheDocument(); + expect(screen.getByText('Failed', { selector: '.rounded-full' })).toBeInTheDocument(); + }); + }); it('should display capacity correctly', async () => { - const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s') + const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s'); useListCoreV1PersistentVolumeQuery.mockReturnValue({ data: { items: [ @@ -179,18 +178,18 @@ describe('PVsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('10Gi')).toBeInTheDocument() - expect(screen.getByText('20Gi')).toBeInTheDocument() - }) - }) + expect(screen.getByText('10Gi')).toBeInTheDocument(); + expect(screen.getByText('20Gi')).toBeInTheDocument(); + }); + }); it('should display access modes correctly', async () => { - const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s') + const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s'); useListCoreV1PersistentVolumeQuery.mockReturnValue({ data: { items: [ @@ -207,18 +206,18 @@ describe('PVsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('RWO')).toBeInTheDocument() - expect(screen.getByText('RWX, ROX')).toBeInTheDocument() - }) - }) + expect(screen.getByText('RWO')).toBeInTheDocument(); + expect(screen.getByText('RWX, ROX')).toBeInTheDocument(); + }); + }); it('should display storage class correctly', async () => { - const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s') + const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s'); useListCoreV1PersistentVolumeQuery.mockReturnValue({ data: { items: [ @@ -235,18 +234,18 @@ describe('PVsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('fast-ssd')).toBeInTheDocument() - expect(screen.getAllByText('None')).toHaveLength(3) // Storage class and other fields - }) - }) + expect(screen.getByText('fast-ssd')).toBeInTheDocument(); + expect(screen.getAllByText('None')).toHaveLength(3); // Storage class and other fields + }); + }); it('should display reclaim policy correctly', async () => { - const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s') + const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s'); useListCoreV1PersistentVolumeQuery.mockReturnValue({ data: { items: [ @@ -263,18 +262,18 @@ describe('PVsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('Retain')).toBeInTheDocument() - expect(screen.getByText('Delete')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Retain')).toBeInTheDocument(); + expect(screen.getByText('Delete')).toBeInTheDocument(); + }); + }); it('should display claim reference correctly', async () => { - const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s') + const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s'); useListCoreV1PersistentVolumeQuery.mockReturnValue({ data: { items: [ @@ -296,64 +295,64 @@ describe('PVsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('default/pvc-1')).toBeInTheDocument() - expect(screen.getByText('Unbound')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('default/pvc-1')).toBeInTheDocument(); + expect(screen.getByText('Unbound')).toBeInTheDocument(); + }); + }); + }); describe('User Interactions', () => { it('should refresh data when refresh button is clicked', async () => { - const user = userEvent.setup() - const mockRefetch = jest.fn() - const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s') + const user = userEvent.setup(); + const mockRefetch = jest.fn(); + const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s'); useListCoreV1PersistentVolumeQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: mockRefetch - }) + }); - render() + render(); - const refreshButton = screen.getByRole('button', { name: '' }) - await user.click(refreshButton) + const refreshButton = screen.getByRole('button', { name: '' }); + await user.click(refreshButton); - expect(mockRefetch).toHaveBeenCalled() - }) + expect(mockRefetch).toHaveBeenCalled(); + }); it('should show create PV alert when create button is clicked', async () => { - const user = userEvent.setup() - const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s') + const user = userEvent.setup(); + const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s'); useListCoreV1PersistentVolumeQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); // Mock alert - const alertSpy = jest.spyOn(window, 'alert').mockImplementation(() => {}) + const alertSpy = jest.spyOn(window, 'alert').mockImplementation(() => {}); - render() + render(); - const createButton = screen.getByRole('button', { name: 'Create PV' }) - await user.click(createButton) + const createButton = screen.getByRole('button', { name: 'Create PV' }); + await user.click(createButton); - expect(alertSpy).toHaveBeenCalledWith('Create PV functionality not yet implemented') + expect(alertSpy).toHaveBeenCalledWith('Create PV functionality not yet implemented'); - alertSpy.mockRestore() - }) + alertSpy.mockRestore(); + }); it('should show delete confirmation when delete button is clicked', async () => { - const user = userEvent.setup() - const { useListCoreV1PersistentVolumeQuery, useDeleteCoreV1PersistentVolume } = require('../../../k8s') - const mockDelete = jest.fn().mockResolvedValue({}) + const user = userEvent.setup(); + const { useListCoreV1PersistentVolumeQuery, useDeleteCoreV1PersistentVolume } = require('../../../k8s'); + const mockDelete = jest.fn().mockResolvedValue({}); useListCoreV1PersistentVolumeQuery.mockReturnValue({ data: { @@ -368,31 +367,31 @@ describe('PVsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); useDeleteCoreV1PersistentVolume.mockReturnValue({ mutateAsync: mockDelete - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('pv-1')).toBeInTheDocument() - }) + expect(screen.getByText('pv-1')).toBeInTheDocument(); + }); - const deleteButtons = screen.getAllByRole('button') + const deleteButtons = screen.getAllByRole('button'); const deleteButton = deleteButtons.find(button => button.querySelector('svg.lucide-trash-2') - ) + ); if (deleteButton) { - await user.click(deleteButton) - expect(deleteButton).toBeInTheDocument() + await user.click(deleteButton); + expect(deleteButton).toBeInTheDocument(); } - }) + }); it('should show view button when view button is clicked', async () => { - const user = userEvent.setup() - const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s') + const user = userEvent.setup(); + const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s'); useListCoreV1PersistentVolumeQuery.mockReturnValue({ data: { items: [ @@ -406,27 +405,27 @@ describe('PVsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('pv-1')).toBeInTheDocument() - }) + expect(screen.getByText('pv-1')).toBeInTheDocument(); + }); - const viewButtons = screen.getAllByRole('button') + const viewButtons = screen.getAllByRole('button'); const viewButton = viewButtons.find(button => button.querySelector('svg.lucide-eye') - ) + ); if (viewButton) { - await user.click(viewButton) - expect(viewButton).toBeInTheDocument() + await user.click(viewButton); + expect(viewButton).toBeInTheDocument(); } - }) + }); it('should disable delete button for bound PVs', async () => { - const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s') + const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s'); useListCoreV1PersistentVolumeQuery.mockReturnValue({ data: { items: [ @@ -440,28 +439,28 @@ describe('PVsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('pv-1')).toBeInTheDocument() - }) + expect(screen.getByText('pv-1')).toBeInTheDocument(); + }); - const deleteButtons = screen.getAllByRole('button') + const deleteButtons = screen.getAllByRole('button'); const deleteButton = deleteButtons.find(button => button.querySelector('svg.lucide-trash-2') - ) + ); if (deleteButton) { - expect(deleteButton).toBeDisabled() + expect(deleteButton).toBeDisabled(); } - }) - }) + }); + }); describe('Status Logic', () => { it('should show Available status correctly', async () => { - const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s') + const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s'); useListCoreV1PersistentVolumeQuery.mockReturnValue({ data: { items: [ @@ -474,17 +473,17 @@ describe('PVsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getAllByText('Available')).toHaveLength(2) // Card title and badge - }) - }) + expect(screen.getAllByText('Available')).toHaveLength(2); // Card title and badge + }); + }); it('should show Bound status correctly', async () => { - const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s') + const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s'); useListCoreV1PersistentVolumeQuery.mockReturnValue({ data: { items: [ @@ -497,17 +496,17 @@ describe('PVsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('Bound', { selector: '.rounded-full' })).toBeInTheDocument() - }) - }) + expect(screen.getByText('Bound', { selector: '.rounded-full' })).toBeInTheDocument(); + }); + }); it('should show Released status correctly', async () => { - const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s') + const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s'); useListCoreV1PersistentVolumeQuery.mockReturnValue({ data: { items: [ @@ -520,17 +519,17 @@ describe('PVsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('Released')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Released')).toBeInTheDocument(); + }); + }); it('should show Failed status correctly', async () => { - const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s') + const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s'); useListCoreV1PersistentVolumeQuery.mockReturnValue({ data: { items: [ @@ -543,97 +542,97 @@ describe('PVsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('Failed')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('Failed')).toBeInTheDocument(); + }); + }); + }); describe('Loading States', () => { it('should show loading spinner when loading', () => { - const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s') + const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s'); useListCoreV1PersistentVolumeQuery.mockReturnValue({ data: undefined, isLoading: true, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('button', { name: '' })).toBeDisabled() // Refresh button - }) - }) + expect(screen.getByRole('button', { name: '' })).toBeDisabled(); // Refresh button + }); + }); describe('Error States', () => { it('should display error message when fetch fails', () => { - const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s') + const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s'); useListCoreV1PersistentVolumeQuery.mockReturnValue({ data: undefined, isLoading: false, error: new Error('Network request failed'), refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByText('Network request failed')).toBeInTheDocument() - }) + expect(screen.getByText('Network request failed')).toBeInTheDocument(); + }); it('should show retry button in error state', () => { - const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s') + const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s'); useListCoreV1PersistentVolumeQuery.mockReturnValue({ data: undefined, isLoading: false, error: new Error('Network request failed'), refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('button', { name: 'Retry' })).toBeInTheDocument() - }) - }) + expect(screen.getByRole('button', { name: 'Retry' })).toBeInTheDocument(); + }); + }); describe('Empty States', () => { it('should display empty state when no PVs', () => { - const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s') + const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s'); useListCoreV1PersistentVolumeQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByText('No persistent volumes found')).toBeInTheDocument() - }) - }) + expect(screen.getByText('No persistent volumes found')).toBeInTheDocument(); + }); + }); describe('Accessibility', () => { it('should have proper button roles and labels', () => { - const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s') + const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s'); useListCoreV1PersistentVolumeQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('button', { name: '' })).toBeInTheDocument() // Refresh button - expect(screen.getByRole('button', { name: 'Create PV' })).toBeInTheDocument() - }) + expect(screen.getByRole('button', { name: '' })).toBeInTheDocument(); // Refresh button + expect(screen.getByRole('button', { name: 'Create PV' })).toBeInTheDocument(); + }); it('should be keyboard navigable', async () => { - const user = userEvent.setup() - const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s') + const user = userEvent.setup(); + const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s'); useListCoreV1PersistentVolumeQuery.mockReturnValue({ data: { items: [ @@ -647,37 +646,37 @@ describe('PVsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); // Wait for data to load first await waitFor(() => { - expect(screen.getByText('pv-1')).toBeInTheDocument() - }) + expect(screen.getByText('pv-1')).toBeInTheDocument(); + }); - const refreshButtons = screen.getAllByRole('button') + const refreshButtons = screen.getAllByRole('button'); const refreshButton = refreshButtons.find(button => button.querySelector('svg.lucide-refresh-cw') && button.classList.contains('h-10') - ) - refreshButton.focus() + ); + refreshButton.focus(); - expect(document.activeElement).toBe(refreshButton) + expect(document.activeElement).toBe(refreshButton); // Test that tab navigation works - await user.tab() + await user.tab(); // The focus should move to the next focusable element - expect(document.activeElement).not.toBe(refreshButton) - }) - }) + expect(document.activeElement).not.toBe(refreshButton); + }); + }); describe('Delete Functionality', () => { it('should handle delete action with confirmation', async () => { - const user = userEvent.setup() - const { useListCoreV1PersistentVolumeQuery, useDeleteCoreV1PersistentVolume } = require('../../../k8s') - const mockDelete = jest.fn().mockResolvedValue({}) - const mockRefetch = jest.fn() + const user = userEvent.setup(); + const { useListCoreV1PersistentVolumeQuery, useDeleteCoreV1PersistentVolume } = require('../../../k8s'); + const mockDelete = jest.fn().mockResolvedValue({}); + const mockRefetch = jest.fn(); useListCoreV1PersistentVolumeQuery.mockReturnValue({ data: { @@ -692,43 +691,43 @@ describe('PVsView', () => { isLoading: false, error: null, refetch: mockRefetch - }) + }); useDeleteCoreV1PersistentVolume.mockReturnValue({ mutateAsync: mockDelete - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('pv-1')).toBeInTheDocument() - }) + expect(screen.getByText('pv-1')).toBeInTheDocument(); + }); - const deleteButtons = screen.getAllByRole('button') + const deleteButtons = screen.getAllByRole('button'); const deleteButton = deleteButtons.find(button => button.querySelector('svg.lucide-trash-2') - ) + ); if (deleteButton) { - await user.click(deleteButton) + await user.click(deleteButton); expect(require('../../../hooks/useConfirm').confirmDialog).toHaveBeenCalledWith({ title: 'Delete Persistent Volume', description: 'Are you sure you want to delete pv-1? This may cause data loss.', confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); expect(mockDelete).toHaveBeenCalledWith({ path: { name: 'pv-1' }, query: {} - }) - expect(mockRefetch).toHaveBeenCalled() + }); + expect(mockRefetch).toHaveBeenCalled(); } - }) + }); it('should handle delete action error', async () => { - const user = userEvent.setup() - const { useListCoreV1PersistentVolumeQuery, useDeleteCoreV1PersistentVolume } = require('../../../k8s') - const mockDelete = jest.fn().mockRejectedValue(new Error('Delete failed')) - const mockRefetch = jest.fn() + const user = userEvent.setup(); + const { useListCoreV1PersistentVolumeQuery, useDeleteCoreV1PersistentVolume } = require('../../../k8s'); + const mockDelete = jest.fn().mockRejectedValue(new Error('Delete failed')); + const mockRefetch = jest.fn(); useListCoreV1PersistentVolumeQuery.mockReturnValue({ data: { @@ -743,39 +742,39 @@ describe('PVsView', () => { isLoading: false, error: null, refetch: mockRefetch - }) + }); useDeleteCoreV1PersistentVolume.mockReturnValue({ mutateAsync: mockDelete - }) + }); // Mock alert - const alertSpy = jest.spyOn(window, 'alert').mockImplementation(() => {}) + const alertSpy = jest.spyOn(window, 'alert').mockImplementation(() => {}); - render() + render(); await waitFor(() => { - expect(screen.getByText('pv-1')).toBeInTheDocument() - }) + expect(screen.getByText('pv-1')).toBeInTheDocument(); + }); - const deleteButtons = screen.getAllByRole('button') + const deleteButtons = screen.getAllByRole('button'); const deleteButton = deleteButtons.find(button => button.querySelector('svg.lucide-trash-2') - ) + ); if (deleteButton) { - await user.click(deleteButton) - expect(alertSpy).toHaveBeenCalledWith('Failed to delete PV: Delete failed') - expect(mockRefetch).not.toHaveBeenCalled() // Refetch should not be called on error + await user.click(deleteButton); + expect(alertSpy).toHaveBeenCalledWith('Failed to delete PV: Delete failed'); + expect(mockRefetch).not.toHaveBeenCalled(); // Refetch should not be called on error } - alertSpy.mockRestore() - }) + alertSpy.mockRestore(); + }); it('should handle delete action with non-Error exception', async () => { - const user = userEvent.setup() - const { useListCoreV1PersistentVolumeQuery, useDeleteCoreV1PersistentVolume } = require('../../../k8s') - const mockDelete = jest.fn().mockRejectedValue('String error') - const mockRefetch = jest.fn() + const user = userEvent.setup(); + const { useListCoreV1PersistentVolumeQuery, useDeleteCoreV1PersistentVolume } = require('../../../k8s'); + const mockDelete = jest.fn().mockRejectedValue('String error'); + const mockRefetch = jest.fn(); useListCoreV1PersistentVolumeQuery.mockReturnValue({ data: { @@ -790,43 +789,43 @@ describe('PVsView', () => { isLoading: false, error: null, refetch: mockRefetch - }) + }); useDeleteCoreV1PersistentVolume.mockReturnValue({ mutateAsync: mockDelete - }) + }); // Mock alert - const alertSpy = jest.spyOn(window, 'alert').mockImplementation(() => {}) + const alertSpy = jest.spyOn(window, 'alert').mockImplementation(() => {}); - render() + render(); await waitFor(() => { - expect(screen.getByText('pv-1')).toBeInTheDocument() - }) + expect(screen.getByText('pv-1')).toBeInTheDocument(); + }); - const deleteButtons = screen.getAllByRole('button') + const deleteButtons = screen.getAllByRole('button'); const deleteButton = deleteButtons.find(button => button.querySelector('svg.lucide-trash-2') - ) + ); if (deleteButton) { - await user.click(deleteButton) - expect(alertSpy).toHaveBeenCalledWith('Failed to delete PV: Unknown error') - expect(mockRefetch).not.toHaveBeenCalled() + await user.click(deleteButton); + expect(alertSpy).toHaveBeenCalledWith('Failed to delete PV: Unknown error'); + expect(mockRefetch).not.toHaveBeenCalled(); } - alertSpy.mockRestore() - }) + alertSpy.mockRestore(); + }); it('should not delete when confirmation is cancelled', async () => { - const user = userEvent.setup() - const { useListCoreV1PersistentVolumeQuery, useDeleteCoreV1PersistentVolume } = require('../../../k8s') - const mockDelete = jest.fn() - const mockRefetch = jest.fn() + const user = userEvent.setup(); + const { useListCoreV1PersistentVolumeQuery, useDeleteCoreV1PersistentVolume } = require('../../../k8s'); + const mockDelete = jest.fn(); + const mockRefetch = jest.fn(); // Mock confirmDialog to return false - const { confirmDialog } = require('../../../hooks/useConfirm') - confirmDialog.mockResolvedValueOnce(false) + const { confirmDialog } = require('../../../hooks/useConfirm'); + confirmDialog.mockResolvedValueOnce(false); useListCoreV1PersistentVolumeQuery.mockReturnValue({ data: { @@ -841,34 +840,34 @@ describe('PVsView', () => { isLoading: false, error: null, refetch: mockRefetch - }) + }); useDeleteCoreV1PersistentVolume.mockReturnValue({ mutateAsync: mockDelete - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('pv-1')).toBeInTheDocument() - }) + expect(screen.getByText('pv-1')).toBeInTheDocument(); + }); - const deleteButtons = screen.getAllByRole('button') + const deleteButtons = screen.getAllByRole('button'); const deleteButton = deleteButtons.find(button => button.querySelector('svg.lucide-trash-2') - ) + ); if (deleteButton) { - await user.click(deleteButton) - expect(confirmDialog).toHaveBeenCalled() - expect(mockDelete).not.toHaveBeenCalled() - expect(mockRefetch).not.toHaveBeenCalled() + await user.click(deleteButton); + expect(confirmDialog).toHaveBeenCalled(); + expect(mockDelete).not.toHaveBeenCalled(); + expect(mockRefetch).not.toHaveBeenCalled(); } - }) - }) + }); + }); describe('Storage Calculation', () => { it('should calculate storage correctly with different units', async () => { - const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s') + const { useListCoreV1PersistentVolumeQuery } = require('../../../k8s'); useListCoreV1PersistentVolumeQuery.mockReturnValue({ data: { items: [ @@ -893,19 +892,19 @@ describe('PVsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('pv-1')).toBeInTheDocument() - expect(screen.getByText('pv-2')).toBeInTheDocument() - expect(screen.getByText('pv-3')).toBeInTheDocument() - expect(screen.getByText('pv-4')).toBeInTheDocument() - }) + expect(screen.getByText('pv-1')).toBeInTheDocument(); + expect(screen.getByText('pv-2')).toBeInTheDocument(); + expect(screen.getByText('pv-3')).toBeInTheDocument(); + expect(screen.getByText('pv-4')).toBeInTheDocument(); + }); // Check that the total capacity is displayed (exact value may vary due to calculation) - expect(screen.getByText(/GB/)).toBeInTheDocument() - }) - }) -}) + expect(screen.getByText(/GB/)).toBeInTheDocument(); + }); + }); +}); diff --git a/apps/ops-dashboard/__tests__/components/resources/replicasets.test.tsx b/apps/ops-dashboard/__tests__/components/resources/replicasets.test.tsx index 5ab2e65..7c5becc 100644 --- a/apps/ops-dashboard/__tests__/components/resources/replicasets.test.tsx +++ b/apps/ops-dashboard/__tests__/components/resources/replicasets.test.tsx @@ -1,19 +1,19 @@ import { screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { render } from '../../utils/test-utils'; -import { server } from '@/__mocks__/server'; + import { - createReplicaSetsList, - createReplicaSetsListError, - createReplicaSetsListSlow, + createReplicaSetDelete, + createReplicaSetDeleteError, createReplicaSetScale, createReplicaSetScaleError, - createReplicaSetDelete, - createReplicaSetDeleteError -} from '@/__mocks__/handlers/replicasets'; - + createReplicaSetsList, + createReplicaSetsListError, + createReplicaSetsListSlow} from '@/__mocks__/handlers/replicasets'; +import { server } from '@/__mocks__/server'; import { ReplicaSetsView } from '@/components/resources/replicasets'; +import { render } from '../../utils/test-utils'; + describe('ReplicaSetsView', () => { const user = userEvent.setup(); @@ -192,58 +192,58 @@ describe('ReplicaSetsView', () => { }); }); - describe('Status Determination', () => { - it('should determine Ready status correctly', async () => { - const readyReplicaSet = { - metadata: { name: 'ready-rs', namespace: 'default', creationTimestamp: '2023-01-01T00:00:00Z' }, - spec: { replicas: 3, template: { spec: { containers: [{ image: 'nginx:latest' }] } } }, - status: { readyReplicas: 3, availableReplicas: 3 } - }; + describe('Status Determination', () => { + it('should determine Ready status correctly', async () => { + const readyReplicaSet = { + metadata: { name: 'ready-rs', namespace: 'default', creationTimestamp: '2023-01-01T00:00:00Z' }, + spec: { replicas: 3, template: { spec: { containers: [{ image: 'nginx:latest' }] } } }, + status: { readyReplicas: 3, availableReplicas: 3 } + }; - server.use(createReplicaSetsList([readyReplicaSet])); + server.use(createReplicaSetsList([readyReplicaSet])); - render(); + render(); - await waitFor(() => { - expect(screen.getByText('ready-rs')).toBeInTheDocument(); - expect(screen.getAllByText('Ready')).toHaveLength(3); // Card title, table header, and badge - }); - }); + await waitFor(() => { + expect(screen.getByText('ready-rs')).toBeInTheDocument(); + expect(screen.getAllByText('Ready')).toHaveLength(3); // Card title, table header, and badge + }); + }); - it('should determine Scaling status correctly', async () => { - const scalingReplicaSet = { - metadata: { name: 'scaling-rs', namespace: 'default', creationTimestamp: '2023-01-01T00:00:00Z' }, - spec: { replicas: 5, template: { spec: { containers: [{ image: 'nginx:latest' }] } } }, - status: { readyReplicas: 3, availableReplicas: 3 } - }; + it('should determine Scaling status correctly', async () => { + const scalingReplicaSet = { + metadata: { name: 'scaling-rs', namespace: 'default', creationTimestamp: '2023-01-01T00:00:00Z' }, + spec: { replicas: 5, template: { spec: { containers: [{ image: 'nginx:latest' }] } } }, + status: { readyReplicas: 3, availableReplicas: 3 } + }; - server.use(createReplicaSetsList([scalingReplicaSet])); + server.use(createReplicaSetsList([scalingReplicaSet])); - render(); + render(); - await waitFor(() => { - expect(screen.getByText('scaling-rs')).toBeInTheDocument(); - expect(screen.getByText('Scaling')).toBeInTheDocument(); - }); - }); + await waitFor(() => { + expect(screen.getByText('scaling-rs')).toBeInTheDocument(); + expect(screen.getByText('Scaling')).toBeInTheDocument(); + }); + }); - it('should determine NotReady status correctly', async () => { - const notReadyReplicaSet = { - metadata: { name: 'notready-rs', namespace: 'default', creationTimestamp: '2023-01-01T00:00:00Z' }, - spec: { replicas: 0, template: { spec: { containers: [{ image: 'nginx:latest' }] } } }, - status: { readyReplicas: 0, availableReplicas: 0 } - }; + it('should determine NotReady status correctly', async () => { + const notReadyReplicaSet = { + metadata: { name: 'notready-rs', namespace: 'default', creationTimestamp: '2023-01-01T00:00:00Z' }, + spec: { replicas: 0, template: { spec: { containers: [{ image: 'nginx:latest' }] } } }, + status: { readyReplicas: 0, availableReplicas: 0 } + }; - server.use(createReplicaSetsList([notReadyReplicaSet])); + server.use(createReplicaSetsList([notReadyReplicaSet])); - render(); + render(); - await waitFor(() => { - expect(screen.getByText('notready-rs')).toBeInTheDocument(); - expect(screen.getByText('NotReady')).toBeInTheDocument(); - }); - }); - }); + await waitFor(() => { + expect(screen.getByText('notready-rs')).toBeInTheDocument(); + expect(screen.getByText('NotReady')).toBeInTheDocument(); + }); + }); + }); describe('ReplicaSet Actions', () => { it('should handle scale action', async () => { @@ -401,20 +401,20 @@ describe('ReplicaSetsView', () => { }); }); - describe('Stats Display', () => { - it('should display correct statistics', async () => { - render(); + describe('Stats Display', () => { + it('should display correct statistics', async () => { + render(); - await waitFor(() => { - expect(screen.getByText('nginx-deployment-1234567890')).toBeInTheDocument(); - }); + await waitFor(() => { + expect(screen.getByText('nginx-deployment-1234567890')).toBeInTheDocument(); + }); - // Check for stats cards - expect(screen.getByText('Total ReplicaSets')).toBeInTheDocument(); - expect(screen.getByRole('heading', { name: 'Ready' })).toBeInTheDocument(); - expect(screen.getByRole('heading', { name: 'Total Replicas' })).toBeInTheDocument(); - }); - }); + // Check for stats cards + expect(screen.getByText('Total ReplicaSets')).toBeInTheDocument(); + expect(screen.getByRole('heading', { name: 'Ready' })).toBeInTheDocument(); + expect(screen.getByRole('heading', { name: 'Total Replicas' })).toBeInTheDocument(); + }); + }); describe('Create ReplicaSet Alert', () => { it('should show create alert when create button is clicked', async () => { diff --git a/apps/ops-dashboard/__tests__/components/resources/resourcequotas.test.tsx b/apps/ops-dashboard/__tests__/components/resources/resourcequotas.test.tsx index 3c31fbb..38243ee 100644 --- a/apps/ops-dashboard/__tests__/components/resources/resourcequotas.test.tsx +++ b/apps/ops-dashboard/__tests__/components/resources/resourcequotas.test.tsx @@ -1,96 +1,95 @@ -import { render, screen, waitFor } from '@testing-library/react' -import userEvent from '@testing-library/user-event' -import { ResourceQuotasView } from '@/components/resources/resourcequotas' -import { server } from '@/__mocks__/server' -import { http, HttpResponse } from 'msw' +import { render, screen, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; + +import { ResourceQuotasView } from '@/components/resources/resourcequotas'; // Mock the confirm dialog jest.mock('../../../hooks/useConfirm', () => ({ confirmDialog: jest.fn().mockResolvedValue(true) -})) +})); // Mock the Kubernetes hooks jest.mock('../../../k8s', () => ({ useListCoreV1NamespacedResourceQuotaQuery: jest.fn(), useListCoreV1ResourceQuotaForAllNamespacesQuery: jest.fn(), useDeleteCoreV1NamespacedResourceQuota: jest.fn() -})) +})); // Mock the namespace context jest.mock('../../../contexts/NamespaceContext', () => ({ usePreferredNamespace: () => ({ namespace: 'default' }) -})) +})); describe('ResourceQuotasView', () => { beforeEach(() => { - jest.clearAllMocks() - }) + jest.clearAllMocks(); + }); describe('Basic Rendering', () => { it('should render resource quotas view with header', () => { - const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s') + const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s'); useListCoreV1NamespacedResourceQuotaQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('heading', { name: 'Resource Quotas', level: 2 })).toBeInTheDocument() - expect(screen.getByText('Manage namespace resource limits and usage')).toBeInTheDocument() - }) + expect(screen.getByRole('heading', { name: 'Resource Quotas', level: 2 })).toBeInTheDocument(); + expect(screen.getByText('Manage namespace resource limits and usage')).toBeInTheDocument(); + }); it('should render refresh button', () => { - const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s') + const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s'); useListCoreV1NamespacedResourceQuotaQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - const refreshButton = screen.getByRole('button', { name: '' }) - expect(refreshButton).toBeInTheDocument() - }) + const refreshButton = screen.getByRole('button', { name: '' }); + expect(refreshButton).toBeInTheDocument(); + }); it('should render create quota button', () => { - const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s') + const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s'); useListCoreV1NamespacedResourceQuotaQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('button', { name: 'Create Quota' })).toBeInTheDocument() - }) + expect(screen.getByRole('button', { name: 'Create Quota' })).toBeInTheDocument(); + }); it('should render stats cards', () => { - const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s') + const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s'); useListCoreV1NamespacedResourceQuotaQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByText('Total Quotas')).toBeInTheDocument() - expect(screen.getByText('Namespaces')).toBeInTheDocument() - expect(screen.getByText('Over 75% Usage')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Total Quotas')).toBeInTheDocument(); + expect(screen.getByText('Namespaces')).toBeInTheDocument(); + expect(screen.getByText('Over 75% Usage')).toBeInTheDocument(); + }); + }); describe('Data Display', () => { it('should display resource quota data', async () => { - const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s') + const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s'); useListCoreV1NamespacedResourceQuotaQuery.mockReturnValue({ data: { items: [ @@ -106,17 +105,17 @@ describe('ResourceQuotasView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('compute-quota', { selector: 'td.font-medium' })).toBeInTheDocument() - }) - }) + expect(screen.getByText('compute-quota', { selector: 'td.font-medium' })).toBeInTheDocument(); + }); + }); it('should display correct statistics', async () => { - const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s') + const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s'); useListCoreV1NamespacedResourceQuotaQuery.mockReturnValue({ data: { items: [ @@ -139,18 +138,18 @@ describe('ResourceQuotasView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getAllByText('2', { selector: '.text-2xl.font-bold' })).toHaveLength(2) // Total Quotas and Namespaces - expect(screen.getByText('0', { selector: '.text-2xl.font-bold.text-yellow-600' })).toBeInTheDocument() // Over 75% Usage - }) - }) + expect(screen.getAllByText('2', { selector: '.text-2xl.font-bold' })).toHaveLength(2); // Total Quotas and Namespaces + expect(screen.getByText('0', { selector: '.text-2xl.font-bold.text-yellow-600' })).toBeInTheDocument(); // Over 75% Usage + }); + }); it('should display resource information correctly', async () => { - const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s') + const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s'); useListCoreV1NamespacedResourceQuotaQuery.mockReturnValue({ data: { items: [ @@ -166,22 +165,22 @@ describe('ResourceQuotasView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('requests.cpu')).toBeInTheDocument() - expect(screen.getByText('requests.memory')).toBeInTheDocument() - expect(screen.getByText('1', { selector: 'td' })).toBeInTheDocument() // Used CPU - expect(screen.getByText('2', { selector: 'td' })).toBeInTheDocument() // Hard limit CPU - expect(screen.getByText('2Gi')).toBeInTheDocument() // Used memory - expect(screen.getByText('4Gi')).toBeInTheDocument() // Hard limit memory - }) - }) + expect(screen.getByText('requests.cpu')).toBeInTheDocument(); + expect(screen.getByText('requests.memory')).toBeInTheDocument(); + expect(screen.getByText('1', { selector: 'td' })).toBeInTheDocument(); // Used CPU + expect(screen.getByText('2', { selector: 'td' })).toBeInTheDocument(); // Hard limit CPU + expect(screen.getByText('2Gi')).toBeInTheDocument(); // Used memory + expect(screen.getByText('4Gi')).toBeInTheDocument(); // Hard limit memory + }); + }); it('should display usage badges correctly', async () => { - const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s') + const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s'); useListCoreV1NamespacedResourceQuotaQuery.mockReturnValue({ data: { items: [ @@ -197,17 +196,17 @@ describe('ResourceQuotasView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('50%')).toBeInTheDocument() // Low usage - }) - }) + expect(screen.getByText('50%')).toBeInTheDocument(); // Low usage + }); + }); it('should display namespace information correctly', async () => { - const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s') + const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s'); useListCoreV1NamespacedResourceQuotaQuery.mockReturnValue({ data: { items: [ @@ -223,63 +222,63 @@ describe('ResourceQuotasView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('default')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('default')).toBeInTheDocument(); + }); + }); + }); describe('User Interactions', () => { it('should refresh data when refresh button is clicked', async () => { - const user = userEvent.setup() - const mockRefetch = jest.fn() - const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s') + const user = userEvent.setup(); + const mockRefetch = jest.fn(); + const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s'); useListCoreV1NamespacedResourceQuotaQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: mockRefetch - }) + }); - render() + render(); - const refreshButton = screen.getByRole('button', { name: '' }) - await user.click(refreshButton) + const refreshButton = screen.getByRole('button', { name: '' }); + await user.click(refreshButton); - expect(mockRefetch).toHaveBeenCalled() - }) + expect(mockRefetch).toHaveBeenCalled(); + }); it('should show create quota alert when create button is clicked', async () => { - const user = userEvent.setup() - const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s') + const user = userEvent.setup(); + const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s'); useListCoreV1NamespacedResourceQuotaQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); // Mock alert - const alertSpy = jest.spyOn(window, 'alert').mockImplementation(() => {}) + const alertSpy = jest.spyOn(window, 'alert').mockImplementation(() => {}); - render() + render(); - const createButton = screen.getByRole('button', { name: 'Create Quota' }) - await user.click(createButton) + const createButton = screen.getByRole('button', { name: 'Create Quota' }); + await user.click(createButton); - expect(alertSpy).toHaveBeenCalledWith('Create Resource Quota functionality not yet implemented') + expect(alertSpy).toHaveBeenCalledWith('Create Resource Quota functionality not yet implemented'); - alertSpy.mockRestore() - }) + alertSpy.mockRestore(); + }); it('should show delete confirmation when delete button is clicked', async () => { - const user = userEvent.setup() - const { useListCoreV1NamespacedResourceQuotaQuery, useDeleteCoreV1NamespacedResourceQuota } = require('../../../k8s') - const mockDelete = jest.fn().mockResolvedValue({}) + const user = userEvent.setup(); + const { useListCoreV1NamespacedResourceQuotaQuery, useDeleteCoreV1NamespacedResourceQuota } = require('../../../k8s'); + const mockDelete = jest.fn().mockResolvedValue({}); useListCoreV1NamespacedResourceQuotaQuery.mockReturnValue({ data: { @@ -296,31 +295,31 @@ describe('ResourceQuotasView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); useDeleteCoreV1NamespacedResourceQuota.mockReturnValue({ mutateAsync: mockDelete - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('test-quota', { selector: 'td.font-medium' })).toBeInTheDocument() - }) + expect(screen.getByText('test-quota', { selector: 'td.font-medium' })).toBeInTheDocument(); + }); - const deleteButtons = screen.getAllByRole('button') + const deleteButtons = screen.getAllByRole('button'); const deleteButton = deleteButtons.find(button => button.querySelector('svg.lucide-trash-2') - ) + ); if (deleteButton) { - await user.click(deleteButton) - expect(deleteButton).toBeInTheDocument() + await user.click(deleteButton); + expect(deleteButton).toBeInTheDocument(); } - }) + }); it('should show view button when view button is clicked', async () => { - const user = userEvent.setup() - const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s') + const user = userEvent.setup(); + const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s'); useListCoreV1NamespacedResourceQuotaQuery.mockReturnValue({ data: { items: [ @@ -336,29 +335,29 @@ describe('ResourceQuotasView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('test-quota', { selector: 'td.font-medium' })).toBeInTheDocument() - }) + expect(screen.getByText('test-quota', { selector: 'td.font-medium' })).toBeInTheDocument(); + }); - const viewButtons = screen.getAllByRole('button') + const viewButtons = screen.getAllByRole('button'); const viewButton = viewButtons.find(button => button.querySelector('svg.lucide-eye') - ) + ); if (viewButton) { - await user.click(viewButton) - expect(viewButton).toBeInTheDocument() + await user.click(viewButton); + expect(viewButton).toBeInTheDocument(); } - }) - }) + }); + }); describe('Usage Calculation Logic', () => { it('should calculate usage percentage correctly', async () => { - const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s') + const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s'); useListCoreV1NamespacedResourceQuotaQuery.mockReturnValue({ data: { items: [ @@ -374,17 +373,17 @@ describe('ResourceQuotasView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('50%')).toBeInTheDocument() - }) - }) + expect(screen.getByText('50%')).toBeInTheDocument(); + }); + }); it('should handle zero hard limits correctly', async () => { - const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s') + const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s'); useListCoreV1NamespacedResourceQuotaQuery.mockReturnValue({ data: { items: [ @@ -400,19 +399,19 @@ describe('ResourceQuotasView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('0%')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('0%')).toBeInTheDocument(); + }); + }); + }); describe('Usage Badge Logic', () => { it('should show success badge for low usage', async () => { - const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s') + const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s'); useListCoreV1NamespacedResourceQuotaQuery.mockReturnValue({ data: { items: [ @@ -428,98 +427,98 @@ describe('ResourceQuotasView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('50%')).toBeInTheDocument() - }) - }) + expect(screen.getByText('50%')).toBeInTheDocument(); + }); + }); - }) + }); describe('Loading States', () => { it('should show loading spinner when loading', () => { - const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s') + const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s'); useListCoreV1NamespacedResourceQuotaQuery.mockReturnValue({ data: undefined, isLoading: true, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('button', { name: '' })).toBeDisabled() // Refresh button - }) - }) + expect(screen.getByRole('button', { name: '' })).toBeDisabled(); // Refresh button + }); + }); describe('Error States', () => { it('should display error message when fetch fails', () => { - const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s') + const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s'); useListCoreV1NamespacedResourceQuotaQuery.mockReturnValue({ data: undefined, isLoading: false, error: new Error('Network request failed'), refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByText('Network request failed')).toBeInTheDocument() - }) + expect(screen.getByText('Network request failed')).toBeInTheDocument(); + }); it('should show retry button in error state', () => { - const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s') + const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s'); useListCoreV1NamespacedResourceQuotaQuery.mockReturnValue({ data: undefined, isLoading: false, error: new Error('Network request failed'), refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('button', { name: 'Retry' })).toBeInTheDocument() - }) - }) + expect(screen.getByRole('button', { name: 'Retry' })).toBeInTheDocument(); + }); + }); describe('Empty States', () => { it('should display empty state when no quotas', () => { - const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s') + const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s'); useListCoreV1NamespacedResourceQuotaQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByText('No resource quotas found')).toBeInTheDocument() - }) - }) + expect(screen.getByText('No resource quotas found')).toBeInTheDocument(); + }); + }); describe('Accessibility', () => { it('should have proper button roles and labels', () => { - const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s') + const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s'); useListCoreV1NamespacedResourceQuotaQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('button', { name: '' })).toBeInTheDocument() // Refresh button - expect(screen.getByRole('button', { name: 'Create Quota' })).toBeInTheDocument() - }) + expect(screen.getByRole('button', { name: '' })).toBeInTheDocument(); // Refresh button + expect(screen.getByRole('button', { name: 'Create Quota' })).toBeInTheDocument(); + }); it('should be keyboard navigable', async () => { - const user = userEvent.setup() - const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s') + const user = userEvent.setup(); + const { useListCoreV1NamespacedResourceQuotaQuery } = require('../../../k8s'); useListCoreV1NamespacedResourceQuotaQuery.mockReturnValue({ data: { items: [ @@ -535,30 +534,30 @@ describe('ResourceQuotasView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); // Wait for data to load first await waitFor(() => { - expect(screen.getByText('test-quota', { selector: 'td.font-medium' })).toBeInTheDocument() - }) + expect(screen.getByText('test-quota', { selector: 'td.font-medium' })).toBeInTheDocument(); + }); - const refreshButtons = screen.getAllByRole('button') + const refreshButtons = screen.getAllByRole('button'); const refreshButton = refreshButtons.find(button => button.querySelector('svg.lucide-refresh-cw') && button.classList.contains('h-4') - ) + ); if (refreshButton) { - refreshButton.focus() - expect(document.activeElement).toBe(refreshButton) + refreshButton.focus(); + expect(document.activeElement).toBe(refreshButton); // Test that tab navigation works - await user.tab() + await user.tab(); // The focus should move to the next focusable element - expect(document.activeElement).not.toBe(refreshButton) + expect(document.activeElement).not.toBe(refreshButton); } - }) - }) -}) + }); + }); +}); diff --git a/apps/ops-dashboard/__tests__/components/resources/rolebindings.test.tsx b/apps/ops-dashboard/__tests__/components/resources/rolebindings.test.tsx index 2497e21..08507cc 100644 --- a/apps/ops-dashboard/__tests__/components/resources/rolebindings.test.tsx +++ b/apps/ops-dashboard/__tests__/components/resources/rolebindings.test.tsx @@ -1,13 +1,12 @@ -import { render, screen, waitFor } from '@testing-library/react' -import userEvent from '@testing-library/user-event' -import { RoleBindingsView } from '@/components/resources/rolebindings' -import { server } from '@/__mocks__/server' -import { http, HttpResponse } from 'msw' +import { render, screen, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; + +import { RoleBindingsView } from '@/components/resources/rolebindings'; // Mock the confirm dialog jest.mock('../../../hooks/useConfirm', () => ({ confirmDialog: jest.fn().mockResolvedValue(true) -})) +})); // Mock the Kubernetes hooks jest.mock('../../../k8s', () => ({ @@ -16,99 +15,99 @@ jest.mock('../../../k8s', () => ({ useDeleteRbacAuthorizationV1NamespacedRoleBinding: jest.fn(), useListRbacAuthorizationV1ClusterRoleBindingQuery: jest.fn(), useDeleteRbacAuthorizationV1ClusterRoleBinding: jest.fn() -})) +})); // Mock the namespace context jest.mock('../../../contexts/NamespaceContext', () => ({ usePreferredNamespace: () => ({ namespace: 'default' }) -})) +})); describe('RoleBindingsView', () => { beforeEach(() => { - jest.clearAllMocks() - }) + jest.clearAllMocks(); + }); describe('Basic Rendering', () => { it('should render role bindings view with header', () => { - const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleBindingQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('heading', { name: 'Role Bindings', level: 2 })).toBeInTheDocument() - expect(screen.getByText('Bind roles to users, groups, and service accounts')).toBeInTheDocument() - }) + expect(screen.getByRole('heading', { name: 'Role Bindings', level: 2 })).toBeInTheDocument(); + expect(screen.getByText('Bind roles to users, groups, and service accounts')).toBeInTheDocument(); + }); it('should render refresh button', () => { - const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleBindingQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - const refreshButton = screen.getByRole('button', { name: '' }) - expect(refreshButton).toBeInTheDocument() - }) + const refreshButton = screen.getByRole('button', { name: '' }); + expect(refreshButton).toBeInTheDocument(); + }); it('should render create binding button', () => { - const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleBindingQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('button', { name: 'Create Binding' })).toBeInTheDocument() - }) + expect(screen.getByRole('button', { name: 'Create Binding' })).toBeInTheDocument(); + }); it('should render binding type toggle buttons', () => { - const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleBindingQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('button', { name: 'Namespace' })).toBeInTheDocument() - expect(screen.getByRole('button', { name: 'Cluster' })).toBeInTheDocument() - }) + expect(screen.getByRole('button', { name: 'Namespace' })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: 'Cluster' })).toBeInTheDocument(); + }); it('should render stats cards', () => { - const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleBindingQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByText('Total Bindings')).toBeInTheDocument() - expect(screen.getByText('Service Accounts')).toBeInTheDocument() - expect(screen.getByText('Users/Groups')).toBeInTheDocument() - expect(screen.getByText('Unique Roles')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Total Bindings')).toBeInTheDocument(); + expect(screen.getByText('Service Accounts')).toBeInTheDocument(); + expect(screen.getByText('Users/Groups')).toBeInTheDocument(); + expect(screen.getByText('Unique Roles')).toBeInTheDocument(); + }); + }); describe('Data Display', () => { it('should display role binding data', async () => { - const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleBindingQuery.mockReturnValue({ data: { items: [ @@ -122,17 +121,17 @@ describe('RoleBindingsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('admin-binding', { selector: 'td.font-medium' })).toBeInTheDocument() - }) - }) + expect(screen.getByText('admin-binding', { selector: 'td.font-medium' })).toBeInTheDocument(); + }); + }); it('should display correct statistics', async () => { - const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleBindingQuery.mockReturnValue({ data: { items: [ @@ -156,19 +155,19 @@ describe('RoleBindingsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getAllByText('3', { selector: '.text-2xl.font-bold' })).toHaveLength(2) // Total Bindings and Unique Roles - expect(screen.getByText('1', { selector: '.text-2xl.font-bold' })).toBeInTheDocument() // Service Accounts - expect(screen.getByText('2', { selector: '.text-2xl.font-bold' })).toBeInTheDocument() // Users/Groups - }) - }) + expect(screen.getAllByText('3', { selector: '.text-2xl.font-bold' })).toHaveLength(2); // Total Bindings and Unique Roles + expect(screen.getByText('1', { selector: '.text-2xl.font-bold' })).toBeInTheDocument(); // Service Accounts + expect(screen.getByText('2', { selector: '.text-2xl.font-bold' })).toBeInTheDocument(); // Users/Groups + }); + }); it('should display role reference correctly', async () => { - const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleBindingQuery.mockReturnValue({ data: { items: [ @@ -182,17 +181,17 @@ describe('RoleBindingsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('Role/admin')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Role/admin')).toBeInTheDocument(); + }); + }); it('should display subjects correctly', async () => { - const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleBindingQuery.mockReturnValue({ data: { items: [ @@ -214,18 +213,18 @@ describe('RoleBindingsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('User/admin-user')).toBeInTheDocument() - expect(screen.getByText('2 subjects')).toBeInTheDocument() - }) - }) + expect(screen.getByText('User/admin-user')).toBeInTheDocument(); + expect(screen.getByText('2 subjects')).toBeInTheDocument(); + }); + }); it('should display subject types correctly', async () => { - const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleBindingQuery.mockReturnValue({ data: { items: [ @@ -242,17 +241,17 @@ describe('RoleBindingsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('User, ServiceAccount')).toBeInTheDocument() - }) - }) + expect(screen.getByText('User, ServiceAccount')).toBeInTheDocument(); + }); + }); it('should display creation date correctly', async () => { - const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleBindingQuery.mockReturnValue({ data: { items: [ @@ -269,17 +268,17 @@ describe('RoleBindingsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('1/1/2024')).toBeInTheDocument() - }) - }) + expect(screen.getByText('1/1/2024')).toBeInTheDocument(); + }); + }); it('should show namespace column for namespace bindings', async () => { - const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleBindingQuery.mockReturnValue({ data: { items: [ @@ -293,90 +292,90 @@ describe('RoleBindingsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('Namespace', { selector: 'th' })).toBeInTheDocument() - expect(screen.getByText('default')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('Namespace', { selector: 'th' })).toBeInTheDocument(); + expect(screen.getByText('default')).toBeInTheDocument(); + }); + }); + }); describe('User Interactions', () => { it('should refresh data when refresh button is clicked', async () => { - const user = userEvent.setup() - const mockRefetch = jest.fn() - const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s') + const user = userEvent.setup(); + const mockRefetch = jest.fn(); + const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleBindingQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: mockRefetch - }) + }); - render() + render(); - const refreshButton = screen.getByRole('button', { name: '' }) - await user.click(refreshButton) + const refreshButton = screen.getByRole('button', { name: '' }); + await user.click(refreshButton); - expect(mockRefetch).toHaveBeenCalled() - }) + expect(mockRefetch).toHaveBeenCalled(); + }); it('should show create binding alert when create button is clicked', async () => { - const user = userEvent.setup() - const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s') + const user = userEvent.setup(); + const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleBindingQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); // Mock alert - const alertSpy = jest.spyOn(window, 'alert').mockImplementation(() => {}) + const alertSpy = jest.spyOn(window, 'alert').mockImplementation(() => {}); - render() + render(); - const createButton = screen.getByRole('button', { name: 'Create Binding' }) - await user.click(createButton) + const createButton = screen.getByRole('button', { name: 'Create Binding' }); + await user.click(createButton); - expect(alertSpy).toHaveBeenCalledWith('Create Role Binding functionality not yet implemented') + expect(alertSpy).toHaveBeenCalledWith('Create Role Binding functionality not yet implemented'); - alertSpy.mockRestore() - }) + alertSpy.mockRestore(); + }); it('should switch between namespace and cluster bindings', async () => { - const user = userEvent.setup() - const { useListRbacAuthorizationV1NamespacedRoleBindingQuery, useListRbacAuthorizationV1ClusterRoleBindingQuery } = require('../../../k8s') + const user = userEvent.setup(); + const { useListRbacAuthorizationV1NamespacedRoleBindingQuery, useListRbacAuthorizationV1ClusterRoleBindingQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleBindingQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); useListRbacAuthorizationV1ClusterRoleBindingQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - const clusterButton = screen.getByRole('button', { name: 'Cluster' }) - await user.click(clusterButton) + const clusterButton = screen.getByRole('button', { name: 'Cluster' }); + await user.click(clusterButton); - expect(screen.getByText('Cluster Role Bindings')).toBeInTheDocument() - }) + expect(screen.getByText('Cluster Role Bindings')).toBeInTheDocument(); + }); it('should show delete confirmation when delete button is clicked', async () => { - const user = userEvent.setup() - const { useListRbacAuthorizationV1NamespacedRoleBindingQuery, useDeleteRbacAuthorizationV1NamespacedRoleBinding } = require('../../../k8s') - const mockDelete = jest.fn().mockResolvedValue({}) + const user = userEvent.setup(); + const { useListRbacAuthorizationV1NamespacedRoleBindingQuery, useDeleteRbacAuthorizationV1NamespacedRoleBinding } = require('../../../k8s'); + const mockDelete = jest.fn().mockResolvedValue({}); useListRbacAuthorizationV1NamespacedRoleBindingQuery.mockReturnValue({ data: { @@ -391,31 +390,31 @@ describe('RoleBindingsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); useDeleteRbacAuthorizationV1NamespacedRoleBinding.mockReturnValue({ mutateAsync: mockDelete - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('user-binding', { selector: 'td.font-medium' })).toBeInTheDocument() - }) + expect(screen.getByText('user-binding', { selector: 'td.font-medium' })).toBeInTheDocument(); + }); - const deleteButtons = screen.getAllByRole('button') + const deleteButtons = screen.getAllByRole('button'); const deleteButton = deleteButtons.find(button => button.querySelector('svg.lucide-trash-2') - ) + ); if (deleteButton) { - await user.click(deleteButton) - expect(deleteButton).toBeInTheDocument() + await user.click(deleteButton); + expect(deleteButton).toBeInTheDocument(); } - }) + }); it('should show view button when view button is clicked', async () => { - const user = userEvent.setup() - const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s') + const user = userEvent.setup(); + const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleBindingQuery.mockReturnValue({ data: { items: [ @@ -429,29 +428,29 @@ describe('RoleBindingsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('user-binding', { selector: 'td.font-medium' })).toBeInTheDocument() - }) + expect(screen.getByText('user-binding', { selector: 'td.font-medium' })).toBeInTheDocument(); + }); - const viewButtons = screen.getAllByRole('button') + const viewButtons = screen.getAllByRole('button'); const viewButton = viewButtons.find(button => button.querySelector('svg.lucide-eye') - ) + ); if (viewButton) { - await user.click(viewButton) - expect(viewButton).toBeInTheDocument() + await user.click(viewButton); + expect(viewButton).toBeInTheDocument(); } - }) - }) + }); + }); describe('Subject Type Logic', () => { it('should identify service account subjects correctly', async () => { - const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleBindingQuery.mockReturnValue({ data: { items: [ @@ -465,17 +464,17 @@ describe('RoleBindingsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('ServiceAccount/kubelet')).toBeInTheDocument() - }) - }) + expect(screen.getByText('ServiceAccount/kubelet')).toBeInTheDocument(); + }); + }); it('should identify user subjects correctly', async () => { - const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleBindingQuery.mockReturnValue({ data: { items: [ @@ -489,17 +488,17 @@ describe('RoleBindingsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('User/admin-user')).toBeInTheDocument() - }) - }) + expect(screen.getByText('User/admin-user')).toBeInTheDocument(); + }); + }); it('should identify group subjects correctly', async () => { - const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleBindingQuery.mockReturnValue({ data: { items: [ @@ -513,19 +512,19 @@ describe('RoleBindingsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('Group/developers')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('Group/developers')).toBeInTheDocument(); + }); + }); + }); describe('Role Type Detection', () => { it('should identify cluster roles correctly', async () => { - const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleBindingQuery.mockReturnValue({ data: { items: [ @@ -539,17 +538,17 @@ describe('RoleBindingsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('ClusterRole/cluster-admin')).toBeInTheDocument() - }) - }) + expect(screen.getByText('ClusterRole/cluster-admin')).toBeInTheDocument(); + }); + }); it('should identify namespace roles correctly', async () => { - const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleBindingQuery.mockReturnValue({ data: { items: [ @@ -563,99 +562,99 @@ describe('RoleBindingsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('Role/admin')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('Role/admin')).toBeInTheDocument(); + }); + }); + }); describe('Loading States', () => { it('should show loading spinner when loading', () => { - const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleBindingQuery.mockReturnValue({ data: undefined, isLoading: true, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('button', { name: '' })).toBeDisabled() // Refresh button - }) - }) + expect(screen.getByRole('button', { name: '' })).toBeDisabled(); // Refresh button + }); + }); describe('Error States', () => { it('should display error message when fetch fails', () => { - const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleBindingQuery.mockReturnValue({ data: undefined, isLoading: false, error: new Error('Network request failed'), refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByText('Network request failed')).toBeInTheDocument() - }) + expect(screen.getByText('Network request failed')).toBeInTheDocument(); + }); it('should show retry button in error state', () => { - const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleBindingQuery.mockReturnValue({ data: undefined, isLoading: false, error: new Error('Network request failed'), refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('button', { name: 'Retry' })).toBeInTheDocument() - }) - }) + expect(screen.getByRole('button', { name: 'Retry' })).toBeInTheDocument(); + }); + }); describe('Empty States', () => { it('should display empty state when no bindings', () => { - const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleBindingQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByText('No role bindings found')).toBeInTheDocument() - }) - }) + expect(screen.getByText('No role bindings found')).toBeInTheDocument(); + }); + }); describe('Accessibility', () => { it('should have proper button roles and labels', () => { - const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleBindingQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('button', { name: '' })).toBeInTheDocument() // Refresh button - expect(screen.getByRole('button', { name: 'Create Binding' })).toBeInTheDocument() - expect(screen.getByRole('button', { name: 'Namespace' })).toBeInTheDocument() - expect(screen.getByRole('button', { name: 'Cluster' })).toBeInTheDocument() - }) + expect(screen.getByRole('button', { name: '' })).toBeInTheDocument(); // Refresh button + expect(screen.getByRole('button', { name: 'Create Binding' })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: 'Namespace' })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: 'Cluster' })).toBeInTheDocument(); + }); it('should be keyboard navigable', async () => { - const user = userEvent.setup() - const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s') + const user = userEvent.setup(); + const { useListRbacAuthorizationV1NamespacedRoleBindingQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleBindingQuery.mockReturnValue({ data: { items: [ @@ -669,30 +668,30 @@ describe('RoleBindingsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); // Wait for data to load first await waitFor(() => { - expect(screen.getByText('user-binding', { selector: 'td.font-medium' })).toBeInTheDocument() - }) + expect(screen.getByText('user-binding', { selector: 'td.font-medium' })).toBeInTheDocument(); + }); - const refreshButtons = screen.getAllByRole('button') + const refreshButtons = screen.getAllByRole('button'); const refreshButton = refreshButtons.find(button => button.querySelector('svg.lucide-refresh-cw') && button.classList.contains('h-4') - ) + ); if (refreshButton) { - refreshButton.focus() - expect(document.activeElement).toBe(refreshButton) + refreshButton.focus(); + expect(document.activeElement).toBe(refreshButton); // Test that tab navigation works - await user.tab() + await user.tab(); // The focus should move to the next focusable element - expect(document.activeElement).not.toBe(refreshButton) + expect(document.activeElement).not.toBe(refreshButton); } - }) - }) -}) + }); + }); +}); diff --git a/apps/ops-dashboard/__tests__/components/resources/roles.test.tsx b/apps/ops-dashboard/__tests__/components/resources/roles.test.tsx index e60b09d..3be9289 100644 --- a/apps/ops-dashboard/__tests__/components/resources/roles.test.tsx +++ b/apps/ops-dashboard/__tests__/components/resources/roles.test.tsx @@ -1,13 +1,12 @@ -import { render, screen, waitFor } from '@testing-library/react' -import userEvent from '@testing-library/user-event' -import { RolesView } from '@/components/resources/roles' -import { server } from '@/__mocks__/server' -import { http, HttpResponse } from 'msw' +import { render, screen, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; + +import { RolesView } from '@/components/resources/roles'; // Mock the confirm dialog jest.mock('../../../hooks/useConfirm', () => ({ confirmDialog: jest.fn().mockResolvedValue(true) -})) +})); // Mock the Kubernetes hooks jest.mock('../../../k8s', () => ({ @@ -16,99 +15,99 @@ jest.mock('../../../k8s', () => ({ useDeleteRbacAuthorizationV1NamespacedRole: jest.fn(), useListRbacAuthorizationV1ClusterRoleQuery: jest.fn(), useDeleteRbacAuthorizationV1ClusterRole: jest.fn() -})) +})); // Mock the namespace context jest.mock('../../../contexts/NamespaceContext', () => ({ usePreferredNamespace: () => ({ namespace: 'default' }) -})) +})); describe('RolesView', () => { beforeEach(() => { - jest.clearAllMocks() - }) + jest.clearAllMocks(); + }); describe('Basic Rendering', () => { it('should render roles view with header', () => { - const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('heading', { name: 'Roles', level: 2 })).toBeInTheDocument() - expect(screen.getByText('Define permissions for accessing resources')).toBeInTheDocument() - }) + expect(screen.getByRole('heading', { name: 'Roles', level: 2 })).toBeInTheDocument(); + expect(screen.getByText('Define permissions for accessing resources')).toBeInTheDocument(); + }); it('should render refresh button', () => { - const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - const refreshButton = screen.getByRole('button', { name: '' }) - expect(refreshButton).toBeInTheDocument() - }) + const refreshButton = screen.getByRole('button', { name: '' }); + expect(refreshButton).toBeInTheDocument(); + }); it('should render create role button', () => { - const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('button', { name: 'Create Role' })).toBeInTheDocument() - }) + expect(screen.getByRole('button', { name: 'Create Role' })).toBeInTheDocument(); + }); it('should render role type toggle buttons', () => { - const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('button', { name: 'Namespace' })).toBeInTheDocument() - expect(screen.getByRole('button', { name: 'Cluster' })).toBeInTheDocument() - }) + expect(screen.getByRole('button', { name: 'Namespace' })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: 'Cluster' })).toBeInTheDocument(); + }); it('should render stats cards', () => { - const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByText('Total Roles')).toBeInTheDocument() - expect(screen.getByText('System Roles')).toBeInTheDocument() - expect(screen.getByText('User Defined')).toBeInTheDocument() - expect(screen.getByText('With Wildcards')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Total Roles')).toBeInTheDocument(); + expect(screen.getByText('System Roles')).toBeInTheDocument(); + expect(screen.getByText('User Defined')).toBeInTheDocument(); + expect(screen.getByText('With Wildcards')).toBeInTheDocument(); + }); + }); describe('Data Display', () => { it('should display role data', async () => { - const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleQuery.mockReturnValue({ data: { items: [ @@ -121,17 +120,17 @@ describe('RolesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('admin', { selector: 'td.font-medium' })).toBeInTheDocument() - }) - }) + expect(screen.getByText('admin', { selector: 'td.font-medium' })).toBeInTheDocument(); + }); + }); it('should display correct statistics', async () => { - const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleQuery.mockReturnValue({ data: { items: [ @@ -143,19 +142,19 @@ describe('RolesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('3', { selector: '.text-2xl.font-bold' })).toBeInTheDocument() // Total Roles - expect(screen.getAllByText('1', { selector: '.text-2xl.font-bold' })).toHaveLength(2) // System Roles and User Defined - expect(screen.getByText('1', { selector: '.text-2xl.font-bold.text-yellow-600' })).toBeInTheDocument() // With Wildcards - }) - }) + expect(screen.getByText('3', { selector: '.text-2xl.font-bold' })).toBeInTheDocument(); // Total Roles + expect(screen.getAllByText('1', { selector: '.text-2xl.font-bold' })).toHaveLength(2); // System Roles and User Defined + expect(screen.getByText('1', { selector: '.text-2xl.font-bold.text-yellow-600' })).toBeInTheDocument(); // With Wildcards + }); + }); it('should display role type badges correctly', async () => { - const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleQuery.mockReturnValue({ data: { items: [ @@ -166,18 +165,18 @@ describe('RolesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('System')).toBeInTheDocument() - expect(screen.getByText('Custom')).toBeInTheDocument() - }) - }) + expect(screen.getByText('System')).toBeInTheDocument(); + expect(screen.getByText('Custom')).toBeInTheDocument(); + }); + }); it('should display rule counts correctly', async () => { - const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleQuery.mockReturnValue({ data: { items: [ @@ -193,17 +192,17 @@ describe('RolesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getAllByText('2', { selector: '.rounded-full' })).toHaveLength(3) // Rules, Resources, and Verbs count - }) - }) + expect(screen.getAllByText('2', { selector: '.rounded-full' })).toHaveLength(3); // Rules, Resources, and Verbs count + }); + }); it('should display top resources correctly', async () => { - const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleQuery.mockReturnValue({ data: { items: [ @@ -219,17 +218,17 @@ describe('RolesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('pods, services, deployments')).toBeInTheDocument() - }) - }) + expect(screen.getByText('pods, services, deployments')).toBeInTheDocument(); + }); + }); it('should display wildcard warning correctly', async () => { - const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleQuery.mockReturnValue({ data: { items: [ @@ -244,17 +243,17 @@ describe('RolesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('Wildcard')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Wildcard')).toBeInTheDocument(); + }); + }); it('should show namespace column for namespace roles', async () => { - const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleQuery.mockReturnValue({ data: { items: [ @@ -267,90 +266,90 @@ describe('RolesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('Namespace', { selector: 'th' })).toBeInTheDocument() - expect(screen.getByText('default')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('Namespace', { selector: 'th' })).toBeInTheDocument(); + expect(screen.getByText('default')).toBeInTheDocument(); + }); + }); + }); describe('User Interactions', () => { it('should refresh data when refresh button is clicked', async () => { - const user = userEvent.setup() - const mockRefetch = jest.fn() - const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s') + const user = userEvent.setup(); + const mockRefetch = jest.fn(); + const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: mockRefetch - }) + }); - render() + render(); - const refreshButton = screen.getByRole('button', { name: '' }) - await user.click(refreshButton) + const refreshButton = screen.getByRole('button', { name: '' }); + await user.click(refreshButton); - expect(mockRefetch).toHaveBeenCalled() - }) + expect(mockRefetch).toHaveBeenCalled(); + }); it('should show create role alert when create button is clicked', async () => { - const user = userEvent.setup() - const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s') + const user = userEvent.setup(); + const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); // Mock alert - const alertSpy = jest.spyOn(window, 'alert').mockImplementation(() => {}) + const alertSpy = jest.spyOn(window, 'alert').mockImplementation(() => {}); - render() + render(); - const createButton = screen.getByRole('button', { name: 'Create Role' }) - await user.click(createButton) + const createButton = screen.getByRole('button', { name: 'Create Role' }); + await user.click(createButton); - expect(alertSpy).toHaveBeenCalledWith('Create Role functionality not yet implemented') + expect(alertSpy).toHaveBeenCalledWith('Create Role functionality not yet implemented'); - alertSpy.mockRestore() - }) + alertSpy.mockRestore(); + }); it('should switch between namespace and cluster roles', async () => { - const user = userEvent.setup() - const { useListRbacAuthorizationV1NamespacedRoleQuery, useListRbacAuthorizationV1ClusterRoleQuery } = require('../../../k8s') + const user = userEvent.setup(); + const { useListRbacAuthorizationV1NamespacedRoleQuery, useListRbacAuthorizationV1ClusterRoleQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); useListRbacAuthorizationV1ClusterRoleQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - const clusterButton = screen.getByRole('button', { name: 'Cluster' }) - await user.click(clusterButton) + const clusterButton = screen.getByRole('button', { name: 'Cluster' }); + await user.click(clusterButton); - expect(screen.getByText('Cluster Roles')).toBeInTheDocument() - }) + expect(screen.getByText('Cluster Roles')).toBeInTheDocument(); + }); it('should show delete confirmation when delete button is clicked', async () => { - const user = userEvent.setup() - const { useListRbacAuthorizationV1NamespacedRoleQuery, useDeleteRbacAuthorizationV1NamespacedRole } = require('../../../k8s') - const mockDelete = jest.fn().mockResolvedValue({}) + const user = userEvent.setup(); + const { useListRbacAuthorizationV1NamespacedRoleQuery, useDeleteRbacAuthorizationV1NamespacedRole } = require('../../../k8s'); + const mockDelete = jest.fn().mockResolvedValue({}); useListRbacAuthorizationV1NamespacedRoleQuery.mockReturnValue({ data: { @@ -364,31 +363,31 @@ describe('RolesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); useDeleteRbacAuthorizationV1NamespacedRole.mockReturnValue({ mutateAsync: mockDelete - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('user-role', { selector: 'td.font-medium' })).toBeInTheDocument() - }) + expect(screen.getByText('user-role', { selector: 'td.font-medium' })).toBeInTheDocument(); + }); - const deleteButtons = screen.getAllByRole('button') + const deleteButtons = screen.getAllByRole('button'); const deleteButton = deleteButtons.find(button => button.querySelector('svg.lucide-trash-2') - ) + ); if (deleteButton) { - await user.click(deleteButton) - expect(deleteButton).toBeInTheDocument() + await user.click(deleteButton); + expect(deleteButton).toBeInTheDocument(); } - }) + }); it('should show view button when view button is clicked', async () => { - const user = userEvent.setup() - const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s') + const user = userEvent.setup(); + const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleQuery.mockReturnValue({ data: { items: [ @@ -401,27 +400,27 @@ describe('RolesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('user-role', { selector: 'td.font-medium' })).toBeInTheDocument() - }) + expect(screen.getByText('user-role', { selector: 'td.font-medium' })).toBeInTheDocument(); + }); - const viewButtons = screen.getAllByRole('button') + const viewButtons = screen.getAllByRole('button'); const viewButton = viewButtons.find(button => button.querySelector('svg.lucide-eye') - ) + ); if (viewButton) { - await user.click(viewButton) - expect(viewButton).toBeInTheDocument() + await user.click(viewButton); + expect(viewButton).toBeInTheDocument(); } - }) + }); it('should disable delete button for system roles', async () => { - const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleQuery.mockReturnValue({ data: { items: [ @@ -434,28 +433,28 @@ describe('RolesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('system:admin', { selector: 'td.font-medium' })).toBeInTheDocument() - }) + expect(screen.getByText('system:admin', { selector: 'td.font-medium' })).toBeInTheDocument(); + }); - const deleteButtons = screen.getAllByRole('button') + const deleteButtons = screen.getAllByRole('button'); const deleteButton = deleteButtons.find(button => button.querySelector('svg.lucide-trash-2') - ) + ); if (deleteButton) { - expect(deleteButton).toBeDisabled() + expect(deleteButton).toBeDisabled(); } - }) - }) + }); + }); describe('Role Type Logic', () => { it('should identify system roles correctly', async () => { - const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleQuery.mockReturnValue({ data: { items: [ @@ -474,17 +473,17 @@ describe('RolesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getAllByText('System')).toHaveLength(4) - }) - }) + expect(screen.getAllByText('System')).toHaveLength(4); + }); + }); it('should identify custom roles correctly', async () => { - const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleQuery.mockReturnValue({ data: { items: [ @@ -494,19 +493,19 @@ describe('RolesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('Custom')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('Custom')).toBeInTheDocument(); + }); + }); + }); describe('Wildcard Detection', () => { it('should detect wildcard access correctly', async () => { - const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleQuery.mockReturnValue({ data: { items: [ @@ -527,99 +526,99 @@ describe('RolesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getAllByText('Wildcard')).toHaveLength(3) - }) - }) - }) + expect(screen.getAllByText('Wildcard')).toHaveLength(3); + }); + }); + }); describe('Loading States', () => { it('should show loading spinner when loading', () => { - const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleQuery.mockReturnValue({ data: undefined, isLoading: true, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('button', { name: '' })).toBeDisabled() // Refresh button - }) - }) + expect(screen.getByRole('button', { name: '' })).toBeDisabled(); // Refresh button + }); + }); describe('Error States', () => { it('should display error message when fetch fails', () => { - const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleQuery.mockReturnValue({ data: undefined, isLoading: false, error: new Error('Network request failed'), refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByText('Network request failed')).toBeInTheDocument() - }) + expect(screen.getByText('Network request failed')).toBeInTheDocument(); + }); it('should show retry button in error state', () => { - const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleQuery.mockReturnValue({ data: undefined, isLoading: false, error: new Error('Network request failed'), refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('button', { name: 'Retry' })).toBeInTheDocument() - }) - }) + expect(screen.getByRole('button', { name: 'Retry' })).toBeInTheDocument(); + }); + }); describe('Empty States', () => { it('should display empty state when no roles', () => { - const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByText('No roles found')).toBeInTheDocument() - }) - }) + expect(screen.getByText('No roles found')).toBeInTheDocument(); + }); + }); describe('Accessibility', () => { it('should have proper button roles and labels', () => { - const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s') + const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('button', { name: '' })).toBeInTheDocument() // Refresh button - expect(screen.getByRole('button', { name: 'Create Role' })).toBeInTheDocument() - expect(screen.getByRole('button', { name: 'Namespace' })).toBeInTheDocument() - expect(screen.getByRole('button', { name: 'Cluster' })).toBeInTheDocument() - }) + expect(screen.getByRole('button', { name: '' })).toBeInTheDocument(); // Refresh button + expect(screen.getByRole('button', { name: 'Create Role' })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: 'Namespace' })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: 'Cluster' })).toBeInTheDocument(); + }); it('should be keyboard navigable', async () => { - const user = userEvent.setup() - const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s') + const user = userEvent.setup(); + const { useListRbacAuthorizationV1NamespacedRoleQuery } = require('../../../k8s'); useListRbacAuthorizationV1NamespacedRoleQuery.mockReturnValue({ data: { items: [ @@ -632,30 +631,30 @@ describe('RolesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); // Wait for data to load first await waitFor(() => { - expect(screen.getByText('user-role', { selector: 'td.font-medium' })).toBeInTheDocument() - }) + expect(screen.getByText('user-role', { selector: 'td.font-medium' })).toBeInTheDocument(); + }); - const refreshButtons = screen.getAllByRole('button') + const refreshButtons = screen.getAllByRole('button'); const refreshButton = refreshButtons.find(button => button.querySelector('svg.lucide-refresh-cw') && button.classList.contains('h-4') - ) + ); if (refreshButton) { - refreshButton.focus() - expect(document.activeElement).toBe(refreshButton) + refreshButton.focus(); + expect(document.activeElement).toBe(refreshButton); // Test that tab navigation works - await user.tab() + await user.tab(); // The focus should move to the next focusable element - expect(document.activeElement).not.toBe(refreshButton) + expect(document.activeElement).not.toBe(refreshButton); } - }) - }) -}) + }); + }); +}); diff --git a/apps/ops-dashboard/__tests__/components/resources/runtimeclasses.test.tsx b/apps/ops-dashboard/__tests__/components/resources/runtimeclasses.test.tsx index fa093bd..6ed9c33 100644 --- a/apps/ops-dashboard/__tests__/components/resources/runtimeclasses.test.tsx +++ b/apps/ops-dashboard/__tests__/components/resources/runtimeclasses.test.tsx @@ -1,17 +1,17 @@ -import { screen, waitFor, fireEvent } from '@testing-library/react'; +import { fireEvent,screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { render } from '../../utils/test-utils'; -import { server } from '@/__mocks__/server'; +import { http, HttpResponse } from 'msw'; + +import { API_BASE } from '@/__mocks__/handlers/common'; import { - createRuntimeClassesList, + createRuntimeClassesList, createRuntimeClassesListError, createRuntimeClassesListSlow, - deleteRuntimeClassHandler, deleteRuntimeClassErrorHandler, - createRuntimeClassesListData -} from '@/__mocks__/handlers/runtimeclasses'; -import { http, HttpResponse } from 'msw'; -import { API_BASE } from '@/__mocks__/handlers/common'; + deleteRuntimeClassHandler} from '@/__mocks__/handlers/runtimeclasses'; +import { server } from '@/__mocks__/server'; + +import { render } from '../../utils/test-utils'; // Mock window.alert for testing const mockAlert = jest.spyOn(window, 'alert').mockImplementation(() => {}); diff --git a/apps/ops-dashboard/__tests__/components/resources/secrets.test.tsx b/apps/ops-dashboard/__tests__/components/resources/secrets.test.tsx index 4b9afe4..652f18e 100644 --- a/apps/ops-dashboard/__tests__/components/resources/secrets.test.tsx +++ b/apps/ops-dashboard/__tests__/components/resources/secrets.test.tsx @@ -1,16 +1,13 @@ import userEvent from '@testing-library/user-event'; -import { render, screen, waitFor, fireEvent } from '@/__tests__/utils/test-utils'; -import { server } from '@/__mocks__/server'; + import { - createSecretsList, - createSecretsListError, createAllSecretsList, - deleteSecretHandler, + createSecretsList, + createSecretsListError, deleteSecretErrorHandler, - createSecretHandler, - createSecretErrorHandler, - createSecretsListData -} from '@/__mocks__/handlers/secrets'; + deleteSecretHandler} from '@/__mocks__/handlers/secrets'; +import { server } from '@/__mocks__/server'; +import { fireEvent,render, screen, waitFor } from '@/__tests__/utils/test-utils'; // Mock window.alert for testing const mockAlert = jest.spyOn(window, 'alert').mockImplementation(() => {}); diff --git a/apps/ops-dashboard/__tests__/components/resources/serviceaccounts.test.tsx b/apps/ops-dashboard/__tests__/components/resources/serviceaccounts.test.tsx index 32fd409..85e26fe 100644 --- a/apps/ops-dashboard/__tests__/components/resources/serviceaccounts.test.tsx +++ b/apps/ops-dashboard/__tests__/components/resources/serviceaccounts.test.tsx @@ -1,97 +1,96 @@ -import { render, screen, waitFor } from '@testing-library/react' -import userEvent from '@testing-library/user-event' -import { ServiceAccountsView } from '@/components/resources/serviceaccounts' -import { server } from '@/__mocks__/server' -import { http, HttpResponse } from 'msw' +import { render, screen, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; + +import { ServiceAccountsView } from '@/components/resources/serviceaccounts'; // Mock the confirm dialog jest.mock('../../../hooks/useConfirm', () => ({ confirmDialog: jest.fn().mockResolvedValue(true) -})) +})); // Mock the Kubernetes hooks jest.mock('../../../k8s', () => ({ useListCoreV1NamespacedServiceAccountQuery: jest.fn(), useListCoreV1ServiceAccountForAllNamespacesQuery: jest.fn(), useDeleteCoreV1NamespacedServiceAccount: jest.fn() -})) +})); // Mock the namespace context jest.mock('../../../contexts/NamespaceContext', () => ({ usePreferredNamespace: () => ({ namespace: 'default' }) -})) +})); describe('ServiceAccountsView', () => { beforeEach(() => { - jest.clearAllMocks() - }) + jest.clearAllMocks(); + }); describe('Basic Rendering', () => { it('should render service accounts view with header', () => { - const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s') + const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s'); useListCoreV1NamespacedServiceAccountQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('heading', { name: 'Service Accounts', level: 2 })).toBeInTheDocument() - expect(screen.getByText('Identities for pods to access the Kubernetes API')).toBeInTheDocument() - }) + expect(screen.getByRole('heading', { name: 'Service Accounts', level: 2 })).toBeInTheDocument(); + expect(screen.getByText('Identities for pods to access the Kubernetes API')).toBeInTheDocument(); + }); it('should render refresh button', () => { - const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s') + const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s'); useListCoreV1NamespacedServiceAccountQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - const refreshButton = screen.getByRole('button', { name: '' }) - expect(refreshButton).toBeInTheDocument() - }) + const refreshButton = screen.getByRole('button', { name: '' }); + expect(refreshButton).toBeInTheDocument(); + }); it('should render create account button', () => { - const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s') + const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s'); useListCoreV1NamespacedServiceAccountQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('button', { name: 'Create Account' })).toBeInTheDocument() - }) + expect(screen.getByRole('button', { name: 'Create Account' })).toBeInTheDocument(); + }); it('should render stats cards', () => { - const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s') + const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s'); useListCoreV1NamespacedServiceAccountQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByText('Total Accounts')).toBeInTheDocument() - expect(screen.getByText('User Accounts')).toBeInTheDocument() - expect(screen.getByText('With Secrets')).toBeInTheDocument() - expect(screen.getByText('Automount Enabled')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Total Accounts')).toBeInTheDocument(); + expect(screen.getByText('User Accounts')).toBeInTheDocument(); + expect(screen.getByText('With Secrets')).toBeInTheDocument(); + expect(screen.getByText('Automount Enabled')).toBeInTheDocument(); + }); + }); describe('Data Display', () => { it('should display service account data', async () => { - const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s') + const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s'); useListCoreV1NamespacedServiceAccountQuery.mockReturnValue({ data: { items: [ @@ -105,17 +104,17 @@ describe('ServiceAccountsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('default', { selector: 'td.font-medium' })).toBeInTheDocument() - }) - }) + expect(screen.getByText('default', { selector: 'td.font-medium' })).toBeInTheDocument(); + }); + }); it('should display correct statistics', async () => { - const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s') + const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s'); useListCoreV1NamespacedServiceAccountQuery.mockReturnValue({ data: { items: [ @@ -128,19 +127,19 @@ describe('ServiceAccountsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('4', { selector: '.text-2xl.font-bold' })).toBeInTheDocument() // Total Accounts - expect(screen.getAllByText('1', { selector: '.text-2xl.font-bold' })).toHaveLength(2) // User Accounts and With Secrets - expect(screen.getByText('3', { selector: '.text-2xl.font-bold' })).toBeInTheDocument() // Automount Enabled - }) - }) + expect(screen.getByText('4', { selector: '.text-2xl.font-bold' })).toBeInTheDocument(); // Total Accounts + expect(screen.getAllByText('1', { selector: '.text-2xl.font-bold' })).toHaveLength(2); // User Accounts and With Secrets + expect(screen.getByText('3', { selector: '.text-2xl.font-bold' })).toBeInTheDocument(); // Automount Enabled + }); + }); it('should display account type badges correctly', async () => { - const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s') + const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s'); useListCoreV1NamespacedServiceAccountQuery.mockReturnValue({ data: { items: [ @@ -152,19 +151,19 @@ describe('ServiceAccountsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('Default')).toBeInTheDocument() - expect(screen.getByText('System')).toBeInTheDocument() - expect(screen.getByText('User')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Default')).toBeInTheDocument(); + expect(screen.getByText('System')).toBeInTheDocument(); + expect(screen.getByText('User')).toBeInTheDocument(); + }); + }); it('should display secrets correctly', async () => { - const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s') + const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s'); useListCoreV1NamespacedServiceAccountQuery.mockReturnValue({ data: { items: [ @@ -188,19 +187,19 @@ describe('ServiceAccountsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('default-token-abc123')).toBeInTheDocument() - expect(screen.getByText('2 secrets')).toBeInTheDocument() - expect(screen.getByText('None', { selector: 'span.text-sm' })).toBeInTheDocument() - }) - }) + expect(screen.getByText('default-token-abc123')).toBeInTheDocument(); + expect(screen.getByText('2 secrets')).toBeInTheDocument(); + expect(screen.getByText('None', { selector: 'span.text-sm' })).toBeInTheDocument(); + }); + }); it('should display image pull secrets correctly', async () => { - const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s') + const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s'); useListCoreV1NamespacedServiceAccountQuery.mockReturnValue({ data: { items: [ @@ -217,18 +216,18 @@ describe('ServiceAccountsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('1', { selector: '.rounded-full' })).toBeInTheDocument() // Image pull secrets count - expect(screen.getByText('None', { selector: '.rounded-full' })).toBeInTheDocument() - }) - }) + expect(screen.getByText('1', { selector: '.rounded-full' })).toBeInTheDocument(); // Image pull secrets count + expect(screen.getByText('None', { selector: '.rounded-full' })).toBeInTheDocument(); + }); + }); it('should display automount token status correctly', async () => { - const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s') + const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s'); useListCoreV1NamespacedServiceAccountQuery.mockReturnValue({ data: { items: [ @@ -245,18 +244,18 @@ describe('ServiceAccountsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('Enabled')).toBeInTheDocument() - expect(screen.getByText('Disabled')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Enabled')).toBeInTheDocument(); + expect(screen.getByText('Disabled')).toBeInTheDocument(); + }); + }); it('should display creation date correctly', async () => { - const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s') + const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s'); useListCoreV1NamespacedServiceAccountQuery.mockReturnValue({ data: { items: [ @@ -271,63 +270,63 @@ describe('ServiceAccountsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('1/1/2024')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('1/1/2024')).toBeInTheDocument(); + }); + }); + }); describe('User Interactions', () => { it('should refresh data when refresh button is clicked', async () => { - const user = userEvent.setup() - const mockRefetch = jest.fn() - const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s') + const user = userEvent.setup(); + const mockRefetch = jest.fn(); + const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s'); useListCoreV1NamespacedServiceAccountQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: mockRefetch - }) + }); - render() + render(); - const refreshButton = screen.getByRole('button', { name: '' }) - await user.click(refreshButton) + const refreshButton = screen.getByRole('button', { name: '' }); + await user.click(refreshButton); - expect(mockRefetch).toHaveBeenCalled() - }) + expect(mockRefetch).toHaveBeenCalled(); + }); it('should show create account alert when create button is clicked', async () => { - const user = userEvent.setup() - const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s') + const user = userEvent.setup(); + const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s'); useListCoreV1NamespacedServiceAccountQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); // Mock alert - const alertSpy = jest.spyOn(window, 'alert').mockImplementation(() => {}) + const alertSpy = jest.spyOn(window, 'alert').mockImplementation(() => {}); - render() + render(); - const createButton = screen.getByRole('button', { name: 'Create Account' }) - await user.click(createButton) + const createButton = screen.getByRole('button', { name: 'Create Account' }); + await user.click(createButton); - expect(alertSpy).toHaveBeenCalledWith('Create Service Account functionality not yet implemented') + expect(alertSpy).toHaveBeenCalledWith('Create Service Account functionality not yet implemented'); - alertSpy.mockRestore() - }) + alertSpy.mockRestore(); + }); it('should show delete confirmation when delete button is clicked', async () => { - const user = userEvent.setup() - const { useListCoreV1NamespacedServiceAccountQuery, useDeleteCoreV1NamespacedServiceAccount } = require('../../../k8s') - const mockDelete = jest.fn().mockResolvedValue({}) + const user = userEvent.setup(); + const { useListCoreV1NamespacedServiceAccountQuery, useDeleteCoreV1NamespacedServiceAccount } = require('../../../k8s'); + const mockDelete = jest.fn().mockResolvedValue({}); useListCoreV1NamespacedServiceAccountQuery.mockReturnValue({ data: { @@ -341,31 +340,31 @@ describe('ServiceAccountsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); useDeleteCoreV1NamespacedServiceAccount.mockReturnValue({ mutateAsync: mockDelete - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('user-account', { selector: 'td' })).toBeInTheDocument() - }) + expect(screen.getByText('user-account', { selector: 'td' })).toBeInTheDocument(); + }); - const deleteButtons = screen.getAllByRole('button') + const deleteButtons = screen.getAllByRole('button'); const deleteButton = deleteButtons.find(button => button.querySelector('svg.lucide-trash-2') - ) + ); if (deleteButton) { - await user.click(deleteButton) - expect(deleteButton).toBeInTheDocument() + await user.click(deleteButton); + expect(deleteButton).toBeInTheDocument(); } - }) + }); it('should show view button when view button is clicked', async () => { - const user = userEvent.setup() - const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s') + const user = userEvent.setup(); + const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s'); useListCoreV1NamespacedServiceAccountQuery.mockReturnValue({ data: { items: [ @@ -378,27 +377,27 @@ describe('ServiceAccountsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('user-account', { selector: 'td' })).toBeInTheDocument() - }) + expect(screen.getByText('user-account', { selector: 'td' })).toBeInTheDocument(); + }); - const viewButtons = screen.getAllByRole('button') + const viewButtons = screen.getAllByRole('button'); const viewButton = viewButtons.find(button => button.querySelector('svg.lucide-eye') - ) + ); if (viewButton) { - await user.click(viewButton) - expect(viewButton).toBeInTheDocument() + await user.click(viewButton); + expect(viewButton).toBeInTheDocument(); } - }) + }); it('should disable delete button for default accounts', async () => { - const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s') + const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s'); useListCoreV1NamespacedServiceAccountQuery.mockReturnValue({ data: { items: [ @@ -411,26 +410,26 @@ describe('ServiceAccountsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('default', { selector: 'td.font-medium' })).toBeInTheDocument() - }) + expect(screen.getByText('default', { selector: 'td.font-medium' })).toBeInTheDocument(); + }); - const deleteButtons = screen.getAllByRole('button') + const deleteButtons = screen.getAllByRole('button'); const deleteButton = deleteButtons.find(button => button.querySelector('svg.lucide-trash-2') - ) + ); if (deleteButton) { - expect(deleteButton).toBeDisabled() + expect(deleteButton).toBeDisabled(); } - }) + }); it('should disable delete button for system accounts', async () => { - const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s') + const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s'); useListCoreV1NamespacedServiceAccountQuery.mockReturnValue({ data: { items: [ @@ -443,28 +442,28 @@ describe('ServiceAccountsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('system:serviceaccount:kube-system:default', { selector: 'td' })).toBeInTheDocument() - }) + expect(screen.getByText('system:serviceaccount:kube-system:default', { selector: 'td' })).toBeInTheDocument(); + }); - const deleteButtons = screen.getAllByRole('button') + const deleteButtons = screen.getAllByRole('button'); const deleteButton = deleteButtons.find(button => button.querySelector('svg.lucide-trash-2') - ) + ); if (deleteButton) { - expect(deleteButton).toBeDisabled() + expect(deleteButton).toBeDisabled(); } - }) - }) + }); + }); describe('Account Type Logic', () => { it('should identify default accounts correctly', async () => { - const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s') + const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s'); useListCoreV1NamespacedServiceAccountQuery.mockReturnValue({ data: { items: [ @@ -474,17 +473,17 @@ describe('ServiceAccountsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('Default')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Default')).toBeInTheDocument(); + }); + }); it('should identify system accounts correctly', async () => { - const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s') + const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s'); useListCoreV1NamespacedServiceAccountQuery.mockReturnValue({ data: { items: [ @@ -496,17 +495,17 @@ describe('ServiceAccountsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getAllByText('System')).toHaveLength(3) - }) - }) + expect(screen.getAllByText('System')).toHaveLength(3); + }); + }); it('should identify user accounts correctly', async () => { - const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s') + const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s'); useListCoreV1NamespacedServiceAccountQuery.mockReturnValue({ data: { items: [ @@ -516,97 +515,97 @@ describe('ServiceAccountsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('User')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('User')).toBeInTheDocument(); + }); + }); + }); describe('Loading States', () => { it('should show loading spinner when loading', () => { - const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s') + const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s'); useListCoreV1NamespacedServiceAccountQuery.mockReturnValue({ data: undefined, isLoading: true, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('button', { name: '' })).toBeDisabled() // Refresh button - }) - }) + expect(screen.getByRole('button', { name: '' })).toBeDisabled(); // Refresh button + }); + }); describe('Error States', () => { it('should display error message when fetch fails', () => { - const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s') + const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s'); useListCoreV1NamespacedServiceAccountQuery.mockReturnValue({ data: undefined, isLoading: false, error: new Error('Network request failed'), refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByText('Network request failed')).toBeInTheDocument() - }) + expect(screen.getByText('Network request failed')).toBeInTheDocument(); + }); it('should show retry button in error state', () => { - const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s') + const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s'); useListCoreV1NamespacedServiceAccountQuery.mockReturnValue({ data: undefined, isLoading: false, error: new Error('Network request failed'), refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('button', { name: 'Retry' })).toBeInTheDocument() - }) - }) + expect(screen.getByRole('button', { name: 'Retry' })).toBeInTheDocument(); + }); + }); describe('Empty States', () => { it('should display empty state when no service accounts', () => { - const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s') + const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s'); useListCoreV1NamespacedServiceAccountQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByText('No service accounts found')).toBeInTheDocument() - }) - }) + expect(screen.getByText('No service accounts found')).toBeInTheDocument(); + }); + }); describe('Accessibility', () => { it('should have proper button roles and labels', () => { - const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s') + const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s'); useListCoreV1NamespacedServiceAccountQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('button', { name: '' })).toBeInTheDocument() // Refresh button - expect(screen.getByRole('button', { name: 'Create Account' })).toBeInTheDocument() - }) + expect(screen.getByRole('button', { name: '' })).toBeInTheDocument(); // Refresh button + expect(screen.getByRole('button', { name: 'Create Account' })).toBeInTheDocument(); + }); it('should be keyboard navigable', async () => { - const user = userEvent.setup() - const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s') + const user = userEvent.setup(); + const { useListCoreV1NamespacedServiceAccountQuery } = require('../../../k8s'); useListCoreV1NamespacedServiceAccountQuery.mockReturnValue({ data: { items: [ @@ -619,30 +618,30 @@ describe('ServiceAccountsView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); // Wait for data to load first await waitFor(() => { - expect(screen.getByText('user-account', { selector: 'td' })).toBeInTheDocument() - }) + expect(screen.getByText('user-account', { selector: 'td' })).toBeInTheDocument(); + }); - const refreshButtons = screen.getAllByRole('button') + const refreshButtons = screen.getAllByRole('button'); const refreshButton = refreshButtons.find(button => button.querySelector('svg.lucide-refresh-cw') && button.classList.contains('h-4') - ) + ); if (refreshButton) { - refreshButton.focus() - expect(document.activeElement).toBe(refreshButton) + refreshButton.focus(); + expect(document.activeElement).toBe(refreshButton); // Test that tab navigation works - await user.tab() + await user.tab(); // The focus should move to the next focusable element - expect(document.activeElement).not.toBe(refreshButton) + expect(document.activeElement).not.toBe(refreshButton); } - }) - }) -}) + }); + }); +}); diff --git a/apps/ops-dashboard/__tests__/components/resources/services.test.tsx b/apps/ops-dashboard/__tests__/components/resources/services.test.tsx index 6a793a8..14e14e6 100644 --- a/apps/ops-dashboard/__tests__/components/resources/services.test.tsx +++ b/apps/ops-dashboard/__tests__/components/resources/services.test.tsx @@ -1,16 +1,13 @@ import userEvent from '@testing-library/user-event'; -import { render, screen, waitFor, fireEvent } from '@/__tests__/utils/test-utils'; -import { server } from '@/__mocks__/server'; + import { - createServicesList, - createServicesListError, createAllServicesList, - deleteServiceHandler, + createServicesList, + createServicesListError, deleteServiceErrorHandler, - createServiceHandler, - createServiceErrorHandler, - createServicesListData -} from '@/__mocks__/handlers/services'; + deleteServiceHandler} from '@/__mocks__/handlers/services'; +import { server } from '@/__mocks__/server'; +import { fireEvent,render, screen, waitFor } from '@/__tests__/utils/test-utils'; // Mock window.alert for testing const mockAlert = jest.spyOn(window, 'alert').mockImplementation(() => {}); diff --git a/apps/ops-dashboard/__tests__/components/resources/statefulsets.test.tsx b/apps/ops-dashboard/__tests__/components/resources/statefulsets.test.tsx index 3ea4318..e73cca2 100644 --- a/apps/ops-dashboard/__tests__/components/resources/statefulsets.test.tsx +++ b/apps/ops-dashboard/__tests__/components/resources/statefulsets.test.tsx @@ -1,380 +1,380 @@ -import React from 'react' -import { render, screen, waitFor } from '../../utils/test-utils' -import userEvent from '@testing-library/user-event' -import { StatefulSetsView } from '../../../components/resources/statefulsets' -import { server } from '@/__mocks__/server' -import { +import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { server } from '@/__mocks__/server'; + +import { + createStatefulSetDelete, + createStatefulSetScale, createStatefulSetsList, - createAllStatefulSetsList, - createStatefulSetsListError, - createStatefulSetsListSlow, createStatefulSetsListData, - createStatefulSetScale, - createStatefulSetDelete -} from '../../../__mocks__/handlers/statefulsets' + createStatefulSetsListError, + createStatefulSetsListSlow} from '../../../__mocks__/handlers/statefulsets'; +import { StatefulSetsView } from '../../../components/resources/statefulsets'; +import { render, screen, waitFor } from '../../utils/test-utils'; // Mock the confirmDialog function jest.mock('../../../hooks/useConfirm', () => ({ ...jest.requireActual('../../../hooks/useConfirm'), confirmDialog: jest.fn() -})) +})); // Mock window.prompt and window.alert Object.defineProperty(window, 'prompt', { value: jest.fn(), writable: true -}) +}); Object.defineProperty(window, 'alert', { value: jest.fn(), writable: true -}) +}); describe('StatefulSetsView', () => { beforeEach(() => { jest.clearAllMocks() // Reset window mocks ;(window.prompt as jest.Mock).mockClear() - ;(window.alert as jest.Mock).mockClear() - }) + ;(window.alert as jest.Mock).mockClear(); + }); describe('Basic Rendering', () => { it('should render statefulsets view with header', () => { - server.use(createStatefulSetsList()) - render() + server.use(createStatefulSetsList()); + render(); - expect(screen.getByRole('heading', { name: 'StatefulSets' })).toBeInTheDocument() - expect(screen.getByText('Manage your Kubernetes stateful applications')).toBeInTheDocument() - }) + expect(screen.getByRole('heading', { name: 'StatefulSets' })).toBeInTheDocument(); + expect(screen.getByText('Manage your Kubernetes stateful applications')).toBeInTheDocument(); + }); it('should render refresh and create buttons', () => { - server.use(createStatefulSetsList()) - render() + server.use(createStatefulSetsList()); + render(); - expect(screen.getAllByRole('button', { name: '' })[0]).toBeInTheDocument() // Refresh button - expect(screen.getByRole('button', { name: /create statefulset/i })).toBeInTheDocument() - }) + expect(screen.getAllByRole('button', { name: '' })[0]).toBeInTheDocument(); // Refresh button + expect(screen.getByRole('button', { name: /create statefulset/i })).toBeInTheDocument(); + }); it('should render stats cards', () => { - server.use(createStatefulSetsList()) - render() + server.use(createStatefulSetsList()); + render(); - expect(screen.getByText('Total StatefulSets')).toBeInTheDocument() - expect(screen.getByText('Running')).toBeInTheDocument() - expect(screen.getByText('Total Replicas')).toBeInTheDocument() - }) + expect(screen.getByText('Total StatefulSets')).toBeInTheDocument(); + expect(screen.getByText('Running')).toBeInTheDocument(); + expect(screen.getByText('Total Replicas')).toBeInTheDocument(); + }); it('should render table with correct headers', async () => { - server.use(createStatefulSetsList()) - render() + server.use(createStatefulSetsList()); + render(); await waitFor(() => { - expect(screen.getByRole('columnheader', { name: 'Name' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Namespace' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Status' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Replicas' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Image' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Created' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Actions' })).toBeInTheDocument() - }) - }) - }) + expect(screen.getByRole('columnheader', { name: 'Name' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Namespace' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Status' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Replicas' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Image' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Created' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Actions' })).toBeInTheDocument(); + }); + }); + }); describe('Data Loading and Display', () => { it('should display statefulsets data correctly', async () => { - server.use(createStatefulSetsList()) - render() + server.use(createStatefulSetsList()); + render(); await waitFor(() => { - expect(screen.getByText('web-statefulset')).toBeInTheDocument() - expect(screen.getByText('db-statefulset')).toBeInTheDocument() - expect(screen.getAllByText('default')).toHaveLength(2) // Two statefulsets in default namespace - expect(screen.getByText('nginx:1.14.2')).toBeInTheDocument() - expect(screen.getByText('postgres:13')).toBeInTheDocument() - }) - }) + expect(screen.getByText('web-statefulset')).toBeInTheDocument(); + expect(screen.getByText('db-statefulset')).toBeInTheDocument(); + expect(screen.getAllByText('default')).toHaveLength(2); // Two statefulsets in default namespace + expect(screen.getByText('nginx:1.14.2')).toBeInTheDocument(); + expect(screen.getByText('postgres:13')).toBeInTheDocument(); + }); + }); it('should display correct statistics', async () => { - server.use(createStatefulSetsList()) - render() + server.use(createStatefulSetsList()); + render(); await waitFor(() => { - expect(screen.getAllByText('2')).toHaveLength(2) // Total StatefulSets and Running count - expect(screen.getByText('4')).toBeInTheDocument() // Total Replicas (3+1) - }) - }) + expect(screen.getAllByText('2')).toHaveLength(2); // Total StatefulSets and Running count + expect(screen.getByText('4')).toBeInTheDocument(); // Total Replicas (3+1) + }); + }); it('should display status badges correctly', async () => { - server.use(createStatefulSetsList()) - render() + server.use(createStatefulSetsList()); + render(); await waitFor(() => { - expect(screen.getAllByText('Running')).toHaveLength(3) // One in header + two in badges - }) - }) + expect(screen.getAllByText('Running')).toHaveLength(3); // One in header + two in badges + }); + }); it('should display replicas correctly', async () => { - server.use(createStatefulSetsList()) - render() + server.use(createStatefulSetsList()); + render(); await waitFor(() => { - expect(screen.getByText('3/3')).toBeInTheDocument() // web-statefulset - expect(screen.getByText('1/1')).toBeInTheDocument() // db-statefulset - }) - }) - }) + expect(screen.getByText('3/3')).toBeInTheDocument(); // web-statefulset + expect(screen.getByText('1/1')).toBeInTheDocument(); // db-statefulset + }); + }); + }); describe('Loading States', () => { it('should show loading spinner when loading', () => { - server.use(createStatefulSetsListSlow()) - render() + server.use(createStatefulSetsListSlow()); + render(); - expect(document.querySelector('svg.lucide-refresh-cw.animate-spin')).toBeInTheDocument() - }) + expect(document.querySelector('svg.lucide-refresh-cw.animate-spin')).toBeInTheDocument(); + }); it('should disable refresh button when loading', () => { - server.use(createStatefulSetsListSlow()) - render() + server.use(createStatefulSetsListSlow()); + render(); - const refreshButton = screen.getAllByRole('button', { name: '' })[0] - expect(refreshButton).toBeDisabled() - }) - }) + const refreshButton = screen.getAllByRole('button', { name: '' })[0]; + expect(refreshButton).toBeDisabled(); + }); + }); describe('Error States', () => { it('should display error message when fetch fails', async () => { - server.use(createStatefulSetsListError(500, 'Server Error')) - render() + server.use(createStatefulSetsListError(500, 'Server Error')); + render(); await waitFor(() => { - expect(screen.getByText(/Server Error/)).toBeInTheDocument() - expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument() - }) - }) + expect(screen.getByText(/Server Error/)).toBeInTheDocument(); + expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument(); + }); + }); it('should show retry button in error state', async () => { - server.use(createStatefulSetsListError()) - render() + server.use(createStatefulSetsListError()); + render(); await waitFor(() => { - const retryButton = screen.getByRole('button', { name: /retry/i }) - expect(retryButton).toBeInTheDocument() - }) - }) - }) + const retryButton = screen.getByRole('button', { name: /retry/i }); + expect(retryButton).toBeInTheDocument(); + }); + }); + }); describe('Empty States', () => { it('should display empty state when no statefulsets', async () => { - server.use(createStatefulSetsList([])) - render() + server.use(createStatefulSetsList([])); + render(); await waitFor(() => { - expect(screen.getByText('No statefulsets found')).toBeInTheDocument() - expect(screen.getByRole('button', { name: /refresh/i })).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('No statefulsets found')).toBeInTheDocument(); + expect(screen.getByRole('button', { name: /refresh/i })).toBeInTheDocument(); + }); + }); + }); describe('User Interactions', () => { it('should refresh data when refresh button is clicked', async () => { - const user = userEvent.setup() - const statefulsets = createStatefulSetsListData() - server.use(createStatefulSetsList(statefulsets)) - render() + const user = userEvent.setup(); + const statefulsets = createStatefulSetsListData(); + server.use(createStatefulSetsList(statefulsets)); + render(); await waitFor(() => { - expect(screen.getByText('web-statefulset')).toBeInTheDocument() - }) + expect(screen.getByText('web-statefulset')).toBeInTheDocument(); + }); // Mock new data for refresh const newStatefulsets = [...statefulsets, { metadata: { name: 'new-statefulset', namespace: 'default', uid: 'ss-new' }, spec: { replicas: 1, selector: { matchLabels: { app: 'new' } }, template: { metadata: { labels: { app: 'new' } }, spec: { containers: [{ name: 'new', image: 'new:latest' }] } } }, status: { replicas: 1, readyReplicas: 1, currentReplicas: 1, updatedReplicas: 1 } - }] - server.use(createStatefulSetsList(newStatefulsets)) + }]; + server.use(createStatefulSetsList(newStatefulsets)); - const refreshButton = screen.getAllByRole('button', { name: '' })[0] - await user.click(refreshButton) + const refreshButton = screen.getAllByRole('button', { name: '' })[0]; + await user.click(refreshButton); await waitFor(() => { - expect(screen.getByText('new-statefulset')).toBeInTheDocument() - }) - }) + expect(screen.getByText('new-statefulset')).toBeInTheDocument(); + }); + }); it('should show create statefulset alert when create button is clicked', async () => { - const user = userEvent.setup() - server.use(createStatefulSetsList()) - render() + const user = userEvent.setup(); + server.use(createStatefulSetsList()); + render(); - const createButton = screen.getByRole('button', { name: /create statefulset/i }) - await user.click(createButton) + const createButton = screen.getByRole('button', { name: /create statefulset/i }); + await user.click(createButton); - expect(window.alert).toHaveBeenCalledWith('Create StatefulSet functionality not yet implemented') - }) + expect(window.alert).toHaveBeenCalledWith('Create StatefulSet functionality not yet implemented'); + }); it('should show scale prompt when scale button is clicked', async () => { - const user = userEvent.setup() - server.use(createStatefulSetsList(), createStatefulSetScale()) - render() + const user = userEvent.setup(); + server.use(createStatefulSetsList(), createStatefulSetScale()); + render(); await waitFor(() => { - expect(screen.getByText('web-statefulset')).toBeInTheDocument() + expect(screen.getByText('web-statefulset')).toBeInTheDocument(); }) - ;(window.prompt as jest.Mock).mockReturnValue('5') + ;(window.prompt as jest.Mock).mockReturnValue('5'); const scaleButton = screen.getAllByRole('button', { name: '' }).find(button => button.querySelector('svg.lucide-scale') - ) - expect(scaleButton).toBeInTheDocument() + ); + expect(scaleButton).toBeInTheDocument(); if (scaleButton) { - await user.click(scaleButton) - expect(window.prompt).toHaveBeenCalledWith('Scale web-statefulset to how many replicas?', '3') + await user.click(scaleButton); + expect(window.prompt).toHaveBeenCalledWith('Scale web-statefulset to how many replicas?', '3'); } - }) + }); it('should show delete confirmation when delete button is clicked', async () => { - const user = userEvent.setup() - const { confirmDialog } = require('../../../hooks/useConfirm') - confirmDialog.mockResolvedValue(true) + const user = userEvent.setup(); + const { confirmDialog } = require('../../../hooks/useConfirm'); + confirmDialog.mockResolvedValue(true); - server.use(createStatefulSetsList(), createStatefulSetDelete()) - render() + server.use(createStatefulSetsList(), createStatefulSetDelete()); + render(); await waitFor(() => { - expect(screen.getByText('web-statefulset')).toBeInTheDocument() - }) + expect(screen.getByText('web-statefulset')).toBeInTheDocument(); + }); const deleteButton = screen.getAllByRole('button').find(button => button.querySelector('svg.lucide-trash2') - ) - expect(deleteButton).toBeInTheDocument() + ); + expect(deleteButton).toBeInTheDocument(); if (deleteButton) { - await user.click(deleteButton) + await user.click(deleteButton); expect(confirmDialog).toHaveBeenCalledWith({ title: 'Delete StatefulSet', description: 'Are you sure you want to delete web-statefulset?', confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); } - }) + }); it('should show view button when view button is clicked', async () => { - const user = userEvent.setup() - server.use(createStatefulSetsList()) - render() + const user = userEvent.setup(); + server.use(createStatefulSetsList()); + render(); await waitFor(() => { - expect(screen.getByText('web-statefulset')).toBeInTheDocument() - }) + expect(screen.getByText('web-statefulset')).toBeInTheDocument(); + }); const viewButton = screen.getAllByRole('button', { name: '' }).find(button => button.querySelector('svg.lucide-eye') - ) - expect(viewButton).toBeInTheDocument() + ); + expect(viewButton).toBeInTheDocument(); if (viewButton) { - await user.click(viewButton) + await user.click(viewButton); // View functionality sets selectedStatefulSet state // This is tested indirectly through the component's internal state } - }) + }); it('should show edit console log when edit button is clicked', async () => { - const user = userEvent.setup() - const consoleSpy = jest.spyOn(console, 'log').mockImplementation() + const user = userEvent.setup(); + const consoleSpy = jest.spyOn(console, 'log').mockImplementation(); - server.use(createStatefulSetsList()) - render() + server.use(createStatefulSetsList()); + render(); await waitFor(() => { - expect(screen.getByText('web-statefulset')).toBeInTheDocument() - }) + expect(screen.getByText('web-statefulset')).toBeInTheDocument(); + }); const editButton = screen.getAllByRole('button').find(button => button.querySelector('svg.lucide-square-pen') - ) - expect(editButton).toBeInTheDocument() + ); + expect(editButton).toBeInTheDocument(); if (editButton) { - await user.click(editButton) - expect(consoleSpy).toHaveBeenCalledWith('Edit', 'web-statefulset') + await user.click(editButton); + expect(consoleSpy).toHaveBeenCalledWith('Edit', 'web-statefulset'); } - consoleSpy.mockRestore() - }) - }) + consoleSpy.mockRestore(); + }); + }); describe('Status Logic', () => { it('should show Running status when all replicas are ready', async () => { - server.use(createStatefulSetsList()) - render() + server.use(createStatefulSetsList()); + render(); await waitFor(() => { - expect(screen.getAllByText('Running')).toHaveLength(3) // Header + two running statefulsets - }) - }) + expect(screen.getAllByText('Running')).toHaveLength(3); // Header + two running statefulsets + }); + }); it('should show Updating status when replicas are not ready', async () => { - const statefulsets = createStatefulSetsListData() + const statefulsets = createStatefulSetsListData(); // Modify one statefulset to have 0 ready replicas - statefulsets[0].status!.readyReplicas = 0 - server.use(createStatefulSetsList(statefulsets)) - render() + statefulsets[0].status!.readyReplicas = 0; + server.use(createStatefulSetsList(statefulsets)); + render(); await waitFor(() => { - expect(screen.getByText('Updating')).toBeInTheDocument() - expect(screen.getAllByText('Running')).toHaveLength(2) // Header + one running - }) - }) - }) + expect(screen.getByText('Updating')).toBeInTheDocument(); + expect(screen.getAllByText('Running')).toHaveLength(2); // Header + one running + }); + }); + }); describe('All Namespaces Mode', () => { it('should show all statefulsets when in all namespaces mode', async () => { // This test is complex due to mocking requirements // For now, we'll skip it and focus on core functionality - expect(true).toBe(true) - }) - }) + expect(true).toBe(true); + }); + }); describe('Accessibility', () => { it('should have proper button roles and labels', () => { - server.use(createStatefulSetsList()) - render() + server.use(createStatefulSetsList()); + render(); - expect(screen.getByRole('button', { name: /create statefulset/i })).toBeInTheDocument() - expect(screen.getAllByRole('button', { name: '' })[0]).toBeInTheDocument() // Refresh button - }) + expect(screen.getByRole('button', { name: /create statefulset/i })).toBeInTheDocument(); + expect(screen.getAllByRole('button', { name: '' })[0]).toBeInTheDocument(); // Refresh button + }); it('should have proper table structure', async () => { - server.use(createStatefulSetsList()) - render() + server.use(createStatefulSetsList()); + render(); await waitFor(() => { - expect(screen.getByRole('table')).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Name' })).toBeInTheDocument() - expect(screen.getByRole('columnheader', { name: 'Namespace' })).toBeInTheDocument() - }) - }) + expect(screen.getByRole('table')).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Name' })).toBeInTheDocument(); + expect(screen.getByRole('columnheader', { name: 'Namespace' })).toBeInTheDocument(); + }); + }); it('should be keyboard navigable', async () => { - const user = userEvent.setup() - server.use(createStatefulSetsList()) - render() + const user = userEvent.setup(); + server.use(createStatefulSetsList()); + render(); - const createButton = screen.getByRole('button', { name: /create statefulset/i }) - createButton.focus() + const createButton = screen.getByRole('button', { name: /create statefulset/i }); + createButton.focus(); - expect(document.activeElement).toBe(createButton) + expect(document.activeElement).toBe(createButton); // Test that tab navigation works - await user.tab() + await user.tab(); // The focus should move to the next focusable element - expect(document.activeElement).not.toBe(createButton) - }) - }) -}) + expect(document.activeElement).not.toBe(createButton); + }); + }); +}); diff --git a/apps/ops-dashboard/__tests__/components/resources/storageclasses.test.tsx b/apps/ops-dashboard/__tests__/components/resources/storageclasses.test.tsx index ca01654..15a5c46 100644 --- a/apps/ops-dashboard/__tests__/components/resources/storageclasses.test.tsx +++ b/apps/ops-dashboard/__tests__/components/resources/storageclasses.test.tsx @@ -1,91 +1,90 @@ -import { render, screen, waitFor } from '@testing-library/react' -import userEvent from '@testing-library/user-event' -import { StorageClassesView } from '@/components/resources/storageclasses' -import { server } from '@/__mocks__/server' -import { http, HttpResponse } from 'msw' +import { render, screen, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; + +import { StorageClassesView } from '@/components/resources/storageclasses'; // Mock the confirm dialog jest.mock('../../../hooks/useConfirm', () => ({ confirmDialog: jest.fn().mockResolvedValue(true) -})) +})); // Mock the Kubernetes hooks jest.mock('../../../k8s', () => ({ useListStorageV1StorageClassQuery: jest.fn(), useDeleteStorageV1StorageClass: jest.fn() -})) +})); describe('StorageClassesView', () => { beforeEach(() => { - jest.clearAllMocks() - }) + jest.clearAllMocks(); + }); describe('Basic Rendering', () => { it('should render storage classes view with header', () => { - const { useListStorageV1StorageClassQuery } = require('../../../k8s') + const { useListStorageV1StorageClassQuery } = require('../../../k8s'); useListStorageV1StorageClassQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('heading', { name: 'Storage Classes', level: 2 })).toBeInTheDocument() - expect(screen.getByText('Dynamic storage provisioning configurations')).toBeInTheDocument() - }) + expect(screen.getByRole('heading', { name: 'Storage Classes', level: 2 })).toBeInTheDocument(); + expect(screen.getByText('Dynamic storage provisioning configurations')).toBeInTheDocument(); + }); it('should render refresh button', () => { - const { useListStorageV1StorageClassQuery } = require('../../../k8s') + const { useListStorageV1StorageClassQuery } = require('../../../k8s'); useListStorageV1StorageClassQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - const refreshButton = screen.getByRole('button', { name: '' }) - expect(refreshButton).toBeInTheDocument() - }) + const refreshButton = screen.getByRole('button', { name: '' }); + expect(refreshButton).toBeInTheDocument(); + }); it('should render create storage class button', () => { - const { useListStorageV1StorageClassQuery } = require('../../../k8s') + const { useListStorageV1StorageClassQuery } = require('../../../k8s'); useListStorageV1StorageClassQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('button', { name: 'Create Storage Class' })).toBeInTheDocument() - }) + expect(screen.getByRole('button', { name: 'Create Storage Class' })).toBeInTheDocument(); + }); it('should render stats cards', () => { - const { useListStorageV1StorageClassQuery } = require('../../../k8s') + const { useListStorageV1StorageClassQuery } = require('../../../k8s'); useListStorageV1StorageClassQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByText('Total Classes')).toBeInTheDocument() - expect(screen.getByText('Default Class')).toBeInTheDocument() - expect(screen.getByText('Expandable')).toBeInTheDocument() - expect(screen.getByText('Provisioners')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Total Classes')).toBeInTheDocument(); + expect(screen.getByText('Default Class')).toBeInTheDocument(); + expect(screen.getByText('Expandable')).toBeInTheDocument(); + expect(screen.getByText('Provisioners')).toBeInTheDocument(); + }); + }); describe('Data Display', () => { it('should display storage class data', async () => { - const { useListStorageV1StorageClassQuery } = require('../../../k8s') + const { useListStorageV1StorageClassQuery } = require('../../../k8s'); useListStorageV1StorageClassQuery.mockReturnValue({ data: { items: [ @@ -101,17 +100,17 @@ describe('StorageClassesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('fast-ssd')).toBeInTheDocument() - }) - }) + expect(screen.getByText('fast-ssd')).toBeInTheDocument(); + }); + }); it('should display correct statistics', async () => { - const { useListStorageV1StorageClassQuery } = require('../../../k8s') + const { useListStorageV1StorageClassQuery } = require('../../../k8s'); useListStorageV1StorageClassQuery.mockReturnValue({ data: { items: [ @@ -135,19 +134,19 @@ describe('StorageClassesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getAllByText('3', { selector: '.text-2xl.font-bold' })).toHaveLength(2) // Total Classes and Provisioners - expect(screen.getByText('fast-ssd', { selector: '.text-sm.font-medium' })).toBeInTheDocument() // Default Class - expect(screen.getByText('2', { selector: '.text-2xl.font-bold' })).toBeInTheDocument() // Expandable - }) - }) + expect(screen.getAllByText('3', { selector: '.text-2xl.font-bold' })).toHaveLength(2); // Total Classes and Provisioners + expect(screen.getByText('fast-ssd', { selector: '.text-sm.font-medium' })).toBeInTheDocument(); // Default Class + expect(screen.getByText('2', { selector: '.text-2xl.font-bold' })).toBeInTheDocument(); // Expandable + }); + }); it('should display provisioner badges correctly', async () => { - const { useListStorageV1StorageClassQuery } = require('../../../k8s') + const { useListStorageV1StorageClassQuery } = require('../../../k8s'); useListStorageV1StorageClassQuery.mockReturnValue({ data: { items: [ @@ -172,20 +171,20 @@ describe('StorageClassesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('AWS EBS')).toBeInTheDocument() - expect(screen.getByText('Azure Disk')).toBeInTheDocument() - expect(screen.getByText('NFS')).toBeInTheDocument() - expect(screen.getByText('Local')).toBeInTheDocument() - }) - }) + expect(screen.getByText('AWS EBS')).toBeInTheDocument(); + expect(screen.getByText('Azure Disk')).toBeInTheDocument(); + expect(screen.getByText('NFS')).toBeInTheDocument(); + expect(screen.getByText('Local')).toBeInTheDocument(); + }); + }); it('should display reclaim policy correctly', async () => { - const { useListStorageV1StorageClassQuery } = require('../../../k8s') + const { useListStorageV1StorageClassQuery } = require('../../../k8s'); useListStorageV1StorageClassQuery.mockReturnValue({ data: { items: [ @@ -202,18 +201,18 @@ describe('StorageClassesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('Delete')).toBeInTheDocument() - expect(screen.getByText('Retain')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Delete')).toBeInTheDocument(); + expect(screen.getByText('Retain')).toBeInTheDocument(); + }); + }); it('should display volume binding mode correctly', async () => { - const { useListStorageV1StorageClassQuery } = require('../../../k8s') + const { useListStorageV1StorageClassQuery } = require('../../../k8s'); useListStorageV1StorageClassQuery.mockReturnValue({ data: { items: [ @@ -230,18 +229,18 @@ describe('StorageClassesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('Immediate')).toBeInTheDocument() - expect(screen.getByText('WaitForFirstConsumer')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Immediate')).toBeInTheDocument(); + expect(screen.getByText('WaitForFirstConsumer')).toBeInTheDocument(); + }); + }); it('should display volume expansion status correctly', async () => { - const { useListStorageV1StorageClassQuery } = require('../../../k8s') + const { useListStorageV1StorageClassQuery } = require('../../../k8s'); useListStorageV1StorageClassQuery.mockReturnValue({ data: { items: [ @@ -258,18 +257,18 @@ describe('StorageClassesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('Allowed')).toBeInTheDocument() - expect(screen.getByText('Not Allowed')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Allowed')).toBeInTheDocument(); + expect(screen.getByText('Not Allowed')).toBeInTheDocument(); + }); + }); it('should display default class status correctly', async () => { - const { useListStorageV1StorageClassQuery } = require('../../../k8s') + const { useListStorageV1StorageClassQuery } = require('../../../k8s'); useListStorageV1StorageClassQuery.mockReturnValue({ data: { items: [ @@ -287,64 +286,64 @@ describe('StorageClassesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('Yes')).toBeInTheDocument() - expect(screen.getByText('No')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('Yes')).toBeInTheDocument(); + expect(screen.getByText('No')).toBeInTheDocument(); + }); + }); + }); describe('User Interactions', () => { it('should refresh data when refresh button is clicked', async () => { - const user = userEvent.setup() - const mockRefetch = jest.fn() - const { useListStorageV1StorageClassQuery } = require('../../../k8s') + const user = userEvent.setup(); + const mockRefetch = jest.fn(); + const { useListStorageV1StorageClassQuery } = require('../../../k8s'); useListStorageV1StorageClassQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: mockRefetch - }) + }); - render() + render(); - const refreshButton = screen.getByRole('button', { name: '' }) - await user.click(refreshButton) + const refreshButton = screen.getByRole('button', { name: '' }); + await user.click(refreshButton); - expect(mockRefetch).toHaveBeenCalled() - }) + expect(mockRefetch).toHaveBeenCalled(); + }); it('should show create storage class alert when create button is clicked', async () => { - const user = userEvent.setup() - const { useListStorageV1StorageClassQuery } = require('../../../k8s') + const user = userEvent.setup(); + const { useListStorageV1StorageClassQuery } = require('../../../k8s'); useListStorageV1StorageClassQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); // Mock alert - const alertSpy = jest.spyOn(window, 'alert').mockImplementation(() => {}) + const alertSpy = jest.spyOn(window, 'alert').mockImplementation(() => {}); - render() + render(); - const createButton = screen.getByRole('button', { name: 'Create Storage Class' }) - await user.click(createButton) + const createButton = screen.getByRole('button', { name: 'Create Storage Class' }); + await user.click(createButton); - expect(alertSpy).toHaveBeenCalledWith('Create Storage Class functionality not yet implemented') + expect(alertSpy).toHaveBeenCalledWith('Create Storage Class functionality not yet implemented'); - alertSpy.mockRestore() - }) + alertSpy.mockRestore(); + }); it('should show delete confirmation when delete button is clicked', async () => { - const user = userEvent.setup() - const { useListStorageV1StorageClassQuery, useDeleteStorageV1StorageClass } = require('../../../k8s') - const mockDelete = jest.fn().mockResolvedValue({}) + const user = userEvent.setup(); + const { useListStorageV1StorageClassQuery, useDeleteStorageV1StorageClass } = require('../../../k8s'); + const mockDelete = jest.fn().mockResolvedValue({}); useListStorageV1StorageClassQuery.mockReturnValue({ data: { @@ -358,31 +357,31 @@ describe('StorageClassesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); useDeleteStorageV1StorageClass.mockReturnValue({ mutateAsync: mockDelete - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('slow-hdd')).toBeInTheDocument() - }) + expect(screen.getByText('slow-hdd')).toBeInTheDocument(); + }); - const deleteButtons = screen.getAllByRole('button') + const deleteButtons = screen.getAllByRole('button'); const deleteButton = deleteButtons.find(button => button.querySelector('svg.lucide-trash-2') - ) + ); if (deleteButton) { - await user.click(deleteButton) - expect(deleteButton).toBeInTheDocument() + await user.click(deleteButton); + expect(deleteButton).toBeInTheDocument(); } - }) + }); it('should show view button when view button is clicked', async () => { - const user = userEvent.setup() - const { useListStorageV1StorageClassQuery } = require('../../../k8s') + const user = userEvent.setup(); + const { useListStorageV1StorageClassQuery } = require('../../../k8s'); useListStorageV1StorageClassQuery.mockReturnValue({ data: { items: [ @@ -395,27 +394,27 @@ describe('StorageClassesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('fast-ssd')).toBeInTheDocument() - }) + expect(screen.getByText('fast-ssd')).toBeInTheDocument(); + }); - const viewButtons = screen.getAllByRole('button') + const viewButtons = screen.getAllByRole('button'); const viewButton = viewButtons.find(button => button.querySelector('svg.lucide-eye') - ) + ); if (viewButton) { - await user.click(viewButton) - expect(viewButton).toBeInTheDocument() + await user.click(viewButton); + expect(viewButton).toBeInTheDocument(); } - }) + }); it('should disable delete button for default storage classes', async () => { - const { useListStorageV1StorageClassQuery } = require('../../../k8s') + const { useListStorageV1StorageClassQuery } = require('../../../k8s'); useListStorageV1StorageClassQuery.mockReturnValue({ data: { items: [ @@ -431,28 +430,28 @@ describe('StorageClassesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getAllByText('fast-ssd')).toHaveLength(2) // Both in stats and table - }) + expect(screen.getAllByText('fast-ssd')).toHaveLength(2); // Both in stats and table + }); - const deleteButtons = screen.getAllByRole('button') + const deleteButtons = screen.getAllByRole('button'); const deleteButton = deleteButtons.find(button => button.querySelector('svg.lucide-trash-2') - ) + ); if (deleteButton) { - expect(deleteButton).toBeDisabled() + expect(deleteButton).toBeDisabled(); } - }) - }) + }); + }); describe('Status Logic', () => { it('should show default class correctly', async () => { - const { useListStorageV1StorageClassQuery } = require('../../../k8s') + const { useListStorageV1StorageClassQuery } = require('../../../k8s'); useListStorageV1StorageClassQuery.mockReturnValue({ data: { items: [ @@ -467,17 +466,17 @@ describe('StorageClassesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('Yes', { selector: '.rounded-full' })).toBeInTheDocument() - }) - }) + expect(screen.getByText('Yes', { selector: '.rounded-full' })).toBeInTheDocument(); + }); + }); it('should show non-default class correctly', async () => { - const { useListStorageV1StorageClassQuery } = require('../../../k8s') + const { useListStorageV1StorageClassQuery } = require('../../../k8s'); useListStorageV1StorageClassQuery.mockReturnValue({ data: { items: [ @@ -489,17 +488,17 @@ describe('StorageClassesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('No', { selector: '.rounded-full' })).toBeInTheDocument() - }) - }) + expect(screen.getByText('No', { selector: '.rounded-full' })).toBeInTheDocument(); + }); + }); it('should show volume expansion allowed correctly', async () => { - const { useListStorageV1StorageClassQuery } = require('../../../k8s') + const { useListStorageV1StorageClassQuery } = require('../../../k8s'); useListStorageV1StorageClassQuery.mockReturnValue({ data: { items: [ @@ -512,17 +511,17 @@ describe('StorageClassesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('Allowed', { selector: '.rounded-full' })).toBeInTheDocument() - }) - }) + expect(screen.getByText('Allowed', { selector: '.rounded-full' })).toBeInTheDocument(); + }); + }); it('should show volume expansion not allowed correctly', async () => { - const { useListStorageV1StorageClassQuery } = require('../../../k8s') + const { useListStorageV1StorageClassQuery } = require('../../../k8s'); useListStorageV1StorageClassQuery.mockReturnValue({ data: { items: [ @@ -535,97 +534,97 @@ describe('StorageClassesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); await waitFor(() => { - expect(screen.getByText('Not Allowed', { selector: '.rounded-full' })).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('Not Allowed', { selector: '.rounded-full' })).toBeInTheDocument(); + }); + }); + }); describe('Loading States', () => { it('should show loading spinner when loading', () => { - const { useListStorageV1StorageClassQuery } = require('../../../k8s') + const { useListStorageV1StorageClassQuery } = require('../../../k8s'); useListStorageV1StorageClassQuery.mockReturnValue({ data: undefined, isLoading: true, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('button', { name: '' })).toBeDisabled() // Refresh button - }) - }) + expect(screen.getByRole('button', { name: '' })).toBeDisabled(); // Refresh button + }); + }); describe('Error States', () => { it('should display error message when fetch fails', () => { - const { useListStorageV1StorageClassQuery } = require('../../../k8s') + const { useListStorageV1StorageClassQuery } = require('../../../k8s'); useListStorageV1StorageClassQuery.mockReturnValue({ data: undefined, isLoading: false, error: new Error('Network request failed'), refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByText('Network request failed')).toBeInTheDocument() - }) + expect(screen.getByText('Network request failed')).toBeInTheDocument(); + }); it('should show retry button in error state', () => { - const { useListStorageV1StorageClassQuery } = require('../../../k8s') + const { useListStorageV1StorageClassQuery } = require('../../../k8s'); useListStorageV1StorageClassQuery.mockReturnValue({ data: undefined, isLoading: false, error: new Error('Network request failed'), refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('button', { name: 'Retry' })).toBeInTheDocument() - }) - }) + expect(screen.getByRole('button', { name: 'Retry' })).toBeInTheDocument(); + }); + }); describe('Empty States', () => { it('should display empty state when no storage classes', () => { - const { useListStorageV1StorageClassQuery } = require('../../../k8s') + const { useListStorageV1StorageClassQuery } = require('../../../k8s'); useListStorageV1StorageClassQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByText('No storage classes found')).toBeInTheDocument() - }) - }) + expect(screen.getByText('No storage classes found')).toBeInTheDocument(); + }); + }); describe('Accessibility', () => { it('should have proper button roles and labels', () => { - const { useListStorageV1StorageClassQuery } = require('../../../k8s') + const { useListStorageV1StorageClassQuery } = require('../../../k8s'); useListStorageV1StorageClassQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); - expect(screen.getByRole('button', { name: '' })).toBeInTheDocument() // Refresh button - expect(screen.getByRole('button', { name: 'Create Storage Class' })).toBeInTheDocument() - }) + expect(screen.getByRole('button', { name: '' })).toBeInTheDocument(); // Refresh button + expect(screen.getByRole('button', { name: 'Create Storage Class' })).toBeInTheDocument(); + }); it('should be keyboard navigable', async () => { - const user = userEvent.setup() - const { useListStorageV1StorageClassQuery } = require('../../../k8s') + const user = userEvent.setup(); + const { useListStorageV1StorageClassQuery } = require('../../../k8s'); useListStorageV1StorageClassQuery.mockReturnValue({ data: { items: [ @@ -638,30 +637,30 @@ describe('StorageClassesView', () => { isLoading: false, error: null, refetch: jest.fn() - }) + }); - render() + render(); // Wait for data to load first await waitFor(() => { - expect(screen.getByText('fast-ssd')).toBeInTheDocument() - }) + expect(screen.getByText('fast-ssd')).toBeInTheDocument(); + }); - const refreshButtons = screen.getAllByRole('button') + const refreshButtons = screen.getAllByRole('button'); const refreshButton = refreshButtons.find(button => button.querySelector('svg.lucide-refresh-cw') && button.classList.contains('h-4') - ) + ); if (refreshButton) { - refreshButton.focus() - expect(document.activeElement).toBe(refreshButton) + refreshButton.focus(); + expect(document.activeElement).toBe(refreshButton); // Test that tab navigation works - await user.tab() + await user.tab(); // The focus should move to the next focusable element - expect(document.activeElement).not.toBe(refreshButton) + expect(document.activeElement).not.toBe(refreshButton); } - }) - }) -}) + }); + }); +}); diff --git a/apps/ops-dashboard/__tests__/components/resources/volumeattachments.test.tsx b/apps/ops-dashboard/__tests__/components/resources/volumeattachments.test.tsx index b098a83..3f72b9e 100644 --- a/apps/ops-dashboard/__tests__/components/resources/volumeattachments.test.tsx +++ b/apps/ops-dashboard/__tests__/components/resources/volumeattachments.test.tsx @@ -1,28 +1,30 @@ -import { render, screen, waitFor, fireEvent } from '../../utils/test-utils' -import userEvent from '@testing-library/user-event' -import { VolumeAttachmentsView } from '@/components/resources/volumeattachments' +import userEvent from '@testing-library/user-event'; + +import { VolumeAttachmentsView } from '@/components/resources/volumeattachments'; + +import {render, screen, waitFor } from '../../utils/test-utils'; // Mock the hooks jest.mock('../../../k8s', () => ({ useListStorageV1VolumeAttachmentQuery: jest.fn(), useDeleteStorageV1VolumeAttachment: jest.fn() -})) +})); // Mock the confirm dialog jest.mock('../../../hooks/useConfirm', () => ({ ...jest.requireActual('../../../hooks/useConfirm'), confirmDialog: jest.fn() -})) +})); describe('VolumeAttachmentsView', () => { - const mockRefetch = jest.fn() - const mockDeleteAttachment = jest.fn() - const mockConfirmDialog = require('../../../hooks/useConfirm').confirmDialog + const mockRefetch = jest.fn(); + const mockDeleteAttachment = jest.fn(); + const mockConfirmDialog = require('../../../hooks/useConfirm').confirmDialog; beforeEach(() => { - jest.clearAllMocks() + jest.clearAllMocks(); - const { useListStorageV1VolumeAttachmentQuery, useDeleteStorageV1VolumeAttachment } = require('../../../k8s') + const { useListStorageV1VolumeAttachmentQuery, useDeleteStorageV1VolumeAttachment } = require('../../../k8s'); useListStorageV1VolumeAttachmentQuery.mockReturnValue({ data: { @@ -72,275 +74,275 @@ describe('VolumeAttachmentsView', () => { isLoading: false, error: null, refetch: mockRefetch - }) + }); useDeleteStorageV1VolumeAttachment.mockReturnValue({ mutateAsync: mockDeleteAttachment - }) + }); - mockConfirmDialog.mockResolvedValue(true) - }) + mockConfirmDialog.mockResolvedValue(true); + }); describe('Basic Rendering', () => { it('should render volume attachments view with header', () => { - render() + render(); - expect(screen.getByText('Volume Attachments', { selector: 'h2' })).toBeInTheDocument() - expect(screen.getByText('Volume attachments to nodes')).toBeInTheDocument() - }) + expect(screen.getByText('Volume Attachments', { selector: 'h2' })).toBeInTheDocument(); + expect(screen.getByText('Volume attachments to nodes')).toBeInTheDocument(); + }); it('should render refresh button', () => { - render() + render(); - const buttons = screen.getAllByRole('button') - expect(buttons.length).toBeGreaterThan(0) - }) + const buttons = screen.getAllByRole('button'); + expect(buttons.length).toBeGreaterThan(0); + }); it('should render stats cards', () => { - render() + render(); - expect(screen.getByText('Total Attachments')).toBeInTheDocument() - expect(screen.getByText('Attached', { selector: 'h3' })).toBeInTheDocument() - expect(screen.getByText('With Errors')).toBeInTheDocument() - expect(screen.getByText('Unique Nodes')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Total Attachments')).toBeInTheDocument(); + expect(screen.getByText('Attached', { selector: 'h3' })).toBeInTheDocument(); + expect(screen.getByText('With Errors')).toBeInTheDocument(); + expect(screen.getByText('Unique Nodes')).toBeInTheDocument(); + }); + }); describe('Data Display', () => { it('should display volume attachment data', async () => { - render() + render(); await waitFor(() => { - expect(screen.getByText('attachment-1')).toBeInTheDocument() - expect(screen.getByText('attachment-2')).toBeInTheDocument() - expect(screen.getByText('worker-node-1')).toBeInTheDocument() - expect(screen.getByText('worker-node-2')).toBeInTheDocument() - expect(screen.getByText('pv-1')).toBeInTheDocument() - expect(screen.getByText('pv-2')).toBeInTheDocument() - }) - }) + expect(screen.getByText('attachment-1')).toBeInTheDocument(); + expect(screen.getByText('attachment-2')).toBeInTheDocument(); + expect(screen.getByText('worker-node-1')).toBeInTheDocument(); + expect(screen.getByText('worker-node-2')).toBeInTheDocument(); + expect(screen.getByText('pv-1')).toBeInTheDocument(); + expect(screen.getByText('pv-2')).toBeInTheDocument(); + }); + }); it('should display correct statistics', async () => { - render() + render(); await waitFor(() => { - expect(screen.getAllByText('2', { selector: '.text-2xl.font-bold' })).toHaveLength(2) // Total Attachments and Unique Nodes - expect(screen.getByText('1', { selector: '.text-2xl.font-bold.text-green-600' })).toBeInTheDocument() // Attached - expect(screen.getByText('1', { selector: '.text-2xl.font-bold.text-red-600' })).toBeInTheDocument() // With Errors - }) - }) + expect(screen.getAllByText('2', { selector: '.text-2xl.font-bold' })).toHaveLength(2); // Total Attachments and Unique Nodes + expect(screen.getByText('1', { selector: '.text-2xl.font-bold.text-green-600' })).toBeInTheDocument(); // Attached + expect(screen.getByText('1', { selector: '.text-2xl.font-bold.text-red-600' })).toBeInTheDocument(); // With Errors + }); + }); it('should display status badges correctly', async () => { - render() + render(); await waitFor(() => { - expect(screen.getByText('Attached', { selector: 'div' })).toBeInTheDocument() - expect(screen.getByText('Detached')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Attached', { selector: 'div' })).toBeInTheDocument(); + expect(screen.getByText('Detached')).toBeInTheDocument(); + }); + }); it('should display attacher information correctly', async () => { - render() + render(); await waitFor(() => { - expect(screen.getAllByText('csi.kubernetes.io')).toHaveLength(2) - }) - }) + expect(screen.getAllByText('csi.kubernetes.io')).toHaveLength(2); + }); + }); it('should display error information correctly', async () => { - render() + render(); await waitFor(() => { - expect(screen.getByText('Attach Error')).toBeInTheDocument() - expect(screen.getByText('None')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('Attach Error')).toBeInTheDocument(); + expect(screen.getByText('None')).toBeInTheDocument(); + }); + }); + }); describe('User Interactions', () => { it('should refresh data when refresh button is clicked', async () => { - const user = userEvent.setup() - render() + const user = userEvent.setup(); + render(); - const buttons = screen.getAllByRole('button') - await user.click(buttons[0]) // First button is the refresh button + const buttons = screen.getAllByRole('button'); + await user.click(buttons[0]); // First button is the refresh button - expect(mockRefetch).toHaveBeenCalledTimes(1) - }) + expect(mockRefetch).toHaveBeenCalledTimes(1); + }); it('should show delete confirmation when delete button is clicked', async () => { - const user = userEvent.setup() - render() + const user = userEvent.setup(); + render(); await waitFor(() => { - const deleteButtons = screen.getAllByRole('button') - expect(deleteButtons.length).toBeGreaterThan(1) - }) + const deleteButtons = screen.getAllByRole('button'); + expect(deleteButtons.length).toBeGreaterThan(1); + }); - const deleteButtons = screen.getAllByRole('button') + const deleteButtons = screen.getAllByRole('button'); // Find the first enabled delete button (not disabled) - const enabledDeleteButton = deleteButtons.find(button => !button.disabled && button.className.includes('text-destructive')) - await user.click(enabledDeleteButton!) + const enabledDeleteButton = deleteButtons.find(button => !button.disabled && button.className.includes('text-destructive')); + await user.click(enabledDeleteButton!); expect(mockConfirmDialog).toHaveBeenCalledWith({ title: 'Delete Volume Attachment', description: 'Are you sure you want to delete attachment-2? This may disrupt attached volumes.', confirmText: 'Delete', confirmVariant: 'destructive' - }) - }) + }); + }); it('should delete volume attachment when confirmed', async () => { - const user = userEvent.setup() - mockConfirmDialog.mockResolvedValue(true) - mockDeleteAttachment.mockResolvedValue({}) + const user = userEvent.setup(); + mockConfirmDialog.mockResolvedValue(true); + mockDeleteAttachment.mockResolvedValue({}); - render() + render(); await waitFor(() => { - const deleteButtons = screen.getAllByRole('button') - expect(deleteButtons.length).toBeGreaterThan(1) - }) + const deleteButtons = screen.getAllByRole('button'); + expect(deleteButtons.length).toBeGreaterThan(1); + }); - const deleteButtons = screen.getAllByRole('button') + const deleteButtons = screen.getAllByRole('button'); // Find the first enabled delete button (not disabled) - const enabledDeleteButton = deleteButtons.find(button => !button.disabled && button.className.includes('text-destructive')) - await user.click(enabledDeleteButton!) + const enabledDeleteButton = deleteButtons.find(button => !button.disabled && button.className.includes('text-destructive')); + await user.click(enabledDeleteButton!); await waitFor(() => { expect(mockDeleteAttachment).toHaveBeenCalledWith({ path: { name: 'attachment-2' }, query: {} - }) - expect(mockRefetch).toHaveBeenCalledTimes(1) - }) - }) + }); + expect(mockRefetch).toHaveBeenCalledTimes(1); + }); + }); it('should show view button when view button is clicked', async () => { - const user = userEvent.setup() - render() + const user = userEvent.setup(); + render(); await waitFor(() => { - const buttons = screen.getAllByRole('button') - expect(buttons.length).toBeGreaterThan(1) - }) + const buttons = screen.getAllByRole('button'); + expect(buttons.length).toBeGreaterThan(1); + }); - const buttons = screen.getAllByRole('button') - await user.click(buttons[2]) // Third button is the first view button + const buttons = screen.getAllByRole('button'); + await user.click(buttons[2]); // Third button is the first view button // The component sets selectedAttachment state, but doesn't render anything visible // This test just ensures the button is clickable - expect(buttons[2]).toBeInTheDocument() - }) - }) + expect(buttons[2]).toBeInTheDocument(); + }); + }); describe('Status Logic', () => { it('should show attached status correctly', async () => { - render() + render(); await waitFor(() => { - expect(screen.getByText('Attached', { selector: 'div' })).toBeInTheDocument() - }) - }) + expect(screen.getByText('Attached', { selector: 'div' })).toBeInTheDocument(); + }); + }); it('should show detached status correctly', async () => { - render() + render(); await waitFor(() => { - expect(screen.getByText('Detached')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Detached')).toBeInTheDocument(); + }); + }); it('should show error badges correctly', async () => { - render() + render(); await waitFor(() => { - expect(screen.getByText('Attach Error')).toBeInTheDocument() - expect(screen.getByText('None')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('Attach Error')).toBeInTheDocument(); + expect(screen.getByText('None')).toBeInTheDocument(); + }); + }); + }); describe('Loading States', () => { it('should show loading spinner when loading', () => { - const { useListStorageV1VolumeAttachmentQuery } = require('../../../k8s') + const { useListStorageV1VolumeAttachmentQuery } = require('../../../k8s'); useListStorageV1VolumeAttachmentQuery.mockReturnValue({ data: null, isLoading: true, error: null, refetch: mockRefetch - }) + }); - render() + render(); - expect(screen.getByRole('button')).toBeDisabled() - }) - }) + expect(screen.getByRole('button')).toBeDisabled(); + }); + }); describe('Error States', () => { it('should display error message when fetch fails', () => { - const { useListStorageV1VolumeAttachmentQuery } = require('../../../k8s') + const { useListStorageV1VolumeAttachmentQuery } = require('../../../k8s'); useListStorageV1VolumeAttachmentQuery.mockReturnValue({ data: null, isLoading: false, error: new Error('Failed to fetch volume attachments'), refetch: mockRefetch - }) + }); - render() + render(); - expect(screen.getByText('Failed to fetch volume attachments')).toBeInTheDocument() - expect(screen.getByText('Retry')).toBeInTheDocument() - }) + expect(screen.getByText('Failed to fetch volume attachments')).toBeInTheDocument(); + expect(screen.getByText('Retry')).toBeInTheDocument(); + }); it('should show retry button in error state', () => { - const { useListStorageV1VolumeAttachmentQuery } = require('../../../k8s') + const { useListStorageV1VolumeAttachmentQuery } = require('../../../k8s'); useListStorageV1VolumeAttachmentQuery.mockReturnValue({ data: null, isLoading: false, error: new Error('Failed to fetch volume attachments'), refetch: mockRefetch - }) + }); - render() + render(); - expect(screen.getByText('Retry')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Retry')).toBeInTheDocument(); + }); + }); describe('Empty States', () => { it('should display empty state when no attachments', () => { - const { useListStorageV1VolumeAttachmentQuery } = require('../../../k8s') + const { useListStorageV1VolumeAttachmentQuery } = require('../../../k8s'); useListStorageV1VolumeAttachmentQuery.mockReturnValue({ data: { items: [] }, isLoading: false, error: null, refetch: mockRefetch - }) + }); - render() + render(); - expect(screen.getByText('No volume attachments found')).toBeInTheDocument() - expect(screen.getByText('Refresh')).toBeInTheDocument() - }) - }) + expect(screen.getByText('No volume attachments found')).toBeInTheDocument(); + expect(screen.getByText('Refresh')).toBeInTheDocument(); + }); + }); describe('Accessibility', () => { it('should have proper button roles and labels', () => { - render() + render(); - const buttons = screen.getAllByRole('button') - expect(buttons.length).toBeGreaterThan(0) - }) + const buttons = screen.getAllByRole('button'); + expect(buttons.length).toBeGreaterThan(0); + }); it('should be keyboard navigable', async () => { - const user = userEvent.setup() - render() + const user = userEvent.setup(); + render(); - const buttons = screen.getAllByRole('button') - await user.tab() + const buttons = screen.getAllByRole('button'); + await user.tab(); - expect(buttons[0]).toHaveFocus() - }) - }) -}) + expect(buttons[0]).toHaveFocus(); + }); + }); +}); diff --git a/apps/ops-dashboard/__tests__/components/scale-deployment-dialog.test.tsx b/apps/ops-dashboard/__tests__/components/scale-deployment-dialog.test.tsx index 8424d3c..7cfcc6b 100644 --- a/apps/ops-dashboard/__tests__/components/scale-deployment-dialog.test.tsx +++ b/apps/ops-dashboard/__tests__/components/scale-deployment-dialog.test.tsx @@ -1,8 +1,10 @@ -import React from 'react' -import { render, screen, waitFor } from '../utils/test-utils' -import userEvent from '@testing-library/user-event' -import { ScaleDeploymentDialog } from '@/components/scale-deployment-dialog' -import type { AppsV1Deployment as Deployment } from '@kubernetesjs/ops' +import type { AppsV1Deployment as Deployment } from '@kubernetesjs/ops'; +import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { ScaleDeploymentDialog } from '@/components/scale-deployment-dialog'; + +import { render, screen, waitFor } from '../utils/test-utils'; // Mock deployment data const mockDeployment: Deployment = { @@ -37,18 +39,18 @@ const mockDeployment: Deployment = { readyReplicas: 3, availableReplicas: 3 } -} +}; describe('ScaleDeploymentDialog', () => { - const user = userEvent.setup() - let mockOnOpenChange: jest.Mock - let mockOnScale: jest.Mock + const user = userEvent.setup(); + let mockOnOpenChange: jest.Mock; + let mockOnScale: jest.Mock; beforeEach(() => { - mockOnOpenChange = jest.fn() - mockOnScale = jest.fn() - jest.clearAllMocks() - }) + mockOnOpenChange = jest.fn(); + mockOnScale = jest.fn(); + jest.clearAllMocks(); + }); describe('Basic Rendering', () => { it('should render dialog when open', () => { @@ -59,13 +61,13 @@ describe('ScaleDeploymentDialog', () => { onOpenChange={mockOnOpenChange} onScale={mockOnScale} /> - ) + ); - expect(screen.getByText('Scale Deployment')).toBeInTheDocument() - expect(screen.getByText('test-deployment')).toBeInTheDocument() - expect(screen.getByText('default')).toBeInTheDocument() - expect(screen.getByLabelText('Number of Replicas')).toBeInTheDocument() - }) + expect(screen.getByText('Scale Deployment')).toBeInTheDocument(); + expect(screen.getByText('test-deployment')).toBeInTheDocument(); + expect(screen.getByText('default')).toBeInTheDocument(); + expect(screen.getByLabelText('Number of Replicas')).toBeInTheDocument(); + }); it('should not render when closed', () => { render( @@ -75,10 +77,10 @@ describe('ScaleDeploymentDialog', () => { onOpenChange={mockOnOpenChange} onScale={mockOnScale} /> - ) + ); - expect(screen.queryByText('Scale Deployment')).not.toBeInTheDocument() - }) + expect(screen.queryByText('Scale Deployment')).not.toBeInTheDocument(); + }); it('should not render when deployment is null', () => { render( @@ -88,10 +90,10 @@ describe('ScaleDeploymentDialog', () => { onOpenChange={mockOnOpenChange} onScale={mockOnScale} /> - ) + ); - expect(screen.queryByText('Scale Deployment')).not.toBeInTheDocument() - }) + expect(screen.queryByText('Scale Deployment')).not.toBeInTheDocument(); + }); it('should display current replica count', () => { render( @@ -101,16 +103,16 @@ describe('ScaleDeploymentDialog', () => { onOpenChange={mockOnOpenChange} onScale={mockOnScale} /> - ) + ); - expect(screen.getByText('Current: 3 replicas')).toBeInTheDocument() - }) + expect(screen.getByText('Current: 3 replicas')).toBeInTheDocument(); + }); it('should handle singular replica count', () => { const singleReplicaDeployment = { ...mockDeployment, spec: { ...mockDeployment.spec, replicas: 1 } - } + }; render( { onOpenChange={mockOnOpenChange} onScale={mockOnScale} /> - ) + ); - expect(screen.getByText('Current: 1 replica')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Current: 1 replica')).toBeInTheDocument(); + }); + }); describe('User Interactions', () => { it('should update replicas when user types', async () => { @@ -134,17 +136,17 @@ describe('ScaleDeploymentDialog', () => { onOpenChange={mockOnOpenChange} onScale={mockOnScale} /> - ) + ); - const input = screen.getByLabelText('Number of Replicas') - await user.clear(input) - await user.type(input, '5') + const input = screen.getByLabelText('Number of Replicas'); + await user.clear(input); + await user.type(input, '5'); - expect(input).toHaveValue(5) - }) + expect(input).toHaveValue(5); + }); it('should submit when user clicks Scale button', async () => { - mockOnScale.mockResolvedValue(undefined) + mockOnScale.mockResolvedValue(undefined); render( { onOpenChange={mockOnOpenChange} onScale={mockOnScale} /> - ) + ); - const input = screen.getByLabelText('Number of Replicas') - await user.clear(input) - await user.type(input, '5') + const input = screen.getByLabelText('Number of Replicas'); + await user.clear(input); + await user.type(input, '5'); - const scaleButton = screen.getByRole('button', { name: 'Scale' }) - await user.click(scaleButton) + const scaleButton = screen.getByRole('button', { name: 'Scale' }); + await user.click(scaleButton); - expect(mockOnScale).toHaveBeenCalledWith(5) - expect(mockOnOpenChange).toHaveBeenCalledWith(false) - }) + expect(mockOnScale).toHaveBeenCalledWith(5); + expect(mockOnOpenChange).toHaveBeenCalledWith(false); + }); it('should submit when user presses Enter', async () => { - mockOnScale.mockResolvedValue(undefined) + mockOnScale.mockResolvedValue(undefined); render( { onOpenChange={mockOnOpenChange} onScale={mockOnScale} /> - ) + ); - const input = screen.getByLabelText('Number of Replicas') - await user.clear(input) - await user.type(input, '5') - await user.keyboard('{Enter}') + const input = screen.getByLabelText('Number of Replicas'); + await user.clear(input); + await user.type(input, '5'); + await user.keyboard('{Enter}'); - expect(mockOnScale).toHaveBeenCalledWith(5) - expect(mockOnOpenChange).toHaveBeenCalledWith(false) - }) + expect(mockOnScale).toHaveBeenCalledWith(5); + expect(mockOnOpenChange).toHaveBeenCalledWith(false); + }); it('should cancel when user clicks Cancel button', async () => { render( @@ -195,13 +197,13 @@ describe('ScaleDeploymentDialog', () => { onOpenChange={mockOnOpenChange} onScale={mockOnScale} /> - ) + ); - const cancelButton = screen.getByRole('button', { name: 'Cancel' }) - await user.click(cancelButton) + const cancelButton = screen.getByRole('button', { name: 'Cancel' }); + await user.click(cancelButton); - expect(mockOnOpenChange).toHaveBeenCalledWith(false) - }) + expect(mockOnOpenChange).toHaveBeenCalledWith(false); + }); it('should reset replicas when canceling', async () => { render( @@ -211,14 +213,14 @@ describe('ScaleDeploymentDialog', () => { onOpenChange={mockOnOpenChange} onScale={mockOnScale} /> - ) + ); - const input = screen.getByLabelText('Number of Replicas') - await user.clear(input) - await user.type(input, '5') + const input = screen.getByLabelText('Number of Replicas'); + await user.clear(input); + await user.type(input, '5'); - const cancelButton = screen.getByRole('button', { name: 'Cancel' }) - await user.click(cancelButton) + const cancelButton = screen.getByRole('button', { name: 'Cancel' }); + await user.click(cancelButton); // Re-open dialog to check if replicas were reset render( @@ -228,11 +230,11 @@ describe('ScaleDeploymentDialog', () => { onOpenChange={mockOnOpenChange} onScale={mockOnScale} /> - ) + ); - expect(screen.getByLabelText('Number of Replicas')).toHaveValue(3) - }) - }) + expect(screen.getByLabelText('Number of Replicas')).toHaveValue(3); + }); + }); describe('Validation', () => { it('should handle empty input', async () => { @@ -243,17 +245,17 @@ describe('ScaleDeploymentDialog', () => { onOpenChange={mockOnOpenChange} onScale={mockOnScale} /> - ) + ); - const input = screen.getByLabelText('Number of Replicas') - await user.clear(input) + const input = screen.getByLabelText('Number of Replicas'); + await user.clear(input); - const scaleButton = screen.getByRole('button', { name: 'Scale' }) - await user.click(scaleButton) + const scaleButton = screen.getByRole('button', { name: 'Scale' }); + await user.click(scaleButton); // Component should not call onScale with empty input - expect(mockOnScale).not.toHaveBeenCalled() - }) + expect(mockOnScale).not.toHaveBeenCalled(); + }); it('should show error for negative numbers', async () => { render( @@ -263,18 +265,18 @@ describe('ScaleDeploymentDialog', () => { onOpenChange={mockOnOpenChange} onScale={mockOnScale} /> - ) + ); - const input = screen.getByLabelText('Number of Replicas') - await user.clear(input) - await user.type(input, '-1') + const input = screen.getByLabelText('Number of Replicas'); + await user.clear(input); + await user.type(input, '-1'); - const scaleButton = screen.getByRole('button', { name: 'Scale' }) - await user.click(scaleButton) + const scaleButton = screen.getByRole('button', { name: 'Scale' }); + await user.click(scaleButton); - expect(screen.getByText('Please enter a valid number of replicas (0 or greater)')).toBeInTheDocument() - expect(mockOnScale).not.toHaveBeenCalled() - }) + expect(screen.getByText('Please enter a valid number of replicas (0 or greater)')).toBeInTheDocument(); + expect(mockOnScale).not.toHaveBeenCalled(); + }); it('should show error for numbers over 100', async () => { render( @@ -284,18 +286,18 @@ describe('ScaleDeploymentDialog', () => { onOpenChange={mockOnOpenChange} onScale={mockOnScale} /> - ) + ); - const input = screen.getByLabelText('Number of Replicas') - await user.clear(input) - await user.type(input, '101') + const input = screen.getByLabelText('Number of Replicas'); + await user.clear(input); + await user.type(input, '101'); - const scaleButton = screen.getByRole('button', { name: 'Scale' }) - await user.click(scaleButton) + const scaleButton = screen.getByRole('button', { name: 'Scale' }); + await user.click(scaleButton); - expect(screen.getByText('For safety, maximum replicas is limited to 100. Please contact admin for higher limits.')).toBeInTheDocument() - expect(mockOnScale).not.toHaveBeenCalled() - }) + expect(screen.getByText('For safety, maximum replicas is limited to 100. Please contact admin for higher limits.')).toBeInTheDocument(); + expect(mockOnScale).not.toHaveBeenCalled(); + }); it('should show warning for zero replicas', async () => { render( @@ -305,19 +307,19 @@ describe('ScaleDeploymentDialog', () => { onOpenChange={mockOnOpenChange} onScale={mockOnScale} /> - ) + ); - const input = screen.getByLabelText('Number of Replicas') - await user.clear(input) - await user.type(input, '0') + const input = screen.getByLabelText('Number of Replicas'); + await user.clear(input); + await user.type(input, '0'); - expect(screen.getByText('Setting replicas to 0 will stop all pods for this deployment.')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Setting replicas to 0 will stop all pods for this deployment.')).toBeInTheDocument(); + }); + }); describe('Loading States', () => { it('should show loading state when submitting', async () => { - mockOnScale.mockImplementation(() => new Promise(resolve => setTimeout(resolve, 100))) + mockOnScale.mockImplementation(() => new Promise(resolve => setTimeout(resolve, 100))); render( { onOpenChange={mockOnOpenChange} onScale={mockOnScale} /> - ) + ); - const input = screen.getByLabelText('Number of Replicas') - await user.clear(input) - await user.type(input, '5') + const input = screen.getByLabelText('Number of Replicas'); + await user.clear(input); + await user.type(input, '5'); - const scaleButton = screen.getByRole('button', { name: 'Scale' }) - await user.click(scaleButton) + const scaleButton = screen.getByRole('button', { name: 'Scale' }); + await user.click(scaleButton); - expect(screen.getByText('Scaling...')).toBeInTheDocument() - expect(scaleButton).toBeDisabled() - expect(screen.getByRole('button', { name: 'Cancel' })).toBeDisabled() - }) + expect(screen.getByText('Scaling...')).toBeInTheDocument(); + expect(scaleButton).toBeDisabled(); + expect(screen.getByRole('button', { name: 'Cancel' })).toBeDisabled(); + }); it('should disable submit button when input is empty', () => { render( @@ -348,20 +350,20 @@ describe('ScaleDeploymentDialog', () => { onOpenChange={mockOnOpenChange} onScale={mockOnScale} /> - ) + ); - const input = screen.getByLabelText('Number of Replicas') - expect(input).toHaveValue(3) + const input = screen.getByLabelText('Number of Replicas'); + expect(input).toHaveValue(3); - const scaleButton = screen.getByRole('button', { name: 'Scale' }) - expect(scaleButton).not.toBeDisabled() - }) - }) + const scaleButton = screen.getByRole('button', { name: 'Scale' }); + expect(scaleButton).not.toBeDisabled(); + }); + }); describe('Error Handling', () => { it('should show error when onScale fails', async () => { - const errorMessage = 'Failed to scale deployment' - mockOnScale.mockRejectedValue(new Error(errorMessage)) + const errorMessage = 'Failed to scale deployment'; + mockOnScale.mockRejectedValue(new Error(errorMessage)); render( { onOpenChange={mockOnOpenChange} onScale={mockOnScale} /> - ) + ); - const input = screen.getByLabelText('Number of Replicas') - await user.clear(input) - await user.type(input, '5') + const input = screen.getByLabelText('Number of Replicas'); + await user.clear(input); + await user.type(input, '5'); - const scaleButton = screen.getByRole('button', { name: 'Scale' }) - await user.click(scaleButton) + const scaleButton = screen.getByRole('button', { name: 'Scale' }); + await user.click(scaleButton); // Wait for error message to appear and ensure all async operations complete await waitFor(() => { - expect(screen.getByText(errorMessage)).toBeInTheDocument() - }) + expect(screen.getByText(errorMessage)).toBeInTheDocument(); + }); // Wait a bit more to ensure the error handling is completely finished await waitFor(() => { - expect(screen.getByRole('button', { name: 'Scale' })).not.toBeDisabled() - }) + expect(screen.getByRole('button', { name: 'Scale' })).not.toBeDisabled(); + }); // Verify that onOpenChange was not called (dialog should remain open) - expect(mockOnOpenChange).not.toHaveBeenCalled() - }) + expect(mockOnOpenChange).not.toHaveBeenCalled(); + }); it('should show generic error for non-Error exceptions', async () => { - mockOnScale.mockRejectedValue('String error') + mockOnScale.mockRejectedValue('String error'); render( { onOpenChange={mockOnOpenChange} onScale={mockOnScale} /> - ) + ); - const input = screen.getByLabelText('Number of Replicas') - await user.clear(input) - await user.type(input, '5') + const input = screen.getByLabelText('Number of Replicas'); + await user.clear(input); + await user.type(input, '5'); - const scaleButton = screen.getByRole('button', { name: 'Scale' }) - await user.click(scaleButton) + const scaleButton = screen.getByRole('button', { name: 'Scale' }); + await user.click(scaleButton); // Wait for error message to appear and ensure all async operations complete await waitFor(() => { - expect(screen.getByText('Failed to scale deployment')).toBeInTheDocument() - }) + expect(screen.getByText('Failed to scale deployment')).toBeInTheDocument(); + }); // Wait a bit more to ensure the error handling is completely finished await waitFor(() => { - expect(screen.getByRole('button', { name: 'Scale' })).not.toBeDisabled() - }) + expect(screen.getByRole('button', { name: 'Scale' })).not.toBeDisabled(); + }); // Verify that onOpenChange was not called (dialog should remain open) - expect(mockOnOpenChange).not.toHaveBeenCalled() - }) - }) + expect(mockOnOpenChange).not.toHaveBeenCalled(); + }); + }); describe('Accessibility', () => { it('should have proper labels and descriptions', () => { @@ -436,14 +438,14 @@ describe('ScaleDeploymentDialog', () => { onOpenChange={mockOnOpenChange} onScale={mockOnScale} /> - ) - - const input = screen.getByLabelText('Number of Replicas') - expect(input).toHaveAttribute('type', 'number') - expect(input).toHaveAttribute('min', '0') - expect(input).toHaveAttribute('max', '100') - expect(input).toHaveAttribute('placeholder', 'Enter number of replicas') - }) + ); + + const input = screen.getByLabelText('Number of Replicas'); + expect(input).toHaveAttribute('type', 'number'); + expect(input).toHaveAttribute('min', '0'); + expect(input).toHaveAttribute('max', '100'); + expect(input).toHaveAttribute('placeholder', 'Enter number of replicas'); + }); it('should be keyboard navigable', async () => { render( @@ -453,15 +455,15 @@ describe('ScaleDeploymentDialog', () => { onOpenChange={mockOnOpenChange} onScale={mockOnScale} /> - ) + ); - const input = screen.getByLabelText('Number of Replicas') - input.focus() + const input = screen.getByLabelText('Number of Replicas'); + input.focus(); - expect(document.activeElement).toBe(input) + expect(document.activeElement).toBe(input); - await user.keyboard('{Tab}') - expect(document.activeElement).not.toBe(input) - }) - }) -}) + await user.keyboard('{Tab}'); + expect(document.activeElement).not.toBe(input); + }); + }); +}); diff --git a/apps/ops-dashboard/__tests__/components/template-dialog.test.tsx b/apps/ops-dashboard/__tests__/components/template-dialog.test.tsx index e32ab79..91217ac 100644 --- a/apps/ops-dashboard/__tests__/components/template-dialog.test.tsx +++ b/apps/ops-dashboard/__tests__/components/template-dialog.test.tsx @@ -1,7 +1,8 @@ -import React from 'react' -import { render, screen, waitFor } from '@testing-library/react' -import userEvent from '@testing-library/user-event' -import { TemplateDialog } from '../../components/templates/template-dialog' +import { render, screen, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { TemplateDialog } from '../../components/templates/template-dialog'; // Mock the Kubernetes hooks jest.mock('../../k8s', () => ({ @@ -11,14 +12,14 @@ jest.mock('../../k8s', () => ({ useCreateCoreV1NamespacedService: () => ({ mutateAsync: jest.fn().mockResolvedValue({}) }) -})) +})); // Mock the namespace context jest.mock('../../contexts/NamespaceContext', () => ({ usePreferredNamespace: () => ({ namespace: 'default' }) -})) +})); const mockTemplate = { id: 'postgres', @@ -34,7 +35,7 @@ const mockTemplate = { POSTGRES_DB: 'postgres' } } -} +}; const mockTemplateWithoutEnv = { id: 'ollama', @@ -45,14 +46,14 @@ const mockTemplateWithoutEnv = { image: 'ollama/ollama:latest', ports: [11434] } -} +}; describe('TemplateDialog', () => { - const mockOnOpenChange = jest.fn() + const mockOnOpenChange = jest.fn(); beforeEach(() => { - jest.clearAllMocks() - }) + jest.clearAllMocks(); + }); describe('Basic Rendering', () => { it('should render dialog when open', () => { @@ -62,11 +63,11 @@ describe('TemplateDialog', () => { open={true} onOpenChange={mockOnOpenChange} /> - ) + ); - expect(screen.getByRole('dialog')).toBeInTheDocument() - expect(screen.getByRole('heading', { name: 'Deploy PostgreSQL' })).toBeInTheDocument() - }) + expect(screen.getByRole('dialog')).toBeInTheDocument(); + expect(screen.getByRole('heading', { name: 'Deploy PostgreSQL' })).toBeInTheDocument(); + }); it('should not render when closed', () => { render( @@ -75,10 +76,10 @@ describe('TemplateDialog', () => { open={false} onOpenChange={mockOnOpenChange} /> - ) + ); - expect(screen.queryByRole('dialog')).not.toBeInTheDocument() - }) + expect(screen.queryByRole('dialog')).not.toBeInTheDocument(); + }); it('should display template details', () => { render( @@ -87,12 +88,12 @@ describe('TemplateDialog', () => { open={true} onOpenChange={mockOnOpenChange} /> - ) + ); - expect(screen.getByText('Configure and deploy the PostgreSQL template to your Kubernetes cluster.')).toBeInTheDocument() - expect(screen.getByText('pyramation/pgvector:13.3-alpine')).toBeInTheDocument() - expect(screen.getByText('5432')).toBeInTheDocument() - }) + expect(screen.getByText('Configure and deploy the PostgreSQL template to your Kubernetes cluster.')).toBeInTheDocument(); + expect(screen.getByText('pyramation/pgvector:13.3-alpine')).toBeInTheDocument(); + expect(screen.getByText('5432')).toBeInTheDocument(); + }); it('should display environment variables when present', () => { render( @@ -101,12 +102,12 @@ describe('TemplateDialog', () => { open={true} onOpenChange={mockOnOpenChange} /> - ) + ); - expect(screen.getByText('POSTGRES_USER: postgres')).toBeInTheDocument() - expect(screen.getByText('POSTGRES_PASSWORD: ••••••••')).toBeInTheDocument() - expect(screen.getByText('POSTGRES_DB: postgres')).toBeInTheDocument() - }) + expect(screen.getByText('POSTGRES_USER: postgres')).toBeInTheDocument(); + expect(screen.getByText('POSTGRES_PASSWORD: ••••••••')).toBeInTheDocument(); + expect(screen.getByText('POSTGRES_DB: postgres')).toBeInTheDocument(); + }); it('should not display environment section when not present', () => { render( @@ -115,10 +116,10 @@ describe('TemplateDialog', () => { open={true} onOpenChange={mockOnOpenChange} /> - ) + ); - expect(screen.queryByText('Environment:')).not.toBeInTheDocument() - }) + expect(screen.queryByText('Environment:')).not.toBeInTheDocument(); + }); it('should initialize form with default values', () => { render( @@ -127,57 +128,57 @@ describe('TemplateDialog', () => { open={true} onOpenChange={mockOnOpenChange} /> - ) + ); - expect(screen.getByDisplayValue('postgres-deployment')).toBeInTheDocument() - expect(screen.getByDisplayValue('default')).toBeInTheDocument() - }) - }) + expect(screen.getByDisplayValue('postgres-deployment')).toBeInTheDocument(); + expect(screen.getByDisplayValue('default')).toBeInTheDocument(); + }); + }); describe('Form Interactions', () => { it('should update deployment name', async () => { - const user = userEvent.setup() + const user = userEvent.setup(); render( - ) + ); - const nameInput = screen.getByDisplayValue('postgres-deployment') - await user.clear(nameInput) - await user.type(nameInput, 'my-postgres') + const nameInput = screen.getByDisplayValue('postgres-deployment'); + await user.clear(nameInput); + await user.type(nameInput, 'my-postgres'); - expect(nameInput).toHaveValue('my-postgres') - }) + expect(nameInput).toHaveValue('my-postgres'); + }); it('should update namespace', async () => { - const user = userEvent.setup() + const user = userEvent.setup(); render( - ) + ); - const namespaceInput = screen.getByDisplayValue('default') - await user.clear(namespaceInput) - await user.type(namespaceInput, 'my-namespace') + const namespaceInput = screen.getByDisplayValue('default'); + await user.clear(namespaceInput); + await user.type(namespaceInput, 'my-namespace'); - expect(namespaceInput).toHaveValue('my-namespace') - }) - }) + expect(namespaceInput).toHaveValue('my-namespace'); + }); + }); describe('Deployment Process', () => { it('should show success message after deployment', async () => { - const user = userEvent.setup() - const { mutateAsync: createDeployment } = require('../../k8s').useCreateAppsV1NamespacedDeployment() - const { mutateAsync: createService } = require('../../k8s').useCreateCoreV1NamespacedService() + const user = userEvent.setup(); + const { mutateAsync: createDeployment } = require('../../k8s').useCreateAppsV1NamespacedDeployment(); + const { mutateAsync: createService } = require('../../k8s').useCreateCoreV1NamespacedService(); - createDeployment.mockResolvedValue({}) - createService.mockResolvedValue({}) + createDeployment.mockResolvedValue({}); + createService.mockResolvedValue({}); render( { open={true} onOpenChange={mockOnOpenChange} /> - ) + ); - const deployButton = screen.getByRole('button', { name: /deploy/i }) - await user.click(deployButton) + const deployButton = screen.getByRole('button', { name: /deploy/i }); + await user.click(deployButton); await waitFor(() => { - expect(screen.getByText('PostgreSQL deployed successfully!')).toBeInTheDocument() - }) - }) + expect(screen.getByText('PostgreSQL deployed successfully!')).toBeInTheDocument(); + }); + }); - }) + }); describe('Form Validation', () => { it('should disable deploy button when name is empty', async () => { - const user = userEvent.setup() + const user = userEvent.setup(); render( - ) + ); - const nameInput = screen.getByDisplayValue('postgres-deployment') - await user.clear(nameInput) + const nameInput = screen.getByDisplayValue('postgres-deployment'); + await user.clear(nameInput); - expect(screen.getByRole('button', { name: /deploy/i })).toBeDisabled() - }) + expect(screen.getByRole('button', { name: /deploy/i })).toBeDisabled(); + }); it('should disable deploy button when namespace is empty', async () => { - const user = userEvent.setup() + const user = userEvent.setup(); render( - ) + ); - const namespaceInput = screen.getByDisplayValue('default') - await user.clear(namespaceInput) + const namespaceInput = screen.getByDisplayValue('default'); + await user.clear(namespaceInput); - expect(screen.getByRole('button', { name: /deploy/i })).toBeDisabled() - }) - }) + expect(screen.getByRole('button', { name: /deploy/i })).toBeDisabled(); + }); + }); describe('Cancel Functionality', () => { it('should close dialog when cancel is clicked', async () => { - const user = userEvent.setup() + const user = userEvent.setup(); render( - ) + ); - const cancelButton = screen.getByRole('button', { name: /cancel/i }) - await user.click(cancelButton) + const cancelButton = screen.getByRole('button', { name: /cancel/i }); + await user.click(cancelButton); - expect(mockOnOpenChange).toHaveBeenCalledWith(false) - }) - }) + expect(mockOnOpenChange).toHaveBeenCalledWith(false); + }); + }); describe('Template-specific Behavior', () => { it('should render MinIO template correctly', () => { @@ -263,7 +264,7 @@ describe('TemplateDialog', () => { MINIO_ROOT_PASSWORD: 'password' } } - } + }; render( { open={true} onOpenChange={mockOnOpenChange} /> - ) + ); - expect(screen.getByRole('heading', { name: 'Deploy MinIO' })).toBeInTheDocument() - expect(screen.getByText('minio/minio:latest')).toBeInTheDocument() - expect(screen.getByText('9000')).toBeInTheDocument() - expect(screen.getByText('MINIO_ROOT_USER: admin')).toBeInTheDocument() - }) - }) + expect(screen.getByRole('heading', { name: 'Deploy MinIO' })).toBeInTheDocument(); + expect(screen.getByText('minio/minio:latest')).toBeInTheDocument(); + expect(screen.getByText('9000')).toBeInTheDocument(); + expect(screen.getByText('MINIO_ROOT_USER: admin')).toBeInTheDocument(); + }); + }); describe('Accessibility', () => { it('should have proper labels and roles', () => { @@ -288,39 +289,39 @@ describe('TemplateDialog', () => { open={true} onOpenChange={mockOnOpenChange} /> - ) + ); - expect(screen.getByRole('dialog')).toBeInTheDocument() - expect(screen.getByRole('heading', { name: 'Deploy PostgreSQL' })).toBeInTheDocument() - expect(screen.getByLabelText('Name')).toBeInTheDocument() - expect(screen.getByLabelText('Namespace')).toBeInTheDocument() - expect(screen.getByRole('button', { name: /cancel/i })).toBeInTheDocument() - expect(screen.getByRole('button', { name: /deploy/i })).toBeInTheDocument() - }) + expect(screen.getByRole('dialog')).toBeInTheDocument(); + expect(screen.getByRole('heading', { name: 'Deploy PostgreSQL' })).toBeInTheDocument(); + expect(screen.getByLabelText('Name')).toBeInTheDocument(); + expect(screen.getByLabelText('Namespace')).toBeInTheDocument(); + expect(screen.getByRole('button', { name: /cancel/i })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: /deploy/i })).toBeInTheDocument(); + }); it('should be keyboard navigable', async () => { - const user = userEvent.setup() + const user = userEvent.setup(); render( - ) + ); - const nameInput = screen.getByLabelText('Name') - nameInput.focus() + const nameInput = screen.getByLabelText('Name'); + nameInput.focus(); - expect(document.activeElement).toBe(nameInput) + expect(document.activeElement).toBe(nameInput); - await user.tab() - expect(document.activeElement).toBe(screen.getByLabelText('Namespace')) + await user.tab(); + expect(document.activeElement).toBe(screen.getByLabelText('Namespace')); - await user.tab() - expect(document.activeElement).toBe(screen.getByRole('button', { name: /cancel/i })) + await user.tab(); + expect(document.activeElement).toBe(screen.getByRole('button', { name: /cancel/i })); - await user.tab() - expect(document.activeElement).toBe(screen.getByRole('button', { name: /deploy/i })) - }) - }) -}) \ No newline at end of file + await user.tab(); + expect(document.activeElement).toBe(screen.getByRole('button', { name: /deploy/i })); + }); + }); +}); \ No newline at end of file diff --git a/apps/ops-dashboard/__tests__/components/templates.test.tsx b/apps/ops-dashboard/__tests__/components/templates.test.tsx index 064be7a..8bd7a5a 100644 --- a/apps/ops-dashboard/__tests__/components/templates.test.tsx +++ b/apps/ops-dashboard/__tests__/components/templates.test.tsx @@ -1,7 +1,8 @@ -import React from 'react' -import { render, screen, waitFor } from '../utils/test-utils' -import userEvent from '@testing-library/user-event' -import { TemplatesView } from '../../components/templates/templates' +import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { TemplatesView } from '../../components/templates/templates'; +import { render, screen, waitFor } from '../utils/test-utils'; // Mock the TemplateDialog component jest.mock('../../components/templates/template-dialog', () => ({ @@ -11,214 +12,214 @@ jest.mock('../../components/templates/template-dialog', () => ({ ) -})) +})); describe('TemplatesView', () => { beforeEach(() => { - jest.clearAllMocks() - }) + jest.clearAllMocks(); + }); describe('Basic Rendering', () => { it('should render templates view with header', () => { - render() + render(); - expect(screen.getByText('Application Templates')).toBeInTheDocument() - expect(screen.getByText(/Deploy pre-configured applications with a single click/)).toBeInTheDocument() - }) + expect(screen.getByText('Application Templates')).toBeInTheDocument(); + expect(screen.getByText(/Deploy pre-configured applications with a single click/)).toBeInTheDocument(); + }); it('should render all template cards', () => { - render() + render(); // Check for all three templates - expect(screen.getByText('PostgreSQL')).toBeInTheDocument() - expect(screen.getByText('MinIO')).toBeInTheDocument() - expect(screen.getByText('Ollama')).toBeInTheDocument() - }) + expect(screen.getByText('PostgreSQL')).toBeInTheDocument(); + expect(screen.getByText('MinIO')).toBeInTheDocument(); + expect(screen.getByText('Ollama')).toBeInTheDocument(); + }); it('should render template descriptions', () => { - render() + render(); - expect(screen.getByText('PostgreSQL database with pgvector extension for vector storage')).toBeInTheDocument() - expect(screen.getByText('High-performance object storage compatible with S3 API')).toBeInTheDocument() - expect(screen.getByText('Run large language models locally with a simple API')).toBeInTheDocument() - }) + expect(screen.getByText('PostgreSQL database with pgvector extension for vector storage')).toBeInTheDocument(); + expect(screen.getByText('High-performance object storage compatible with S3 API')).toBeInTheDocument(); + expect(screen.getByText('Run large language models locally with a simple API')).toBeInTheDocument(); + }); it('should render template details', () => { - render() + render(); // Check PostgreSQL details - expect(screen.getByText('pyramation/pgvector:13.3-alpine')).toBeInTheDocument() - expect(screen.getByText('5432')).toBeInTheDocument() + expect(screen.getByText('pyramation/pgvector:13.3-alpine')).toBeInTheDocument(); + expect(screen.getByText('5432')).toBeInTheDocument(); // Check MinIO details - expect(screen.getByText('minio/minio:latest')).toBeInTheDocument() - expect(screen.getByText('9000')).toBeInTheDocument() + expect(screen.getByText('minio/minio:latest')).toBeInTheDocument(); + expect(screen.getByText('9000')).toBeInTheDocument(); // Check Ollama details - expect(screen.getByText('ollama/ollama:latest')).toBeInTheDocument() - expect(screen.getByText('11434')).toBeInTheDocument() - }) + expect(screen.getByText('ollama/ollama:latest')).toBeInTheDocument(); + expect(screen.getByText('11434')).toBeInTheDocument(); + }); it('should render environment variables for templates that have them', () => { - render() + render(); // PostgreSQL environment variables - expect(screen.getByText('POSTGRES_USER: postgres')).toBeInTheDocument() - expect(screen.getByText('POSTGRES_PASSWORD: ••••••••')).toBeInTheDocument() - expect(screen.getByText('POSTGRES_DB: postgres')).toBeInTheDocument() + expect(screen.getByText('POSTGRES_USER: postgres')).toBeInTheDocument(); + expect(screen.getByText('POSTGRES_PASSWORD: ••••••••')).toBeInTheDocument(); + expect(screen.getByText('POSTGRES_DB: postgres')).toBeInTheDocument(); // MinIO environment variables - expect(screen.getByText('MINIO_ROOT_USER: minioadmin')).toBeInTheDocument() - expect(screen.getByText('MINIO_ROOT_PASSWORD: ••••••••')).toBeInTheDocument() - }) + expect(screen.getByText('MINIO_ROOT_USER: minioadmin')).toBeInTheDocument(); + expect(screen.getByText('MINIO_ROOT_PASSWORD: ••••••••')).toBeInTheDocument(); + }); it('should render deploy buttons for all templates', () => { - render() + render(); - expect(screen.getByRole('button', { name: 'Deploy PostgreSQL' })).toBeInTheDocument() - expect(screen.getByRole('button', { name: 'Deploy MinIO' })).toBeInTheDocument() - expect(screen.getByRole('button', { name: 'Deploy Ollama' })).toBeInTheDocument() - }) + expect(screen.getByRole('button', { name: 'Deploy PostgreSQL' })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: 'Deploy MinIO' })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: 'Deploy Ollama' })).toBeInTheDocument(); + }); it('should render template badges', () => { - render() + render(); - const badges = screen.getAllByText('Template') - expect(badges).toHaveLength(3) - }) - }) + const badges = screen.getAllByText('Template'); + expect(badges).toHaveLength(3); + }); + }); describe('User Interactions', () => { it('should open template dialog when deploy button is clicked', async () => { - const user = userEvent.setup() - render() + const user = userEvent.setup(); + render(); - const deployButton = screen.getByRole('button', { name: 'Deploy PostgreSQL' }) - await user.click(deployButton) + const deployButton = screen.getByRole('button', { name: 'Deploy PostgreSQL' }); + await user.click(deployButton); - expect(screen.getByTestId('template-dialog')).toBeInTheDocument() - expect(screen.getByTestId('template-dialog')).toHaveTextContent('Deploy PostgreSQL') - }) + expect(screen.getByTestId('template-dialog')).toBeInTheDocument(); + expect(screen.getByTestId('template-dialog')).toHaveTextContent('Deploy PostgreSQL'); + }); it('should open dialog for different templates', async () => { - const user = userEvent.setup() - render() + const user = userEvent.setup(); + render(); // Click MinIO deploy button - const minioButton = screen.getByRole('button', { name: 'Deploy MinIO' }) - await user.click(minioButton) + const minioButton = screen.getByRole('button', { name: 'Deploy MinIO' }); + await user.click(minioButton); - expect(screen.getByTestId('template-dialog')).toHaveTextContent('Deploy MinIO') + expect(screen.getByTestId('template-dialog')).toHaveTextContent('Deploy MinIO'); // Close dialog - const closeButton = screen.getByRole('button', { name: 'Close' }) - await user.click(closeButton) + const closeButton = screen.getByRole('button', { name: 'Close' }); + await user.click(closeButton); // Click Ollama deploy button - const ollamaButton = screen.getByRole('button', { name: 'Deploy Ollama' }) - await user.click(ollamaButton) + const ollamaButton = screen.getByRole('button', { name: 'Deploy Ollama' }); + await user.click(ollamaButton); - expect(screen.getByTestId('template-dialog')).toHaveTextContent('Deploy Ollama') - }) + expect(screen.getByTestId('template-dialog')).toHaveTextContent('Deploy Ollama'); + }); it('should close dialog when close button is clicked', async () => { - const user = userEvent.setup() - render() + const user = userEvent.setup(); + render(); // Open dialog - const deployButton = screen.getByRole('button', { name: 'Deploy PostgreSQL' }) - await user.click(deployButton) + const deployButton = screen.getByRole('button', { name: 'Deploy PostgreSQL' }); + await user.click(deployButton); - expect(screen.getByTestId('template-dialog')).toBeInTheDocument() + expect(screen.getByTestId('template-dialog')).toBeInTheDocument(); // Close dialog - const closeButton = screen.getByRole('button', { name: 'Close' }) - await user.click(closeButton) + const closeButton = screen.getByRole('button', { name: 'Close' }); + await user.click(closeButton); await waitFor(() => { - const dialog = screen.queryByTestId('template-dialog') - expect(dialog).toHaveAttribute('data-open', 'false') - }) - }) - }) + const dialog = screen.queryByTestId('template-dialog'); + expect(dialog).toHaveAttribute('data-open', 'false'); + }); + }); + }); describe('Template Data', () => { it('should display correct PostgreSQL template data', () => { - render() + render(); - const postgresCard = screen.getByText('PostgreSQL').closest('.hover\\:shadow-lg') - expect(postgresCard).toBeInTheDocument() + const postgresCard = screen.getByText('PostgreSQL').closest('.hover\\:shadow-lg'); + expect(postgresCard).toBeInTheDocument(); // Check image - expect(screen.getByText('pyramation/pgvector:13.3-alpine')).toBeInTheDocument() + expect(screen.getByText('pyramation/pgvector:13.3-alpine')).toBeInTheDocument(); // Check ports - expect(screen.getByText('5432')).toBeInTheDocument() + expect(screen.getByText('5432')).toBeInTheDocument(); // Check environment variables - expect(screen.getByText('POSTGRES_USER: postgres')).toBeInTheDocument() - expect(screen.getByText('POSTGRES_PASSWORD: ••••••••')).toBeInTheDocument() - expect(screen.getByText('POSTGRES_DB: postgres')).toBeInTheDocument() - }) + expect(screen.getByText('POSTGRES_USER: postgres')).toBeInTheDocument(); + expect(screen.getByText('POSTGRES_PASSWORD: ••••••••')).toBeInTheDocument(); + expect(screen.getByText('POSTGRES_DB: postgres')).toBeInTheDocument(); + }); it('should display correct MinIO template data', () => { - render() + render(); // Check image - expect(screen.getByText('minio/minio:latest')).toBeInTheDocument() + expect(screen.getByText('minio/minio:latest')).toBeInTheDocument(); // Check ports - expect(screen.getByText('9000')).toBeInTheDocument() + expect(screen.getByText('9000')).toBeInTheDocument(); // Check environment variables - expect(screen.getByText('MINIO_ROOT_USER: minioadmin')).toBeInTheDocument() - expect(screen.getByText('MINIO_ROOT_PASSWORD: ••••••••')).toBeInTheDocument() - }) + expect(screen.getByText('MINIO_ROOT_USER: minioadmin')).toBeInTheDocument(); + expect(screen.getByText('MINIO_ROOT_PASSWORD: ••••••••')).toBeInTheDocument(); + }); it('should display correct Ollama template data', () => { - render() + render(); // Check image - expect(screen.getByText('ollama/ollama:latest')).toBeInTheDocument() + expect(screen.getByText('ollama/ollama:latest')).toBeInTheDocument(); // Check ports - expect(screen.getByText('11434')).toBeInTheDocument() + expect(screen.getByText('11434')).toBeInTheDocument(); // Ollama should not have environment variables - check that there are only 2 "Environment Variables:" texts (PostgreSQL and MinIO) - const envVars = screen.queryAllByText('Environment Variables:') - expect(envVars).toHaveLength(2) // Only PostgreSQL and MinIO have them - }) - }) + const envVars = screen.queryAllByText('Environment Variables:'); + expect(envVars).toHaveLength(2); // Only PostgreSQL and MinIO have them + }); + }); describe('Accessibility', () => { it('should have proper button roles and labels', () => { - render() + render(); - expect(screen.getByRole('button', { name: 'Deploy PostgreSQL' })).toBeInTheDocument() - expect(screen.getByRole('button', { name: 'Deploy MinIO' })).toBeInTheDocument() - expect(screen.getByRole('button', { name: 'Deploy Ollama' })).toBeInTheDocument() - }) + expect(screen.getByRole('button', { name: 'Deploy PostgreSQL' })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: 'Deploy MinIO' })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: 'Deploy Ollama' })).toBeInTheDocument(); + }); it('should have proper heading structure', () => { - render() + render(); - expect(screen.getByRole('heading', { name: 'Application Templates' })).toBeInTheDocument() - }) + expect(screen.getByRole('heading', { name: 'Application Templates' })).toBeInTheDocument(); + }); it('should be keyboard navigable', async () => { - const user = userEvent.setup() - render() + const user = userEvent.setup(); + render(); - const firstButton = screen.getByRole('button', { name: 'Deploy PostgreSQL' }) - firstButton.focus() + const firstButton = screen.getByRole('button', { name: 'Deploy PostgreSQL' }); + firstButton.focus(); - expect(document.activeElement).toBe(firstButton) + expect(document.activeElement).toBe(firstButton); - await user.tab() - expect(document.activeElement).toBe(screen.getByRole('button', { name: 'Deploy MinIO' })) + await user.tab(); + expect(document.activeElement).toBe(screen.getByRole('button', { name: 'Deploy MinIO' })); - await user.tab() - expect(document.activeElement).toBe(screen.getByRole('button', { name: 'Deploy Ollama' })) - }) - }) -}) + await user.tab(); + expect(document.activeElement).toBe(screen.getByRole('button', { name: 'Deploy Ollama' })); + }); + }); +}); diff --git a/apps/ops-dashboard/__tests__/components/theme-toggle.test.tsx b/apps/ops-dashboard/__tests__/components/theme-toggle.test.tsx index d90655c..10d69b3 100644 --- a/apps/ops-dashboard/__tests__/components/theme-toggle.test.tsx +++ b/apps/ops-dashboard/__tests__/components/theme-toggle.test.tsx @@ -1,5 +1,6 @@ -import { render, screen, fireEvent, waitFor } from '@testing-library/react'; +import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; + import { ThemeToggle } from '../../components/ui/theme-toggle'; // Mock localStorage diff --git a/apps/ops-dashboard/__tests__/components/view-edit-deployment-dialog.test.tsx b/apps/ops-dashboard/__tests__/components/view-edit-deployment-dialog.test.tsx index ca99eb7..3b08771 100644 --- a/apps/ops-dashboard/__tests__/components/view-edit-deployment-dialog.test.tsx +++ b/apps/ops-dashboard/__tests__/components/view-edit-deployment-dialog.test.tsx @@ -1,8 +1,10 @@ -import React from 'react' -import { render, screen, waitFor, cleanup } from '../utils/test-utils' -import userEvent from '@testing-library/user-event' -import { ViewEditDeploymentDialog } from '@/components/view-edit-deployment-dialog' -import type { AppsV1Deployment as Deployment } from '@kubernetesjs/ops' +import type { AppsV1Deployment as Deployment } from '@kubernetesjs/ops'; +import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { ViewEditDeploymentDialog } from '@/components/view-edit-deployment-dialog'; + +import { cleanup,render, screen, waitFor } from '../utils/test-utils'; // Mock the YAMLEditor component jest.mock('../../components/yaml-editor', () => ({ @@ -21,13 +23,13 @@ jest.mock('../../components/yaml-editor', () => ({ placeholder="YAML content" /> ) -})) +})); // Mock js-yaml jest.mock('js-yaml', () => ({ dump: jest.fn((obj) => 'mocked yaml content'), load: jest.fn((yaml) => ({ apiVersion: 'apps/v1', kind: 'Deployment' })) -})) +})); // Mock the React Query hook jest.mock('../../k8s', () => ({ @@ -40,7 +42,7 @@ jest.mock('../../k8s', () => ({ isLoading: false, error: null })) -})) +})); const mockDeployment: Deployment = { metadata: { @@ -61,15 +63,15 @@ const mockDeployment: Deployment = { readyReplicas: 3, availableReplicas: 3 } -} +}; describe('ViewEditDeploymentDialog', () => { - const mockOnOpenChange = jest.fn() - const mockOnSubmit = jest.fn() + const mockOnOpenChange = jest.fn(); + const mockOnSubmit = jest.fn(); beforeEach(() => { - jest.clearAllMocks() - cleanup() + jest.clearAllMocks(); + cleanup(); // Reset fetch mock global.fetch = jest.fn(() => @@ -80,8 +82,8 @@ describe('ViewEditDeploymentDialog', () => { status: { readyReplicas: 3 } }), }) - ) as jest.Mock - }) + ) as jest.Mock; + }); describe('Basic Rendering', () => { it('should render dialog when open with deployment', () => { @@ -92,13 +94,13 @@ describe('ViewEditDeploymentDialog', () => { onOpenChange={mockOnOpenChange} mode="view" /> - ) + ); - expect(screen.getByText('View Deployment: test-deployment')).toBeInTheDocument() - expect(screen.getByText('Viewing deployment configuration in YAML format')).toBeInTheDocument() - expect(screen.getByRole('tab', { name: /view/i })).toBeInTheDocument() - expect(screen.getByRole('tab', { name: /edit/i })).toBeInTheDocument() - }) + expect(screen.getByText('View Deployment: test-deployment')).toBeInTheDocument(); + expect(screen.getByText('Viewing deployment configuration in YAML format')).toBeInTheDocument(); + expect(screen.getByRole('tab', { name: /view/i })).toBeInTheDocument(); + expect(screen.getByRole('tab', { name: /edit/i })).toBeInTheDocument(); + }); it('should not render dialog when closed', () => { render( @@ -108,10 +110,10 @@ describe('ViewEditDeploymentDialog', () => { onOpenChange={mockOnOpenChange} mode="view" /> - ) + ); - expect(screen.queryByText('View Deployment: test-deployment')).not.toBeInTheDocument() - }) + expect(screen.queryByText('View Deployment: test-deployment')).not.toBeInTheDocument(); + }); it('should not render when deployment is null', () => { render( @@ -121,10 +123,10 @@ describe('ViewEditDeploymentDialog', () => { onOpenChange={mockOnOpenChange} mode="view" /> - ) + ); - expect(screen.queryByText('View Deployment:')).not.toBeInTheDocument() - }) + expect(screen.queryByText('View Deployment:')).not.toBeInTheDocument(); + }); it('should show edit mode when initial mode is edit', () => { render( @@ -135,12 +137,12 @@ describe('ViewEditDeploymentDialog', () => { mode="edit" onSubmit={mockOnSubmit} /> - ) + ); - expect(screen.getByText('Edit Deployment: test-deployment')).toBeInTheDocument() - expect(screen.getByText('Edit deployment configuration using YAML')).toBeInTheDocument() - }) - }) + expect(screen.getByText('Edit Deployment: test-deployment')).toBeInTheDocument(); + expect(screen.getByText('Edit deployment configuration using YAML')).toBeInTheDocument(); + }); + }); describe('Data Loading', () => { it('should fetch deployment data when opened', async () => { @@ -151,21 +153,21 @@ describe('ViewEditDeploymentDialog', () => { onOpenChange={mockOnOpenChange} mode="view" /> - ) + ); await waitFor(() => { - expect(screen.getByTestId('yaml-editor')).toBeInTheDocument() - }) - }) + expect(screen.getByTestId('yaml-editor')).toBeInTheDocument(); + }); + }); it('should show loading state while fetching data', () => { // Mock loading state - const { useReadAppsV1NamespacedDeploymentQuery } = require('../../k8s') + const { useReadAppsV1NamespacedDeploymentQuery } = require('../../k8s'); useReadAppsV1NamespacedDeploymentQuery.mockReturnValue({ data: null, isLoading: true, error: null - }) + }); render( { onOpenChange={mockOnOpenChange} mode="view" /> - ) + ); - expect(screen.getByText('Loading deployment...')).toBeInTheDocument() - }) + expect(screen.getByText('Loading deployment...')).toBeInTheDocument(); + }); it('should show error when fetch fails', async () => { // Mock error state - const { useReadAppsV1NamespacedDeploymentQuery } = require('../../k8s') + const { useReadAppsV1NamespacedDeploymentQuery } = require('../../k8s'); useReadAppsV1NamespacedDeploymentQuery.mockReturnValue({ data: null, isLoading: false, error: new Error('Network error') - }) + }); render( { onOpenChange={mockOnOpenChange} mode="view" /> - ) + ); await waitFor(() => { - expect(screen.getByText('Failed to load deployment data')).toBeInTheDocument() - }) - }) - }) + expect(screen.getByText('Failed to load deployment data')).toBeInTheDocument(); + }); + }); + }); describe('Tab Switching', () => { it('should switch between view and edit tabs', async () => { - const user = userEvent.setup() + const user = userEvent.setup(); render( { mode="view" onSubmit={mockOnSubmit} /> - ) + ); await waitFor(() => { - expect(screen.getByTestId('yaml-editor')).toBeInTheDocument() - }) + expect(screen.getByTestId('yaml-editor')).toBeInTheDocument(); + }); // Switch to edit tab - const editTab = screen.getByRole('tab', { name: /edit/i }) - await user.click(editTab) + const editTab = screen.getByRole('tab', { name: /edit/i }); + await user.click(editTab); - expect(screen.getByText('Edit Deployment: test-deployment')).toBeInTheDocument() - expect(screen.getByText('Edit deployment configuration using YAML')).toBeInTheDocument() - }) + expect(screen.getByText('Edit Deployment: test-deployment')).toBeInTheDocument(); + expect(screen.getByText('Edit deployment configuration using YAML')).toBeInTheDocument(); + }); it('should show save button only in edit mode', async () => { - const user = userEvent.setup() + const user = userEvent.setup(); render( { mode="view" onSubmit={mockOnSubmit} /> - ) + ); await waitFor(() => { - expect(screen.getByTestId('yaml-editor')).toBeInTheDocument() - }) + expect(screen.getByTestId('yaml-editor')).toBeInTheDocument(); + }); // In view mode, no save button - expect(screen.queryByRole('button', { name: /save changes/i })).not.toBeInTheDocument() + expect(screen.queryByRole('button', { name: /save changes/i })).not.toBeInTheDocument(); // Switch to edit mode - const editTab = screen.getByRole('tab', { name: /edit/i }) - await user.click(editTab) + const editTab = screen.getByRole('tab', { name: /edit/i }); + await user.click(editTab); // Now save button should appear - expect(screen.getByRole('button', { name: /save changes/i })).toBeInTheDocument() - }) - }) + expect(screen.getByRole('button', { name: /save changes/i })).toBeInTheDocument(); + }); + }); describe('User Interactions', () => { it('should handle cancel button click', async () => { - const user = userEvent.setup() + const user = userEvent.setup(); render( { onOpenChange={mockOnOpenChange} mode="view" /> - ) + ); await waitFor(() => { - expect(screen.getByTestId('yaml-editor')).toBeInTheDocument() - }) + expect(screen.getByTestId('yaml-editor')).toBeInTheDocument(); + }); // Use getAllByRole to get all close buttons and click the first one - const cancelButtons = screen.getAllByRole('button', { name: /close/i }) - await user.click(cancelButtons[0]) + const cancelButtons = screen.getAllByRole('button', { name: /close/i }); + await user.click(cancelButtons[0]); - expect(mockOnOpenChange).toHaveBeenCalledWith(false) - }) + expect(mockOnOpenChange).toHaveBeenCalledWith(false); + }); it('should handle successful submission in edit mode', async () => { - const user = userEvent.setup() - mockOnSubmit.mockResolvedValue(undefined) + const user = userEvent.setup(); + mockOnSubmit.mockResolvedValue(undefined); render( { mode="edit" onSubmit={mockOnSubmit} /> - ) + ); // Wait for YAML editor to be rendered await waitFor(() => { - expect(screen.getByTestId('yaml-editor')).toBeInTheDocument() - }) + expect(screen.getByTestId('yaml-editor')).toBeInTheDocument(); + }); // Type some content in the YAML editor - const yamlEditor = screen.getByTestId('yaml-editor') - await user.type(yamlEditor, 'test yaml content') + const yamlEditor = screen.getByTestId('yaml-editor'); + await user.type(yamlEditor, 'test yaml content'); - const saveButton = screen.getByRole('button', { name: /save changes/i }) - await user.click(saveButton) + const saveButton = screen.getByRole('button', { name: /save changes/i }); + await user.click(saveButton); await waitFor(() => { - expect(mockOnSubmit).toHaveBeenCalledWith('test yaml content') - expect(mockOnOpenChange).toHaveBeenCalledWith(false) - }) - }) - }) + expect(mockOnSubmit).toHaveBeenCalledWith('test yaml content'); + expect(mockOnOpenChange).toHaveBeenCalledWith(false); + }); + }); + }); describe('YAML Editor Behavior', () => { it('should make YAML editor read-only in view mode', async () => { @@ -321,15 +323,15 @@ describe('ViewEditDeploymentDialog', () => { onOpenChange={mockOnOpenChange} mode="view" /> - ) + ); await waitFor(() => { - expect(screen.getByTestId('yaml-editor')).toBeInTheDocument() - }) + expect(screen.getByTestId('yaml-editor')).toBeInTheDocument(); + }); - const yamlEditor = screen.getByTestId('yaml-editor') - expect(yamlEditor).toHaveAttribute('readOnly') - }) + const yamlEditor = screen.getByTestId('yaml-editor'); + expect(yamlEditor).toHaveAttribute('readOnly'); + }); it('should make YAML editor editable in edit mode', async () => { render( @@ -340,18 +342,18 @@ describe('ViewEditDeploymentDialog', () => { mode="edit" onSubmit={mockOnSubmit} /> - ) + ); await waitFor(() => { - expect(screen.getByTestId('yaml-editor')).toBeInTheDocument() - }) + expect(screen.getByTestId('yaml-editor')).toBeInTheDocument(); + }); - const yamlEditor = screen.getByTestId('yaml-editor') - expect(yamlEditor).not.toHaveAttribute('readOnly') - }) + const yamlEditor = screen.getByTestId('yaml-editor'); + expect(yamlEditor).not.toHaveAttribute('readOnly'); + }); it('should handle YAML content changes in edit mode', async () => { - const user = userEvent.setup() + const user = userEvent.setup(); render( { mode="edit" onSubmit={mockOnSubmit} /> - ) + ); await waitFor(() => { - expect(screen.getByTestId('yaml-editor')).toBeInTheDocument() - }) + expect(screen.getByTestId('yaml-editor')).toBeInTheDocument(); + }); - const yamlEditor = screen.getByTestId('yaml-editor') + const yamlEditor = screen.getByTestId('yaml-editor'); // Clear the existing content and type new content - await user.clear(yamlEditor) - await user.type(yamlEditor, 'new yaml content') + await user.clear(yamlEditor); + await user.type(yamlEditor, 'new yaml content'); // The value should be updated through the onChange handler - expect(yamlEditor.value).toBe('new yaml content') - }) - }) -}) \ No newline at end of file + expect(yamlEditor.value).toBe('new yaml content'); + }); + }); +}); \ No newline at end of file diff --git a/apps/ops-dashboard/__tests__/components/yaml-editor.test.tsx b/apps/ops-dashboard/__tests__/components/yaml-editor.test.tsx index 68ab048..dd4613c 100644 --- a/apps/ops-dashboard/__tests__/components/yaml-editor.test.tsx +++ b/apps/ops-dashboard/__tests__/components/yaml-editor.test.tsx @@ -1,7 +1,9 @@ -import React from 'react' -import { render, screen, waitFor } from '../utils/test-utils' -import userEvent from '@testing-library/user-event' -import { YAMLEditor } from '@/components/yaml-editor' +import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { YAMLEditor } from '@/components/yaml-editor'; + +import { render, screen, waitFor } from '../utils/test-utils'; // Mock localStorage const mockLocalStorage = { @@ -9,104 +11,104 @@ const mockLocalStorage = { setItem: jest.fn(), removeItem: jest.fn(), clear: jest.fn(), -} +}; Object.defineProperty(window, 'localStorage', { value: mockLocalStorage, -}) +}); describe('YAMLEditor', () => { - const user = userEvent.setup() - const mockOnChange = jest.fn() + const user = userEvent.setup(); + const mockOnChange = jest.fn(); beforeEach(() => { - jest.clearAllMocks() - mockLocalStorage.getItem.mockReturnValue('light') - }) + jest.clearAllMocks(); + mockLocalStorage.getItem.mockReturnValue('light'); + }); describe('Basic Rendering', () => { it('should render YAML editor with initial value', () => { - const initialValue = 'apiVersion: v1\nkind: Pod' + const initialValue = 'apiVersion: v1\nkind: Pod'; - render() + render(); - const textarea = screen.getByRole('textbox') - expect(textarea).toBeInTheDocument() - expect(textarea).toHaveValue(initialValue) - }) + const textarea = screen.getByRole('textbox'); + expect(textarea).toBeInTheDocument(); + expect(textarea).toHaveValue(initialValue); + }); it('should render with custom height', () => { - render() + render(); - const container = screen.getByRole('textbox').closest('div') - expect(container).toHaveStyle({ height: '500px' }) - }) + const container = screen.getByRole('textbox').closest('div'); + expect(container).toHaveStyle({ height: '500px' }); + }); it('should render in read-only mode when specified', () => { - render() + render(); - const textarea = screen.getByRole('textbox') - expect(textarea).toHaveAttribute('readOnly') - expect(textarea).toHaveClass('cursor-not-allowed', 'opacity-90') - }) - }) + const textarea = screen.getByRole('textbox'); + expect(textarea).toHaveAttribute('readOnly'); + expect(textarea).toHaveClass('cursor-not-allowed', 'opacity-90'); + }); + }); describe('Theme Support', () => { it('should apply light theme by default', () => { - mockLocalStorage.getItem.mockReturnValue('light') + mockLocalStorage.getItem.mockReturnValue('light'); - render() + render(); - const textarea = screen.getByRole('textbox') - expect(textarea).toHaveClass('bg-white', 'text-slate-900') - }) + const textarea = screen.getByRole('textbox'); + expect(textarea).toHaveClass('bg-white', 'text-slate-900'); + }); it('should apply dark theme when localStorage has dark theme', () => { - mockLocalStorage.getItem.mockReturnValue('dark') + mockLocalStorage.getItem.mockReturnValue('dark'); - render() + render(); - const textarea = screen.getByRole('textbox') - expect(textarea).toHaveClass('bg-slate-900', 'text-slate-100') - }) + const textarea = screen.getByRole('textbox'); + expect(textarea).toHaveClass('bg-slate-900', 'text-slate-100'); + }); it('should listen for theme changes from localStorage', async () => { - mockLocalStorage.getItem.mockReturnValue('light') + mockLocalStorage.getItem.mockReturnValue('light'); - render() + render(); - const textarea = screen.getByRole('textbox') - expect(textarea).toHaveClass('bg-white', 'text-slate-900') + const textarea = screen.getByRole('textbox'); + expect(textarea).toHaveClass('bg-white', 'text-slate-900'); // Simulate theme change - mockLocalStorage.getItem.mockReturnValue('dark') - window.dispatchEvent(new StorageEvent('storage', { key: 'theme', newValue: 'dark' })) + mockLocalStorage.getItem.mockReturnValue('dark'); + window.dispatchEvent(new StorageEvent('storage', { key: 'theme', newValue: 'dark' })); await waitFor(() => { - expect(textarea).toHaveClass('bg-slate-900', 'text-slate-100') - }) - }) - }) + expect(textarea).toHaveClass('bg-slate-900', 'text-slate-100'); + }); + }); + }); describe('User Interactions', () => { it('should call onChange when user types', async () => { - render() + render(); - const textarea = screen.getByRole('textbox') - await user.type(textarea, 'test') + const textarea = screen.getByRole('textbox'); + await user.type(textarea, 'test'); // user.type triggers onChange for each character - expect(mockOnChange).toHaveBeenCalledTimes(4) // 't', 'e', 's', 't' - }) + expect(mockOnChange).toHaveBeenCalledTimes(4); // 't', 'e', 's', 't' + }); it('should not call onChange when in read-only mode', async () => { - render() + render(); - const textarea = screen.getByRole('textbox') - await user.type(textarea, 'new content') + const textarea = screen.getByRole('textbox'); + await user.type(textarea, 'new content'); - expect(mockOnChange).not.toHaveBeenCalled() - }) + expect(mockOnChange).not.toHaveBeenCalled(); + }); it('should handle complex YAML content', () => { const complexYaml = `apiVersion: v1 @@ -116,59 +118,59 @@ metadata: spec: containers: - name: nginx - image: nginx:latest` + image: nginx:latest`; - render() + render(); - const textarea = screen.getByRole('textbox') - expect(textarea).toHaveValue(complexYaml) - }) - }) + const textarea = screen.getByRole('textbox'); + expect(textarea).toHaveValue(complexYaml); + }); + }); describe('Accessibility', () => { it('should have proper textarea attributes', () => { - render() + render(); - const textarea = screen.getByRole('textbox') - expect(textarea).toHaveAttribute('spellCheck', 'false') - expect(textarea).toHaveClass('font-mono', 'text-sm') - }) + const textarea = screen.getByRole('textbox'); + expect(textarea).toHaveAttribute('spellCheck', 'false'); + expect(textarea).toHaveClass('font-mono', 'text-sm'); + }); it('should be keyboard navigable', async () => { - render() + render(); - const textarea = screen.getByRole('textbox') - textarea.focus() + const textarea = screen.getByRole('textbox'); + textarea.focus(); - expect(document.activeElement).toBe(textarea) + expect(document.activeElement).toBe(textarea); - await user.keyboard('{ArrowRight}') - expect(document.activeElement).toBe(textarea) - }) - }) + await user.keyboard('{ArrowRight}'); + expect(document.activeElement).toBe(textarea); + }); + }); describe('Edge Cases', () => { it('should handle empty value', () => { - render() + render(); - const textarea = screen.getByRole('textbox') - expect(textarea).toHaveValue('') - }) + const textarea = screen.getByRole('textbox'); + expect(textarea).toHaveValue(''); + }); it('should handle undefined onChange', () => { - render() + render(); - const textarea = screen.getByRole('textbox') - expect(textarea).toBeInTheDocument() - }) + const textarea = screen.getByRole('textbox'); + expect(textarea).toBeInTheDocument(); + }); it('should handle very long content', () => { - const longContent = 'a'.repeat(10000) + const longContent = 'a'.repeat(10000); - render() + render(); - const textarea = screen.getByRole('textbox') - expect(textarea).toHaveValue(longContent) - }) - }) -}) + const textarea = screen.getByRole('textbox'); + expect(textarea).toHaveValue(longContent); + }); + }); +}); diff --git a/apps/ops-dashboard/__tests__/e2e/setup.ts b/apps/ops-dashboard/__tests__/e2e/setup.ts index 2956b30..be61831 100644 --- a/apps/ops-dashboard/__tests__/e2e/setup.ts +++ b/apps/ops-dashboard/__tests__/e2e/setup.ts @@ -1,4 +1,4 @@ -import { test as setup, expect } from '@playwright/test'; +import { expect,test as setup } from '@playwright/test'; const authFile = 'playwright/.auth/user.json'; diff --git a/apps/ops-dashboard/__tests__/e2e/utils/deployment-helpers.ts b/apps/ops-dashboard/__tests__/e2e/utils/deployment-helpers.ts index a98d238..692521d 100644 --- a/apps/ops-dashboard/__tests__/e2e/utils/deployment-helpers.ts +++ b/apps/ops-dashboard/__tests__/e2e/utils/deployment-helpers.ts @@ -1,5 +1,5 @@ -import { Page, expect } from '@playwright/test'; -import { verifyPageLoadedSuccessfully } from './page-verification'; +import { expect,Page } from '@playwright/test'; + /** * Set namespace to a specific namespace using the namespace switcher @@ -112,8 +112,8 @@ function generateDeploymentYAML(name: string, config: DeploymentConfig): string const envVars = config.env || {}; const envYAML = Object.keys(envVars).length > 0 ? Object.entries(envVars) - .map(([key, value]) => ` - name: ${key}\n value: ${value}`) - .join('\n') + .map(([key, value]) => ` - name: ${key}\n value: ${value}`) + .join('\n') : ''; const envSection = envYAML ? `\n env:\n${envYAML}` : ''; diff --git a/apps/ops-dashboard/__tests__/e2e/utils/page-objects.ts b/apps/ops-dashboard/__tests__/e2e/utils/page-objects.ts index 2337295..33a70c4 100644 --- a/apps/ops-dashboard/__tests__/e2e/utils/page-objects.ts +++ b/apps/ops-dashboard/__tests__/e2e/utils/page-objects.ts @@ -1,4 +1,4 @@ -import { Page, Locator } from '@playwright/test'; +import {Page } from '@playwright/test'; /** * Base page object for common dashboard functionality diff --git a/apps/ops-dashboard/__tests__/e2e/utils/page-verification.ts b/apps/ops-dashboard/__tests__/e2e/utils/page-verification.ts index 41ba0c6..db186a7 100644 --- a/apps/ops-dashboard/__tests__/e2e/utils/page-verification.ts +++ b/apps/ops-dashboard/__tests__/e2e/utils/page-verification.ts @@ -1,4 +1,4 @@ -import { Page, expect } from '@playwright/test'; +import { expect,Page } from '@playwright/test'; /** * Page verification utilities for more reliable e2e testing diff --git a/apps/ops-dashboard/__tests__/e2e/utils/test-helpers.ts b/apps/ops-dashboard/__tests__/e2e/utils/test-helpers.ts index 604ca91..2c71a54 100644 --- a/apps/ops-dashboard/__tests__/e2e/utils/test-helpers.ts +++ b/apps/ops-dashboard/__tests__/e2e/utils/test-helpers.ts @@ -1,4 +1,4 @@ -import { Page, expect } from '@playwright/test'; +import { expect,Page } from '@playwright/test'; /** * Wait for the dashboard to be fully loaded diff --git a/apps/ops-dashboard/__tests__/e2e/utils/workflow-helpers.ts b/apps/ops-dashboard/__tests__/e2e/utils/workflow-helpers.ts index 96bc0df..53e27b5 100644 --- a/apps/ops-dashboard/__tests__/e2e/utils/workflow-helpers.ts +++ b/apps/ops-dashboard/__tests__/e2e/utils/workflow-helpers.ts @@ -1,6 +1,7 @@ -import { Page, expect } from '@playwright/test'; -import { verifyPageLoadedSuccessfully } from './page-verification'; import { InterwebClient } from '@kubernetesjs/ops'; +import { expect,Page } from '@playwright/test'; + +import { verifyPageLoadedSuccessfully } from './page-verification'; const interweb = new InterwebClient({ restEndpoint: 'http://127.0.0.1:8001', diff --git a/apps/ops-dashboard/__tests__/e2e/workflow-deployment-lifecycle.spec.ts b/apps/ops-dashboard/__tests__/e2e/workflow-deployment-lifecycle.spec.ts index f0ff8d7..518ab5d 100644 --- a/apps/ops-dashboard/__tests__/e2e/workflow-deployment-lifecycle.spec.ts +++ b/apps/ops-dashboard/__tests__/e2e/workflow-deployment-lifecycle.spec.ts @@ -1,19 +1,11 @@ -import { test, expect } from '@playwright/test'; +import { expect,test } from '@playwright/test'; + import { - setNamespaceTo, + cleanupResources, + verifyClusterState} from './utils/cluster-verification'; +import { createDeployment, - verifyDeploymentCreated, - testDeploymentUI, - deleteDeployment, - verifyDeploymentDeleted, - checkDeploymentPods -} from './utils/deployment-helpers'; -import { - verifyClusterState, - waitForDeploymentReady, - waitForPodReady, - cleanupResources -} from './utils/cluster-verification'; + setNamespaceTo} from './utils/deployment-helpers'; test.describe('Workflow 2: Deployment Lifecycle Management', () => { diff --git a/apps/ops-dashboard/__tests__/e2e/workflow-operator-database-focused.spec.ts b/apps/ops-dashboard/__tests__/e2e/workflow-operator-database-focused.spec.ts index c2b39b1..178e44c 100644 --- a/apps/ops-dashboard/__tests__/e2e/workflow-operator-database-focused.spec.ts +++ b/apps/ops-dashboard/__tests__/e2e/workflow-operator-database-focused.spec.ts @@ -1,9 +1,9 @@ -import { test, expect } from '@playwright/test'; +import { expect,test } from '@playwright/test'; test.describe('Workflow 1: Operator Installation & Database Management (Focused)', () => { test('Complete Operator Installation & Database Management Workflow', async ({ page }) => { - test.setTimeout(600000) + test.setTimeout(600000); // Step 1: Open dashboard and navigate to admin/operators await test.step('1. Navigate to admin/operators', async () => { await page.goto('/admin/operators'); diff --git a/apps/ops-dashboard/__tests__/hooks/use-breakpoint.test.ts b/apps/ops-dashboard/__tests__/hooks/use-breakpoint.test.ts index acefcc3..8755f99 100644 --- a/apps/ops-dashboard/__tests__/hooks/use-breakpoint.test.ts +++ b/apps/ops-dashboard/__tests__/hooks/use-breakpoint.test.ts @@ -1,4 +1,5 @@ import { renderHook } from '@testing-library/react'; + import { useBreakpoint } from '@/hooks/use-breakpoint'; // Mock the useMediaQuery hook diff --git a/apps/ops-dashboard/__tests__/hooks/use-cluster-status.test.tsx b/apps/ops-dashboard/__tests__/hooks/use-cluster-status.test.tsx index 1b86f99..e61b84a 100644 --- a/apps/ops-dashboard/__tests__/hooks/use-cluster-status.test.tsx +++ b/apps/ops-dashboard/__tests__/hooks/use-cluster-status.test.tsx @@ -1,7 +1,8 @@ -import { useClusterStatus } from '../../hooks/use-cluster-status' -import { server } from '../../__mocks__/server' -import { renderHook, waitFor } from '../utils/test-utils' -import { http, HttpResponse } from 'msw' +import { http, HttpResponse } from 'msw'; + +import { server } from '../../__mocks__/server'; +import { useClusterStatus } from '../../hooks/use-cluster-status'; +import { renderHook, waitFor } from '../utils/test-utils'; describe('useClusterStatus', () => { it('should fetch cluster status successfully', async () => { @@ -19,63 +20,63 @@ describe('useClusterStatus', () => { }, namespaces: 5, version: 'v1.28.0' - } + }; const handler = http.get('/api/cluster/status', () => { - return HttpResponse.json(mockClusterOverview) - }) + return HttpResponse.json(mockClusterOverview); + }); - server.use(handler) + server.use(handler); - const { result } = renderHook(() => useClusterStatus()) + const { result } = renderHook(() => useClusterStatus()); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).toEqual(mockClusterOverview) - expect(result.current.isLoading).toBe(false) - }) + expect(result.current.data).toEqual(mockClusterOverview); + expect(result.current.isLoading).toBe(false); + }); it('should handle API errors', async () => { const handler = http.get('/api/cluster/status', () => { - return HttpResponse.json({ error: 'Internal Server Error' }, { status: 500 }) - }) + return HttpResponse.json({ error: 'Internal Server Error' }, { status: 500 }); + }); - server.use(handler) + server.use(handler); - const { result } = renderHook(() => useClusterStatus()) + const { result } = renderHook(() => useClusterStatus()); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); it('should handle network errors', async () => { const handler = http.get('/api/cluster/status', () => { - return HttpResponse.error() - }) + return HttpResponse.error(); + }); - server.use(handler) + server.use(handler); - const { result } = renderHook(() => useClusterStatus()) + const { result } = renderHook(() => useClusterStatus()); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - }) + expect(result.current.error).toBeDefined(); + }); it('should have correct query configuration', () => { - const { result } = renderHook(() => useClusterStatus()) + const { result } = renderHook(() => useClusterStatus()); - expect(result.current.isLoading).toBe(true) - expect(result.current.data).toBeUndefined() - }) + expect(result.current.isLoading).toBe(true); + expect(result.current.data).toBeUndefined(); + }); it('should refetch on interval', async () => { const mockClusterOverview = { @@ -83,23 +84,23 @@ describe('useClusterStatus', () => { pods: { total: 15, running: 12, pending: 2, failed: 1 }, namespaces: 5, version: 'v1.28.0' - } + }; - let callCount = 0 + let callCount = 0; const handler = http.get('/api/cluster/status', () => { - callCount++ - return HttpResponse.json(mockClusterOverview) - }) + callCount++; + return HttpResponse.json(mockClusterOverview); + }); - server.use(handler) + server.use(handler); - const { result } = renderHook(() => useClusterStatus()) + const { result } = renderHook(() => useClusterStatus()); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); // Wait for potential refetch (this test mainly verifies the configuration) - expect(callCount).toBeGreaterThanOrEqual(1) - }) -}) + expect(callCount).toBeGreaterThanOrEqual(1); + }); +}); diff --git a/apps/ops-dashboard/__tests__/hooks/use-copy-to-clipboard.test.ts b/apps/ops-dashboard/__tests__/hooks/use-copy-to-clipboard.test.ts index 73d76b5..969cd03 100644 --- a/apps/ops-dashboard/__tests__/hooks/use-copy-to-clipboard.test.ts +++ b/apps/ops-dashboard/__tests__/hooks/use-copy-to-clipboard.test.ts @@ -1,129 +1,130 @@ -import { renderHook, act } from '@testing-library/react' -import { useCopyToClipboard } from '../../hooks/use-copy-to-clipboard' +import { act,renderHook } from '@testing-library/react'; + +import { useCopyToClipboard } from '../../hooks/use-copy-to-clipboard'; describe('useCopyToClipboard', () => { - let mockWriteText: jest.Mock + let mockWriteText: jest.Mock; beforeEach(() => { - jest.useFakeTimers() - mockWriteText = jest.fn() + jest.useFakeTimers(); + mockWriteText = jest.fn(); Object.assign(navigator, { clipboard: { writeText: mockWriteText, }, - }) - }) + }); + }); afterEach(() => { - jest.useRealTimers() - jest.clearAllMocks() - }) + jest.useRealTimers(); + jest.clearAllMocks(); + }); it('should initialize with false isCopied state', () => { - const { result } = renderHook(() => useCopyToClipboard()) + const { result } = renderHook(() => useCopyToClipboard()); - expect(typeof result.current[0]).toBe('function') - expect(result.current[1]).toBe(false) - }) + expect(typeof result.current[0]).toBe('function'); + expect(result.current[1]).toBe(false); + }); it('should copy text to clipboard successfully', async () => { - mockWriteText.mockResolvedValueOnce(undefined) + mockWriteText.mockResolvedValueOnce(undefined); - const { result } = renderHook(() => useCopyToClipboard()) - const [copyToClipboard] = result.current + const { result } = renderHook(() => useCopyToClipboard()); + const [copyToClipboard] = result.current; - let copyResult: boolean + let copyResult: boolean; await act(async () => { - copyResult = await copyToClipboard('test text') - }) + copyResult = await copyToClipboard('test text'); + }); - expect(mockWriteText).toHaveBeenCalledWith('test text') - expect(copyResult!).toBe(true) - expect(result.current[1]).toBe(true) - }) + expect(mockWriteText).toHaveBeenCalledWith('test text'); + expect(copyResult!).toBe(true); + expect(result.current[1]).toBe(true); + }); it('should reset isCopied state after timeout', async () => { - mockWriteText.mockResolvedValueOnce(undefined) + mockWriteText.mockResolvedValueOnce(undefined); - const { result } = renderHook(() => useCopyToClipboard()) - const [copyToClipboard] = result.current + const { result } = renderHook(() => useCopyToClipboard()); + const [copyToClipboard] = result.current; await act(async () => { - await copyToClipboard('test text') - }) + await copyToClipboard('test text'); + }); - expect(result.current[1]).toBe(true) + expect(result.current[1]).toBe(true); act(() => { - jest.advanceTimersByTime(800) - }) + jest.advanceTimersByTime(800); + }); - expect(result.current[1]).toBe(false) - }) + expect(result.current[1]).toBe(false); + }); it('should handle clipboard write failure', async () => { - const error = new Error('Clipboard write failed') - mockWriteText.mockRejectedValueOnce(error) + const error = new Error('Clipboard write failed'); + mockWriteText.mockRejectedValueOnce(error); - const { result } = renderHook(() => useCopyToClipboard()) - const [copyToClipboard] = result.current + const { result } = renderHook(() => useCopyToClipboard()); + const [copyToClipboard] = result.current; - let copyResult: boolean + let copyResult: boolean; await act(async () => { - copyResult = await copyToClipboard('test text') - }) + copyResult = await copyToClipboard('test text'); + }); - expect(mockWriteText).toHaveBeenCalledWith('test text') - expect(copyResult!).toBe(false) - expect(result.current[1]).toBe(false) - }) + expect(mockWriteText).toHaveBeenCalledWith('test text'); + expect(copyResult!).toBe(false); + expect(result.current[1]).toBe(false); + }); it('should handle when clipboard API is not available', async () => { Object.assign(navigator, { clipboard: undefined, - }) + }); - const { result } = renderHook(() => useCopyToClipboard()) - const [copyToClipboard] = result.current + const { result } = renderHook(() => useCopyToClipboard()); + const [copyToClipboard] = result.current; - let copyResult: boolean + let copyResult: boolean; await act(async () => { - copyResult = await copyToClipboard('test text') - }) + copyResult = await copyToClipboard('test text'); + }); - expect(copyResult!).toBe(false) - expect(result.current[1]).toBe(false) - }) + expect(copyResult!).toBe(false); + expect(result.current[1]).toBe(false); + }); it('should handle empty string', async () => { - mockWriteText.mockResolvedValueOnce(undefined) + mockWriteText.mockResolvedValueOnce(undefined); - const { result } = renderHook(() => useCopyToClipboard()) - const [copyToClipboard] = result.current + const { result } = renderHook(() => useCopyToClipboard()); + const [copyToClipboard] = result.current; - let copyResult: boolean + let copyResult: boolean; await act(async () => { - copyResult = await copyToClipboard('') - }) + copyResult = await copyToClipboard(''); + }); - expect(mockWriteText).toHaveBeenCalledWith('') - expect(copyResult!).toBe(true) - expect(result.current[1]).toBe(true) - }) + expect(mockWriteText).toHaveBeenCalledWith(''); + expect(copyResult!).toBe(true); + expect(result.current[1]).toBe(true); + }); it('should handle multiple rapid copies', async () => { - mockWriteText.mockResolvedValue(undefined) + mockWriteText.mockResolvedValue(undefined); - const { result } = renderHook(() => useCopyToClipboard()) - const [copyToClipboard] = result.current + const { result } = renderHook(() => useCopyToClipboard()); + const [copyToClipboard] = result.current; await act(async () => { - await copyToClipboard('first text') - await copyToClipboard('second text') - }) - - expect(mockWriteText).toHaveBeenCalledTimes(2) - expect(result.current[1]).toBe(true) - }) -}) + await copyToClipboard('first text'); + await copyToClipboard('second text'); + }); + + expect(mockWriteText).toHaveBeenCalledTimes(2); + expect(result.current[1]).toBe(true); + }); +}); diff --git a/apps/ops-dashboard/__tests__/hooks/use-database-status.test.tsx b/apps/ops-dashboard/__tests__/hooks/use-database-status.test.tsx index 66ff5b6..5800d86 100644 --- a/apps/ops-dashboard/__tests__/hooks/use-database-status.test.tsx +++ b/apps/ops-dashboard/__tests__/hooks/use-database-status.test.tsx @@ -1,13 +1,12 @@ -import { useDatabaseStatus, type DatabaseStatusSummary, type DatabaseInstanceRow } from '../../hooks/use-database-status' -import { server } from '../../__mocks__/server' -import { renderHook, waitFor } from '../utils/test-utils' -import { http, HttpResponse } from 'msw' +import { http, HttpResponse } from 'msw'; + import { createDatabaseStatus, createDatabaseStatusError, - createDatabaseStatusNetworkError, - createDatabaseStatusData -} from '../../__mocks__/handlers/databases' + createDatabaseStatusNetworkError} from '../../__mocks__/handlers/databases'; +import { server } from '../../__mocks__/server'; +import {type DatabaseStatusSummary, useDatabaseStatus } from '../../hooks/use-database-status'; +import { renderHook, waitFor } from '../utils/test-utils'; describe('useDatabaseStatus', () => { const mockDatabaseStatus: DatabaseStatusSummary = { @@ -67,58 +66,58 @@ describe('useDatabaseStatus', () => { restarts: 1 } ] - } + }; it('should fetch database status successfully', async () => { - server.use(createDatabaseStatus(mockDatabaseStatus)) + server.use(createDatabaseStatus(mockDatabaseStatus)); - const { result } = renderHook(() => useDatabaseStatus('default', 'postgres-cluster')) + const { result } = renderHook(() => useDatabaseStatus('default', 'postgres-cluster')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).toEqual(mockDatabaseStatus) - expect(result.current.isLoading).toBe(false) - }) + expect(result.current.data).toEqual(mockDatabaseStatus); + expect(result.current.isLoading).toBe(false); + }); it('should handle API errors', async () => { - server.use(createDatabaseStatusError(404, 'Database not found')) + server.use(createDatabaseStatusError(404, 'Database not found')); - const { result } = renderHook(() => useDatabaseStatus('default', 'non-existent')) + const { result } = renderHook(() => useDatabaseStatus('default', 'non-existent')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); it('should handle network errors', async () => { - server.use(createDatabaseStatusNetworkError()) + server.use(createDatabaseStatusNetworkError()); - const { result } = renderHook(() => useDatabaseStatus('default', 'postgres-cluster')) + const { result } = renderHook(() => useDatabaseStatus('default', 'postgres-cluster')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - }) + expect(result.current.error).toBeDefined(); + }); it('should have correct query configuration with namespace and name', async () => { - server.use(createDatabaseStatus(mockDatabaseStatus)) + server.use(createDatabaseStatus(mockDatabaseStatus)); - const { result } = renderHook(() => useDatabaseStatus('production', 'mysql-cluster')) + const { result } = renderHook(() => useDatabaseStatus('production', 'mysql-cluster')); - expect(result.current.isLoading).toBe(true) - expect(result.current.data).toBeUndefined() + expect(result.current.isLoading).toBe(true); + expect(result.current.data).toBeUndefined(); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) - }) + expect(result.current.isSuccess).toBe(true); + }); + }); it('should handle different database statuses', async () => { const differentStatus: DatabaseStatusSummary = { @@ -138,20 +137,20 @@ describe('useDatabaseStatus', () => { restarts: 3 } ] - } + }; - server.use(createDatabaseStatus(differentStatus)) + server.use(createDatabaseStatus(differentStatus)); - const { result } = renderHook(() => useDatabaseStatus('staging', 'mysql-cluster')) + const { result } = renderHook(() => useDatabaseStatus('staging', 'mysql-cluster')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.phase).toBe('Pending') - expect(result.current.data?.readyInstances).toBe(0) - expect(result.current.data?.instancesTable[0].status).toBe('NotReady') - }) + expect(result.current.data?.phase).toBe('Pending'); + expect(result.current.data?.readyInstances).toBe(0); + expect(result.current.data?.instancesTable[0].status).toBe('NotReady'); + }); it('should handle database with no backups configured', async () => { const noBackupsStatus: DatabaseStatusSummary = { @@ -160,19 +159,19 @@ describe('useDatabaseStatus', () => { configured: false, scheduledCount: 0 } - } + }; - server.use(createDatabaseStatus(noBackupsStatus)) + server.use(createDatabaseStatus(noBackupsStatus)); - const { result } = renderHook(() => useDatabaseStatus('default', 'postgres-cluster')) + const { result } = renderHook(() => useDatabaseStatus('default', 'postgres-cluster')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.backups.configured).toBe(false) - expect(result.current.data?.backups.scheduledCount).toBe(0) - }) + expect(result.current.data?.backups.configured).toBe(false); + expect(result.current.data?.backups.scheduledCount).toBe(0); + }); it('should handle database with no streaming configured', async () => { const noStreamingStatus: DatabaseStatusSummary = { @@ -181,36 +180,36 @@ describe('useDatabaseStatus', () => { configured: false, replicas: 0 } - } + }; - server.use(createDatabaseStatus(noStreamingStatus)) + server.use(createDatabaseStatus(noStreamingStatus)); - const { result } = renderHook(() => useDatabaseStatus('default', 'postgres-cluster')) + const { result } = renderHook(() => useDatabaseStatus('default', 'postgres-cluster')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.streaming.configured).toBe(false) - expect(result.current.data?.streaming.replicas).toBe(0) - }) + expect(result.current.data?.streaming.configured).toBe(false); + expect(result.current.data?.streaming.replicas).toBe(0); + }); it('should refetch on interval', async () => { - let callCount = 0 + let callCount = 0; const handler = http.get('/api/databases/:namespace/:name/status', () => { - callCount++ - return HttpResponse.json(mockDatabaseStatus) - }) + callCount++; + return HttpResponse.json(mockDatabaseStatus); + }); - server.use(handler) + server.use(handler); - const { result } = renderHook(() => useDatabaseStatus('default', 'postgres-cluster')) + const { result } = renderHook(() => useDatabaseStatus('default', 'postgres-cluster')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); // Wait for potential refetch (this test mainly verifies the configuration) - expect(callCount).toBeGreaterThanOrEqual(1) - }) -}) + expect(callCount).toBeGreaterThanOrEqual(1); + }); +}); diff --git a/apps/ops-dashboard/__tests__/hooks/use-google-analytics.test.tsx b/apps/ops-dashboard/__tests__/hooks/use-google-analytics.test.tsx index 7e11db1..4bcfde1 100644 --- a/apps/ops-dashboard/__tests__/hooks/use-google-analytics.test.tsx +++ b/apps/ops-dashboard/__tests__/hooks/use-google-analytics.test.tsx @@ -4,43 +4,44 @@ jest.mock('../../lib/constants', () => ({ COOKIE_NAME: 'analytics-consent', GA_ID: 'GA-123456789' } -})) +})); jest.mock('../../lib/utils', () => ({ getCookie: jest.fn() -})) +})); -import { useGoogleAnalytics } from '../../hooks/use-google-analytics' -import { renderHook, act } from '@testing-library/react' -import { getCookie } from '../../lib/utils' +import { act,renderHook } from '@testing-library/react'; + +import { useGoogleAnalytics } from '../../hooks/use-google-analytics'; +import { getCookie } from '../../lib/utils'; // Get the mocked function -const mockGetCookie = getCookie as jest.MockedFunction +const mockGetCookie = getCookie as jest.MockedFunction; describe('useGoogleAnalytics', () => { - const mockGtag = jest.fn() + const mockGtag = jest.fn(); beforeEach(() => { // Reset mocks - jest.clearAllMocks() - mockGetCookie.mockReturnValue('true') + jest.clearAllMocks(); + mockGetCookie.mockReturnValue('true'); // Mock window.gtag Object.defineProperty(window, 'gtag', { value: mockGtag, writable: true, configurable: true - }) - }) + }); + }); afterEach(() => { - delete (window as any).gtag - }) + delete (window as any).gtag; + }); it('should track event when GA is enabled and consent is given', () => { - mockGetCookie.mockReturnValue('true') + mockGetCookie.mockReturnValue('true'); - const { result } = renderHook(() => useGoogleAnalytics()) + const { result } = renderHook(() => useGoogleAnalytics()); act(() => { result.current.trackEvent({ @@ -48,94 +49,94 @@ describe('useGoogleAnalytics', () => { category: 'button', label: 'submit', value: 1 - }) - }) + }); + }); - expect(mockGtag).toHaveBeenCalled() - expect(mockGtag).toHaveBeenCalledWith('event', 'click', expect.any(Object)) - }) + expect(mockGtag).toHaveBeenCalled(); + expect(mockGtag).toHaveBeenCalledWith('event', 'click', expect.any(Object)); + }); it('should not track event when consent is not given', () => { - mockGetCookie.mockReturnValue('false') + mockGetCookie.mockReturnValue('false'); - const { result } = renderHook(() => useGoogleAnalytics()) + const { result } = renderHook(() => useGoogleAnalytics()); act(() => { result.current.trackEvent({ action: 'click', category: 'button' - }) - }) + }); + }); - expect(mockGtag).not.toHaveBeenCalled() - }) + expect(mockGtag).not.toHaveBeenCalled(); + }); it('should not track event when GA ID is not available', () => { // This test is covered by the main mock setup // The GA_ID is already set to 'GA-123456789' in the main mock // We can't easily change it mid-test, so we'll skip this test // or test the behavior differently - expect(true).toBe(true) // Placeholder test - }) + expect(true).toBe(true); // Placeholder test + }); it('should not track event when window.gtag is not available', () => { - mockGetCookie.mockReturnValue('true') + mockGetCookie.mockReturnValue('true'); // Remove window.gtag - delete (window as any).gtag + delete (window as any).gtag; - const { result } = renderHook(() => useGoogleAnalytics()) + const { result } = renderHook(() => useGoogleAnalytics()); act(() => { result.current.trackEvent({ action: 'click', category: 'button' - }) - }) + }); + }); - expect(mockGtag).not.toHaveBeenCalled() - }) + expect(mockGtag).not.toHaveBeenCalled(); + }); it('should not track event when window.gtag is not a function', () => { - mockGetCookie.mockReturnValue('true') + mockGetCookie.mockReturnValue('true'); // Set window.gtag to non-function Object.defineProperty(window, 'gtag', { value: 'not-a-function', writable: true - }) + }); - const { result } = renderHook(() => useGoogleAnalytics()) + const { result } = renderHook(() => useGoogleAnalytics()); act(() => { result.current.trackEvent({ action: 'click', category: 'button' - }) - }) + }); + }); - expect(mockGtag).not.toHaveBeenCalled() - }) + expect(mockGtag).not.toHaveBeenCalled(); + }); it('should handle events with minimal options', () => { - mockGetCookie.mockReturnValue('true') + mockGetCookie.mockReturnValue('true'); - const { result } = renderHook(() => useGoogleAnalytics()) + const { result } = renderHook(() => useGoogleAnalytics()); act(() => { result.current.trackEvent({ action: 'page_view' - }) - }) + }); + }); - expect(mockGtag).toHaveBeenCalled() - expect(mockGtag).toHaveBeenCalledWith('event', 'page_view', expect.any(Object)) - }) + expect(mockGtag).toHaveBeenCalled(); + expect(mockGtag).toHaveBeenCalledWith('event', 'page_view', expect.any(Object)); + }); it('should handle events with custom properties', () => { - mockGetCookie.mockReturnValue('true') + mockGetCookie.mockReturnValue('true'); - const { result } = renderHook(() => useGoogleAnalytics()) + const { result } = renderHook(() => useGoogleAnalytics()); act(() => { result.current.trackEvent({ @@ -145,31 +146,31 @@ describe('useGoogleAnalytics', () => { value: 99.99, custom_property: 'custom_value', another_property: 42 - }) - }) + }); + }); - expect(mockGtag).toHaveBeenCalled() - expect(mockGtag).toHaveBeenCalledWith('event', 'purchase', expect.any(Object)) - }) + expect(mockGtag).toHaveBeenCalled(); + expect(mockGtag).toHaveBeenCalledWith('event', 'purchase', expect.any(Object)); + }); it('should handle SSR environment (window is undefined)', () => { // This test verifies that the hook handles SSR correctly // The actual SSR behavior is tested by the hook's implementation // which checks `typeof window !== 'undefined'` - expect(true).toBe(true) // Placeholder test - }) + expect(true).toBe(true); // Placeholder test + }); it('should return stable trackEvent function reference', () => { - mockGetCookie.mockReturnValue('true') + mockGetCookie.mockReturnValue('true'); - const { result, rerender } = renderHook(() => useGoogleAnalytics()) + const { result, rerender } = renderHook(() => useGoogleAnalytics()); - const firstTrackEvent = result.current.trackEvent + const firstTrackEvent = result.current.trackEvent; - rerender() + rerender(); - const secondTrackEvent = result.current.trackEvent + const secondTrackEvent = result.current.trackEvent; - expect(firstTrackEvent).toBe(secondTrackEvent) - }) -}) + expect(firstTrackEvent).toBe(secondTrackEvent); + }); +}); diff --git a/apps/ops-dashboard/__tests__/hooks/use-image-cache.test.tsx b/apps/ops-dashboard/__tests__/hooks/use-image-cache.test.tsx index 633e0cd..4ab7c90 100644 --- a/apps/ops-dashboard/__tests__/hooks/use-image-cache.test.tsx +++ b/apps/ops-dashboard/__tests__/hooks/use-image-cache.test.tsx @@ -1,5 +1,5 @@ -import { useImageCache } from '../../hooks/use-image-cache' -import { renderHook, act } from '../utils/test-utils' +import { useImageCache } from '../../hooks/use-image-cache'; +import { act,renderHook } from '../utils/test-utils'; // Mock Image constructor const mockImage = { @@ -8,221 +8,221 @@ const mockImage = { src: '', addEventListener: jest.fn(), removeEventListener: jest.fn() -} +}; // Mock global Image Object.defineProperty(global, 'Image', { value: jest.fn(() => mockImage), writable: true -}) +}); describe('useImageCache', () => { beforeEach(() => { - jest.clearAllMocks() + jest.clearAllMocks(); // Reset the mock image - mockImage.onload = null - mockImage.onerror = null - mockImage.src = '' - }) + mockImage.onload = null; + mockImage.onerror = null; + mockImage.src = ''; + }); it('should initialize with cached image', () => { - const src = 'https://example.com/image.jpg' + const src = 'https://example.com/image.jpg'; // Pre-populate the cache by creating a hook instance first - const { result: firstResult } = renderHook(() => useImageCache(src)) + const { result: firstResult } = renderHook(() => useImageCache(src)); // Simulate successful load to populate cache act(() => { if (mockImage.onload) { - mockImage.onload() + mockImage.onload(); } - }) + }); - expect(firstResult.current.isLoaded).toBe(true) + expect(firstResult.current.isLoaded).toBe(true); // Now test with a new instance - it should use the cache - const { result } = renderHook(() => useImageCache(src)) - expect(result.current.isLoaded).toBe(true) - expect(result.current.hasError).toBe(false) - expect(result.current.imgSrc).toBe(src) - }) + const { result } = renderHook(() => useImageCache(src)); + expect(result.current.isLoaded).toBe(true); + expect(result.current.hasError).toBe(false); + expect(result.current.imgSrc).toBe(src); + }); it('should initialize with loading state for new image', () => { - const src = 'https://example.com/new-image.jpg' + const src = 'https://example.com/new-image.jpg'; - const { result } = renderHook(() => useImageCache(src)) + const { result } = renderHook(() => useImageCache(src)); - expect(result.current.isLoaded).toBe(false) - expect(result.current.hasError).toBe(false) - expect(result.current.imgSrc).toBe(src) - }) + expect(result.current.isLoaded).toBe(false); + expect(result.current.hasError).toBe(false); + expect(result.current.imgSrc).toBe(src); + }); it('should handle successful image load', async () => { - const src = 'https://example.com/success-image.jpg' + const src = 'https://example.com/success-image.jpg'; - const { result } = renderHook(() => useImageCache(src)) + const { result } = renderHook(() => useImageCache(src)); - expect(result.current.isLoaded).toBe(false) + expect(result.current.isLoaded).toBe(false); // Simulate successful load act(() => { if (mockImage.onload) { - mockImage.onload() + mockImage.onload(); } - }) + }); - expect(result.current.isLoaded).toBe(true) - expect(result.current.hasError).toBe(false) - }) + expect(result.current.isLoaded).toBe(true); + expect(result.current.hasError).toBe(false); + }); it('should handle image load error', async () => { - const src = 'https://example.com/error-image.jpg' + const src = 'https://example.com/error-image.jpg'; - const { result } = renderHook(() => useImageCache(src)) + const { result } = renderHook(() => useImageCache(src)); - expect(result.current.hasError).toBe(false) + expect(result.current.hasError).toBe(false); // Simulate load error act(() => { if (mockImage.onerror) { - mockImage.onerror() + mockImage.onerror(); } - }) + }); - expect(result.current.isLoaded).toBe(false) - expect(result.current.hasError).toBe(true) - }) + expect(result.current.isLoaded).toBe(false); + expect(result.current.hasError).toBe(true); + }); it('should set correct src on Image object', () => { - const src = 'https://example.com/test-image.jpg' + const src = 'https://example.com/test-image.jpg'; - renderHook(() => useImageCache(src)) + renderHook(() => useImageCache(src)); - expect(global.Image).toHaveBeenCalled() - expect(mockImage.src).toBe(src) - }) + expect(global.Image).toHaveBeenCalled(); + expect(mockImage.src).toBe(src); + }); it('should not create new Image when src is empty', () => { - const { result } = renderHook(() => useImageCache('')) + const { result } = renderHook(() => useImageCache('')); - expect(global.Image).not.toHaveBeenCalled() - expect(result.current.isLoaded).toBe(false) - expect(result.current.hasError).toBe(false) - }) + expect(global.Image).not.toHaveBeenCalled(); + expect(result.current.isLoaded).toBe(false); + expect(result.current.hasError).toBe(false); + }); it('should not create new Image when src is already cached', () => { - const src = 'https://example.com/cached-image.jpg' + const src = 'https://example.com/cached-image.jpg'; // First load to populate cache - const { result: firstResult } = renderHook(() => useImageCache(src)) + const { result: firstResult } = renderHook(() => useImageCache(src)); act(() => { if (mockImage.onload) { - mockImage.onload() + mockImage.onload(); } - }) + }); // Clear the mock to track new calls - jest.clearAllMocks() + jest.clearAllMocks(); // Second load should use cache - renderHook(() => useImageCache(src)) + renderHook(() => useImageCache(src)); - expect(global.Image).not.toHaveBeenCalled() - }) + expect(global.Image).not.toHaveBeenCalled(); + }); it('should update when src changes', () => { - const initialSrc = 'https://example.com/initial.jpg' - const newSrc = 'https://example.com/new.jpg' + const initialSrc = 'https://example.com/initial.jpg'; + const newSrc = 'https://example.com/new.jpg'; const { result, rerender } = renderHook( ({ src }) => useImageCache(src), { initialProps: { src: initialSrc } } - ) + ); - expect(mockImage.src).toBe(initialSrc) - expect(result.current.imgSrc).toBe(initialSrc) + expect(mockImage.src).toBe(initialSrc); + expect(result.current.imgSrc).toBe(initialSrc); - rerender({ src: newSrc }) + rerender({ src: newSrc }); - expect(mockImage.src).toBe(newSrc) + expect(mockImage.src).toBe(newSrc); // Note: imgSrc state update might be async, so we just check the Image src - }) + }); it('should clean up event listeners on unmount', () => { - const src = 'https://example.com/cleanup-test.jpg' + const src = 'https://example.com/cleanup-test.jpg'; - const { unmount } = renderHook(() => useImageCache(src)) + const { unmount } = renderHook(() => useImageCache(src)); - expect(mockImage.onload).toBeDefined() - expect(mockImage.onerror).toBeDefined() + expect(mockImage.onload).toBeDefined(); + expect(mockImage.onerror).toBeDefined(); - unmount() + unmount(); - expect(mockImage.onload).toBeNull() - expect(mockImage.onerror).toBeNull() - }) + expect(mockImage.onload).toBeNull(); + expect(mockImage.onerror).toBeNull(); + }); it('should clean up event listeners when src changes', () => { - const src1 = 'https://example.com/src1.jpg' - const src2 = 'https://example.com/src2.jpg' + const src1 = 'https://example.com/src1.jpg'; + const src2 = 'https://example.com/src2.jpg'; const { rerender } = renderHook( ({ src }) => useImageCache(src), { initialProps: { src: src1 } } - ) + ); - expect(mockImage.onload).toBeDefined() - expect(mockImage.onerror).toBeDefined() + expect(mockImage.onload).toBeDefined(); + expect(mockImage.onerror).toBeDefined(); - rerender({ src: src2 }) + rerender({ src: src2 }); // New listeners should be set - expect(mockImage.onload).toBeDefined() - expect(mockImage.onerror).toBeDefined() - }) + expect(mockImage.onload).toBeDefined(); + expect(mockImage.onerror).toBeDefined(); + }); it('should handle setImgSrc function', () => { - const initialSrc = 'https://example.com/initial.jpg' - const newSrc = 'https://example.com/new.jpg' + const initialSrc = 'https://example.com/initial.jpg'; + const newSrc = 'https://example.com/new.jpg'; - const { result } = renderHook(() => useImageCache(initialSrc)) + const { result } = renderHook(() => useImageCache(initialSrc)); - expect(result.current.imgSrc).toBe(initialSrc) + expect(result.current.imgSrc).toBe(initialSrc); act(() => { - result.current.setImgSrc(newSrc) - }) + result.current.setImgSrc(newSrc); + }); - expect(result.current.imgSrc).toBe(newSrc) - }) + expect(result.current.imgSrc).toBe(newSrc); + }); it('should maintain separate state for different instances', () => { - const src1 = 'https://example.com/image1.jpg' - const src2 = 'https://example.com/image2.jpg' + const src1 = 'https://example.com/image1.jpg'; + const src2 = 'https://example.com/image2.jpg'; - const { result: result1 } = renderHook(() => useImageCache(src1)) - const { result: result2 } = renderHook(() => useImageCache(src2)) + const { result: result1 } = renderHook(() => useImageCache(src1)); + const { result: result2 } = renderHook(() => useImageCache(src2)); - expect(result1.current.imgSrc).toBe(src1) - expect(result2.current.imgSrc).toBe(src2) - expect(result1.current.isLoaded).toBe(false) - expect(result2.current.isLoaded).toBe(false) - }) + expect(result1.current.imgSrc).toBe(src1); + expect(result2.current.imgSrc).toBe(src2); + expect(result1.current.isLoaded).toBe(false); + expect(result2.current.isLoaded).toBe(false); + }); it('should handle rapid src changes', () => { - const initialSrc = 'https://example.com/img1.jpg' - const newSrc = 'https://example.com/img2.jpg' + const initialSrc = 'https://example.com/img1.jpg'; + const newSrc = 'https://example.com/img2.jpg'; const { result, rerender } = renderHook( ({ src }) => useImageCache(src), { initialProps: { src: initialSrc } } - ) + ); // Test initial state - expect(result.current.imgSrc).toBe(initialSrc) + expect(result.current.imgSrc).toBe(initialSrc); // Change src - rerender({ src: newSrc }) - expect(mockImage.src).toBe(newSrc) - }) -}) + rerender({ src: newSrc }); + expect(mockImage.src).toBe(newSrc); + }); +}); diff --git a/apps/ops-dashboard/__tests__/hooks/use-is-mounted.test.ts b/apps/ops-dashboard/__tests__/hooks/use-is-mounted.test.ts index 203606f..103fbec 100644 --- a/apps/ops-dashboard/__tests__/hooks/use-is-mounted.test.ts +++ b/apps/ops-dashboard/__tests__/hooks/use-is-mounted.test.ts @@ -1,63 +1,64 @@ -import { renderHook } from '@testing-library/react' -import { useIsMounted } from '../../hooks/use-is-mounted' +import { renderHook } from '@testing-library/react'; + +import { useIsMounted } from '../../hooks/use-is-mounted'; describe('useIsMounted', () => { it('should return true when component is mounted', () => { - const { result } = renderHook(() => useIsMounted()) + const { result } = renderHook(() => useIsMounted()); - expect(result.current).toBe(true) - }) + expect(result.current).toBe(true); + }); it('should return false after component is unmounted', () => { - const { result, unmount } = renderHook(() => useIsMounted()) + const { result, unmount } = renderHook(() => useIsMounted()); - expect(result.current).toBe(true) + expect(result.current).toBe(true); - unmount() + unmount(); // After unmount, the hook result should still be true since it's a snapshot // The hook doesn't actually change after unmount - expect(result.current).toBe(true) - }) + expect(result.current).toBe(true); + }); it('should return consistent function reference', () => { - const { result, rerender } = renderHook(() => useIsMounted()) + const { result, rerender } = renderHook(() => useIsMounted()); - const firstRender = result.current + const firstRender = result.current; - rerender() + rerender(); - const secondRender = result.current + const secondRender = result.current; - expect(firstRender).toBe(secondRender) - }) + expect(firstRender).toBe(secondRender); + }); it('should work correctly across multiple mount/unmount cycles', () => { - const { result: result1, unmount: unmount1 } = renderHook(() => useIsMounted()) - expect(result1.current).toBe(true) + const { result: result1, unmount: unmount1 } = renderHook(() => useIsMounted()); + expect(result1.current).toBe(true); - unmount1() + unmount1(); // Hook result doesn't change after unmount - expect(result1.current).toBe(true) + expect(result1.current).toBe(true); - const { result: result2, unmount: unmount2 } = renderHook(() => useIsMounted()) - expect(result2.current).toBe(true) + const { result: result2, unmount: unmount2 } = renderHook(() => useIsMounted()); + expect(result2.current).toBe(true); - unmount2() + unmount2(); // Hook result doesn't change after unmount - expect(result2.current).toBe(true) - }) + expect(result2.current).toBe(true); + }); it('should handle rapid mount/unmount', () => { for (let i = 0; i < 10; i++) { - const { result, unmount } = renderHook(() => useIsMounted()) + const { result, unmount } = renderHook(() => useIsMounted()); - expect(result.current).toBe(true) + expect(result.current).toBe(true); - unmount() + unmount(); // Hook result doesn't change after unmount - expect(result.current).toBe(true) + expect(result.current).toBe(true); } - }) -}) + }); +}); diff --git a/apps/ops-dashboard/__tests__/hooks/use-media-query.test.ts b/apps/ops-dashboard/__tests__/hooks/use-media-query.test.ts index 4b07a0b..2fede87 100644 --- a/apps/ops-dashboard/__tests__/hooks/use-media-query.test.ts +++ b/apps/ops-dashboard/__tests__/hooks/use-media-query.test.ts @@ -1,14 +1,15 @@ -import { renderHook, act } from '@testing-library/react' -import { useMediaQuery } from '../../hooks/use-media-query' +import { act,renderHook } from '@testing-library/react'; + +import { useMediaQuery } from '../../hooks/use-media-query'; describe('useMediaQuery', () => { - let mockMatchMedia: jest.MockedFunction + let mockMatchMedia: jest.MockedFunction; let mockMediaQueryList: { matches: boolean media: string addEventListener: jest.Mock removeEventListener: jest.Mock - } + }; beforeEach(() => { mockMediaQueryList = { @@ -16,97 +17,97 @@ describe('useMediaQuery', () => { media: '', addEventListener: jest.fn(), removeEventListener: jest.fn(), - } + }; - mockMatchMedia = jest.fn().mockReturnValue(mockMediaQueryList) + mockMatchMedia = jest.fn().mockReturnValue(mockMediaQueryList); Object.defineProperty(window, 'matchMedia', { writable: true, value: mockMatchMedia, - }) - }) + }); + }); afterEach(() => { - jest.clearAllMocks() - }) + jest.clearAllMocks(); + }); it('should return false initially when media query does not match', () => { - mockMediaQueryList.matches = false + mockMediaQueryList.matches = false; - const { result } = renderHook(() => useMediaQuery('(min-width: 768px)')) + const { result } = renderHook(() => useMediaQuery('(min-width: 768px)')); - expect(result.current).toBe(false) - expect(mockMatchMedia).toHaveBeenCalledWith('(min-width: 768px)') - }) + expect(result.current).toBe(false); + expect(mockMatchMedia).toHaveBeenCalledWith('(min-width: 768px)'); + }); it('should return true initially when media query matches', () => { - mockMediaQueryList.matches = true + mockMediaQueryList.matches = true; - const { result } = renderHook(() => useMediaQuery('(min-width: 768px)')) + const { result } = renderHook(() => useMediaQuery('(min-width: 768px)')); - expect(result.current).toBe(true) - }) + expect(result.current).toBe(true); + }); it('should add event listener on mount', () => { - renderHook(() => useMediaQuery('(min-width: 768px)')) + renderHook(() => useMediaQuery('(min-width: 768px)')); expect(mockMediaQueryList.addEventListener).toHaveBeenCalledWith( 'change', expect.any(Function) - ) - }) + ); + }); it('should remove event listener on unmount', () => { - const { unmount } = renderHook(() => useMediaQuery('(min-width: 768px)')) + const { unmount } = renderHook(() => useMediaQuery('(min-width: 768px)')); - unmount() + unmount(); expect(mockMediaQueryList.removeEventListener).toHaveBeenCalledWith( 'change', expect.any(Function) - ) - }) + ); + }); it('should update when media query match changes', () => { - let changeHandler: (e: MediaQueryListEvent) => void + let changeHandler: (e: MediaQueryListEvent) => void; mockMediaQueryList.addEventListener.mockImplementation((event, handler) => { if (event === 'change') { - changeHandler = handler + changeHandler = handler; } - }) + }); - const { result } = renderHook(() => useMediaQuery('(min-width: 768px)')) + const { result } = renderHook(() => useMediaQuery('(min-width: 768px)')); - expect(result.current).toBe(false) + expect(result.current).toBe(false); // Simulate media query change to match act(() => { - changeHandler({ matches: true } as MediaQueryListEvent) - }) + changeHandler({ matches: true } as MediaQueryListEvent); + }); - expect(result.current).toBe(true) + expect(result.current).toBe(true); // Simulate media query change to not match act(() => { - changeHandler({ matches: false } as MediaQueryListEvent) - }) + changeHandler({ matches: false } as MediaQueryListEvent); + }); - expect(result.current).toBe(false) - }) + expect(result.current).toBe(false); + }); it('should work with different media queries', () => { const { result, rerender } = renderHook( ({ query }) => useMediaQuery(query), { initialProps: { query: '(min-width: 768px)' } } - ) + ); - expect(mockMatchMedia).toHaveBeenCalledWith('(min-width: 768px)') + expect(mockMatchMedia).toHaveBeenCalledWith('(min-width: 768px)'); // Note: The current useMediaQuery implementation doesn't re-run when query changes // due to empty dependency array in useEffect. This test documents the current behavior. - rerender({ query: '(max-width: 480px)' }) + rerender({ query: '(max-width: 480px)' }); // The hook doesn't re-run, so matchMedia is not called again - expect(mockMatchMedia).toHaveBeenCalledTimes(1) - }) -}) + expect(mockMatchMedia).toHaveBeenCalledTimes(1); + }); +}); diff --git a/apps/ops-dashboard/__tests__/hooks/use-pagination.test.ts b/apps/ops-dashboard/__tests__/hooks/use-pagination.test.ts index 5d2f4c8..e020dab 100644 --- a/apps/ops-dashboard/__tests__/hooks/use-pagination.test.ts +++ b/apps/ops-dashboard/__tests__/hooks/use-pagination.test.ts @@ -1,12 +1,13 @@ -import { renderHook } from '@testing-library/react' -import { usePagination } from '../../hooks/use-pagination' +import { renderHook } from '@testing-library/react'; + +import { usePagination } from '../../hooks/use-pagination'; describe('usePagination', () => { - const mockOnPageChange = jest.fn() + const mockOnPageChange = jest.fn(); beforeEach(() => { - mockOnPageChange.mockClear() - }) + mockOnPageChange.mockClear(); + }); it('should calculate total pages correctly', () => { const { result } = renderHook(() => usePagination({ @@ -14,10 +15,10 @@ describe('usePagination', () => { itemsPerPage: 10, currentPage: 1, onPageChange: mockOnPageChange, - })) + })); - expect(result.current.totalPages).toBe(10) - }) + expect(result.current.totalPages).toBe(10); + }); it('should handle totalItems as bigint', () => { const { result } = renderHook(() => usePagination({ @@ -25,10 +26,10 @@ describe('usePagination', () => { itemsPerPage: 10, currentPage: 1, onPageChange: mockOnPageChange, - })) + })); - expect(result.current.totalPages).toBe(15) - }) + expect(result.current.totalPages).toBe(15); + }); it('should return minimum 1 page when totalItems is 0', () => { const { result } = renderHook(() => usePagination({ @@ -36,11 +37,11 @@ describe('usePagination', () => { itemsPerPage: 10, currentPage: 1, onPageChange: mockOnPageChange, - })) + })); - expect(result.current.totalPages).toBe(1) - expect(result.current.pageNumbers).toEqual([1]) - }) + expect(result.current.totalPages).toBe(1); + expect(result.current.pageNumbers).toEqual([1]); + }); it('should generate correct page numbers for small page count', () => { const { result } = renderHook(() => usePagination({ @@ -48,11 +49,11 @@ describe('usePagination', () => { itemsPerPage: 10, currentPage: 2, onPageChange: mockOnPageChange, - })) + })); - expect(result.current.totalPages).toBe(3) - expect(result.current.pageNumbers).toEqual([1, 2, 3]) - }) + expect(result.current.totalPages).toBe(3); + expect(result.current.pageNumbers).toEqual([1, 2, 3]); + }); it('should generate correct page numbers with ellipsis for large page count', () => { const { result } = renderHook(() => usePagination({ @@ -60,14 +61,14 @@ describe('usePagination', () => { itemsPerPage: 10, currentPage: 50, onPageChange: mockOnPageChange, - })) + })); - expect(result.current.totalPages).toBe(100) - expect(result.current.pageNumbers).toContain(-1) // ellipsis - expect(result.current.pageNumbers).toContain(1) - expect(result.current.pageNumbers).toContain(50) - expect(result.current.pageNumbers).toContain(100) - }) + expect(result.current.totalPages).toBe(100); + expect(result.current.pageNumbers).toContain(-1); // ellipsis + expect(result.current.pageNumbers).toContain(1); + expect(result.current.pageNumbers).toContain(50); + expect(result.current.pageNumbers).toContain(100); + }); it('should create correct pagination summary', () => { const { result } = renderHook(() => usePagination({ @@ -75,10 +76,10 @@ describe('usePagination', () => { itemsPerPage: 10, currentPage: 5, onPageChange: mockOnPageChange, - })) + })); - expect(result.current.paginationSummary).toBe('41 - 50 of 157 items') - }) + expect(result.current.paginationSummary).toBe('41 - 50 of 157 items'); + }); it('should handle last page correctly in pagination summary', () => { const { result } = renderHook(() => usePagination({ @@ -86,10 +87,10 @@ describe('usePagination', () => { itemsPerPage: 10, currentPage: 16, // last page onPageChange: mockOnPageChange, - })) + })); - expect(result.current.paginationSummary).toBe('151 - 157 of 157 items') - }) + expect(result.current.paginationSummary).toBe('151 - 157 of 157 items'); + }); it('should return "0 items" when totalItems is 0', () => { const { result } = renderHook(() => usePagination({ @@ -97,10 +98,10 @@ describe('usePagination', () => { itemsPerPage: 10, currentPage: 1, onPageChange: mockOnPageChange, - })) + })); - expect(result.current.paginationSummary).toBe('0 items') - }) + expect(result.current.paginationSummary).toBe('0 items'); + }); it('should call onPageChange when goToPage is called with valid page', () => { const { result } = renderHook(() => usePagination({ @@ -108,11 +109,11 @@ describe('usePagination', () => { itemsPerPage: 10, currentPage: 5, onPageChange: mockOnPageChange, - })) + })); - result.current.goToPage(3) - expect(mockOnPageChange).toHaveBeenCalledWith(3) - }) + result.current.goToPage(3); + expect(mockOnPageChange).toHaveBeenCalledWith(3); + }); it('should not call onPageChange when goToPage is called with invalid page', () => { const { result } = renderHook(() => usePagination({ @@ -120,12 +121,12 @@ describe('usePagination', () => { itemsPerPage: 10, currentPage: 5, onPageChange: mockOnPageChange, - })) + })); - result.current.goToPage(0) // invalid - result.current.goToPage(11) // invalid (totalPages is 10) - expect(mockOnPageChange).not.toHaveBeenCalled() - }) + result.current.goToPage(0); // invalid + result.current.goToPage(11); // invalid (totalPages is 10) + expect(mockOnPageChange).not.toHaveBeenCalled(); + }); it('should go to previous page', () => { const { result } = renderHook(() => usePagination({ @@ -133,11 +134,11 @@ describe('usePagination', () => { itemsPerPage: 10, currentPage: 5, onPageChange: mockOnPageChange, - })) + })); - result.current.goToPreviousPage() - expect(mockOnPageChange).toHaveBeenCalledWith(4) - }) + result.current.goToPreviousPage(); + expect(mockOnPageChange).toHaveBeenCalledWith(4); + }); it('should go to next page', () => { const { result } = renderHook(() => usePagination({ @@ -145,11 +146,11 @@ describe('usePagination', () => { itemsPerPage: 10, currentPage: 5, onPageChange: mockOnPageChange, - })) + })); - result.current.goToNextPage() - expect(mockOnPageChange).toHaveBeenCalledWith(6) - }) + result.current.goToNextPage(); + expect(mockOnPageChange).toHaveBeenCalledWith(6); + }); it('should not go to previous page when on first page', () => { const { result } = renderHook(() => usePagination({ @@ -157,11 +158,11 @@ describe('usePagination', () => { itemsPerPage: 10, currentPage: 1, onPageChange: mockOnPageChange, - })) + })); - result.current.goToPreviousPage() - expect(mockOnPageChange).not.toHaveBeenCalled() - }) + result.current.goToPreviousPage(); + expect(mockOnPageChange).not.toHaveBeenCalled(); + }); it('should not go to next page when on last page', () => { const { result } = renderHook(() => usePagination({ @@ -169,11 +170,11 @@ describe('usePagination', () => { itemsPerPage: 10, currentPage: 10, onPageChange: mockOnPageChange, - })) + })); - result.current.goToNextPage() - expect(mockOnPageChange).not.toHaveBeenCalled() - }) + result.current.goToNextPage(); + expect(mockOnPageChange).not.toHaveBeenCalled(); + }); it('should update when props change', () => { const { result, rerender } = renderHook( @@ -184,14 +185,14 @@ describe('usePagination', () => { onPageChange: mockOnPageChange, }), { initialProps: { totalItems: 100, currentPage: 5 } } - ) + ); - expect(result.current.totalPages).toBe(10) - expect(result.current.paginationSummary).toBe('41 - 50 of 100 items') + expect(result.current.totalPages).toBe(10); + expect(result.current.paginationSummary).toBe('41 - 50 of 100 items'); - rerender({ totalItems: 200, currentPage: 8 }) + rerender({ totalItems: 200, currentPage: 8 }); - expect(result.current.totalPages).toBe(20) - expect(result.current.paginationSummary).toBe('71 - 80 of 200 items') - }) -}) + expect(result.current.totalPages).toBe(20); + expect(result.current.paginationSummary).toBe('71 - 80 of 200 items'); + }); +}); diff --git a/apps/ops-dashboard/__tests__/hooks/use-routes.test.ts b/apps/ops-dashboard/__tests__/hooks/use-routes.test.ts index 63a734f..97296f2 100644 --- a/apps/ops-dashboard/__tests__/hooks/use-routes.test.ts +++ b/apps/ops-dashboard/__tests__/hooks/use-routes.test.ts @@ -1,9 +1,10 @@ -import { renderHook } from '@testing-library/react' -import { useRoutes } from '../../hooks/use-routes' +import { renderHook } from '@testing-library/react'; + +import { useRoutes } from '../../hooks/use-routes'; describe('useRoutes', () => { it('should return base routes', () => { - const { result } = renderHook(() => useRoutes()) + const { result } = renderHook(() => useRoutes()); expect(result.current.baseRoutes).toEqual({ home: '/', @@ -11,114 +12,114 @@ describe('useRoutes', () => { learn: '/learn', blog: '/blog', docs: '/docs' - }) - }) + }); + }); it('should return route generator functions', () => { - const { result } = renderHook(() => useRoutes()) + const { result } = renderHook(() => useRoutes()); - expect(typeof result.current.getProductRoute).toBe('function') - expect(typeof result.current.getCourseRoute).toBe('function') - expect(typeof result.current.getLessonRoute).toBe('function') - expect(typeof result.current.getPostRoute).toBe('function') - }) + expect(typeof result.current.getProductRoute).toBe('function'); + expect(typeof result.current.getCourseRoute).toBe('function'); + expect(typeof result.current.getLessonRoute).toBe('function'); + expect(typeof result.current.getPostRoute).toBe('function'); + }); it('should generate product route correctly', () => { - const { result } = renderHook(() => useRoutes()) + const { result } = renderHook(() => useRoutes()); - const productRoute = result.current.getProductRoute('my-product') - expect(productRoute).toBe('/stack/my-product') - }) + const productRoute = result.current.getProductRoute('my-product'); + expect(productRoute).toBe('/stack/my-product'); + }); it('should generate course route correctly', () => { - const { result } = renderHook(() => useRoutes()) + const { result } = renderHook(() => useRoutes()); - const courseRoute = result.current.getCourseRoute('react-course') - expect(courseRoute).toBe('/learn/react-course') - }) + const courseRoute = result.current.getCourseRoute('react-course'); + expect(courseRoute).toBe('/learn/react-course'); + }); it('should generate lesson route correctly', () => { - const { result } = renderHook(() => useRoutes()) + const { result } = renderHook(() => useRoutes()); - const lessonRoute = result.current.getLessonRoute('react-course', 'lesson-1') - expect(lessonRoute).toBe('/learn/react-course/lesson-1') - }) + const lessonRoute = result.current.getLessonRoute('react-course', 'lesson-1'); + expect(lessonRoute).toBe('/learn/react-course/lesson-1'); + }); it('should generate post route correctly', () => { - const { result } = renderHook(() => useRoutes()) + const { result } = renderHook(() => useRoutes()); - const postRoute = result.current.getPostRoute('my-blog-post') - expect(postRoute).toBe('/blog/my-blog-post') - }) + const postRoute = result.current.getPostRoute('my-blog-post'); + expect(postRoute).toBe('/blog/my-blog-post'); + }); it('should handle empty strings in route generation', () => { - const { result } = renderHook(() => useRoutes()) + const { result } = renderHook(() => useRoutes()); - expect(result.current.getProductRoute('')).toBe('/stack/') - expect(result.current.getCourseRoute('')).toBe('/learn/') - expect(result.current.getLessonRoute('', '')).toBe('/learn//') - expect(result.current.getPostRoute('')).toBe('/blog/') - }) + expect(result.current.getProductRoute('')).toBe('/stack/'); + expect(result.current.getCourseRoute('')).toBe('/learn/'); + expect(result.current.getLessonRoute('', '')).toBe('/learn//'); + expect(result.current.getPostRoute('')).toBe('/blog/'); + }); it('should handle special characters in route generation', () => { - const { result } = renderHook(() => useRoutes()) + const { result } = renderHook(() => useRoutes()); - expect(result.current.getProductRoute('my-product-123')).toBe('/stack/my-product-123') - expect(result.current.getCourseRoute('react-course_v2')).toBe('/learn/react-course_v2') - expect(result.current.getLessonRoute('react-course', 'lesson-1-intro')).toBe('/learn/react-course/lesson-1-intro') - expect(result.current.getPostRoute('my-blog-post-2024')).toBe('/blog/my-blog-post-2024') - }) + expect(result.current.getProductRoute('my-product-123')).toBe('/stack/my-product-123'); + expect(result.current.getCourseRoute('react-course_v2')).toBe('/learn/react-course_v2'); + expect(result.current.getLessonRoute('react-course', 'lesson-1-intro')).toBe('/learn/react-course/lesson-1-intro'); + expect(result.current.getPostRoute('my-blog-post-2024')).toBe('/blog/my-blog-post-2024'); + }); it('should maintain consistent function behavior across renders', () => { - const { result, rerender } = renderHook(() => useRoutes()) + const { result, rerender } = renderHook(() => useRoutes()); const firstRender = { getProductRoute: result.current.getProductRoute, getCourseRoute: result.current.getCourseRoute, getLessonRoute: result.current.getLessonRoute, getPostRoute: result.current.getPostRoute - } + }; - rerender() + rerender(); const secondRender = { getProductRoute: result.current.getProductRoute, getCourseRoute: result.current.getCourseRoute, getLessonRoute: result.current.getLessonRoute, getPostRoute: result.current.getPostRoute - } + }; // Functions should behave the same way - expect(firstRender.getProductRoute('test')).toBe(secondRender.getProductRoute('test')) - expect(firstRender.getCourseRoute('test')).toBe(secondRender.getCourseRoute('test')) - expect(firstRender.getLessonRoute('test', 'lesson')).toBe(secondRender.getLessonRoute('test', 'lesson')) - expect(firstRender.getPostRoute('test')).toBe(secondRender.getPostRoute('test')) - }) + expect(firstRender.getProductRoute('test')).toBe(secondRender.getProductRoute('test')); + expect(firstRender.getCourseRoute('test')).toBe(secondRender.getCourseRoute('test')); + expect(firstRender.getLessonRoute('test', 'lesson')).toBe(secondRender.getLessonRoute('test', 'lesson')); + expect(firstRender.getPostRoute('test')).toBe(secondRender.getPostRoute('test')); + }); it('should maintain consistent base routes across renders', () => { - const { result, rerender } = renderHook(() => useRoutes()) + const { result, rerender } = renderHook(() => useRoutes()); - const firstBaseRoutes = result.current.baseRoutes - rerender() - const secondBaseRoutes = result.current.baseRoutes + const firstBaseRoutes = result.current.baseRoutes; + rerender(); + const secondBaseRoutes = result.current.baseRoutes; - expect(firstBaseRoutes).toStrictEqual(secondBaseRoutes) - }) + expect(firstBaseRoutes).toStrictEqual(secondBaseRoutes); + }); it('should work with different parameter combinations', () => { - const { result } = renderHook(() => useRoutes()) + const { result } = renderHook(() => useRoutes()); // Test various parameter combinations - expect(result.current.getProductRoute('product-1')).toBe('/stack/product-1') - expect(result.current.getProductRoute('product-2')).toBe('/stack/product-2') + expect(result.current.getProductRoute('product-1')).toBe('/stack/product-1'); + expect(result.current.getProductRoute('product-2')).toBe('/stack/product-2'); - expect(result.current.getCourseRoute('course-a')).toBe('/learn/course-a') - expect(result.current.getCourseRoute('course-b')).toBe('/learn/course-b') + expect(result.current.getCourseRoute('course-a')).toBe('/learn/course-a'); + expect(result.current.getCourseRoute('course-b')).toBe('/learn/course-b'); - expect(result.current.getLessonRoute('course-a', 'lesson-1')).toBe('/learn/course-a/lesson-1') - expect(result.current.getLessonRoute('course-b', 'lesson-2')).toBe('/learn/course-b/lesson-2') + expect(result.current.getLessonRoute('course-a', 'lesson-1')).toBe('/learn/course-a/lesson-1'); + expect(result.current.getLessonRoute('course-b', 'lesson-2')).toBe('/learn/course-b/lesson-2'); - expect(result.current.getPostRoute('post-1')).toBe('/blog/post-1') - expect(result.current.getPostRoute('post-2')).toBe('/blog/post-2') - }) -}) + expect(result.current.getPostRoute('post-1')).toBe('/blog/post-1'); + expect(result.current.getPostRoute('post-2')).toBe('/blog/post-2'); + }); +}); diff --git a/apps/ops-dashboard/__tests__/hooks/use-search-data.test.ts b/apps/ops-dashboard/__tests__/hooks/use-search-data.test.ts index f73e0ca..c4a88b1 100644 --- a/apps/ops-dashboard/__tests__/hooks/use-search-data.test.ts +++ b/apps/ops-dashboard/__tests__/hooks/use-search-data.test.ts @@ -1,11 +1,11 @@ -import { renderHook, act } from '../utils/test-utils' -import { useSearchData } from '../../hooks/use-search-data' +import { useSearchData } from '../../hooks/use-search-data'; +import { act,renderHook } from '../utils/test-utils'; // Mock nuqs -const mockSetSearchQuery = jest.fn() +const mockSetSearchQuery = jest.fn(); jest.mock('nuqs', () => ({ useQueryState: jest.fn(() => [null, mockSetSearchQuery]) -})) +})); // Mock data for testing const mockData = [ @@ -14,58 +14,58 @@ const mockData = [ { id: 3, name: 'Carrot', category: 'vegetable', color: 'orange' }, { id: 4, name: 'Date', category: 'fruit', color: 'brown' }, { id: 5, name: 'Eggplant', category: 'vegetable', color: 'purple' } -] +]; -const searchFields = ['name', 'category', 'color'] as const +const searchFields = ['name', 'category', 'color'] as const; describe('useSearchData', () => { beforeEach(() => { - jest.clearAllMocks() - }) + jest.clearAllMocks(); + }); it('should return all data when searchQuery is empty', () => { const { result } = renderHook(() => useSearchData({ data: mockData, fields: searchFields - })) + })); - expect(result.current.filteredData).toEqual(mockData) - expect(result.current.searchQuery).toBe('') - expect(typeof result.current.setSearchQuery).toBe('function') - }) + expect(result.current.filteredData).toEqual(mockData); + expect(result.current.searchQuery).toBe(''); + expect(typeof result.current.setSearchQuery).toBe('function'); + }); it('should handle custom matcher function', () => { const customMatcher = (item: typeof mockData[0], query: string) => { - return item.name.toLowerCase().includes(query.toLowerCase()) - } + return item.name.toLowerCase().includes(query.toLowerCase()); + }; const { result } = renderHook(() => useSearchData({ data: mockData, fields: searchFields, matcherFn: customMatcher - })) + })); - expect(result.current.filteredData).toEqual(mockData) - expect(typeof result.current.setSearchQuery).toBe('function') - }) + expect(result.current.filteredData).toEqual(mockData); + expect(typeof result.current.setSearchQuery).toBe('function'); + }); it('should update searchQuery when setSearchQuery is called', async () => { const { result } = renderHook(() => useSearchData({ data: mockData, fields: searchFields - })) + })); act(() => { - result.current.setSearchQuery('apple') - }) + result.current.setSearchQuery('apple'); + }); // Wait for debounce to complete await act(async () => { - await new Promise(resolve => setTimeout(resolve, 350)) - }) + await new Promise(resolve => setTimeout(resolve, 350)); + }); - expect(result.current.searchQuery).toBe('apple') - }) + expect(result.current.searchQuery).toBe('apple'); + }); it('should handle data updates', () => { const { result, rerender } = renderHook( @@ -74,84 +74,84 @@ describe('useSearchData', () => { fields: searchFields }), { initialProps: { data: mockData } } - ) + ); - expect(result.current.filteredData).toHaveLength(5) + expect(result.current.filteredData).toHaveLength(5); - const updatedData = mockData.slice(0, 2) - rerender({ data: updatedData }) + const updatedData = mockData.slice(0, 2); + rerender({ data: updatedData }); - expect(result.current.filteredData).toHaveLength(2) - }) + expect(result.current.filteredData).toHaveLength(2); + }); it('should handle empty data array', () => { const { result } = renderHook(() => useSearchData({ data: [], fields: searchFields - })) + })); - expect(result.current.filteredData).toEqual([]) - }) + expect(result.current.filteredData).toEqual([]); + }); it('should work with different field configurations', () => { const { result } = renderHook(() => useSearchData({ data: mockData, fields: ['name'] // Only search by name - })) + })); - expect(result.current.filteredData).toEqual(mockData) - }) + expect(result.current.filteredData).toEqual(mockData); + }); it('should handle null setSearchQuery calls', () => { const { result } = renderHook(() => useSearchData({ data: mockData, fields: searchFields - })) + })); act(() => { - result.current.setSearchQuery(null) - }) + result.current.setSearchQuery(null); + }); - expect(result.current.searchQuery).toBe('') - }) + expect(result.current.searchQuery).toBe(''); + }); it('should debounce search query updates', async () => { - jest.useFakeTimers() + jest.useFakeTimers(); const { result } = renderHook(() => useSearchData({ data: mockData, fields: searchFields - })) + })); act(() => { - result.current.setSearchQuery('test') - }) + result.current.setSearchQuery('test'); + }); // Before debounce completes - expect(result.current.searchQuery).toBe('') + expect(result.current.searchQuery).toBe(''); act(() => { - jest.advanceTimersByTime(300) - }) + jest.advanceTimersByTime(300); + }); // After debounce completes - expect(result.current.searchQuery).toBe('test') + expect(result.current.searchQuery).toBe('test'); - jest.useRealTimers() - }) + jest.useRealTimers(); + }); it('should provide stable function references', () => { const { result, rerender } = renderHook(() => useSearchData({ data: mockData, fields: searchFields - })) + })); - const firstSetSearchQuery = result.current.setSearchQuery + const firstSetSearchQuery = result.current.setSearchQuery; - rerender() + rerender(); // Note: Due to useCallback dependencies, the function reference may change // but the functionality should remain the same - expect(typeof result.current.setSearchQuery).toBe('function') - }) -}) + expect(typeof result.current.setSearchQuery).toBe('function'); + }); +}); diff --git a/apps/ops-dashboard/__tests__/hooks/use-show-more.test.ts b/apps/ops-dashboard/__tests__/hooks/use-show-more.test.ts index 5afd820..deb5c03 100644 --- a/apps/ops-dashboard/__tests__/hooks/use-show-more.test.ts +++ b/apps/ops-dashboard/__tests__/hooks/use-show-more.test.ts @@ -1,109 +1,110 @@ -import { renderHook, act } from '@testing-library/react' -import { useShowMore } from '../../hooks/use-show-more' +import { act,renderHook } from '@testing-library/react'; + +import { useShowMore } from '../../hooks/use-show-more'; describe('useShowMore', () => { - const testItems = ['item1', 'item2', 'item3', 'item4', 'item5'] - const defaultVisibleCount = 3 + const testItems = ['item1', 'item2', 'item3', 'item4', 'item5']; + const defaultVisibleCount = 3; it('should initialize with showMore as false', () => { - const { result } = renderHook(() => useShowMore({ items: testItems, defaultVisibleCount })) + const { result } = renderHook(() => useShowMore({ items: testItems, defaultVisibleCount })); - expect(result.current.isShowMore).toBe(false) - expect(result.current.visibleItems).toEqual(['item1', 'item2', 'item3']) - expect(result.current.btnText).toBe('Show More') - expect(typeof result.current.toggleShowMore).toBe('function') - }) + expect(result.current.isShowMore).toBe(false); + expect(result.current.visibleItems).toEqual(['item1', 'item2', 'item3']); + expect(result.current.btnText).toBe('Show More'); + expect(typeof result.current.toggleShowMore).toBe('function'); + }); it('should initialize with custom initial value', () => { - const { result } = renderHook(() => useShowMore({ items: testItems, defaultVisibleCount: 2 })) + const { result } = renderHook(() => useShowMore({ items: testItems, defaultVisibleCount: 2 })); - expect(result.current.isShowMore).toBe(false) - expect(result.current.visibleItems).toEqual(['item1', 'item2']) - }) + expect(result.current.isShowMore).toBe(false); + expect(result.current.visibleItems).toEqual(['item1', 'item2']); + }); it('should toggle showMore state', () => { - const { result } = renderHook(() => useShowMore({ items: testItems, defaultVisibleCount })) + const { result } = renderHook(() => useShowMore({ items: testItems, defaultVisibleCount })); - expect(result.current.isShowMore).toBe(false) - expect(result.current.visibleItems).toEqual(['item1', 'item2', 'item3']) + expect(result.current.isShowMore).toBe(false); + expect(result.current.visibleItems).toEqual(['item1', 'item2', 'item3']); act(() => { - result.current.toggleShowMore() - }) + result.current.toggleShowMore(); + }); - expect(result.current.isShowMore).toBe(true) - expect(result.current.visibleItems).toEqual(testItems) - expect(result.current.btnText).toBe('Show Less') + expect(result.current.isShowMore).toBe(true); + expect(result.current.visibleItems).toEqual(testItems); + expect(result.current.btnText).toBe('Show Less'); act(() => { - result.current.toggleShowMore() - }) + result.current.toggleShowMore(); + }); - expect(result.current.isShowMore).toBe(false) - expect(result.current.visibleItems).toEqual(['item1', 'item2', 'item3']) - expect(result.current.btnText).toBe('Show More') - }) + expect(result.current.isShowMore).toBe(false); + expect(result.current.visibleItems).toEqual(['item1', 'item2', 'item3']); + expect(result.current.btnText).toBe('Show More'); + }); it('should handle multiple rapid toggles', () => { - const { result } = renderHook(() => useShowMore({ items: testItems, defaultVisibleCount })) + const { result } = renderHook(() => useShowMore({ items: testItems, defaultVisibleCount })); - expect(result.current.isShowMore).toBe(false) + expect(result.current.isShowMore).toBe(false); act(() => { - result.current.toggleShowMore() - result.current.toggleShowMore() - result.current.toggleShowMore() - }) + result.current.toggleShowMore(); + result.current.toggleShowMore(); + result.current.toggleShowMore(); + }); - expect(result.current.isShowMore).toBe(true) - }) + expect(result.current.isShowMore).toBe(true); + }); it('should maintain state across rerenders', () => { const { result, rerender } = renderHook( ({ items, defaultVisibleCount }) => useShowMore({ items, defaultVisibleCount }), { initialProps: { items: testItems, defaultVisibleCount } } - ) + ); act(() => { - result.current.toggleShowMore() - }) + result.current.toggleShowMore(); + }); - expect(result.current.isShowMore).toBe(true) + expect(result.current.isShowMore).toBe(true); - rerender({ items: testItems, defaultVisibleCount }) + rerender({ items: testItems, defaultVisibleCount }); // State should persist through rerender - expect(result.current.isShowMore).toBe(true) - }) + expect(result.current.isShowMore).toBe(true); + }); it('should work with different initial values', () => { - const { result: result1 } = renderHook(() => useShowMore({ items: testItems, defaultVisibleCount: 2 })) - const { result: result2 } = renderHook(() => useShowMore({ items: testItems, defaultVisibleCount: 4 })) + const { result: result1 } = renderHook(() => useShowMore({ items: testItems, defaultVisibleCount: 2 })); + const { result: result2 } = renderHook(() => useShowMore({ items: testItems, defaultVisibleCount: 4 })); - expect(result1.current.visibleItems).toEqual(['item1', 'item2']) - expect(result2.current.visibleItems).toEqual(['item1', 'item2', 'item3', 'item4']) + expect(result1.current.visibleItems).toEqual(['item1', 'item2']); + expect(result2.current.visibleItems).toEqual(['item1', 'item2', 'item3', 'item4']); act(() => { - result1.current.toggleShowMore() - result2.current.toggleShowMore() - }) + result1.current.toggleShowMore(); + result2.current.toggleShowMore(); + }); - expect(result1.current.isShowMore).toBe(true) - expect(result2.current.isShowMore).toBe(true) - }) + expect(result1.current.isShowMore).toBe(true); + expect(result2.current.isShowMore).toBe(true); + }); it('should return stable function reference', () => { - const { result, rerender } = renderHook(() => useShowMore({ items: testItems, defaultVisibleCount })) + const { result, rerender } = renderHook(() => useShowMore({ items: testItems, defaultVisibleCount })); - const firstToggle = result.current.toggleShowMore + const firstToggle = result.current.toggleShowMore; - rerender() + rerender(); - const secondToggle = result.current.toggleShowMore + const secondToggle = result.current.toggleShowMore; // Note: Due to React's internal optimizations, function references may change // but the functionality should remain the same - expect(typeof firstToggle).toBe('function') - expect(typeof secondToggle).toBe('function') - }) -}) + expect(typeof firstToggle).toBe('function'); + expect(typeof secondToggle).toBe('function'); + }); +}); diff --git a/apps/ops-dashboard/__tests__/hooks/use-toast.test.ts b/apps/ops-dashboard/__tests__/hooks/use-toast.test.ts index e6eaace..052bb54 100644 --- a/apps/ops-dashboard/__tests__/hooks/use-toast.test.ts +++ b/apps/ops-dashboard/__tests__/hooks/use-toast.test.ts @@ -1,187 +1,188 @@ -import { renderHook, act } from '@testing-library/react' -import { useToast } from '../../hooks/use-toast' +import { act,renderHook } from '@testing-library/react'; + +import { useToast } from '../../hooks/use-toast'; describe('useToast', () => { it('should initialize with empty toasts array', () => { - const { result } = renderHook(() => useToast()) + const { result } = renderHook(() => useToast()); - expect(result.current.toasts).toEqual([]) - expect(typeof result.current.toast).toBe('function') - expect(typeof result.current.dismiss).toBe('function') - }) + expect(result.current.toasts).toEqual([]); + expect(typeof result.current.toast).toBe('function'); + expect(typeof result.current.dismiss).toBe('function'); + }); it('should add toast when toast function is called', () => { - const { result } = renderHook(() => useToast()) + const { result } = renderHook(() => useToast()); act(() => { result.current.toast({ title: 'Test Toast', description: 'This is a test toast' - }) - }) - - expect(result.current.toasts).toHaveLength(1) - expect(result.current.toasts[0].title).toBe('Test Toast') - expect(result.current.toasts[0].description).toBe('This is a test toast') - expect(result.current.toasts[0].id).toBeDefined() - }) + }); + }); + + expect(result.current.toasts).toHaveLength(1); + expect(result.current.toasts[0].title).toBe('Test Toast'); + expect(result.current.toasts[0].description).toBe('This is a test toast'); + expect(result.current.toasts[0].id).toBeDefined(); + }); it('should add multiple toasts', () => { - const { result } = renderHook(() => useToast()) + const { result } = renderHook(() => useToast()); act(() => { - result.current.toast({ title: 'First Toast' }) - result.current.toast({ title: 'Second Toast' }) - }) + result.current.toast({ title: 'First Toast' }); + result.current.toast({ title: 'Second Toast' }); + }); // Due to TOAST_LIMIT = 1, only the latest toast is kept - expect(result.current.toasts).toHaveLength(1) - expect(result.current.toasts[0].title).toBe('Second Toast') - }) + expect(result.current.toasts).toHaveLength(1); + expect(result.current.toasts[0].title).toBe('Second Toast'); + }); it('should generate unique IDs for toasts', () => { - const { result } = renderHook(() => useToast()) + const { result } = renderHook(() => useToast()); act(() => { - result.current.toast({ title: 'Toast 1' }) - result.current.toast({ title: 'Toast 2' }) - }) + result.current.toast({ title: 'Toast 1' }); + result.current.toast({ title: 'Toast 2' }); + }); // Due to TOAST_LIMIT = 1, only one toast is kept - expect(result.current.toasts).toHaveLength(1) - expect(result.current.toasts[0].id).toBeDefined() - }) + expect(result.current.toasts).toHaveLength(1); + expect(result.current.toasts[0].id).toBeDefined(); + }); it('should dismiss toast by ID', () => { - const { result } = renderHook(() => useToast()) + const { result } = renderHook(() => useToast()); - let toastId: string + let toastId: string; act(() => { - result.current.toast({ title: 'Toast 1' }) - result.current.toast({ title: 'Toast 2' }) - toastId = result.current.toasts[0].id - }) + result.current.toast({ title: 'Toast 1' }); + result.current.toast({ title: 'Toast 2' }); + toastId = result.current.toasts[0].id; + }); // Due to TOAST_LIMIT = 1, only the latest toast is kept - expect(result.current.toasts).toHaveLength(1) + expect(result.current.toasts).toHaveLength(1); act(() => { - result.current.dismiss(toastId) - }) + result.current.dismiss(toastId); + }); // The dismiss action should be called (the actual behavior may vary) - expect(result.current.toasts).toHaveLength(1) - }) + expect(result.current.toasts).toHaveLength(1); + }); it('should dismiss all toasts when called without ID', () => { - const { result } = renderHook(() => useToast()) + const { result } = renderHook(() => useToast()); act(() => { - result.current.toast({ title: 'Toast 1' }) - result.current.toast({ title: 'Toast 2' }) - result.current.toast({ title: 'Toast 3' }) - }) + result.current.toast({ title: 'Toast 1' }); + result.current.toast({ title: 'Toast 2' }); + result.current.toast({ title: 'Toast 3' }); + }); // Due to TOAST_LIMIT = 1, only the latest toast is kept - expect(result.current.toasts).toHaveLength(1) + expect(result.current.toasts).toHaveLength(1); act(() => { - result.current.dismiss() - }) + result.current.dismiss(); + }); // Toast should be dismissed (marked as open: false) - expect(result.current.toasts[0].open).toBe(false) - }) + expect(result.current.toasts[0].open).toBe(false); + }); it('should handle toast with different variants', () => { - const { result } = renderHook(() => useToast()) + const { result } = renderHook(() => useToast()); act(() => { result.current.toast({ title: 'Success Toast', variant: 'default' - }) + }); result.current.toast({ title: 'Error Toast', variant: 'destructive' - }) - }) + }); + }); // Due to TOAST_LIMIT = 1, only the latest toast is kept - expect(result.current.toasts).toHaveLength(1) - expect(result.current.toasts[0].variant).toBe('destructive') - }) + expect(result.current.toasts).toHaveLength(1); + expect(result.current.toasts[0].variant).toBe('destructive'); + }); it('should handle toast with actions', () => { - const { result } = renderHook(() => useToast()) + const { result } = renderHook(() => useToast()); const mockAction = { altText: 'Close', onClick: jest.fn() - } + }; act(() => { result.current.toast({ title: 'Toast with Action', action: mockAction - }) - }) + }); + }); - expect(result.current.toasts).toHaveLength(1) - expect(result.current.toasts[0].action).toBe(mockAction) - }) + expect(result.current.toasts).toHaveLength(1); + expect(result.current.toasts[0].action).toBe(mockAction); + }); it('should not dismiss non-existent toast', () => { - const { result } = renderHook(() => useToast()) + const { result } = renderHook(() => useToast()); act(() => { - result.current.toast({ title: 'Test Toast' }) - }) + result.current.toast({ title: 'Test Toast' }); + }); - expect(result.current.toasts).toHaveLength(1) + expect(result.current.toasts).toHaveLength(1); act(() => { - result.current.dismiss('non-existent-id') - }) + result.current.dismiss('non-existent-id'); + }); - expect(result.current.toasts).toHaveLength(1) - }) + expect(result.current.toasts).toHaveLength(1); + }); it('should maintain toast order', () => { - const { result } = renderHook(() => useToast()) + const { result } = renderHook(() => useToast()); act(() => { - result.current.toast({ title: 'First' }) - result.current.toast({ title: 'Second' }) - result.current.toast({ title: 'Third' }) - }) + result.current.toast({ title: 'First' }); + result.current.toast({ title: 'Second' }); + result.current.toast({ title: 'Third' }); + }); // Due to TOAST_LIMIT = 1, only the latest toast is kept - const titles = result.current.toasts.map(t => t.title) - expect(titles).toEqual(['Third']) - }) + const titles = result.current.toasts.map(t => t.title); + expect(titles).toEqual(['Third']); + }); it('should handle rapid toast additions and dismissals', () => { - const { result } = renderHook(() => useToast()) + const { result } = renderHook(() => useToast()); act(() => { // Add multiple toasts rapidly for (let i = 0; i < 5; i++) { - result.current.toast({ title: `Toast ${i}` }) + result.current.toast({ title: `Toast ${i}` }); } - }) + }); // Due to TOAST_LIMIT = 1, only the latest toast is kept - expect(result.current.toasts).toHaveLength(1) + expect(result.current.toasts).toHaveLength(1); act(() => { // Dismiss the current toast - const toastId = result.current.toasts[0].id - result.current.dismiss(toastId) - }) + const toastId = result.current.toasts[0].id; + result.current.dismiss(toastId); + }); // Toast should be dismissed (marked as open: false) - expect(result.current.toasts[0].open).toBe(false) - }) -}) + expect(result.current.toasts[0].open).toBe(false); + }); +}); diff --git a/apps/ops-dashboard/__tests__/hooks/use-window-dimensions.test.ts b/apps/ops-dashboard/__tests__/hooks/use-window-dimensions.test.ts index 148e1de..abc7a58 100644 --- a/apps/ops-dashboard/__tests__/hooks/use-window-dimensions.test.ts +++ b/apps/ops-dashboard/__tests__/hooks/use-window-dimensions.test.ts @@ -1,9 +1,10 @@ -import { renderHook, act } from '@testing-library/react' -import { useWindowDimensions } from '../../hooks/use-window-dimensions' +import { act,renderHook } from '@testing-library/react'; + +import { useWindowDimensions } from '../../hooks/use-window-dimensions'; describe('useWindowDimensions', () => { - const originalInnerWidth = window.innerWidth - const originalInnerHeight = window.innerHeight + const originalInnerWidth = window.innerWidth; + const originalInnerHeight = window.innerHeight; beforeEach(() => { // Set initial window dimensions @@ -11,13 +12,13 @@ describe('useWindowDimensions', () => { writable: true, configurable: true, value: 1024, - }) + }); Object.defineProperty(window, 'innerHeight', { writable: true, configurable: true, value: 768, - }) - }) + }); + }); afterEach(() => { // Restore original values @@ -25,33 +26,33 @@ describe('useWindowDimensions', () => { writable: true, configurable: true, value: originalInnerWidth, - }) + }); Object.defineProperty(window, 'innerHeight', { writable: true, configurable: true, value: originalInnerHeight, - }) + }); // Clean up any event listeners - window.removeEventListener('resize', jest.fn()) - }) + window.removeEventListener('resize', jest.fn()); + }); it('should return initial window dimensions', () => { - const { result } = renderHook(() => useWindowDimensions()) + const { result } = renderHook(() => useWindowDimensions()); expect(result.current).toEqual({ width: 1024, height: 768, - }) - }) + }); + }); it('should update dimensions when window is resized', () => { - const { result } = renderHook(() => useWindowDimensions()) + const { result } = renderHook(() => useWindowDimensions()); expect(result.current).toEqual({ width: 1024, height: 768, - }) + }); // Simulate window resize act(() => { @@ -59,70 +60,70 @@ describe('useWindowDimensions', () => { writable: true, configurable: true, value: 800, - }) + }); Object.defineProperty(window, 'innerHeight', { writable: true, configurable: true, value: 600, - }) + }); // Trigger resize event - window.dispatchEvent(new Event('resize')) - }) + window.dispatchEvent(new Event('resize')); + }); expect(result.current).toEqual({ width: 800, height: 600, - }) - }) + }); + }); it('should handle multiple resize events', () => { - const { result } = renderHook(() => useWindowDimensions()) + const { result } = renderHook(() => useWindowDimensions()); // First resize act(() => { - Object.defineProperty(window, 'innerWidth', { value: 1200 }) - Object.defineProperty(window, 'innerHeight', { value: 900 }) - window.dispatchEvent(new Event('resize')) - }) + Object.defineProperty(window, 'innerWidth', { value: 1200 }); + Object.defineProperty(window, 'innerHeight', { value: 900 }); + window.dispatchEvent(new Event('resize')); + }); expect(result.current).toEqual({ width: 1200, height: 900, - }) + }); // Second resize act(() => { - Object.defineProperty(window, 'innerWidth', { value: 320 }) - Object.defineProperty(window, 'innerHeight', { value: 568 }) - window.dispatchEvent(new Event('resize')) - }) + Object.defineProperty(window, 'innerWidth', { value: 320 }); + Object.defineProperty(window, 'innerHeight', { value: 568 }); + window.dispatchEvent(new Event('resize')); + }); expect(result.current).toEqual({ width: 320, height: 568, - }) - }) + }); + }); it('should clean up resize listener on unmount', () => { - const removeEventListenerSpy = jest.spyOn(window, 'removeEventListener') + const removeEventListenerSpy = jest.spyOn(window, 'removeEventListener'); - const { unmount } = renderHook(() => useWindowDimensions()) + const { unmount } = renderHook(() => useWindowDimensions()); - unmount() + unmount(); - expect(removeEventListenerSpy).toHaveBeenCalledWith('resize', expect.any(Function)) + expect(removeEventListenerSpy).toHaveBeenCalledWith('resize', expect.any(Function)); - removeEventListenerSpy.mockRestore() - }) + removeEventListenerSpy.mockRestore(); + }); it('should add resize listener on mount', () => { - const addEventListenerSpy = jest.spyOn(window, 'addEventListener') + const addEventListenerSpy = jest.spyOn(window, 'addEventListener'); - renderHook(() => useWindowDimensions()) + renderHook(() => useWindowDimensions()); - expect(addEventListenerSpy).toHaveBeenCalledWith('resize', expect.any(Function)) + expect(addEventListenerSpy).toHaveBeenCalledWith('resize', expect.any(Function)); - addEventListenerSpy.mockRestore() - }) -}) + addEventListenerSpy.mockRestore(); + }); +}); diff --git a/apps/ops-dashboard/__tests__/hooks/useAppMode.test.tsx b/apps/ops-dashboard/__tests__/hooks/useAppMode.test.tsx index 4977c97..49a50e3 100644 --- a/apps/ops-dashboard/__tests__/hooks/useAppMode.test.tsx +++ b/apps/ops-dashboard/__tests__/hooks/useAppMode.test.tsx @@ -1,6 +1,6 @@ -import { renderHook, act } from '../utils/test-utils' -import { useAppMode } from '../../contexts/AppContext' -import { AppProvider } from '../../contexts/AppContext' +import { useAppMode } from '../../contexts/AppContext'; +import { AppProvider } from '../../contexts/AppContext'; +import { act,renderHook } from '../utils/test-utils'; describe('useAppMode', () => { it('should return initial mode', () => { @@ -8,170 +8,170 @@ describe('useAppMode', () => { {children} - ) + ); - const { result } = renderHook(() => useAppMode(), { wrapper }) + const { result } = renderHook(() => useAppMode(), { wrapper }); - expect(result.current.mode).toBe('infra') - expect(typeof result.current.setMode).toBe('function') - }) + expect(result.current.mode).toBe('infra'); + expect(typeof result.current.setMode).toBe('function'); + }); it('should return custom initial mode', () => { const wrapper = ({ children }: { children: React.ReactNode }) => ( {children} - ) + ); - const { result } = renderHook(() => useAppMode(), { wrapper }) + const { result } = renderHook(() => useAppMode(), { wrapper }); - expect(result.current.mode).toBe('smart-objects') - expect(typeof result.current.setMode).toBe('function') - }) + expect(result.current.mode).toBe('smart-objects'); + expect(typeof result.current.setMode).toBe('function'); + }); it('should update mode when setMode is called', () => { const wrapper = ({ children }: { children: React.ReactNode }) => ( {children} - ) + ); - const { result } = renderHook(() => useAppMode(), { wrapper }) + const { result } = renderHook(() => useAppMode(), { wrapper }); - expect(result.current.mode).toBe('infra') + expect(result.current.mode).toBe('infra'); act(() => { - result.current.setMode('smart-objects') - }) + result.current.setMode('smart-objects'); + }); - expect(result.current.mode).toBe('smart-objects') - }) + expect(result.current.mode).toBe('smart-objects'); + }); it('should support switching between modes', () => { const wrapper = ({ children }: { children: React.ReactNode }) => ( {children} - ) + ); - const { result } = renderHook(() => useAppMode(), { wrapper }) + const { result } = renderHook(() => useAppMode(), { wrapper }); - expect(result.current.mode).toBe('infra') + expect(result.current.mode).toBe('infra'); act(() => { - result.current.setMode('smart-objects') - }) - expect(result.current.mode).toBe('smart-objects') + result.current.setMode('smart-objects'); + }); + expect(result.current.mode).toBe('smart-objects'); act(() => { - result.current.setMode('infra') - }) - expect(result.current.mode).toBe('infra') - }) + result.current.setMode('infra'); + }); + expect(result.current.mode).toBe('infra'); + }); it('should throw error when used outside AppProvider', () => { // Suppress console.error for this test - const originalError = console.error - console.error = jest.fn() + const originalError = console.error; + console.error = jest.fn(); expect(() => { - renderHook(() => useAppMode(), { wrapper: ({ children }) => <>{children} }) - }).toThrow('useAppMode must be used within an AppProvider') + renderHook(() => useAppMode(), { wrapper: ({ children }) => <>{children} }); + }).toThrow('useAppMode must be used within an AppProvider'); - console.error = originalError - }) + console.error = originalError; + }); it('should maintain referential stability of setMode function', () => { const wrapper = ({ children }: { children: React.ReactNode }) => ( {children} - ) + ); - const { result, rerender } = renderHook(() => useAppMode(), { wrapper }) + const { result, rerender } = renderHook(() => useAppMode(), { wrapper }); - const firstSetMode = result.current.setMode + const firstSetMode = result.current.setMode; // Rerender without changing mode - rerender() + rerender(); - expect(result.current.setMode).toBe(firstSetMode) - }) + expect(result.current.setMode).toBe(firstSetMode); + }); it('should handle rapid mode changes', () => { const wrapper = ({ children }: { children: React.ReactNode }) => ( {children} - ) + ); - const { result } = renderHook(() => useAppMode(), { wrapper }) + const { result } = renderHook(() => useAppMode(), { wrapper }); // Rapidly change mode multiple times act(() => { - result.current.setMode('smart-objects') - result.current.setMode('infra') - result.current.setMode('smart-objects') - }) + result.current.setMode('smart-objects'); + result.current.setMode('infra'); + result.current.setMode('smart-objects'); + }); - expect(result.current.mode).toBe('smart-objects') - }) + expect(result.current.mode).toBe('smart-objects'); + }); it('should work with both valid modes', () => { - const modes = ['infra', 'smart-objects'] as const + const modes = ['infra', 'smart-objects'] as const; modes.forEach(mode => { const wrapper = ({ children }: { children: React.ReactNode }) => ( {children} - ) + ); - const { result } = renderHook(() => useAppMode(), { wrapper }) + const { result } = renderHook(() => useAppMode(), { wrapper }); - expect(result.current.mode).toBe(mode) - }) - }) + expect(result.current.mode).toBe(mode); + }); + }); it('should handle mode changes with TypeScript type safety', () => { const wrapper = ({ children }: { children: React.ReactNode }) => ( {children} - ) + ); - const { result } = renderHook(() => useAppMode(), { wrapper }) + const { result } = renderHook(() => useAppMode(), { wrapper }); // Test that TypeScript types are correctly enforced act(() => { - result.current.setMode('smart-objects') - }) - expect(result.current.mode).toBe('smart-objects') + result.current.setMode('smart-objects'); + }); + expect(result.current.mode).toBe('smart-objects'); act(() => { - result.current.setMode('infra') - }) - expect(result.current.mode).toBe('infra') - }) + result.current.setMode('infra'); + }); + expect(result.current.mode).toBe('infra'); + }); it('should maintain state across re-renders', () => { const wrapper = ({ children }: { children: React.ReactNode }) => ( {children} - ) + ); - const { result, rerender } = renderHook(() => useAppMode(), { wrapper }) + const { result, rerender } = renderHook(() => useAppMode(), { wrapper }); act(() => { - result.current.setMode('smart-objects') - }) + result.current.setMode('smart-objects'); + }); - expect(result.current.mode).toBe('smart-objects') + expect(result.current.mode).toBe('smart-objects'); // Rerender and check state is maintained - rerender() + rerender(); - expect(result.current.mode).toBe('smart-objects') - }) -}) + expect(result.current.mode).toBe('smart-objects'); + }); +}); diff --git a/apps/ops-dashboard/__tests__/hooks/useConfigMaps.test.tsx b/apps/ops-dashboard/__tests__/hooks/useConfigMaps.test.tsx index 860665d..a618edc 100644 --- a/apps/ops-dashboard/__tests__/hooks/useConfigMaps.test.tsx +++ b/apps/ops-dashboard/__tests__/hooks/useConfigMaps.test.tsx @@ -1,166 +1,165 @@ +import { http, HttpResponse } from 'msw'; + import { - useConfigMaps, - useConfigMap, - useCreateConfigMap, - useUpdateConfigMap, - useDeleteConfigMap -} from '../../hooks/useConfigMaps' -import { server } from '../../__mocks__/server' -import { http, HttpResponse } from 'msw' -import { renderHook, waitFor, act } from '../utils/test-utils' -import { - createConfigMapsList, createAllConfigMapsList, + createAllConfigMapsListError, + createConfigMap, + createConfigMapDelete, + createConfigMapsList, createConfigMapsListData, createConfigMapsListError, - createAllConfigMapsListError, createConfigMapsListNetworkError, createConfigMapsListSlow, - getConfigMap, - createConfigMap, createConfigMapUpdate, - createConfigMapDelete -} from '../../__mocks__/handlers/configmaps' + getConfigMap} from '../../__mocks__/handlers/configmaps'; +import { server } from '../../__mocks__/server'; +import { + useConfigMap, + useConfigMaps, + useCreateConfigMap, + useDeleteConfigMap, + useUpdateConfigMap} from '../../hooks/useConfigMaps'; +import { act,renderHook, waitFor } from '../utils/test-utils'; describe('useConfigMaps', () => { it('should successfully fetch configmaps list', async () => { - server.use(createConfigMapsList()) + server.use(createConfigMapsList()); - const { result } = renderHook(() => useConfigMaps('default')) + const { result } = renderHook(() => useConfigMaps('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).toBeDefined() - expect(result.current.data?.items).toHaveLength(3) - expect(result.current.data?.items[0].metadata.name).toBe('app-config') - expect(result.current.data?.items[1].metadata.name).toBe('redis-config') - expect(result.current.data?.items[2].metadata.name).toBe('empty-config') - }) + expect(result.current.data).toBeDefined(); + expect(result.current.data?.items).toHaveLength(3); + expect(result.current.data?.items[0].metadata.name).toBe('app-config'); + expect(result.current.data?.items[1].metadata.name).toBe('redis-config'); + expect(result.current.data?.items[2].metadata.name).toBe('empty-config'); + }); it('should handle empty configmaps list', async () => { - server.use(createConfigMapsList([])) + server.use(createConfigMapsList([])); - const { result } = renderHook(() => useConfigMaps('default')) + const { result } = renderHook(() => useConfigMaps('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(0) - }) + expect(result.current.data?.items).toHaveLength(0); + }); it('should support _all namespace', async () => { - const mock = createConfigMapsListData() - server.use(createAllConfigMapsList(mock)) + const mock = createConfigMapsListData(); + server.use(createAllConfigMapsList(mock)); - const { result } = renderHook(() => useConfigMaps('_all')) + const { result } = renderHook(() => useConfigMaps('_all')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(3) - expect(result.current.data?.items[0].metadata.name).toBe(mock[0]?.metadata?.name) - expect(result.current.data?.items[1].metadata.name).toBe(mock[1]?.metadata?.name) - }) + expect(result.current.data?.items).toHaveLength(3); + expect(result.current.data?.items[0].metadata.name).toBe(mock[0]?.metadata?.name); + expect(result.current.data?.items[1].metadata.name).toBe(mock[1]?.metadata?.name); + }); it('should complete loading successfully', async () => { - server.use(createConfigMapsList()) + server.use(createConfigMapsList()); - const { result } = renderHook(() => useConfigMaps('default')) + const { result } = renderHook(() => useConfigMaps('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.isLoading).toBe(false) - expect(result.current.data).toBeDefined() - }) + expect(result.current.isLoading).toBe(false); + expect(result.current.data).toBeDefined(); + }); it('should show loading state initially', async () => { - server.use(createConfigMapsListSlow([], 100)) + server.use(createConfigMapsListSlow([], 100)); - const { result } = renderHook(() => useConfigMaps('default')) + const { result } = renderHook(() => useConfigMaps('default')); - expect(result.current.isLoading).toBe(true) - expect(result.current.data).toBeUndefined() + expect(result.current.isLoading).toBe(true); + expect(result.current.data).toBeUndefined(); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.isLoading).toBe(false) - expect(result.current.data).toBeDefined() - }) + expect(result.current.isLoading).toBe(false); + expect(result.current.data).toBeDefined(); + }); it('should handle slow responses', async () => { - server.use(createConfigMapsListSlow(createConfigMapsListData(), 200)) + server.use(createConfigMapsListSlow(createConfigMapsListData(), 200)); - const { result } = renderHook(() => useConfigMaps('default')) + const { result } = renderHook(() => useConfigMaps('default')); - expect(result.current.isLoading).toBe(true) + expect(result.current.isLoading).toBe(true); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }, { timeout: 1000 }) + expect(result.current.isSuccess).toBe(true); + }, { timeout: 1000 }); - expect(result.current.isLoading).toBe(false) - expect(result.current.data?.items).toHaveLength(3) - }) + expect(result.current.isLoading).toBe(false); + expect(result.current.data?.items).toHaveLength(3); + }); it('should handle API errors (500)', async () => { - server.use(createConfigMapsListError(500, 'Internal Server Error')) + server.use(createConfigMapsListError(500, 'Internal Server Error')); - const { result } = renderHook(() => useConfigMaps('default')) + const { result } = renderHook(() => useConfigMaps('default')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); it('should handle API errors (404)', async () => { - server.use(createConfigMapsListError(404, 'Not Found')) + server.use(createConfigMapsListError(404, 'Not Found')); - const { result } = renderHook(() => useConfigMaps('default')) + const { result } = renderHook(() => useConfigMaps('default')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); it('should handle network errors', async () => { - server.use(createConfigMapsListNetworkError()) + server.use(createConfigMapsListNetworkError()); - const { result } = renderHook(() => useConfigMaps('default')) + const { result } = renderHook(() => useConfigMaps('default')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); it('should handle _all namespace API errors', async () => { - server.use(createAllConfigMapsListError(500, 'Server Error')) + server.use(createAllConfigMapsListError(500, 'Server Error')); - const { result } = renderHook(() => useConfigMaps('_all')) + const { result } = renderHook(() => useConfigMaps('_all')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); it('should correctly transform configmap data', async () => { const customConfigMaps = [ @@ -176,21 +175,21 @@ describe('useConfigMaps', () => { 'secrets.env': 'API_KEY=secret123\nDB_PASSWORD=password' } } - ] + ]; - server.use(createConfigMapsList(customConfigMaps)) + server.use(createConfigMapsList(customConfigMaps)); - const { result } = renderHook(() => useConfigMaps('default')) + const { result } = renderHook(() => useConfigMaps('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(1) - expect(result.current.data?.items[0].metadata.name).toBe('test-config') - expect(result.current.data?.items[0].data['config.yaml']).toContain('database:') - expect(result.current.data?.items[0].data['secrets.env']).toContain('API_KEY=secret123') - }) + expect(result.current.data?.items).toHaveLength(1); + expect(result.current.data?.items[0].metadata.name).toBe('test-config'); + expect(result.current.data?.items[0].data['config.yaml']).toContain('database:'); + expect(result.current.data?.items[0].data['secrets.env']).toContain('API_KEY=secret123'); + }); it('should handle configmaps with different data structures', async () => { const multiDataConfigMaps = [ @@ -222,61 +221,61 @@ describe('useConfigMaps', () => { 'binary.data': Buffer.from('binary content').toString('base64') } } - ] + ]; - server.use(createConfigMapsList(multiDataConfigMaps)) + server.use(createConfigMapsList(multiDataConfigMaps)); - const { result } = renderHook(() => useConfigMaps('default')) + const { result } = renderHook(() => useConfigMaps('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(3) - expect(result.current.data?.items[0].data['app.json']).toContain('"name": "my-app"') - expect(Object.keys(result.current.data?.items[1].data || {})).toHaveLength(0) - expect(result.current.data?.items[2].data['binary.data']).toBeDefined() - }) + expect(result.current.data?.items).toHaveLength(3); + expect(result.current.data?.items[0].data['app.json']).toContain('"name": "my-app"'); + expect(Object.keys(result.current.data?.items[1].data || {})).toHaveLength(0); + expect(result.current.data?.items[2].data['binary.data']).toBeDefined(); + }); it('should cache data between renders', async () => { - server.use(createConfigMapsList()) + server.use(createConfigMapsList()); - const { result, rerender } = renderHook(() => useConfigMaps('default')) + const { result, rerender } = renderHook(() => useConfigMaps('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - const firstData = result.current.data + const firstData = result.current.data; - rerender() + rerender(); - expect(result.current.data).toBe(firstData) - }) + expect(result.current.data).toBe(firstData); + }); it('should refetch when namespace changes', async () => { - server.use(createConfigMapsList()) + server.use(createConfigMapsList()); const { result, rerender } = renderHook( ({ namespace }) => useConfigMaps(namespace), { initialProps: { namespace: 'default' } } - ) + ); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - const firstData = result.current.data + const firstData = result.current.data; - rerender({ namespace: 'kube-system' }) + rerender({ namespace: 'kube-system' }); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).not.toBe(firstData) - }) -}) + expect(result.current.data).not.toBe(firstData); + }); +}); // ============================================================================ // MUTATION HOOKS TESTS @@ -287,117 +286,117 @@ describe('useConfigMap', () => { const mockConfigMap = { metadata: { name: 'test-config', namespace: 'default', uid: 'cm-1' }, data: { key: 'value' } - } + }; - server.use(getConfigMap(mockConfigMap)) + server.use(getConfigMap(mockConfigMap)); - const { result } = renderHook(() => useConfigMap('test-config', 'default')) + const { result } = renderHook(() => useConfigMap('test-config', 'default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).toEqual(mockConfigMap) - }) + expect(result.current.data).toEqual(mockConfigMap); + }); it('should handle configmap not found', async () => { const handler = http.get('http://localhost:8001/api/v1/namespaces/:namespace/configmaps/:name', () => { - return HttpResponse.json({ error: 'ConfigMap not found' }, { status: 404 }) - }) + return HttpResponse.json({ error: 'ConfigMap not found' }, { status: 404 }); + }); - server.use(handler) + server.use(handler); - const { result } = renderHook(() => useConfigMap('non-existent', 'default')) + const { result } = renderHook(() => useConfigMap('non-existent', 'default')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - }) -}) + expect(result.current.error).toBeDefined(); + }); +}); describe('useCreateConfigMap', () => { const mockConfigMap = { metadata: { name: 'new-config', namespace: 'default', uid: 'cm-new' }, data: { key: 'value' } - } + }; it('should create configmap successfully', async () => { - server.use(createConfigMap()) + server.use(createConfigMap()); - const { result } = renderHook(() => useCreateConfigMap()) + const { result } = renderHook(() => useCreateConfigMap()); await act(async () => { await result.current.mutateAsync({ configMap: mockConfigMap, namespace: 'default' - }) - }) + }); + }); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) - }) + expect(result.current.isSuccess).toBe(true); + }); + }); it('should handle creation errors', async () => { const handler = http.post('http://localhost:8001/api/v1/namespaces/:namespace/configmaps', () => { - return HttpResponse.json({ error: 'Creation failed' }, { status: 400 }) - }) + return HttpResponse.json({ error: 'Creation failed' }, { status: 400 }); + }); - server.use(handler) + server.use(handler); - const { result } = renderHook(() => useCreateConfigMap()) + const { result } = renderHook(() => useCreateConfigMap()); await act(async () => { try { await result.current.mutateAsync({ configMap: {} as any, namespace: 'default' - }) + }); } catch (error) { // Expected to throw } - }) + }); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) - }) -}) + expect(result.current.isError).toBe(true); + }); + }); +}); describe('useUpdateConfigMap', () => { const mockConfigMap = { metadata: { name: 'updated-config', namespace: 'default', uid: 'cm-updated' }, data: { key: 'updated-value' } - } + }; it('should update configmap successfully', async () => { - server.use(createConfigMapUpdate()) + server.use(createConfigMapUpdate()); - const { result } = renderHook(() => useUpdateConfigMap()) + const { result } = renderHook(() => useUpdateConfigMap()); await act(async () => { await result.current.mutateAsync({ name: 'updated-config', configMap: mockConfigMap, namespace: 'default' - }) - }) + }); + }); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) - }) + expect(result.current.isSuccess).toBe(true); + }); + }); it('should handle update errors', async () => { const handler = http.put('http://localhost:8001/api/v1/namespaces/:namespace/configmaps/:name', () => { - return HttpResponse.json({ error: 'Update failed' }, { status: 400 }) - }) + return HttpResponse.json({ error: 'Update failed' }, { status: 400 }); + }); - server.use(handler) + server.use(handler); - const { result } = renderHook(() => useUpdateConfigMap()) + const { result } = renderHook(() => useUpdateConfigMap()); await act(async () => { try { @@ -405,59 +404,59 @@ describe('useUpdateConfigMap', () => { name: 'updated-config', configMap: {} as any, namespace: 'default' - }) + }); } catch (error) { // Expected to throw } - }) + }); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) - }) -}) + expect(result.current.isError).toBe(true); + }); + }); +}); describe('useDeleteConfigMap', () => { it('should delete configmap successfully', async () => { - server.use(createConfigMapDelete()) + server.use(createConfigMapDelete()); - const { result } = renderHook(() => useDeleteConfigMap()) + const { result } = renderHook(() => useDeleteConfigMap()); await act(async () => { await result.current.mutateAsync({ name: 'test-config', namespace: 'default' - }) - }) + }); + }); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) - }) + expect(result.current.isSuccess).toBe(true); + }); + }); it('should handle deletion errors', async () => { const handler = http.delete('http://localhost:8001/api/v1/namespaces/:namespace/configmaps/:name', () => { - return HttpResponse.json({ error: 'Deletion failed' }, { status: 404 }) - }) + return HttpResponse.json({ error: 'Deletion failed' }, { status: 404 }); + }); - server.use(handler) + server.use(handler); - const { result } = renderHook(() => useDeleteConfigMap()) + const { result } = renderHook(() => useDeleteConfigMap()); await act(async () => { try { await result.current.mutateAsync({ name: 'non-existent-config', namespace: 'default' - }) + }); } catch (error) { // Expected to throw } - }) + }); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) - }) -}) + expect(result.current.isError).toBe(true); + }); + }); +}); diff --git a/apps/ops-dashboard/__tests__/hooks/useConfirm.test.tsx b/apps/ops-dashboard/__tests__/hooks/useConfirm.test.tsx index 9b0bd9c..f64814b 100644 --- a/apps/ops-dashboard/__tests__/hooks/useConfirm.test.tsx +++ b/apps/ops-dashboard/__tests__/hooks/useConfirm.test.tsx @@ -1,14 +1,16 @@ -import { useState } from 'react' -import { confirmDialog, useConfirm } from '../../hooks/useConfirm' -import { render, screen } from '@/__tests__/utils/test-utils' -import userEvent from '@testing-library/user-event' +import userEvent from '@testing-library/user-event'; +import { useState } from 'react'; + +import { render, screen } from '@/__tests__/utils/test-utils'; + +import { confirmDialog, useConfirm } from '../../hooks/useConfirm'; const MockConfirmDialogElement = () => { - const {confirm} = useConfirm() + const {confirm} = useConfirm(); - const [isConfirmed, setIsConfirmed] = useState(false) + const [isConfirmed, setIsConfirmed] = useState(false); const handleConfirm = async () => { const confirmed = await confirm({ @@ -17,42 +19,42 @@ const MockConfirmDialogElement = () => { confirmText: 'Confirm', cancelText: 'Cancel', confirmVariant: 'default', - }) - setIsConfirmed(confirmed) - } + }); + setIsConfirmed(confirmed); + }; return (
{isConfirmed &&
Confirmed
}
- ) -} + ); +}; describe('useConfirm', () => { it('should open a dialog', async () =>{ - render() + render(); - await userEvent.click(screen.getByText('Open a confirm dialog')) + await userEvent.click(screen.getByText('Open a confirm dialog')); - expect(screen.getByText('Test Confirm Dialog')).toBeInTheDocument() - }) + expect(screen.getByText('Test Confirm Dialog')).toBeInTheDocument(); + }); it('should return true when confirmed', async () => { - render() + render(); - await userEvent.click(screen.getByText('Open a confirm dialog')) + await userEvent.click(screen.getByText('Open a confirm dialog')); - expect(screen.getByText('Test Confirm Dialog')).toBeInTheDocument() + expect(screen.getByText('Test Confirm Dialog')).toBeInTheDocument(); - await userEvent.click(screen.getByText('Confirm')) + await userEvent.click(screen.getByText('Confirm')); - expect(screen.getByText('Confirmed')).toBeInTheDocument() - }) -}) + expect(screen.getByText('Confirmed')).toBeInTheDocument(); + }); +}); const MockConfirmDialogElementImperative = () => { - const [confirmed, setConfirmed] = useState(false) + const [confirmed, setConfirmed] = useState(false); const handleConfirm = async () => { const confirmed = await confirmDialog({ @@ -61,43 +63,43 @@ const MockConfirmDialogElementImperative = () => { confirmText: 'Confirm', cancelText: 'Cancel', confirmVariant: 'default', - }) + }); if(confirmed) { - setConfirmed(confirmed) + setConfirmed(confirmed); } - } + }; return (
{confirmed &&
Confirmed
}
- ) + ); -} +}; describe('confirmDialogImperative', () => { it('should return true when confirmed', async () => { - render() + render(); - await userEvent.click(screen.getByText('Open a confirm dialog')) + await userEvent.click(screen.getByText('Open a confirm dialog')); - expect(screen.getByText('Test Confirm Imperative Dialog')).toBeInTheDocument() + expect(screen.getByText('Test Confirm Imperative Dialog')).toBeInTheDocument(); - await userEvent.click(screen.getByText('Confirm')) + await userEvent.click(screen.getByText('Confirm')); - expect(screen.getByText('Confirmed')).toBeInTheDocument() - }) + expect(screen.getByText('Confirmed')).toBeInTheDocument(); + }); it('should open a dialog', async () =>{ - render() + render(); - await userEvent.click(screen.getByText('Open a confirm dialog')) + await userEvent.click(screen.getByText('Open a confirm dialog')); - expect(screen.getByText('Test Confirm Imperative Dialog')).toBeInTheDocument() - }) + expect(screen.getByText('Test Confirm Imperative Dialog')).toBeInTheDocument(); + }); -}) \ No newline at end of file +}); \ No newline at end of file diff --git a/apps/ops-dashboard/__tests__/hooks/useDaemonSets.test.tsx b/apps/ops-dashboard/__tests__/hooks/useDaemonSets.test.tsx index a8b740a..eaa3911 100644 --- a/apps/ops-dashboard/__tests__/hooks/useDaemonSets.test.tsx +++ b/apps/ops-dashboard/__tests__/hooks/useDaemonSets.test.tsx @@ -1,166 +1,167 @@ -import { useDaemonSets, useDaemonSet, useDeleteDaemonSet } from '../../hooks/useDaemonSets' -import { server } from '../../__mocks__/server' -import { renderHook, waitFor } from '../utils/test-utils' -import { http, HttpResponse } from 'msw' +import { http, HttpResponse } from 'msw'; + import { - createDaemonSetsList, createAllDaemonSetsList, - createDaemonSetsListData, + createAllDaemonSetsListError, createDaemonSetDetails, + createDaemonSetsList, + createDaemonSetsListData, createDaemonSetsListError, - createAllDaemonSetsListError, createDaemonSetsListNetworkError, createDaemonSetsListSlow -} from '../../__mocks__/handlers/daemonsets' +} from '../../__mocks__/handlers/daemonsets'; +import { server } from '../../__mocks__/server'; +import { useDaemonSet, useDaemonSets, useDeleteDaemonSet } from '../../hooks/useDaemonSets'; +import { renderHook, waitFor } from '../utils/test-utils'; -const API_BASE = 'http://localhost:8001' +const API_BASE = 'http://localhost:8001'; describe('useDaemonSets', () => { describe('Success scenarios', () => { it('should successfully fetch daemonsets list', async () => { - server.use(createDaemonSetsList()) + server.use(createDaemonSetsList()); - const { result } = renderHook(() => useDaemonSets('default')) + const { result } = renderHook(() => useDaemonSets('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).toBeDefined() - expect(result.current.data?.items).toHaveLength(2) // default namespace has 2 daemonsets - expect(result.current.data?.items[0].metadata.name).toBe('nginx-daemonset') - expect(result.current.data?.items[1].metadata.name).toBe('redis-daemonset') - }) + expect(result.current.data).toBeDefined(); + expect(result.current.data?.items).toHaveLength(2); // default namespace has 2 daemonsets + expect(result.current.data?.items[0].metadata.name).toBe('nginx-daemonset'); + expect(result.current.data?.items[1].metadata.name).toBe('redis-daemonset'); + }); it('should handle empty daemonsets list', async () => { - server.use(createDaemonSetsList([])) + server.use(createDaemonSetsList([])); - const { result } = renderHook(() => useDaemonSets('default')) + const { result } = renderHook(() => useDaemonSets('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(0) - }) + expect(result.current.data?.items).toHaveLength(0); + }); it('should support _all namespace', async () => { - const mock = createDaemonSetsListData() - server.use(createAllDaemonSetsList(mock)) + const mock = createDaemonSetsListData(); + server.use(createAllDaemonSetsList(mock)); - const { result } = renderHook(() => useDaemonSets('_all')) + const { result } = renderHook(() => useDaemonSets('_all')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(3) - expect(result.current.data?.items[0].metadata.name).toBe(mock[0]?.metadata?.name) - expect(result.current.data?.items[1].metadata.name).toBe(mock[1]?.metadata?.name) - expect(result.current.data?.items[2].metadata.name).toBe(mock[2]?.metadata?.name) - }) - }) + expect(result.current.data?.items).toHaveLength(3); + expect(result.current.data?.items[0].metadata.name).toBe(mock[0]?.metadata?.name); + expect(result.current.data?.items[1].metadata.name).toBe(mock[1]?.metadata?.name); + expect(result.current.data?.items[2].metadata.name).toBe(mock[2]?.metadata?.name); + }); + }); describe('Loading states', () => { it('should complete loading successfully', async () => { - server.use(createDaemonSetsList()) + server.use(createDaemonSetsList()); - const { result } = renderHook(() => useDaemonSets('default')) + const { result } = renderHook(() => useDaemonSets('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.isLoading).toBe(false) - expect(result.current.data).toBeDefined() - }) + expect(result.current.isLoading).toBe(false); + expect(result.current.data).toBeDefined(); + }); it('should show loading state initially', async () => { - server.use(createDaemonSetsListSlow([], 100)) + server.use(createDaemonSetsListSlow([], 100)); - const { result } = renderHook(() => useDaemonSets('default')) + const { result } = renderHook(() => useDaemonSets('default')); - expect(result.current.isLoading).toBe(true) - expect(result.current.data).toBeUndefined() + expect(result.current.isLoading).toBe(true); + expect(result.current.data).toBeUndefined(); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.isLoading).toBe(false) - expect(result.current.data).toBeDefined() - }) + expect(result.current.isLoading).toBe(false); + expect(result.current.data).toBeDefined(); + }); it('should handle slow responses', async () => { - server.use(createDaemonSetsListSlow(createDaemonSetsListData(), 200)) + server.use(createDaemonSetsListSlow(createDaemonSetsListData(), 200)); - const { result } = renderHook(() => useDaemonSets('default')) + const { result } = renderHook(() => useDaemonSets('default')); - expect(result.current.isLoading).toBe(true) + expect(result.current.isLoading).toBe(true); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }, { timeout: 1000 }) + expect(result.current.isSuccess).toBe(true); + }, { timeout: 1000 }); - expect(result.current.isLoading).toBe(false) - expect(result.current.data?.items).toHaveLength(2) - }) - }) + expect(result.current.isLoading).toBe(false); + expect(result.current.data?.items).toHaveLength(2); + }); + }); describe('Error handling', () => { it('should handle API errors (500)', async () => { - server.use(createDaemonSetsListError(500, 'Internal Server Error')) + server.use(createDaemonSetsListError(500, 'Internal Server Error')); - const { result } = renderHook(() => useDaemonSets('default')) + const { result } = renderHook(() => useDaemonSets('default')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); it('should handle API errors (404)', async () => { - server.use(createDaemonSetsListError(404, 'Not Found')) + server.use(createDaemonSetsListError(404, 'Not Found')); - const { result } = renderHook(() => useDaemonSets('default')) + const { result } = renderHook(() => useDaemonSets('default')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); it('should handle network errors', async () => { - server.use(createDaemonSetsListNetworkError()) + server.use(createDaemonSetsListNetworkError()); - const { result } = renderHook(() => useDaemonSets('default')) + const { result } = renderHook(() => useDaemonSets('default')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); it('should handle _all namespace API errors', async () => { - server.use(createAllDaemonSetsListError(500, 'Server Error')) + server.use(createAllDaemonSetsListError(500, 'Server Error')); - const { result } = renderHook(() => useDaemonSets('_all')) + const { result } = renderHook(() => useDaemonSets('_all')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); + }); describe('Data transformation', () => { it('should correctly transform daemonset data', async () => { @@ -186,21 +187,21 @@ describe('useDaemonSets', () => { numberAvailable: 2 } } - ] + ]; - server.use(createDaemonSetsList(customDaemonSets)) + server.use(createDaemonSetsList(customDaemonSets)); - const { result } = renderHook(() => useDaemonSets('default')) + const { result } = renderHook(() => useDaemonSets('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(1) - expect(result.current.data?.items[0].metadata.name).toBe('test-daemonset') - expect(result.current.data?.items[0].status.currentNumberScheduled).toBe(2) - expect(result.current.data?.items[0].spec.template.spec.containers[0].image).toBe('nginx:latest') - }) + expect(result.current.data?.items).toHaveLength(1); + expect(result.current.data?.items[0].metadata.name).toBe('test-daemonset'); + expect(result.current.data?.items[0].status.currentNumberScheduled).toBe(2); + expect(result.current.data?.items[0].spec.template.spec.containers[0].image).toBe('nginx:latest'); + }); it('should handle different daemonset statuses', async () => { const multiStatusDaemonSets = [ @@ -244,63 +245,63 @@ describe('useDaemonSets', () => { numberAvailable: 0 } } - ] + ]; - server.use(createDaemonSetsList(multiStatusDaemonSets)) + server.use(createDaemonSetsList(multiStatusDaemonSets)); - const { result } = renderHook(() => useDaemonSets('default')) + const { result } = renderHook(() => useDaemonSets('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(2) - expect(result.current.data?.items[0].status.numberReady).toBe(3) - expect(result.current.data?.items[1].status.numberReady).toBe(0) - }) - }) + expect(result.current.data?.items).toHaveLength(2); + expect(result.current.data?.items[0].status.numberReady).toBe(3); + expect(result.current.data?.items[1].status.numberReady).toBe(0); + }); + }); describe('Caching behavior', () => { it('should cache data between renders', async () => { - server.use(createDaemonSetsList()) + server.use(createDaemonSetsList()); - const { result, rerender } = renderHook(() => useDaemonSets('default')) + const { result, rerender } = renderHook(() => useDaemonSets('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - const firstData = result.current.data + const firstData = result.current.data; - rerender() + rerender(); - expect(result.current.data).toBe(firstData) - }) + expect(result.current.data).toBe(firstData); + }); it('should refetch when namespace changes', async () => { - server.use(createDaemonSetsList()) + server.use(createDaemonSetsList()); const { result, rerender } = renderHook( ({ namespace }) => useDaemonSets(namespace), { initialProps: { namespace: 'default' } } - ) + ); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - const firstData = result.current.data + const firstData = result.current.data; - rerender({ namespace: 'kube-system' }) + rerender({ namespace: 'kube-system' }); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).not.toBe(firstData) - }) - }) -}) + expect(result.current.data).not.toBe(firstData); + }); + }); +}); describe('useDaemonSet', () => { @@ -324,35 +325,35 @@ describe('useDaemonSet', () => { desiredNumberScheduled: 1, numberAvailable: 1 } - } + }; - server.use(createDaemonSetDetails(mockDaemonSet)) + server.use(createDaemonSetDetails(mockDaemonSet)); - const { result } = renderHook(() => useDaemonSet('test-daemonset', 'default')) + const { result } = renderHook(() => useDaemonSet('test-daemonset', 'default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).toBeDefined() - expect(result.current.data?.metadata.name).toBe('test-daemonset') - }) -}) + expect(result.current.data).toBeDefined(); + expect(result.current.data?.metadata.name).toBe('test-daemonset'); + }); +}); describe('useDeleteDaemonSet', () => { it('should delete daemonset successfully', async () => { server.use( http.delete(`${API_BASE}/apis/apps/v1/namespaces/:namespace/daemonsets/:name`, () => { - return HttpResponse.json({}, { status: 200 }) + return HttpResponse.json({}, { status: 200 }); }) - ) + ); - const { result } = renderHook(() => useDeleteDaemonSet()) + const { result } = renderHook(() => useDeleteDaemonSet()); - expect(result.current.mutate).toBeDefined() - expect(result.current.mutateAsync).toBeDefined() - expect(typeof result.current.mutate).toBe('function') - expect(typeof result.current.mutateAsync).toBe('function') - }) -}) + expect(result.current.mutate).toBeDefined(); + expect(result.current.mutateAsync).toBeDefined(); + expect(typeof result.current.mutate).toBe('function'); + expect(typeof result.current.mutateAsync).toBe('function'); + }); +}); diff --git a/apps/ops-dashboard/__tests__/hooks/useDatabases.test.tsx b/apps/ops-dashboard/__tests__/hooks/useDatabases.test.tsx index 10aee90..c635afb 100644 --- a/apps/ops-dashboard/__tests__/hooks/useDatabases.test.tsx +++ b/apps/ops-dashboard/__tests__/hooks/useDatabases.test.tsx @@ -1,9 +1,10 @@ -import { renderHook, waitFor, act } from '../utils/test-utils' -import { useCreateDatabases, useQueryBackups, useCreateBackup } from '../../hooks/useDatabases' -import { server } from '../../__mocks__/server' -import { http, HttpResponse } from 'msw' +import { http, HttpResponse } from 'msw'; -const API_BASE = 'http://localhost:8001' +import { server } from '../../__mocks__/server'; +import { useCreateBackup,useCreateDatabases, useQueryBackups } from '../../hooks/useDatabases'; +import { act,renderHook, waitFor } from '../utils/test-utils'; + +const API_BASE = 'http://localhost:8001'; describe('useCreateDatabases', () => { describe('Success scenarios', () => { @@ -13,11 +14,11 @@ describe('useCreateDatabases', () => { return HttpResponse.json({ success: true, message: 'Database created successfully' - }) + }); }) - ) + ); - const { result } = renderHook(() => useCreateDatabases()) + const { result } = renderHook(() => useCreateDatabases()); const params = { ns: 'default', @@ -31,18 +32,18 @@ describe('useCreateDatabases', () => { enablePooler: true, poolerName: 'test-pooler', poolerInstances: 1 - } + }; await act(async () => { - await result.current.mutateAsync(params) - }) + await result.current.mutateAsync(params); + }); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).toBeDefined() - }) + expect(result.current.data).toBeDefined(); + }); it('should handle different database configurations', async () => { server.use( @@ -50,11 +51,11 @@ describe('useCreateDatabases', () => { return HttpResponse.json({ success: true, message: 'Database created successfully' - }) + }); }) - ) + ); - const { result } = renderHook(() => useCreateDatabases()) + const { result } = renderHook(() => useCreateDatabases()); const params = { ns: 'production', @@ -68,17 +69,17 @@ describe('useCreateDatabases', () => { enablePooler: false, poolerName: '', poolerInstances: 0 - } + }; await act(async () => { - await result.current.mutateAsync(params) - }) + await result.current.mutateAsync(params); + }); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) - }) - }) + expect(result.current.isSuccess).toBe(true); + }); + }); + }); describe('Error handling', () => { it('should handle creation errors', async () => { @@ -87,11 +88,11 @@ describe('useCreateDatabases', () => { return HttpResponse.json( { error: 'Database creation failed' }, { status: 500 } - ) + ); }) - ) + ); - const { result } = renderHook(() => useCreateDatabases()) + const { result } = renderHook(() => useCreateDatabases()); const params = { ns: 'default', @@ -105,21 +106,21 @@ describe('useCreateDatabases', () => { enablePooler: false, poolerName: '', poolerInstances: 0 - } + }; await act(async () => { try { - await result.current.mutateAsync(params) + await result.current.mutateAsync(params); } catch (error) { // Expected to throw } - }) + }); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) - expect(result.current.error).toBeDefined() - }) + expect(result.current.isError).toBe(true); + }); + expect(result.current.error).toBeDefined(); + }); it('should handle validation errors', async () => { server.use( @@ -127,11 +128,11 @@ describe('useCreateDatabases', () => { return HttpResponse.json( { error: 'Invalid parameters' }, { status: 400 } - ) + ); }) - ) + ); - const { result } = renderHook(() => useCreateDatabases()) + const { result } = renderHook(() => useCreateDatabases()); const params = { ns: 'default', @@ -145,32 +146,32 @@ describe('useCreateDatabases', () => { enablePooler: false, poolerName: '', poolerInstances: 0 - } + }; await act(async () => { try { - await result.current.mutateAsync(params) + await result.current.mutateAsync(params); } catch (error) { // Expected to throw } - }) + }); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) - }) - }) + expect(result.current.isError).toBe(true); + }); + }); + }); describe('Loading states', () => { it('should show loading state during creation', async () => { server.use( http.post('/api/databases/:ns/:name/deploy', async () => { - await new Promise(resolve => setTimeout(resolve, 100)) - return HttpResponse.json({ success: true }) + await new Promise(resolve => setTimeout(resolve, 100)); + return HttpResponse.json({ success: true }); }) - ) + ); - const { result } = renderHook(() => useCreateDatabases()) + const { result } = renderHook(() => useCreateDatabases()); const params = { ns: 'default', @@ -184,23 +185,23 @@ describe('useCreateDatabases', () => { enablePooler: false, poolerName: '', poolerInstances: 0 - } + }; act(() => { - result.current.mutate(params) - }) + result.current.mutate(params); + }); // Check that mutation is pending (may be very quick) - expect(result.current.isPending).toBeDefined() + expect(result.current.isPending).toBeDefined(); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.isPending).toBe(false) - }) - }) -}) + expect(result.current.isPending).toBe(false); + }); + }); +}); describe('useQueryBackups', () => { describe('Success scenarios', () => { @@ -208,39 +209,39 @@ describe('useQueryBackups', () => { const mockBackups = [ { id: 'backup-1', name: 'backup-1', createdAt: '2024-01-01T10:00:00Z', status: 'completed' }, { id: 'backup-2', name: 'backup-2', createdAt: '2024-01-02T10:00:00Z', status: 'completed' } - ] + ]; server.use( http.get('/api/databases/:ns/:name/backups', () => { - return HttpResponse.json(mockBackups) + return HttpResponse.json(mockBackups); }) - ) + ); - const { result } = renderHook(() => useQueryBackups('default', 'test-db')) + const { result } = renderHook(() => useQueryBackups('default', 'test-db')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).toEqual(mockBackups) - }) + expect(result.current.data).toEqual(mockBackups); + }); it('should handle empty backups list', async () => { server.use( http.get('/api/databases/:ns/:name/backups', () => { - return HttpResponse.json([]) + return HttpResponse.json([]); }) - ) + ); - const { result } = renderHook(() => useQueryBackups('default', 'test-db')) + const { result } = renderHook(() => useQueryBackups('default', 'test-db')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).toEqual([]) - }) - }) + expect(result.current.data).toEqual([]); + }); + }); describe('Error handling', () => { it('should handle backup fetch errors', async () => { @@ -249,20 +250,20 @@ describe('useQueryBackups', () => { return HttpResponse.json( { error: 'Failed to fetch backups' }, { status: 500 } - ) + ); }) - ) + ); - const { result } = renderHook(() => useQueryBackups('default', 'test-db')) + const { result } = renderHook(() => useQueryBackups('default', 'test-db')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - }) - }) -}) + expect(result.current.error).toBeDefined(); + }); + }); +}); describe('useCreateBackup', () => { describe('Success scenarios', () => { @@ -273,27 +274,27 @@ describe('useCreateBackup', () => { success: true, message: 'Backup created successfully', backupId: 'backup-123' - }) + }); }) - ) + ); - const { result } = renderHook(() => useCreateBackup()) + const { result } = renderHook(() => useCreateBackup()); const params = { ns: 'default', name: 'test-db', method: 'pg_dump' - } + }; await act(async () => { - await result.current.mutateAsync(params) - }) + await result.current.mutateAsync(params); + }); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) - expect(result.current.data).toBeDefined() - }) + expect(result.current.isSuccess).toBe(true); + }); + expect(result.current.data).toBeDefined(); + }); it('should create backup with default method', async () => { server.use( @@ -301,26 +302,26 @@ describe('useCreateBackup', () => { return HttpResponse.json({ success: true, message: 'Backup created successfully' - }) + }); }) - ) + ); - const { result } = renderHook(() => useCreateBackup()) + const { result } = renderHook(() => useCreateBackup()); const params = { ns: 'default', name: 'test-db' - } + }; await act(async () => { - await result.current.mutateAsync(params) - }) + await result.current.mutateAsync(params); + }); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) - }) - }) + expect(result.current.isSuccess).toBe(true); + }); + }); + }); describe('Error handling', () => { it('should handle backup creation errors', async () => { @@ -329,62 +330,62 @@ describe('useCreateBackup', () => { return HttpResponse.json( { error: 'Backup creation failed' }, { status: 500 } - ) + ); }) - ) + ); - const { result } = renderHook(() => useCreateBackup()) + const { result } = renderHook(() => useCreateBackup()); const params = { ns: 'default', name: 'test-db', method: 'pg_dump' - } + }; await act(async () => { try { - await result.current.mutateAsync(params) + await result.current.mutateAsync(params); } catch (error) { // Expected to throw } - }) + }); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) - expect(result.current.error).toBeDefined() - }) - }) + expect(result.current.isError).toBe(true); + }); + expect(result.current.error).toBeDefined(); + }); + }); describe('Loading states', () => { it('should show loading state during backup creation', async () => { server.use( http.post('/api/databases/:ns/:name/backups', async () => { - await new Promise(resolve => setTimeout(resolve, 100)) - return HttpResponse.json({ success: true }) + await new Promise(resolve => setTimeout(resolve, 100)); + return HttpResponse.json({ success: true }); }) - ) + ); - const { result } = renderHook(() => useCreateBackup()) + const { result } = renderHook(() => useCreateBackup()); const params = { ns: 'default', name: 'test-db', method: 'pg_dump' - } + }; act(() => { - result.current.mutate(params) - }) + result.current.mutate(params); + }); // Check that mutation is pending (may be very quick) - expect(result.current.isPending).toBeDefined() + expect(result.current.isPending).toBeDefined(); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.isPending).toBe(false) - }) - }) -}) \ No newline at end of file + expect(result.current.isPending).toBe(false); + }); + }); +}); \ No newline at end of file diff --git a/apps/ops-dashboard/__tests__/hooks/useDebounce.test.ts b/apps/ops-dashboard/__tests__/hooks/useDebounce.test.ts index cbe5511..1900322 100644 --- a/apps/ops-dashboard/__tests__/hooks/useDebounce.test.ts +++ b/apps/ops-dashboard/__tests__/hooks/useDebounce.test.ts @@ -1,119 +1,120 @@ -import { renderHook, act } from '@testing-library/react' -import { useDebounce } from '../../hooks/use-debounce' +import { act,renderHook } from '@testing-library/react'; + +import { useDebounce } from '../../hooks/use-debounce'; describe('useDebounce', () => { beforeEach(() => { - jest.useFakeTimers() - }) + jest.useFakeTimers(); + }); afterEach(() => { - jest.useRealTimers() - }) + jest.useRealTimers(); + }); it('应该返回初始值', () => { - const { result } = renderHook(() => useDebounce('initial', 100)) + const { result } = renderHook(() => useDebounce('initial', 100)); - expect(result.current).toBe('initial') - }) + expect(result.current).toBe('initial'); + }); it('应该在延迟后更新值', () => { const { result, rerender } = renderHook( ({ value, delay }) => useDebounce(value, delay), { initialProps: { value: 'initial', delay: 100 } } - ) + ); - expect(result.current).toBe('initial') + expect(result.current).toBe('initial'); // 更新值 - rerender({ value: 'updated', delay: 100 }) + rerender({ value: 'updated', delay: 100 }); // 延迟时间未到,值应该还是旧的 - expect(result.current).toBe('initial') + expect(result.current).toBe('initial'); // 快进时间 act(() => { - jest.advanceTimersByTime(100) - }) + jest.advanceTimersByTime(100); + }); // 现在值应该更新了 - expect(result.current).toBe('updated') - }) + expect(result.current).toBe('updated'); + }); it('应该取消之前的更新如果值再次改变', () => { const { result, rerender } = renderHook( ({ value, delay }) => useDebounce(value, delay), { initialProps: { value: 'initial', delay: 100 } } - ) + ); // 第一次更新 - rerender({ value: 'first', delay: 100 }) + rerender({ value: 'first', delay: 100 }); // 快进50ms act(() => { - jest.advanceTimersByTime(50) - }) + jest.advanceTimersByTime(50); + }); // 值应该还是旧的 - expect(result.current).toBe('initial') + expect(result.current).toBe('initial'); // 第二次更新(应该取消第一次) - rerender({ value: 'second', delay: 100 }) + rerender({ value: 'second', delay: 100 }); // 快进100ms(完整的延迟时间) act(() => { - jest.advanceTimersByTime(100) - }) + jest.advanceTimersByTime(100); + }); // 值应该是第二次更新的值 - expect(result.current).toBe('second') - }) + expect(result.current).toBe('second'); + }); it('应该处理空值', () => { const { result, rerender } = renderHook( ({ value, delay }) => useDebounce(value, delay), { initialProps: { value: null, delay: 100 } } - ) + ); - expect(result.current).toBe(null) + expect(result.current).toBe(null); - rerender({ value: 'test', delay: 100 }) + rerender({ value: 'test', delay: 100 }); act(() => { - jest.advanceTimersByTime(100) - }) + jest.advanceTimersByTime(100); + }); - expect(result.current).toBe('test') - }) + expect(result.current).toBe('test'); + }); it('应该处理零延迟', () => { const { result, rerender } = renderHook( ({ value, delay }) => useDebounce(value, delay), { initialProps: { value: 'initial', delay: 0 } } - ) + ); - rerender({ value: 'updated', delay: 0 }) + rerender({ value: 'updated', delay: 0 }); // 零延迟应该立即更新 act(() => { - jest.runAllTimers() - }) + jest.runAllTimers(); + }); - expect(result.current).toBe('updated') - }) + expect(result.current).toBe('updated'); + }); it('应该清理定时器在组件卸载时', () => { - const clearTimeoutSpy = jest.spyOn(global, 'clearTimeout') + const clearTimeoutSpy = jest.spyOn(global, 'clearTimeout'); const { unmount, rerender } = renderHook( ({ value, delay }) => useDebounce(value, delay), { initialProps: { value: 'initial', delay: 100 } } - ) + ); - rerender({ value: 'updated', delay: 100 }) + rerender({ value: 'updated', delay: 100 }); - unmount() + unmount(); - expect(clearTimeoutSpy).toHaveBeenCalled() + expect(clearTimeoutSpy).toHaveBeenCalled(); - clearTimeoutSpy.mockRestore() - }) -}) + clearTimeoutSpy.mockRestore(); + }); +}); diff --git a/apps/ops-dashboard/__tests__/hooks/useDeployments.test.tsx b/apps/ops-dashboard/__tests__/hooks/useDeployments.test.tsx index 034834b..ae1d04a 100644 --- a/apps/ops-dashboard/__tests__/hooks/useDeployments.test.tsx +++ b/apps/ops-dashboard/__tests__/hooks/useDeployments.test.tsx @@ -1,32 +1,30 @@ -import { renderHook, waitFor, act } from '../utils/test-utils' -import { - useDeployments, - useCreateDeployment, - useUpdateDeployment, - useDeleteDeployment, - useScaleDeployment -} from '../../hooks/useDeployments' -import { server } from '../../__mocks__/server' import { createAllDeploymentsList, + createAllDeploymentsListError, + createDeploymentErrorHandler, + createDeploymentHandler, createDeploymentsList, createDeploymentsListData, createDeploymentsListError, - createAllDeploymentsListError, createDeploymentsListNetworkError, createDeploymentsListSlow, - createDeploymentHandler, - createDeploymentErrorHandler, - updateDeploymentHandler, - updateDeploymentErrorHandler, - deleteDeploymentHandler, deleteDeploymentErrorHandler, - scaleDeploymentHandler, + deleteDeploymentHandler, scaleDeploymentErrorHandler, - scaleDeploymentWithNamespaceValidationHandler -} from '../../__mocks__/handlers/deployments' + scaleDeploymentHandler, + scaleDeploymentWithNamespaceValidationHandler, + updateDeploymentErrorHandler, + updateDeploymentHandler} from '../../__mocks__/handlers/deployments'; +import { server } from '../../__mocks__/server'; +import { + useCreateDeployment, + useDeleteDeployment, + useDeployments, + useScaleDeployment, + useUpdateDeployment} from '../../hooks/useDeployments'; +import { act,renderHook, waitFor } from '../utils/test-utils'; /** * useDeployments Hook Tests @@ -56,142 +54,142 @@ import { describe('useDeployments', () => { it('should successfully fetch deployment list', async () => { - server.use(createDeploymentsList()) + server.use(createDeploymentsList()); - const { result } = renderHook(() => useDeployments('default')) + const { result } = renderHook(() => useDeployments('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).toBeDefined() - expect(result.current.data?.items).toHaveLength(2) - expect(result.current.data?.items[0].metadata.name).toBe('nginx-deployment') - expect(result.current.data?.items[1].metadata.name).toBe('redis-deployment') - }) + expect(result.current.data).toBeDefined(); + expect(result.current.data?.items).toHaveLength(2); + expect(result.current.data?.items[0].metadata.name).toBe('nginx-deployment'); + expect(result.current.data?.items[1].metadata.name).toBe('redis-deployment'); + }); it('should handle empty deployment list', async () => { - server.use(createDeploymentsList([])) + server.use(createDeploymentsList([])); - const { result } = renderHook(() => useDeployments('default')) + const { result } = renderHook(() => useDeployments('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(0) - }) + expect(result.current.data?.items).toHaveLength(0); + }); it('should support _all namespace', async () => { - const mock = createDeploymentsListData() - server.use(createAllDeploymentsList(mock)) + const mock = createDeploymentsListData(); + server.use(createAllDeploymentsList(mock)); - const { result } = renderHook(() => useDeployments('_all')) + const { result } = renderHook(() => useDeployments('_all')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(2) - expect(result.current.data?.items[0].metadata.name).toBe(mock[0]?.metadata?.name) - expect(result.current.data?.items[1].metadata.name).toBe(mock[1]?.metadata?.name) - }) + expect(result.current.data?.items).toHaveLength(2); + expect(result.current.data?.items[0].metadata.name).toBe(mock[0]?.metadata?.name); + expect(result.current.data?.items[1].metadata.name).toBe(mock[1]?.metadata?.name); + }); it('should complete loading successfully', async () => { - server.use(createDeploymentsList()) + server.use(createDeploymentsList()); - const { result } = renderHook(() => useDeployments('default')) + const { result } = renderHook(() => useDeployments('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.isLoading).toBe(false) - expect(result.current.data).toBeDefined() - }) + expect(result.current.isLoading).toBe(false); + expect(result.current.data).toBeDefined(); + }); it('should show loading state initially', async () => { - server.use(createDeploymentsListSlow([], 100)) + server.use(createDeploymentsListSlow([], 100)); - const { result } = renderHook(() => useDeployments('default')) + const { result } = renderHook(() => useDeployments('default')); - expect(result.current.isLoading).toBe(true) - expect(result.current.data).toBeUndefined() + expect(result.current.isLoading).toBe(true); + expect(result.current.data).toBeUndefined(); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.isLoading).toBe(false) - expect(result.current.data).toBeDefined() - }) + expect(result.current.isLoading).toBe(false); + expect(result.current.data).toBeDefined(); + }); it('should handle slow responses', async () => { - server.use(createDeploymentsListSlow(createDeploymentsListData(), 200)) + server.use(createDeploymentsListSlow(createDeploymentsListData(), 200)); - const { result } = renderHook(() => useDeployments('default')) + const { result } = renderHook(() => useDeployments('default')); - expect(result.current.isLoading).toBe(true) + expect(result.current.isLoading).toBe(true); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }, { timeout: 1000 }) + expect(result.current.isSuccess).toBe(true); + }, { timeout: 1000 }); - expect(result.current.isLoading).toBe(false) - expect(result.current.data?.items).toHaveLength(2) - }) + expect(result.current.isLoading).toBe(false); + expect(result.current.data?.items).toHaveLength(2); + }); it('should handle API errors (500)', async () => { - server.use(createDeploymentsListError(500, 'Internal Server Error')) + server.use(createDeploymentsListError(500, 'Internal Server Error')); - const { result } = renderHook(() => useDeployments('default')) + const { result } = renderHook(() => useDeployments('default')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); it('should handle API errors (404)', async () => { - server.use(createDeploymentsListError(404, 'Not Found')) + server.use(createDeploymentsListError(404, 'Not Found')); - const { result } = renderHook(() => useDeployments('default')) + const { result } = renderHook(() => useDeployments('default')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); it('should handle network errors', async () => { - server.use(createDeploymentsListNetworkError()) + server.use(createDeploymentsListNetworkError()); - const { result } = renderHook(() => useDeployments('default')) + const { result } = renderHook(() => useDeployments('default')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); it('should handle _all namespace API errors', async () => { - server.use(createAllDeploymentsListError(500, 'Server Error')) + server.use(createAllDeploymentsListError(500, 'Server Error')); - const { result } = renderHook(() => useDeployments('_all')) + const { result } = renderHook(() => useDeployments('_all')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); it('should correctly transform deployment data', async () => { const customDeployments = [ @@ -219,21 +217,21 @@ describe('useDeployments', () => { ] } } - ] + ]; - server.use(createDeploymentsList(customDeployments)) + server.use(createDeploymentsList(customDeployments)); - const { result } = renderHook(() => useDeployments('default')) + const { result } = renderHook(() => useDeployments('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(1) - expect(result.current.data?.items[0].metadata.name).toBe('test-deployment') - expect(result.current.data?.items[0].spec.replicas).toBe(2) - expect(result.current.data?.items[0].status.readyReplicas).toBe(2) - }) + expect(result.current.data?.items).toHaveLength(1); + expect(result.current.data?.items[0].metadata.name).toBe('test-deployment'); + expect(result.current.data?.items[0].spec.replicas).toBe(2); + expect(result.current.data?.items[0].status.readyReplicas).toBe(2); + }); it('should handle different namespaces correctly', async () => { const multiNamespaceDeployments = [ @@ -255,63 +253,63 @@ describe('useDeployments', () => { spec: { replicas: 1 }, status: { readyReplicas: 1, replicas: 1 } } - ] + ]; - server.use(createDeploymentsList(multiNamespaceDeployments)) + server.use(createDeploymentsList(multiNamespaceDeployments)); - const { result } = renderHook(() => useDeployments('default')) + const { result } = renderHook(() => useDeployments('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); // Should only return deployments from 'default' namespace - expect(result.current.data?.items).toHaveLength(1) - expect(result.current.data?.items[0].metadata.namespace).toBe('default') - }) + expect(result.current.data?.items).toHaveLength(1); + expect(result.current.data?.items[0].metadata.namespace).toBe('default'); + }); it('should cache data between renders', async () => { - server.use(createDeploymentsList()) + server.use(createDeploymentsList()); - const { result, rerender } = renderHook(() => useDeployments('default')) + const { result, rerender } = renderHook(() => useDeployments('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - const firstData = result.current.data + const firstData = result.current.data; // Re-render should use cached data - rerender() + rerender(); - expect(result.current.data).toBe(firstData) - }) + expect(result.current.data).toBe(firstData); + }); it('should refetch when namespace changes', async () => { - server.use(createDeploymentsList()) + server.use(createDeploymentsList()); const { result, rerender } = renderHook( ({ namespace }) => useDeployments(namespace), { initialProps: { namespace: 'default' } } - ) + ); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - const firstData = result.current.data + const firstData = result.current.data; // Change namespace - rerender({ namespace: 'kube-system' }) + rerender({ namespace: 'kube-system' }); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); // Should have different data (even if empty, it's a new query) - expect(result.current.data).not.toBe(firstData) - }) -}) + expect(result.current.data).not.toBe(firstData); + }); +}); // ============================================================================ // MUTATION HOOKS TESTS @@ -334,46 +332,46 @@ describe('useCreateDeployment', () => { } }, status: { readyReplicas: 0, replicas: 0 } - } + }; it('should create deployment successfully', async () => { - server.use(createDeploymentHandler(mockDeployment)) + server.use(createDeploymentHandler(mockDeployment)); - const { result } = renderHook(() => useCreateDeployment()) + const { result } = renderHook(() => useCreateDeployment()); await act(async () => { await result.current.mutateAsync({ deployment: mockDeployment, namespace: 'default' - }) - }) + }); + }); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) - }) + expect(result.current.isSuccess).toBe(true); + }); + }); it('should handle creation errors', async () => { - server.use(createDeploymentErrorHandler(400, 'Creation failed')) + server.use(createDeploymentErrorHandler(400, 'Creation failed')); - const { result } = renderHook(() => useCreateDeployment()) + const { result } = renderHook(() => useCreateDeployment()); await act(async () => { try { await result.current.mutateAsync({ deployment: {} as any, namespace: 'default' - }) + }); } catch (error) { // Expected to throw } - }) + }); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) - }) -}) + expect(result.current.isError).toBe(true); + }); + }); +}); describe('useUpdateDeployment', () => { const mockDeployment = { @@ -392,30 +390,30 @@ describe('useUpdateDeployment', () => { } }, status: { readyReplicas: 0, replicas: 0 } - } + }; it('should update deployment successfully', async () => { - server.use(updateDeploymentHandler(mockDeployment)) + server.use(updateDeploymentHandler(mockDeployment)); - const { result } = renderHook(() => useUpdateDeployment()) + const { result } = renderHook(() => useUpdateDeployment()); await act(async () => { await result.current.mutateAsync({ name: 'test-deployment', deployment: mockDeployment, namespace: 'default' - }) - }) + }); + }); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) - }) + expect(result.current.isSuccess).toBe(true); + }); + }); it('should handle update errors', async () => { - server.use(updateDeploymentErrorHandler(400, 'Update failed')) + server.use(updateDeploymentErrorHandler(400, 'Update failed')); - const { result } = renderHook(() => useUpdateDeployment()) + const { result } = renderHook(() => useUpdateDeployment()); await act(async () => { try { @@ -423,81 +421,81 @@ describe('useUpdateDeployment', () => { name: 'test-deployment', deployment: {} as any, namespace: 'default' - }) + }); } catch (error) { // Expected to throw } - }) + }); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) - }) -}) + expect(result.current.isError).toBe(true); + }); + }); +}); describe('useDeleteDeployment', () => { it('should delete deployment successfully', async () => { - server.use(deleteDeploymentHandler()) + server.use(deleteDeploymentHandler()); - const { result } = renderHook(() => useDeleteDeployment()) + const { result } = renderHook(() => useDeleteDeployment()); await act(async () => { await result.current.mutateAsync({ name: 'test-deployment', namespace: 'default' - }) - }) + }); + }); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) - }) + expect(result.current.isSuccess).toBe(true); + }); + }); it('should handle deletion errors', async () => { - server.use(deleteDeploymentErrorHandler(404, 'Deletion failed')) + server.use(deleteDeploymentErrorHandler(404, 'Deletion failed')); - const { result } = renderHook(() => useDeleteDeployment()) + const { result } = renderHook(() => useDeleteDeployment()); await act(async () => { try { await result.current.mutateAsync({ name: 'non-existent-deployment', namespace: 'default' - }) + }); } catch (error) { // Expected to throw } - }) + }); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) - }) -}) + expect(result.current.isError).toBe(true); + }); + }); +}); describe('useScaleDeployment', () => { it('should scale deployment successfully', async () => { - server.use(scaleDeploymentHandler(5)) + server.use(scaleDeploymentHandler(5)); - const { result } = renderHook(() => useScaleDeployment()) + const { result } = renderHook(() => useScaleDeployment()); await act(async () => { await result.current.mutateAsync({ name: 'test-deployment', replicas: 5, namespace: 'default' - }) - }) + }); + }); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) - }) + expect(result.current.isSuccess).toBe(true); + }); + }); it('should handle scaling errors', async () => { - server.use(scaleDeploymentErrorHandler(400, 'Scaling failed')) + server.use(scaleDeploymentErrorHandler(400, 'Scaling failed')); - const { result } = renderHook(() => useScaleDeployment()) + const { result } = renderHook(() => useScaleDeployment()); await act(async () => { try { @@ -505,32 +503,32 @@ describe('useScaleDeployment', () => { name: 'test-deployment', replicas: -1, // Invalid replicas namespace: 'default' - }) + }); } catch (error) { // Expected to throw } - }) + }); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) - }) + expect(result.current.isError).toBe(true); + }); + }); it('should use default namespace when not provided', async () => { - server.use(scaleDeploymentWithNamespaceValidationHandler(3, 'default')) + server.use(scaleDeploymentWithNamespaceValidationHandler(3, 'default')); - const { result } = renderHook(() => useScaleDeployment()) + const { result } = renderHook(() => useScaleDeployment()); await act(async () => { await result.current.mutateAsync({ name: 'test-deployment', replicas: 3 // No namespace provided, should use default - }) - }) + }); + }); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) - }) -}) + expect(result.current.isSuccess).toBe(true); + }); + }); +}); diff --git a/apps/ops-dashboard/__tests__/hooks/useNamespaces.test.tsx b/apps/ops-dashboard/__tests__/hooks/useNamespaces.test.tsx index 22112ba..8a19650 100644 --- a/apps/ops-dashboard/__tests__/hooks/useNamespaces.test.tsx +++ b/apps/ops-dashboard/__tests__/hooks/useNamespaces.test.tsx @@ -1,135 +1,134 @@ +import { http, HttpResponse } from 'msw'; + import { - useNamespaces, - useNamespace, - useCreateNamespace, - useDeleteNamespace -} from '../../hooks/useNamespaces' -import { server } from '../../__mocks__/server' -import { http, HttpResponse } from 'msw' -import { renderHook, waitFor, act } from '../utils/test-utils' -import { + createNamespace, createNamespacesList, createNamespacesListData, createNamespacesListError, createNamespacesListNetworkError, createNamespacesListSlow, - getNamespace, - createNamespace, - deleteNamespace -} from '../../__mocks__/handlers/namespaces' + deleteNamespace, + getNamespace} from '../../__mocks__/handlers/namespaces'; +import { server } from '../../__mocks__/server'; +import { + useCreateNamespace, + useDeleteNamespace, + useNamespace, + useNamespaces} from '../../hooks/useNamespaces'; +import { act,renderHook, waitFor } from '../utils/test-utils'; describe('useNamespaces', () => { it('should successfully fetch namespaces list', async () => { - server.use(createNamespacesList()) + server.use(createNamespacesList()); - const { result } = renderHook(() => useNamespaces()) + const { result } = renderHook(() => useNamespaces()); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).toBeDefined() - expect(result.current.data?.items).toHaveLength(4) - expect(result.current.data?.items[0].metadata.name).toBe('default') - expect(result.current.data?.items[1].metadata.name).toBe('kube-system') - expect(result.current.data?.items[2].metadata.name).toBe('kube-public') - expect(result.current.data?.items[3].metadata.name).toBe('test-namespace') - }) + expect(result.current.data).toBeDefined(); + expect(result.current.data?.items).toHaveLength(4); + expect(result.current.data?.items[0].metadata.name).toBe('default'); + expect(result.current.data?.items[1].metadata.name).toBe('kube-system'); + expect(result.current.data?.items[2].metadata.name).toBe('kube-public'); + expect(result.current.data?.items[3].metadata.name).toBe('test-namespace'); + }); it('should handle empty namespaces list', async () => { - server.use(createNamespacesList([])) + server.use(createNamespacesList([])); - const { result } = renderHook(() => useNamespaces()) + const { result } = renderHook(() => useNamespaces()); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(0) - }) + expect(result.current.data?.items).toHaveLength(0); + }); it('should complete loading successfully', async () => { - server.use(createNamespacesList()) + server.use(createNamespacesList()); - const { result } = renderHook(() => useNamespaces()) + const { result } = renderHook(() => useNamespaces()); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.isLoading).toBe(false) - expect(result.current.data).toBeDefined() - }) + expect(result.current.isLoading).toBe(false); + expect(result.current.data).toBeDefined(); + }); it('should show loading state initially', async () => { - server.use(createNamespacesListSlow([], 100)) + server.use(createNamespacesListSlow([], 100)); - const { result } = renderHook(() => useNamespaces()) + const { result } = renderHook(() => useNamespaces()); - expect(result.current.isLoading).toBe(true) - expect(result.current.data).toBeUndefined() + expect(result.current.isLoading).toBe(true); + expect(result.current.data).toBeUndefined(); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.isLoading).toBe(false) - expect(result.current.data).toBeDefined() - }) + expect(result.current.isLoading).toBe(false); + expect(result.current.data).toBeDefined(); + }); it('should handle slow responses', async () => { - server.use(createNamespacesListSlow(createNamespacesListData(), 200)) + server.use(createNamespacesListSlow(createNamespacesListData(), 200)); - const { result } = renderHook(() => useNamespaces()) + const { result } = renderHook(() => useNamespaces()); - expect(result.current.isLoading).toBe(true) + expect(result.current.isLoading).toBe(true); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }, { timeout: 1000 }) + expect(result.current.isSuccess).toBe(true); + }, { timeout: 1000 }); - expect(result.current.isLoading).toBe(false) - expect(result.current.data?.items).toHaveLength(4) - }) + expect(result.current.isLoading).toBe(false); + expect(result.current.data?.items).toHaveLength(4); + }); it('should handle API errors (500)', async () => { - server.use(createNamespacesListError(500, 'Internal Server Error')) + server.use(createNamespacesListError(500, 'Internal Server Error')); - const { result } = renderHook(() => useNamespaces()) + const { result } = renderHook(() => useNamespaces()); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); it('should handle API errors (403)', async () => { - server.use(createNamespacesListError(403, 'Forbidden')) + server.use(createNamespacesListError(403, 'Forbidden')); - const { result } = renderHook(() => useNamespaces()) + const { result } = renderHook(() => useNamespaces()); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); it('should handle network errors', async () => { - server.use(createNamespacesListNetworkError()) + server.use(createNamespacesListNetworkError()); - const { result } = renderHook(() => useNamespaces()) + const { result } = renderHook(() => useNamespaces()); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); it('should correctly transform namespace data', async () => { const customNamespaces = [ @@ -139,28 +138,28 @@ describe('useNamespaces', () => { uid: 'ns-1', labels: { 'kubernetes.io/metadata.name': 'custom-namespace', - 'environment': 'production' + environment: 'production' }, creationTimestamp: new Date('2023-06-01T12:00:00Z') }, spec: {}, status: { phase: 'Active' } } - ] + ]; - server.use(createNamespacesList(customNamespaces)) + server.use(createNamespacesList(customNamespaces)); - const { result } = renderHook(() => useNamespaces()) + const { result } = renderHook(() => useNamespaces()); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(1) - expect(result.current.data?.items[0].metadata.name).toBe('custom-namespace') - expect(result.current.data?.items[0].status.phase).toBe('Active') - expect(result.current.data?.items[0].metadata.labels?.environment).toBe('production') - }) + expect(result.current.data?.items).toHaveLength(1); + expect(result.current.data?.items[0].metadata.name).toBe('custom-namespace'); + expect(result.current.data?.items[0].status.phase).toBe('Active'); + expect(result.current.data?.items[0].metadata.labels?.environment).toBe('production'); + }); it('should handle different namespace statuses', async () => { const multiStatusNamespaces = [ @@ -182,37 +181,37 @@ describe('useNamespaces', () => { spec: {}, status: { phase: 'Terminating' } } - ] + ]; - server.use(createNamespacesList(multiStatusNamespaces)) + server.use(createNamespacesList(multiStatusNamespaces)); - const { result } = renderHook(() => useNamespaces()) + const { result } = renderHook(() => useNamespaces()); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(2) - expect(result.current.data?.items[0].status.phase).toBe('Active') - expect(result.current.data?.items[1].status.phase).toBe('Terminating') - }) + expect(result.current.data?.items).toHaveLength(2); + expect(result.current.data?.items[0].status.phase).toBe('Active'); + expect(result.current.data?.items[1].status.phase).toBe('Terminating'); + }); it('should cache data between renders', async () => { - server.use(createNamespacesList()) + server.use(createNamespacesList()); - const { result, rerender } = renderHook(() => useNamespaces()) + const { result, rerender } = renderHook(() => useNamespaces()); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - const firstData = result.current.data + const firstData = result.current.data; - rerender() + rerender(); - expect(result.current.data).toBe(firstData) - }) -}) + expect(result.current.data).toBe(firstData); + }); +}); // ============================================================================ // MUTATION HOOKS TESTS @@ -224,149 +223,149 @@ describe('useNamespace', () => { metadata: { name: 'test-namespace', uid: 'ns-1' }, spec: {}, status: { phase: 'Active' } - } + }; - server.use(getNamespace(mockNamespace)) + server.use(getNamespace(mockNamespace)); - const { result } = renderHook(() => useNamespace('test-namespace')) + const { result } = renderHook(() => useNamespace('test-namespace')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).toEqual(mockNamespace) - }) + expect(result.current.data).toEqual(mockNamespace); + }); it('should handle namespace not found', async () => { const handler = http.get('http://localhost:8001/api/v1/namespaces/:name', () => { - return HttpResponse.json({ error: 'Namespace not found' }, { status: 404 }) - }) + return HttpResponse.json({ error: 'Namespace not found' }, { status: 404 }); + }); - server.use(handler) + server.use(handler); - const { result } = renderHook(() => useNamespace('non-existent')) + const { result } = renderHook(() => useNamespace('non-existent')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - }) -}) + expect(result.current.error).toBeDefined(); + }); +}); describe('useCreateNamespace', () => { it('should create namespace successfully', async () => { - server.use(createNamespace()) + server.use(createNamespace()); - const { result } = renderHook(() => useCreateNamespace()) + const { result } = renderHook(() => useCreateNamespace()); await act(async () => { await result.current.mutateAsync({ name: 'new-namespace', labels: { environment: 'test' } - }) - }) + }); + }); - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); it('should create namespace without labels', async () => { - server.use(createNamespace()) + server.use(createNamespace()); - const { result } = renderHook(() => useCreateNamespace()) + const { result } = renderHook(() => useCreateNamespace()); await act(async () => { await result.current.mutateAsync({ name: 'new-namespace' - }) - }) + }); + }); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) - }) + expect(result.current.isSuccess).toBe(true); + }); + }); it('should handle creation errors', async () => { const handler = http.post('http://localhost:8001/api/v1/namespaces', () => { - return HttpResponse.json({ error: 'Creation failed' }, { status: 400 }) - }) + return HttpResponse.json({ error: 'Creation failed' }, { status: 400 }); + }); - server.use(handler) + server.use(handler); - const { result } = renderHook(() => useCreateNamespace()) + const { result } = renderHook(() => useCreateNamespace()); await act(async () => { try { await result.current.mutateAsync({ name: 'invalid-namespace-name!' - }) + }); } catch (error) { // Expected to throw } - }) + }); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) - }) -}) + expect(result.current.isError).toBe(true); + }); + }); +}); describe('useDeleteNamespace', () => { it('should delete namespace successfully', async () => { - server.use(deleteNamespace()) + server.use(deleteNamespace()); - const { result } = renderHook(() => useDeleteNamespace()) + const { result } = renderHook(() => useDeleteNamespace()); await act(async () => { - await result.current.mutateAsync('test-namespace') - }) + await result.current.mutateAsync('test-namespace'); + }); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) - }) + expect(result.current.isSuccess).toBe(true); + }); + }); it('should handle deletion errors', async () => { const handler = http.delete('http://localhost:8001/api/v1/namespaces/:name', () => { - return HttpResponse.json({ error: 'Deletion failed' }, { status: 404 }) - }) + return HttpResponse.json({ error: 'Deletion failed' }, { status: 404 }); + }); - server.use(handler) + server.use(handler); - const { result } = renderHook(() => useDeleteNamespace()) + const { result } = renderHook(() => useDeleteNamespace()); await act(async () => { try { - await result.current.mutateAsync('non-existent-namespace') + await result.current.mutateAsync('non-existent-namespace'); } catch (error) { // Expected to throw } - }) + }); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) - }) + expect(result.current.isError).toBe(true); + }); + }); it('should handle forbidden deletion', async () => { const handler = http.delete('http://localhost:8001/api/v1/namespaces/:name', () => { - return HttpResponse.json({ error: 'Forbidden' }, { status: 403 }) - }) + return HttpResponse.json({ error: 'Forbidden' }, { status: 403 }); + }); - server.use(handler) + server.use(handler); - const { result } = renderHook(() => useDeleteNamespace()) + const { result } = renderHook(() => useDeleteNamespace()); await act(async () => { try { - await result.current.mutateAsync('kube-system') + await result.current.mutateAsync('kube-system'); } catch (error) { // Expected to throw } - }) + }); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) - }) -}) \ No newline at end of file + expect(result.current.isError).toBe(true); + }); + }); +}); \ No newline at end of file diff --git a/apps/ops-dashboard/__tests__/hooks/useOperators.test.tsx b/apps/ops-dashboard/__tests__/hooks/useOperators.test.tsx index 7b7992b..7c77de0 100644 --- a/apps/ops-dashboard/__tests__/hooks/useOperators.test.tsx +++ b/apps/ops-dashboard/__tests__/hooks/useOperators.test.tsx @@ -1,146 +1,144 @@ -import { renderHook, waitFor, act } from '../utils/test-utils' -import { useOperators, useOperatorMutation } from '../../hooks/use-operators' -import { server } from '../../__mocks__/server' -import { http, HttpResponse } from 'msw' + import { + createInstallOperator, + createInstallOperatorError, + createInstallOperatorSlow, createOperatorsList, - createOperatorsListData, createOperatorsListError, createOperatorsListNetworkError, - createInstallOperator, - createInstallOperatorError, createUninstallOperator, - createUninstallOperatorError, - createInstallOperatorSlow -} from '../../__mocks__/handlers/operators' + createUninstallOperatorError} from '../../__mocks__/handlers/operators'; +import { server } from '../../__mocks__/server'; +import { useOperatorMutation,useOperators } from '../../hooks/use-operators'; +import { act,renderHook, waitFor } from '../utils/test-utils'; -const API_BASE = 'http://localhost:8001' +const API_BASE = 'http://localhost:8001'; describe('useOperators', () => { describe('Success scenarios', () => { it('should successfully fetch operators list', async () => { - server.use(createOperatorsList()) + server.use(createOperatorsList()); - const { result } = renderHook(() => useOperators()) + const { result } = renderHook(() => useOperators()); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).toBeDefined() - expect(result.current.data).toHaveLength(5) - expect(result.current.data?.[0].name).toBe('cert-manager') - expect(result.current.data?.[0].status).toBe('installed') - expect(result.current.data?.[1].name).toBe('cloudnative-pg') - expect(result.current.data?.[1].status).toBe('installed') - }) + expect(result.current.data).toBeDefined(); + expect(result.current.data).toHaveLength(5); + expect(result.current.data?.[0].name).toBe('cert-manager'); + expect(result.current.data?.[0].status).toBe('installed'); + expect(result.current.data?.[1].name).toBe('cloudnative-pg'); + expect(result.current.data?.[1].status).toBe('installed'); + }); it('should handle empty operators list', async () => { - server.use(createOperatorsList([])) + server.use(createOperatorsList([])); - const { result } = renderHook(() => useOperators()) + const { result } = renderHook(() => useOperators()); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).toHaveLength(0) - }) + expect(result.current.data).toHaveLength(0); + }); it('should refetch at specified interval', async () => { - server.use(createOperatorsList()) + server.use(createOperatorsList()); - const { result } = renderHook(() => useOperators()) + const { result } = renderHook(() => useOperators()); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).toHaveLength(5) - expect(result.current.isRefetching).toBe(false) - }) - }) + expect(result.current.data).toHaveLength(5); + expect(result.current.isRefetching).toBe(false); + }); + }); describe('Loading states', () => { it('should show loading state initially', async () => { - server.use(createOperatorsList()) + server.use(createOperatorsList()); - const { result } = renderHook(() => useOperators()) + const { result } = renderHook(() => useOperators()); - expect(result.current.isLoading).toBe(true) - expect(result.current.data).toBeUndefined() + expect(result.current.isLoading).toBe(true); + expect(result.current.data).toBeUndefined(); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.isLoading).toBe(false) - expect(result.current.data).toBeDefined() - }) + expect(result.current.isLoading).toBe(false); + expect(result.current.data).toBeDefined(); + }); it('should handle refetching state', async () => { - server.use(createOperatorsList()) + server.use(createOperatorsList()); - const { result } = renderHook(() => useOperators()) + const { result } = renderHook(() => useOperators()); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); // Trigger a refetch act(() => { - result.current.refetch() - }) + result.current.refetch(); + }); // Check that refetching is happening (may be very quick) - expect(result.current.isRefetching).toBeDefined() + expect(result.current.isRefetching).toBeDefined(); await waitFor(() => { - expect(result.current.isRefetching).toBe(false) - }) - }) - }) + expect(result.current.isRefetching).toBe(false); + }); + }); + }); describe('Error handling', () => { it('should handle API errors (500)', async () => { - server.use(createOperatorsListError(500, 'Internal Server Error')) + server.use(createOperatorsListError(500, 'Internal Server Error')); - const { result } = renderHook(() => useOperators()) + const { result } = renderHook(() => useOperators()); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); it('should handle API errors (404)', async () => { - server.use(createOperatorsListError(404, 'Not Found')) + server.use(createOperatorsListError(404, 'Not Found')); - const { result } = renderHook(() => useOperators()) + const { result } = renderHook(() => useOperators()); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); it('should handle network errors', async () => { - server.use(createOperatorsListNetworkError()) + server.use(createOperatorsListNetworkError()); - const { result } = renderHook(() => useOperators()) + const { result } = renderHook(() => useOperators()); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); + }); describe('Data transformation', () => { it('should correctly transform operator data', async () => { @@ -156,22 +154,22 @@ describe('useOperators', () => { status: 'not-installed' as const, description: 'Another test operator' } - ] + ]; - server.use(createOperatorsList(customOperators)) + server.use(createOperatorsList(customOperators)); - const { result } = renderHook(() => useOperators()) + const { result } = renderHook(() => useOperators()); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).toHaveLength(2) - expect(result.current.data?.[0].name).toBe('test-operator') - expect(result.current.data?.[0].status).toBe('installed') - expect(result.current.data?.[0].version).toBe('v1.0.0') - expect(result.current.data?.[1].status).toBe('not-installed') - }) + expect(result.current.data).toHaveLength(2); + expect(result.current.data?.[0].name).toBe('test-operator'); + expect(result.current.data?.[0].status).toBe('installed'); + expect(result.current.data?.[0].version).toBe('v1.0.0'); + expect(result.current.data?.[1].status).toBe('not-installed'); + }); it('should handle different operator statuses', async () => { const multiStatusOperators = [ @@ -179,212 +177,212 @@ describe('useOperators', () => { { name: 'not-installed-op', status: 'not-installed' as const }, { name: 'installing-op', status: 'installing' as const }, { name: 'error-op', status: 'error' as const, version: 'v0.9.0' } - ] + ]; - server.use(createOperatorsList(multiStatusOperators)) + server.use(createOperatorsList(multiStatusOperators)); - const { result } = renderHook(() => useOperators()) + const { result } = renderHook(() => useOperators()); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).toHaveLength(4) - expect(result.current.data?.[0].status).toBe('installed') - expect(result.current.data?.[1].status).toBe('not-installed') - expect(result.current.data?.[2].status).toBe('installing') - expect(result.current.data?.[3].status).toBe('error') - }) - }) + expect(result.current.data).toHaveLength(4); + expect(result.current.data?.[0].status).toBe('installed'); + expect(result.current.data?.[1].status).toBe('not-installed'); + expect(result.current.data?.[2].status).toBe('installing'); + expect(result.current.data?.[3].status).toBe('error'); + }); + }); describe('Caching behavior', () => { it('should cache data between renders', async () => { - server.use(createOperatorsList()) + server.use(createOperatorsList()); - const { result, rerender } = renderHook(() => useOperators()) + const { result, rerender } = renderHook(() => useOperators()); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - const firstData = result.current.data + const firstData = result.current.data; - rerender() + rerender(); - expect(result.current.data).toBe(firstData) - }) + expect(result.current.data).toBe(firstData); + }); it('should have staleTime of 0 for immediate refetch', async () => { - server.use(createOperatorsList()) + server.use(createOperatorsList()); - const { result } = renderHook(() => useOperators()) + const { result } = renderHook(() => useOperators()); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); // Data should be considered stale immediately - expect(result.current.isStale).toBe(true) - }) - }) -}) + expect(result.current.isStale).toBe(true); + }); + }); +}); describe('useOperatorMutation', () => { describe('Install operator', () => { it('should install operator successfully', async () => { - server.use(createInstallOperator('cert-manager')) + server.use(createInstallOperator('cert-manager')); - const { result } = renderHook(() => useOperatorMutation()) + const { result } = renderHook(() => useOperatorMutation()); await act(async () => { - await result.current.installOperator.mutateAsync('cert-manager') - }) + await result.current.installOperator.mutateAsync('cert-manager'); + }); - expect(result.current.installOperator.isSuccess).toBe(true) - expect(result.current.installOperator.data).toBeDefined() - }) + expect(result.current.installOperator.isSuccess).toBe(true); + expect(result.current.installOperator.data).toBeDefined(); + }); it('should handle install operator errors', async () => { - server.use(createInstallOperatorError('cert-manager', 500, 'Installation failed')) + server.use(createInstallOperatorError('cert-manager', 500, 'Installation failed')); - const { result } = renderHook(() => useOperatorMutation()) + const { result } = renderHook(() => useOperatorMutation()); await act(async () => { try { - await result.current.installOperator.mutateAsync('cert-manager') + await result.current.installOperator.mutateAsync('cert-manager'); } catch (error) { // Expected to throw } - }) + }); - expect(result.current.installOperator.isError).toBe(true) - expect(result.current.installOperator.error).toBeDefined() - }) + expect(result.current.installOperator.isError).toBe(true); + expect(result.current.installOperator.error).toBeDefined(); + }); it('should handle slow install operations', async () => { - server.use(createInstallOperatorSlow('cert-manager', 1000)) + server.use(createInstallOperatorSlow('cert-manager', 1000)); - const { result } = renderHook(() => useOperatorMutation()) + const { result } = renderHook(() => useOperatorMutation()); act(() => { - result.current.installOperator.mutate('cert-manager') - }) + result.current.installOperator.mutate('cert-manager'); + }); // Check that mutation is pending (may be very quick) - expect(result.current.installOperator.isPending).toBeDefined() + expect(result.current.installOperator.isPending).toBeDefined(); await waitFor(() => { - expect(result.current.installOperator.isSuccess).toBe(true) - }, { timeout: 2000 }) + expect(result.current.installOperator.isSuccess).toBe(true); + }, { timeout: 2000 }); - expect(result.current.installOperator.isPending).toBe(false) - }) + expect(result.current.installOperator.isPending).toBe(false); + }); it('should invalidate queries on successful install', async () => { - server.use(createInstallOperator('cert-manager')) + server.use(createInstallOperator('cert-manager')); - const { result } = renderHook(() => useOperatorMutation()) + const { result } = renderHook(() => useOperatorMutation()); await act(async () => { - await result.current.installOperator.mutateAsync('cert-manager') - }) + await result.current.installOperator.mutateAsync('cert-manager'); + }); - expect(result.current.installOperator.isSuccess).toBe(true) - }) - }) + expect(result.current.installOperator.isSuccess).toBe(true); + }); + }); describe('Uninstall operator', () => { it('should uninstall operator successfully', async () => { - server.use(createUninstallOperator('cert-manager')) + server.use(createUninstallOperator('cert-manager')); - const { result } = renderHook(() => useOperatorMutation()) + const { result } = renderHook(() => useOperatorMutation()); await act(async () => { - await result.current.uninstallOperator.mutateAsync('cert-manager') - }) + await result.current.uninstallOperator.mutateAsync('cert-manager'); + }); - expect(result.current.uninstallOperator.isSuccess).toBe(true) - expect(result.current.uninstallOperator.data).toBeDefined() - }) + expect(result.current.uninstallOperator.isSuccess).toBe(true); + expect(result.current.uninstallOperator.data).toBeDefined(); + }); it('should handle uninstall operator errors', async () => { - server.use(createUninstallOperatorError('cert-manager', 500, 'Uninstallation failed')) + server.use(createUninstallOperatorError('cert-manager', 500, 'Uninstallation failed')); - const { result } = renderHook(() => useOperatorMutation()) + const { result } = renderHook(() => useOperatorMutation()); await act(async () => { try { - await result.current.uninstallOperator.mutateAsync('cert-manager') + await result.current.uninstallOperator.mutateAsync('cert-manager'); } catch (error) { // Expected to throw } - }) + }); - expect(result.current.uninstallOperator.isError).toBe(true) - expect(result.current.uninstallOperator.error).toBeDefined() - }) + expect(result.current.uninstallOperator.isError).toBe(true); + expect(result.current.uninstallOperator.error).toBeDefined(); + }); it('should invalidate queries on successful uninstall', async () => { - server.use(createUninstallOperator('cert-manager')) + server.use(createUninstallOperator('cert-manager')); - const { result } = renderHook(() => useOperatorMutation()) + const { result } = renderHook(() => useOperatorMutation()); await act(async () => { - await result.current.uninstallOperator.mutateAsync('cert-manager') - }) + await result.current.uninstallOperator.mutateAsync('cert-manager'); + }); await waitFor(() => { - expect(result.current.uninstallOperator.isSuccess).toBe(true) - }) - }) - }) + expect(result.current.uninstallOperator.isSuccess).toBe(true); + }); + }); + }); describe('Mutation state management', () => { it('should reset mutation state on new mutation', async () => { - server.use(createInstallOperator('cert-manager')) + server.use(createInstallOperator('cert-manager')); - const { result } = renderHook(() => useOperatorMutation()) + const { result } = renderHook(() => useOperatorMutation()); // First mutation act(() => { - result.current.installOperator.mutate('cert-manager') - }) + result.current.installOperator.mutate('cert-manager'); + }); await waitFor(() => { - expect(result.current.installOperator.isSuccess).toBe(true) - }) + expect(result.current.installOperator.isSuccess).toBe(true); + }); // Reset and start new mutation act(() => { - result.current.installOperator.reset() - }) + result.current.installOperator.reset(); + }); // After reset, mutation should be reset // Check that reset was called (the exact state may vary) - expect(typeof result.current.installOperator.reset).toBe('function') - }) + expect(typeof result.current.installOperator.reset).toBe('function'); + }); it('should handle multiple operators', async () => { server.use( createInstallOperator('cert-manager'), createInstallOperator('cloudnative-pg') - ) + ); - const { result } = renderHook(() => useOperatorMutation()) + const { result } = renderHook(() => useOperatorMutation()); // Install first operator await act(async () => { - await result.current.installOperator.mutateAsync('cert-manager') - }) + await result.current.installOperator.mutateAsync('cert-manager'); + }); - expect(result.current.installOperator.isSuccess).toBe(true) + expect(result.current.installOperator.isSuccess).toBe(true); // Install second operator await act(async () => { - await result.current.installOperator.mutateAsync('cloudnative-pg') - }) + await result.current.installOperator.mutateAsync('cloudnative-pg'); + }); - expect(result.current.installOperator.isSuccess).toBe(true) - }) - }) -}) + expect(result.current.installOperator.isSuccess).toBe(true); + }); + }); +}); diff --git a/apps/ops-dashboard/__tests__/hooks/usePods.test.tsx b/apps/ops-dashboard/__tests__/hooks/usePods.test.tsx index a5281f4..55ff606 100644 --- a/apps/ops-dashboard/__tests__/hooks/usePods.test.tsx +++ b/apps/ops-dashboard/__tests__/hooks/usePods.test.tsx @@ -1,169 +1,169 @@ -import { usePods, usePod, usePodLogs, useDeletePod, usePodsForDeployment } from '../../hooks/usePods' -import { server } from '../../__mocks__/server' -import { renderHook, waitFor } from '../utils/test-utils' -import { http, HttpResponse } from 'msw' +import { http, HttpResponse } from 'msw'; + import { - createPodsList, createAllPodsList, - createPodsListData, + createAllPodsListError, createPodDetails, - createPodLogs, createPodLogsHandler, + createPodsList, + createPodsListData, createPodsListError, - createAllPodsListError, createPodsListNetworkError, createPodsListSlow -} from '../../__mocks__/handlers/pods' +} from '../../__mocks__/handlers/pods'; +import { server } from '../../__mocks__/server'; +import { useDeletePod, usePod, usePodLogs, usePods, usePodsForDeployment } from '../../hooks/usePods'; +import { renderHook, waitFor } from '../utils/test-utils'; -const API_BASE = 'http://localhost:8001' +const API_BASE = 'http://localhost:8001'; describe('usePods', () => { describe('Success scenarios', () => { it('should successfully fetch pods list', async () => { - server.use(createPodsList()) + server.use(createPodsList()); - const { result } = renderHook(() => usePods('default')) + const { result } = renderHook(() => usePods('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).toBeDefined() - expect(result.current.data?.items).toHaveLength(5) - expect(result.current.data?.items[0].metadata.name).toBe('nginx-pod-1') - expect(result.current.data?.items[1].metadata.name).toBe('redis-pod-1') - expect(result.current.data?.items[2].metadata.name).toBe('pending-pod') - }) + expect(result.current.data).toBeDefined(); + expect(result.current.data?.items).toHaveLength(5); + expect(result.current.data?.items[0].metadata.name).toBe('nginx-pod-1'); + expect(result.current.data?.items[1].metadata.name).toBe('redis-pod-1'); + expect(result.current.data?.items[2].metadata.name).toBe('pending-pod'); + }); it('should handle empty pods list', async () => { - server.use(createPodsList([])) + server.use(createPodsList([])); - const { result } = renderHook(() => usePods('default')) + const { result } = renderHook(() => usePods('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(0) - }) + expect(result.current.data?.items).toHaveLength(0); + }); it('should support _all namespace', async () => { - const mock = createPodsListData() - server.use(createAllPodsList(mock)) + const mock = createPodsListData(); + server.use(createAllPodsList(mock)); - const { result } = renderHook(() => usePods('_all')) + const { result } = renderHook(() => usePods('_all')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(5) - expect(result.current.data?.items[0].metadata.name).toBe(mock[0]?.metadata?.name) - expect(result.current.data?.items[1].metadata.name).toBe(mock[1]?.metadata?.name) - expect(result.current.data?.items[2].metadata.name).toBe(mock[2]?.metadata?.name) - }) - }) + expect(result.current.data?.items).toHaveLength(5); + expect(result.current.data?.items[0].metadata.name).toBe(mock[0]?.metadata?.name); + expect(result.current.data?.items[1].metadata.name).toBe(mock[1]?.metadata?.name); + expect(result.current.data?.items[2].metadata.name).toBe(mock[2]?.metadata?.name); + }); + }); describe('Loading states', () => { it('should complete loading successfully', async () => { - server.use(createPodsList()) + server.use(createPodsList()); - const { result } = renderHook(() => usePods('default')) + const { result } = renderHook(() => usePods('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.isLoading).toBe(false) - expect(result.current.data).toBeDefined() - }) + expect(result.current.isLoading).toBe(false); + expect(result.current.data).toBeDefined(); + }); it('should show loading state initially', async () => { - server.use(createPodsListSlow([], 100)) + server.use(createPodsListSlow([], 100)); - const { result } = renderHook(() => usePods('default')) + const { result } = renderHook(() => usePods('default')); - expect(result.current.isLoading).toBe(true) - expect(result.current.data).toBeUndefined() + expect(result.current.isLoading).toBe(true); + expect(result.current.data).toBeUndefined(); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.isLoading).toBe(false) - expect(result.current.data).toBeDefined() - }) + expect(result.current.isLoading).toBe(false); + expect(result.current.data).toBeDefined(); + }); it('should handle slow responses', async () => { - server.use(createPodsListSlow(createPodsListData(), 200)) + server.use(createPodsListSlow(createPodsListData(), 200)); - const { result } = renderHook(() => usePods('default')) + const { result } = renderHook(() => usePods('default')); - expect(result.current.isLoading).toBe(true) + expect(result.current.isLoading).toBe(true); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }, { timeout: 1000 }) + expect(result.current.isSuccess).toBe(true); + }, { timeout: 1000 }); - expect(result.current.isLoading).toBe(false) - expect(result.current.data?.items).toHaveLength(5) - }) - }) + expect(result.current.isLoading).toBe(false); + expect(result.current.data?.items).toHaveLength(5); + }); + }); describe('Error handling', () => { it('should handle API errors (500)', async () => { - server.use(createPodsListError(500, 'Internal Server Error')) + server.use(createPodsListError(500, 'Internal Server Error')); - const { result } = renderHook(() => usePods('default')) + const { result } = renderHook(() => usePods('default')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); it('should handle API errors (404)', async () => { - server.use(createPodsListError(404, 'Not Found')) + server.use(createPodsListError(404, 'Not Found')); - const { result } = renderHook(() => usePods('default')) + const { result } = renderHook(() => usePods('default')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); it('should handle network errors', async () => { - server.use(createPodsListNetworkError()) + server.use(createPodsListNetworkError()); - const { result } = renderHook(() => usePods('default')) + const { result } = renderHook(() => usePods('default')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); it('should handle _all namespace API errors', async () => { - server.use(createAllPodsListError(500, 'Server Error')) + server.use(createAllPodsListError(500, 'Server Error')); - const { result } = renderHook(() => usePods('_all')) + const { result } = renderHook(() => usePods('_all')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); + }); describe('Data transformation', () => { it('should correctly transform pod data', async () => { @@ -183,21 +183,21 @@ describe('usePods', () => { podIP: '10.244.1.1' } } - ] + ]; - server.use(createPodsList(customPods)) + server.use(createPodsList(customPods)); - const { result } = renderHook(() => usePods('default')) + const { result } = renderHook(() => usePods('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(1) - expect(result.current.data?.items[0].metadata.name).toBe('test-pod') - expect(result.current.data?.items[0].status.phase).toBe('Running') - expect(result.current.data?.items[0].spec.containers[0].image).toBe('nginx:latest') - }) + expect(result.current.data?.items).toHaveLength(1); + expect(result.current.data?.items[0].metadata.name).toBe('test-pod'); + expect(result.current.data?.items[0].status.phase).toBe('Running'); + expect(result.current.data?.items[0].spec.containers[0].image).toBe('nginx:latest'); + }); it('should handle different pod statuses', async () => { const multiStatusPods = [ @@ -228,64 +228,64 @@ describe('usePods', () => { spec: { containers: [{ name: 'main' }] }, status: { phase: 'Failed' } } - ] + ]; - server.use(createPodsList(multiStatusPods)) + server.use(createPodsList(multiStatusPods)); - const { result } = renderHook(() => usePods('default')) + const { result } = renderHook(() => usePods('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(3) - expect(result.current.data?.items[0].status.phase).toBe('Running') - expect(result.current.data?.items[1].status.phase).toBe('Pending') - expect(result.current.data?.items[2].status.phase).toBe('Failed') - }) - }) + expect(result.current.data?.items).toHaveLength(3); + expect(result.current.data?.items[0].status.phase).toBe('Running'); + expect(result.current.data?.items[1].status.phase).toBe('Pending'); + expect(result.current.data?.items[2].status.phase).toBe('Failed'); + }); + }); describe('Caching behavior', () => { it('should cache data between renders', async () => { - server.use(createPodsList()) + server.use(createPodsList()); - const { result, rerender } = renderHook(() => usePods('default')) + const { result, rerender } = renderHook(() => usePods('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - const firstData = result.current.data + const firstData = result.current.data; - rerender() + rerender(); - expect(result.current.data).toBe(firstData) - }) + expect(result.current.data).toBe(firstData); + }); it('should refetch when namespace changes', async () => { - server.use(createPodsList()) + server.use(createPodsList()); const { result, rerender } = renderHook( ({ namespace }) => usePods(namespace), { initialProps: { namespace: 'default' } } - ) + ); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - const firstData = result.current.data + const firstData = result.current.data; - rerender({ namespace: 'kube-system' }) + rerender({ namespace: 'kube-system' }); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).not.toBe(firstData) - }) - }) -}) + expect(result.current.data).not.toBe(firstData); + }); + }); +}); describe('usePod', () => { @@ -298,112 +298,112 @@ describe('usePod', () => { }, spec: { containers: [{ name: 'main' }] }, status: { phase: 'Running' } - } + }; - server.use(createPodDetails(mockPod)) + server.use(createPodDetails(mockPod)); - const { result } = renderHook(() => usePod('test-pod', 'default')) + const { result } = renderHook(() => usePod('test-pod', 'default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).toBeDefined() - expect(result.current.data?.metadata.name).toBe('test-pod') - }) -}) + expect(result.current.data).toBeDefined(); + expect(result.current.data?.metadata.name).toBe('test-pod'); + }); +}); describe('usePodLogs', () => { it('should fetch pod logs successfully', async () => { // Skip due to undici polyfill issues with pod logs API - const mockLogs = '2024-01-01T10:00:00Z [INFO] Application started\n2024-01-01T10:01:00Z [INFO] Server listening on port 8080' - server.use(createPodLogsHandler(mockLogs)) + const mockLogs = '2024-01-01T10:00:00Z [INFO] Application started\n2024-01-01T10:01:00Z [INFO] Server listening on port 8080'; + server.use(createPodLogsHandler(mockLogs)); - const { result } = renderHook(() => usePodLogs('test-pod', 'default')) + const { result } = renderHook(() => usePodLogs('test-pod', 'default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).toBe(mockLogs) + expect(result.current.data).toBe(mockLogs); - expect(result.current.isLoading).toBe(false) - expect(result.current.isError).toBe(false) - }) + expect(result.current.isLoading).toBe(false); + expect(result.current.isError).toBe(false); + }); it('should handle container parameter', async () => { // Skip due to undici polyfill issues with pod logs API - const mockLogs = '2024-01-01T10:00:00Z [INFO] Container logs\n2024-01-01T10:01:00Z [INFO] Container ready' - server.use(createPodLogsHandler(mockLogs)) + const mockLogs = '2024-01-01T10:00:00Z [INFO] Container logs\n2024-01-01T10:01:00Z [INFO] Container ready'; + server.use(createPodLogsHandler(mockLogs)); - const { result } = renderHook(() => usePodLogs('test-pod', 'default', 'main-container')) + const { result } = renderHook(() => usePodLogs('test-pod', 'default', 'main-container')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).toBe(mockLogs) - }) + expect(result.current.data).toBe(mockLogs); + }); it('should handle empty logs', async () => { // Skip due to undici polyfill issues with pod logs API - const mockLogs = '' - server.use(createPodLogsHandler(mockLogs)) + const mockLogs = ''; + server.use(createPodLogsHandler(mockLogs)); - const { result } = renderHook(() => usePodLogs('test-pod', 'default')) + const { result } = renderHook(() => usePodLogs('test-pod', 'default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).toBe('') - }) + expect(result.current.data).toBe(''); + }); it('should handle pod not found error', async () => { server.use( http.get(`${API_BASE}/api/v1/namespaces/:namespace/pods/:name/log`, () => { - return HttpResponse.json({ error: 'Pod not found' }, { status: 404 }) + return HttpResponse.json({ error: 'Pod not found' }, { status: 404 }); }) - ) + ); - const { result } = renderHook(() => usePodLogs('nonexistent-pod', 'default')) + const { result } = renderHook(() => usePodLogs('nonexistent-pod', 'default')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() + expect(result.current.error).toBeDefined(); // Note: Error structure may vary, just check that error exists - }) + }); it('should handle network errors', async () => { server.use( http.get(`${API_BASE}/api/v1/namespaces/:namespace/pods/:name/log`, () => { - return HttpResponse.error() + return HttpResponse.error(); }) - ) + ); - const { result } = renderHook(() => usePodLogs('test-pod', 'default')) + const { result } = renderHook(() => usePodLogs('test-pod', 'default')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - }) -}) + expect(result.current.error).toBeDefined(); + }); +}); describe('useDeletePod', () => { it('should delete pod successfully', async () => { - const { result } = renderHook(() => useDeletePod()) + const { result } = renderHook(() => useDeletePod()); - expect(result.current.mutate).toBeDefined() - expect(result.current.mutateAsync).toBeDefined() - expect(typeof result.current.mutate).toBe('function') - expect(typeof result.current.mutateAsync).toBe('function') - }) -}) + expect(result.current.mutate).toBeDefined(); + expect(result.current.mutateAsync).toBeDefined(); + expect(typeof result.current.mutate).toBe('function'); + expect(typeof result.current.mutateAsync).toBe('function'); + }); +}); describe('usePodsForDeployment', () => { it('should fetch pods for specific deployment', async () => { @@ -425,42 +425,42 @@ describe('usePodsForDeployment', () => { containerStatuses: [{ name: 'nginx', ready: true, restartCount: 0 }] } } - ] + ]; - server.use(createPodsList(mockPods)) + server.use(createPodsList(mockPods)); - const { result } = renderHook(() => usePodsForDeployment('nginx', 'default')) + const { result } = renderHook(() => usePodsForDeployment('nginx', 'default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(1) - expect(result.current.data?.items[0].metadata.name).toBe('nginx-deployment-1234567890-abc123') - }) + expect(result.current.data?.items).toHaveLength(1); + expect(result.current.data?.items[0].metadata.name).toBe('nginx-deployment-1234567890-abc123'); + }); it('should handle empty pods list for deployment', async () => { - server.use(createPodsList([])) + server.use(createPodsList([])); - const { result } = renderHook(() => usePodsForDeployment('nonexistent-deployment', 'default')) + const { result } = renderHook(() => usePodsForDeployment('nonexistent-deployment', 'default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(0) - }) + expect(result.current.data?.items).toHaveLength(0); + }); it('should handle API errors', async () => { - server.use(createPodsListError(500, 'Internal Server Error')) + server.use(createPodsListError(500, 'Internal Server Error')); - const { result } = renderHook(() => usePodsForDeployment('nginx', 'default')) + const { result } = renderHook(() => usePodsForDeployment('nginx', 'default')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() + expect(result.current.error).toBeDefined(); // Note: Error structure may vary, just check that error exists - }) -}) \ No newline at end of file + }); +}); \ No newline at end of file diff --git a/apps/ops-dashboard/__tests__/hooks/usePreferredNamespace.test.tsx b/apps/ops-dashboard/__tests__/hooks/usePreferredNamespace.test.tsx index 9d48572..858a8d3 100644 --- a/apps/ops-dashboard/__tests__/hooks/usePreferredNamespace.test.tsx +++ b/apps/ops-dashboard/__tests__/hooks/usePreferredNamespace.test.tsx @@ -1,6 +1,6 @@ -import { renderHook, act } from '../utils/test-utils' -import { usePreferredNamespace } from '../../contexts/NamespaceContext' -import { NamespaceProvider } from '../../contexts/NamespaceContext' +import { usePreferredNamespace } from '../../contexts/NamespaceContext'; +import { NamespaceProvider } from '../../contexts/NamespaceContext'; +import { act,renderHook } from '../utils/test-utils'; describe('usePreferredNamespace', () => { it('should return initial namespace', () => { @@ -8,152 +8,152 @@ describe('usePreferredNamespace', () => { {children} - ) + ); - const { result } = renderHook(() => usePreferredNamespace(), { wrapper }) + const { result } = renderHook(() => usePreferredNamespace(), { wrapper }); - expect(result.current.namespace).toBe('default') - expect(typeof result.current.setNamespace).toBe('function') - }) + expect(result.current.namespace).toBe('default'); + expect(typeof result.current.setNamespace).toBe('function'); + }); it('should return custom initial namespace', () => { const wrapper = ({ children }: { children: React.ReactNode }) => ( {children} - ) + ); - const { result } = renderHook(() => usePreferredNamespace(), { wrapper }) + const { result } = renderHook(() => usePreferredNamespace(), { wrapper }); - expect(result.current.namespace).toBe('kube-system') - expect(typeof result.current.setNamespace).toBe('function') - }) + expect(result.current.namespace).toBe('kube-system'); + expect(typeof result.current.setNamespace).toBe('function'); + }); it('should update namespace when setNamespace is called', () => { const wrapper = ({ children }: { children: React.ReactNode }) => ( {children} - ) + ); - const { result } = renderHook(() => usePreferredNamespace(), { wrapper }) + const { result } = renderHook(() => usePreferredNamespace(), { wrapper }); - expect(result.current.namespace).toBe('default') + expect(result.current.namespace).toBe('default'); act(() => { - result.current.setNamespace('kube-system') - }) + result.current.setNamespace('kube-system'); + }); - expect(result.current.namespace).toBe('kube-system') - }) + expect(result.current.namespace).toBe('kube-system'); + }); it('should support multiple namespace changes', () => { const wrapper = ({ children }: { children: React.ReactNode }) => ( {children} - ) + ); - const { result } = renderHook(() => usePreferredNamespace(), { wrapper }) + const { result } = renderHook(() => usePreferredNamespace(), { wrapper }); - expect(result.current.namespace).toBe('default') + expect(result.current.namespace).toBe('default'); act(() => { - result.current.setNamespace('kube-system') - }) - expect(result.current.namespace).toBe('kube-system') + result.current.setNamespace('kube-system'); + }); + expect(result.current.namespace).toBe('kube-system'); act(() => { - result.current.setNamespace('monitoring') - }) - expect(result.current.namespace).toBe('monitoring') + result.current.setNamespace('monitoring'); + }); + expect(result.current.namespace).toBe('monitoring'); act(() => { - result.current.setNamespace('default') - }) - expect(result.current.namespace).toBe('default') - }) + result.current.setNamespace('default'); + }); + expect(result.current.namespace).toBe('default'); + }); it('should support _all namespace', () => { const wrapper = ({ children }: { children: React.ReactNode }) => ( {children} - ) + ); - const { result } = renderHook(() => usePreferredNamespace(), { wrapper }) + const { result } = renderHook(() => usePreferredNamespace(), { wrapper }); act(() => { - result.current.setNamespace('_all') - }) + result.current.setNamespace('_all'); + }); - expect(result.current.namespace).toBe('_all') - }) + expect(result.current.namespace).toBe('_all'); + }); it('should throw error when used outside NamespaceProvider', () => { // Suppress console.error for this test - const originalError = console.error - console.error = jest.fn() + const originalError = console.error; + console.error = jest.fn(); expect(() => { - renderHook(() => usePreferredNamespace(), { wrapper: ({ children }) => <>{children} }) - }).toThrow('usePreferredNamespace must be used within a NamespaceProvider') + renderHook(() => usePreferredNamespace(), { wrapper: ({ children }) => <>{children} }); + }).toThrow('usePreferredNamespace must be used within a NamespaceProvider'); - console.error = originalError - }) + console.error = originalError; + }); it('should maintain referential stability of setNamespace function', () => { const wrapper = ({ children }: { children: React.ReactNode }) => ( {children} - ) + ); - const { result, rerender } = renderHook(() => usePreferredNamespace(), { wrapper }) + const { result, rerender } = renderHook(() => usePreferredNamespace(), { wrapper }); - const firstSetNamespace = result.current.setNamespace + const firstSetNamespace = result.current.setNamespace; // Rerender without changing namespace - rerender() + rerender(); // Note: Due to startTransition wrapper, the function reference may change // but the functionality should remain the same - expect(typeof result.current.setNamespace).toBe('function') - expect(result.current.namespace).toBe('default') - }) + expect(typeof result.current.setNamespace).toBe('function'); + expect(result.current.namespace).toBe('default'); + }); it('should handle rapid namespace changes', () => { const wrapper = ({ children }: { children: React.ReactNode }) => ( {children} - ) + ); - const { result } = renderHook(() => usePreferredNamespace(), { wrapper }) + const { result } = renderHook(() => usePreferredNamespace(), { wrapper }); // Rapidly change namespace multiple times act(() => { - result.current.setNamespace('kube-system') - result.current.setNamespace('monitoring') - result.current.setNamespace('default') - }) + result.current.setNamespace('kube-system'); + result.current.setNamespace('monitoring'); + result.current.setNamespace('default'); + }); - expect(result.current.namespace).toBe('default') - }) + expect(result.current.namespace).toBe('default'); + }); it('should work with different initial namespaces', () => { - const testCases = ['default', 'kube-system', 'monitoring', 'istio-system', '_all'] + const testCases = ['default', 'kube-system', 'monitoring', 'istio-system', '_all']; testCases.forEach(initialNamespace => { const wrapper = ({ children }: { children: React.ReactNode }) => ( {children} - ) + ); - const { result } = renderHook(() => usePreferredNamespace(), { wrapper }) + const { result } = renderHook(() => usePreferredNamespace(), { wrapper }); - expect(result.current.namespace).toBe(initialNamespace) - }) - }) -}) + expect(result.current.namespace).toBe(initialNamespace); + }); + }); +}); diff --git a/apps/ops-dashboard/__tests__/hooks/useReplicaSets.test.tsx b/apps/ops-dashboard/__tests__/hooks/useReplicaSets.test.tsx index 09cfed2..e62689a 100644 --- a/apps/ops-dashboard/__tests__/hooks/useReplicaSets.test.tsx +++ b/apps/ops-dashboard/__tests__/hooks/useReplicaSets.test.tsx @@ -1,165 +1,164 @@ +import { http, HttpResponse } from 'msw'; + import { - useReplicaSets, - useReplicaSet, - useDeleteReplicaSet, - useScaleReplicaSet -} from '../../hooks/useReplicaSets' -import { server } from '../../__mocks__/server' -import { http, HttpResponse } from 'msw' -import { renderHook, waitFor, act } from '../utils/test-utils' -import { - createReplicaSetsList, createAllReplicaSetsList, + createAllReplicaSetsListError, + createReplicaSetDelete, + createReplicaSetScale, + createReplicaSetsList, createReplicaSetsListData, createReplicaSetsListError, - createAllReplicaSetsListError, createReplicaSetsListNetworkError, createReplicaSetsListSlow, - getReplicaSet, - updateReplicaSet, - createReplicaSetDelete, - createReplicaSetScale -} from '../../__mocks__/handlers/replicasets' + getReplicaSet} from '../../__mocks__/handlers/replicasets'; +import { server } from '../../__mocks__/server'; +import { + useDeleteReplicaSet, + useReplicaSet, + useReplicaSets, + useScaleReplicaSet +} from '../../hooks/useReplicaSets'; +import { act,renderHook, waitFor } from '../utils/test-utils'; describe('useReplicaSets', () => { it('should successfully fetch replicasets list', async () => { - server.use(createReplicaSetsList()) + server.use(createReplicaSetsList()); - const { result } = renderHook(() => useReplicaSets('default')) + const { result } = renderHook(() => useReplicaSets('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).toBeDefined() - expect(result.current.data?.items).toHaveLength(3) - expect(result.current.data?.items[0].metadata.name).toBe('nginx-deployment-1234567890') - expect(result.current.data?.items[1].metadata.name).toBe('redis-deployment-abcdefghij') - expect(result.current.data?.items[2].metadata.name).toBe('orphaned-replicaset') - }) + expect(result.current.data).toBeDefined(); + expect(result.current.data?.items).toHaveLength(3); + expect(result.current.data?.items[0].metadata.name).toBe('nginx-deployment-1234567890'); + expect(result.current.data?.items[1].metadata.name).toBe('redis-deployment-abcdefghij'); + expect(result.current.data?.items[2].metadata.name).toBe('orphaned-replicaset'); + }); it('should handle empty replicasets list', async () => { - server.use(createReplicaSetsList([])) + server.use(createReplicaSetsList([])); - const { result } = renderHook(() => useReplicaSets('default')) + const { result } = renderHook(() => useReplicaSets('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(0) - }) + expect(result.current.data?.items).toHaveLength(0); + }); it('should support _all namespace', async () => { - const mock = createReplicaSetsListData() - server.use(createAllReplicaSetsList(mock)) + const mock = createReplicaSetsListData(); + server.use(createAllReplicaSetsList(mock)); - const { result } = renderHook(() => useReplicaSets('_all')) + const { result } = renderHook(() => useReplicaSets('_all')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(3) - expect(result.current.data?.items[0].metadata.name).toBe(mock[0]?.metadata?.name) - expect(result.current.data?.items[1].metadata.name).toBe(mock[1]?.metadata?.name) - }) + expect(result.current.data?.items).toHaveLength(3); + expect(result.current.data?.items[0].metadata.name).toBe(mock[0]?.metadata?.name); + expect(result.current.data?.items[1].metadata.name).toBe(mock[1]?.metadata?.name); + }); it('should complete loading successfully', async () => { - server.use(createReplicaSetsList()) + server.use(createReplicaSetsList()); - const { result } = renderHook(() => useReplicaSets('default')) + const { result } = renderHook(() => useReplicaSets('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.isLoading).toBe(false) - expect(result.current.data).toBeDefined() - }) + expect(result.current.isLoading).toBe(false); + expect(result.current.data).toBeDefined(); + }); it('should show loading state initially', async () => { - server.use(createReplicaSetsListSlow([], 100)) + server.use(createReplicaSetsListSlow([], 100)); - const { result } = renderHook(() => useReplicaSets('default')) + const { result } = renderHook(() => useReplicaSets('default')); - expect(result.current.isLoading).toBe(true) - expect(result.current.data).toBeUndefined() + expect(result.current.isLoading).toBe(true); + expect(result.current.data).toBeUndefined(); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.isLoading).toBe(false) - expect(result.current.data).toBeDefined() - }) + expect(result.current.isLoading).toBe(false); + expect(result.current.data).toBeDefined(); + }); it('should handle slow responses', async () => { - server.use(createReplicaSetsListSlow(createReplicaSetsListData(), 200)) + server.use(createReplicaSetsListSlow(createReplicaSetsListData(), 200)); - const { result } = renderHook(() => useReplicaSets('default')) + const { result } = renderHook(() => useReplicaSets('default')); - expect(result.current.isLoading).toBe(true) + expect(result.current.isLoading).toBe(true); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }, { timeout: 1000 }) + expect(result.current.isSuccess).toBe(true); + }, { timeout: 1000 }); - expect(result.current.isLoading).toBe(false) - expect(result.current.data?.items).toHaveLength(3) - }) + expect(result.current.isLoading).toBe(false); + expect(result.current.data?.items).toHaveLength(3); + }); it('should handle API errors (500)', async () => { - server.use(createReplicaSetsListError(500, 'Internal Server Error')) + server.use(createReplicaSetsListError(500, 'Internal Server Error')); - const { result } = renderHook(() => useReplicaSets('default')) + const { result } = renderHook(() => useReplicaSets('default')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); it('should handle API errors (404)', async () => { - server.use(createReplicaSetsListError(404, 'Not Found')) + server.use(createReplicaSetsListError(404, 'Not Found')); - const { result } = renderHook(() => useReplicaSets('default')) + const { result } = renderHook(() => useReplicaSets('default')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); it('should handle network errors', async () => { - server.use(createReplicaSetsListNetworkError()) + server.use(createReplicaSetsListNetworkError()); - const { result } = renderHook(() => useReplicaSets('default')) + const { result } = renderHook(() => useReplicaSets('default')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); it('should handle _all namespace API errors', async () => { - server.use(createAllReplicaSetsListError(500, 'Server Error')) + server.use(createAllReplicaSetsListError(500, 'Server Error')); - const { result } = renderHook(() => useReplicaSets('_all')) + const { result } = renderHook(() => useReplicaSets('_all')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); it('should correctly transform replicaset data', async () => { const customReplicaSets = [ @@ -188,22 +187,22 @@ describe('useReplicaSets', () => { observedGeneration: 1 } } - ] + ]; - server.use(createReplicaSetsList(customReplicaSets)) + server.use(createReplicaSetsList(customReplicaSets)); - const { result } = renderHook(() => useReplicaSets('default')) + const { result } = renderHook(() => useReplicaSets('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(1) - expect(result.current.data?.items[0].metadata.name).toBe('test-rs-1') - expect(result.current.data?.items[0].spec.replicas).toBe(2) - expect(result.current.data?.items[0].status.readyReplicas).toBe(2) - expect(result.current.data?.items[0].metadata.ownerReferences?.[0].kind).toBe('Deployment') - }) + expect(result.current.data?.items).toHaveLength(1); + expect(result.current.data?.items[0].metadata.name).toBe('test-rs-1'); + expect(result.current.data?.items[0].spec.replicas).toBe(2); + expect(result.current.data?.items[0].status.readyReplicas).toBe(2); + expect(result.current.data?.items[0].metadata.ownerReferences?.[0].kind).toBe('Deployment'); + }); it('should handle replicasets with different statuses', async () => { const multiStatusReplicaSets = [ @@ -246,21 +245,21 @@ describe('useReplicaSets', () => { observedGeneration: 1 } } - ] + ]; - server.use(createReplicaSetsList(multiStatusReplicaSets)) + server.use(createReplicaSetsList(multiStatusReplicaSets)); - const { result } = renderHook(() => useReplicaSets('default')) + const { result } = renderHook(() => useReplicaSets('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(3) - expect(result.current.data?.items[0].status.readyReplicas).toBe(3) - expect(result.current.data?.items[1].status.readyReplicas).toBe(3) - expect(result.current.data?.items[2].status.readyReplicas).toBe(0) - }) + expect(result.current.data?.items).toHaveLength(3); + expect(result.current.data?.items[0].status.readyReplicas).toBe(3); + expect(result.current.data?.items[1].status.readyReplicas).toBe(3); + expect(result.current.data?.items[2].status.readyReplicas).toBe(0); + }); it('should handle replicasets with owner references', async () => { const ownedReplicaSets = [ @@ -291,61 +290,61 @@ describe('useReplicaSets', () => { spec: { replicas: 1 }, status: { readyReplicas: 1, replicas: 1 } } - ] + ]; - server.use(createReplicaSetsList(ownedReplicaSets)) + server.use(createReplicaSetsList(ownedReplicaSets)); - const { result } = renderHook(() => useReplicaSets('default')) + const { result } = renderHook(() => useReplicaSets('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(2) - expect(result.current.data?.items[0].metadata.ownerReferences).toHaveLength(1) - expect(result.current.data?.items[0].metadata.ownerReferences?.[0].kind).toBe('Deployment') - expect(result.current.data?.items[1].metadata.ownerReferences).toBeUndefined() - }) + expect(result.current.data?.items).toHaveLength(2); + expect(result.current.data?.items[0].metadata.ownerReferences).toHaveLength(1); + expect(result.current.data?.items[0].metadata.ownerReferences?.[0].kind).toBe('Deployment'); + expect(result.current.data?.items[1].metadata.ownerReferences).toBeUndefined(); + }); it('should cache data between renders', async () => { - server.use(createReplicaSetsList()) + server.use(createReplicaSetsList()); - const { result, rerender } = renderHook(() => useReplicaSets('default')) + const { result, rerender } = renderHook(() => useReplicaSets('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - const firstData = result.current.data + const firstData = result.current.data; - rerender() + rerender(); - expect(result.current.data).toBe(firstData) - }) + expect(result.current.data).toBe(firstData); + }); it('should refetch when namespace changes', async () => { - server.use(createReplicaSetsList()) + server.use(createReplicaSetsList()); const { result, rerender } = renderHook( ({ namespace }) => useReplicaSets(namespace), { initialProps: { namespace: 'default' } } - ) + ); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - const firstData = result.current.data + const firstData = result.current.data; - rerender({ namespace: 'kube-system' }) + rerender({ namespace: 'kube-system' }); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).not.toBe(firstData) - }) -}) + expect(result.current.data).not.toBe(firstData); + }); +}); // ============================================================================ // MUTATION HOOKS TESTS @@ -357,107 +356,107 @@ describe('useReplicaSet', () => { metadata: { name: 'test-rs', namespace: 'default', uid: 'rs-1' }, spec: { replicas: 3 }, status: { readyReplicas: 3, replicas: 3 } - } + }; - server.use(getReplicaSet(mockReplicaSet)) + server.use(getReplicaSet(mockReplicaSet)); - const { result } = renderHook(() => useReplicaSet('test-rs', 'default')) + const { result } = renderHook(() => useReplicaSet('test-rs', 'default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).toEqual(mockReplicaSet) - }) + expect(result.current.data).toEqual(mockReplicaSet); + }); it('should handle replicaset not found', async () => { const handler = http.get('http://localhost:8001/apis/apps/v1/namespaces/:namespace/replicasets/:name', () => { - return HttpResponse.json({ error: 'ReplicaSet not found' }, { status: 404 }) - }) + return HttpResponse.json({ error: 'ReplicaSet not found' }, { status: 404 }); + }); - server.use(handler) + server.use(handler); - const { result } = renderHook(() => useReplicaSet('non-existent', 'default')) + const { result } = renderHook(() => useReplicaSet('non-existent', 'default')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - }) -}) + expect(result.current.error).toBeDefined(); + }); +}); describe('useDeleteReplicaSet', () => { it('should delete replicaset successfully', async () => { - server.use(createReplicaSetDelete()) + server.use(createReplicaSetDelete()); - const { result } = renderHook(() => useDeleteReplicaSet()) + const { result } = renderHook(() => useDeleteReplicaSet()); await act(async () => { await result.current.mutateAsync({ name: 'test-rs', namespace: 'default' - }) - }) + }); + }); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) - }) + expect(result.current.isSuccess).toBe(true); + }); + }); it('should handle deletion errors', async () => { const handler = http.delete('http://localhost:8001/apis/apps/v1/namespaces/:namespace/replicasets/:name', () => { - return HttpResponse.json({ error: 'Deletion failed' }, { status: 404 }) - }) + return HttpResponse.json({ error: 'Deletion failed' }, { status: 404 }); + }); - server.use(handler) + server.use(handler); - const { result } = renderHook(() => useDeleteReplicaSet()) + const { result } = renderHook(() => useDeleteReplicaSet()); await act(async () => { try { await result.current.mutateAsync({ name: 'non-existent-rs', namespace: 'default' - }) + }); } catch (error) { // Expected to throw } - }) + }); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) - }) -}) + expect(result.current.isError).toBe(true); + }); + }); +}); describe('useScaleReplicaSet', () => { it('should scale replicaset successfully', async () => { - server.use(createReplicaSetScale()) + server.use(createReplicaSetScale()); - const { result } = renderHook(() => useScaleReplicaSet()) + const { result } = renderHook(() => useScaleReplicaSet()); await act(async () => { await result.current.mutateAsync({ name: 'test-rs', replicas: 5, namespace: 'default' - }) - }) + }); + }); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) - }) + expect(result.current.isSuccess).toBe(true); + }); + }); it('should handle scaling errors', async () => { const handler = http.put('http://localhost:8001/apis/apps/v1/namespaces/:namespace/replicasets/:name/scale', () => { - return HttpResponse.json({ error: 'Scaling failed' }, { status: 400 }) - }) + return HttpResponse.json({ error: 'Scaling failed' }, { status: 400 }); + }); - server.use(handler) + server.use(handler); - const { result } = renderHook(() => useScaleReplicaSet()) + const { result } = renderHook(() => useScaleReplicaSet()); await act(async () => { try { @@ -465,32 +464,32 @@ describe('useScaleReplicaSet', () => { name: 'test-rs', replicas: -1, // Invalid replicas namespace: 'default' - }) + }); } catch (error) { // Expected to throw } - }) + }); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) - }) + expect(result.current.isError).toBe(true); + }); + }); it('should use default namespace when not provided', async () => { - server.use(createReplicaSetScale()) + server.use(createReplicaSetScale()); - const { result } = renderHook(() => useScaleReplicaSet()) + const { result } = renderHook(() => useScaleReplicaSet()); await act(async () => { await result.current.mutateAsync({ name: 'test-rs', replicas: 3 // No namespace provided, should use default - }) - }) + }); + }); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) - }) -}) + expect(result.current.isSuccess).toBe(true); + }); + }); +}); diff --git a/apps/ops-dashboard/__tests__/hooks/useSecrets.test.tsx b/apps/ops-dashboard/__tests__/hooks/useSecrets.test.tsx index 3da5a2a..1db481e 100644 --- a/apps/ops-dashboard/__tests__/hooks/useSecrets.test.tsx +++ b/apps/ops-dashboard/__tests__/hooks/useSecrets.test.tsx @@ -1,166 +1,165 @@ +import { http, HttpResponse } from 'msw'; + import { - useSecrets, - useSecret, - useCreateSecret, - useUpdateSecret, - useDeleteSecret -} from '../../hooks/useSecrets' -import { server } from '../../__mocks__/server' -import { http, HttpResponse } from 'msw' -import { renderHook, waitFor, act } from '../utils/test-utils' -import { - createSecretsList, createAllSecretsList, + createAllSecretsListError, + createSecretHandler, + createSecretsList, createSecretsListData, createSecretsListError, - createAllSecretsListError, createSecretsListNetworkError, createSecretsListSlow, + deleteSecretHandler, getSecret, - createSecretHandler, - updateSecret, - deleteSecretHandler -} from '../../__mocks__/handlers/secrets' + updateSecret} from '../../__mocks__/handlers/secrets'; +import { server } from '../../__mocks__/server'; +import { + useCreateSecret, + useDeleteSecret, + useSecret, + useSecrets, + useUpdateSecret} from '../../hooks/useSecrets'; +import { act,renderHook, waitFor } from '../utils/test-utils'; describe('useSecrets', () => { it('should successfully fetch secrets list', async () => { - server.use(createSecretsList()) + server.use(createSecretsList()); - const { result } = renderHook(() => useSecrets('default')) + const { result } = renderHook(() => useSecrets('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).toBeDefined() - expect(result.current.data?.items).toHaveLength(2) - expect(result.current.data?.items[0].metadata.name).toBe('test-secret-1') - expect(result.current.data?.items[1].metadata.name).toBe('test-secret-2') - }) + expect(result.current.data).toBeDefined(); + expect(result.current.data?.items).toHaveLength(2); + expect(result.current.data?.items[0].metadata.name).toBe('test-secret-1'); + expect(result.current.data?.items[1].metadata.name).toBe('test-secret-2'); + }); it('should handle empty secrets list', async () => { - server.use(createSecretsList([])) + server.use(createSecretsList([])); - const { result } = renderHook(() => useSecrets('default')) + const { result } = renderHook(() => useSecrets('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(0) - }) + expect(result.current.data?.items).toHaveLength(0); + }); it('should support _all namespace', async () => { - const mock = createSecretsListData() - server.use(createAllSecretsList(mock)) + const mock = createSecretsListData(); + server.use(createAllSecretsList(mock)); - const { result } = renderHook(() => useSecrets('_all')) + const { result } = renderHook(() => useSecrets('_all')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(3) - expect(result.current.data?.items[0].metadata.name).toBe(mock[0]?.metadata?.name) - expect(result.current.data?.items[1].metadata.name).toBe(mock[1]?.metadata?.name) - expect(result.current.data?.items[2].metadata.name).toBe(mock[2]?.metadata?.name) - }) + expect(result.current.data?.items).toHaveLength(3); + expect(result.current.data?.items[0].metadata.name).toBe(mock[0]?.metadata?.name); + expect(result.current.data?.items[1].metadata.name).toBe(mock[1]?.metadata?.name); + expect(result.current.data?.items[2].metadata.name).toBe(mock[2]?.metadata?.name); + }); it('should complete loading successfully', async () => { - server.use(createSecretsList()) + server.use(createSecretsList()); - const { result } = renderHook(() => useSecrets('default')) + const { result } = renderHook(() => useSecrets('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.isLoading).toBe(false) - expect(result.current.data).toBeDefined() - }) + expect(result.current.isLoading).toBe(false); + expect(result.current.data).toBeDefined(); + }); it('should show loading state initially', async () => { - server.use(createSecretsListSlow([], 100)) + server.use(createSecretsListSlow([], 100)); - const { result } = renderHook(() => useSecrets('default')) + const { result } = renderHook(() => useSecrets('default')); - expect(result.current.isLoading).toBe(true) - expect(result.current.data).toBeUndefined() + expect(result.current.isLoading).toBe(true); + expect(result.current.data).toBeUndefined(); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.isLoading).toBe(false) - expect(result.current.data).toBeDefined() - }) + expect(result.current.isLoading).toBe(false); + expect(result.current.data).toBeDefined(); + }); it('should handle slow responses', async () => { - server.use(createSecretsListSlow(createSecretsListData(), 200)) + server.use(createSecretsListSlow(createSecretsListData(), 200)); - const { result } = renderHook(() => useSecrets('default')) + const { result } = renderHook(() => useSecrets('default')); - expect(result.current.isLoading).toBe(true) + expect(result.current.isLoading).toBe(true); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }, { timeout: 1000 }) + expect(result.current.isSuccess).toBe(true); + }, { timeout: 1000 }); - expect(result.current.isLoading).toBe(false) - expect(result.current.data?.items).toHaveLength(2) - }) + expect(result.current.isLoading).toBe(false); + expect(result.current.data?.items).toHaveLength(2); + }); it('should handle API errors (500)', async () => { - server.use(createSecretsListError(500, 'Internal Server Error')) + server.use(createSecretsListError(500, 'Internal Server Error')); - const { result } = renderHook(() => useSecrets('default')) + const { result } = renderHook(() => useSecrets('default')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); it('should handle API errors (403)', async () => { - server.use(createSecretsListError(403, 'Forbidden')) + server.use(createSecretsListError(403, 'Forbidden')); - const { result } = renderHook(() => useSecrets('default')) + const { result } = renderHook(() => useSecrets('default')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); it('should handle network errors', async () => { - server.use(createSecretsListNetworkError()) + server.use(createSecretsListNetworkError()); - const { result } = renderHook(() => useSecrets('default')) + const { result } = renderHook(() => useSecrets('default')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); it('should handle _all namespace API errors', async () => { - server.use(createAllSecretsListError(500, 'Server Error')) + server.use(createAllSecretsListError(500, 'Server Error')); - const { result } = renderHook(() => useSecrets('_all')) + const { result } = renderHook(() => useSecrets('_all')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); it('should correctly transform secret data', async () => { const customSecrets = [ @@ -173,26 +172,26 @@ describe('useSecrets', () => { }, type: 'Opaque', data: { - 'username': Buffer.from('testuser').toString('base64'), - 'password': Buffer.from('testpass').toString('base64') + username: Buffer.from('testuser').toString('base64'), + password: Buffer.from('testpass').toString('base64') } } - ] + ]; - server.use(createSecretsList(customSecrets)) + server.use(createSecretsList(customSecrets)); - const { result } = renderHook(() => useSecrets('default')) + const { result } = renderHook(() => useSecrets('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(1) - expect(result.current.data?.items[0].metadata.name).toBe('test-secret') - expect(result.current.data?.items[0].type).toBe('Opaque') - expect(result.current.data?.items[0].data.username).toBeDefined() - expect(result.current.data?.items[0].data.password).toBeDefined() - }) + expect(result.current.data?.items).toHaveLength(1); + expect(result.current.data?.items[0].metadata.name).toBe('test-secret'); + expect(result.current.data?.items[0].type).toBe('Opaque'); + expect(result.current.data?.items[0].data.username).toBeDefined(); + expect(result.current.data?.items[0].data.password).toBeDefined(); + }); it('should handle different secret types correctly', async () => { const multiTypeSecrets = [ @@ -203,7 +202,7 @@ describe('useSecrets', () => { uid: 'secret-1' }, type: 'Opaque', - data: { 'key': 'value' } + data: { key: 'value' } }, { metadata: { @@ -228,21 +227,21 @@ describe('useSecrets', () => { '.dockerconfigjson': 'docker-config-data' } } - ] + ]; - server.use(createSecretsList(multiTypeSecrets)) + server.use(createSecretsList(multiTypeSecrets)); - const { result } = renderHook(() => useSecrets('default')) + const { result } = renderHook(() => useSecrets('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(3) - expect(result.current.data?.items[0].type).toBe('Opaque') - expect(result.current.data?.items[1].type).toBe('kubernetes.io/tls') - expect(result.current.data?.items[2].type).toBe('kubernetes.io/dockerconfigjson') - }) + expect(result.current.data?.items).toHaveLength(3); + expect(result.current.data?.items[0].type).toBe('Opaque'); + expect(result.current.data?.items[1].type).toBe('kubernetes.io/tls'); + expect(result.current.data?.items[2].type).toBe('kubernetes.io/dockerconfigjson'); + }); it('should handle base64 encoded data correctly', async () => { const base64Secrets = [ @@ -254,67 +253,67 @@ describe('useSecrets', () => { }, type: 'Opaque', data: { - 'username': Buffer.from('admin').toString('base64'), - 'password': Buffer.from('secret123').toString('base64'), - 'json': Buffer.from(JSON.stringify({ key: 'value' })).toString('base64') + username: Buffer.from('admin').toString('base64'), + password: Buffer.from('secret123').toString('base64'), + json: Buffer.from(JSON.stringify({ key: 'value' })).toString('base64') } } - ] + ]; - server.use(createSecretsList(base64Secrets)) + server.use(createSecretsList(base64Secrets)); - const { result } = renderHook(() => useSecrets('default')) + const { result } = renderHook(() => useSecrets('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(1) - const secret = result.current.data?.items[0] - expect(secret.data.username).toBe(Buffer.from('admin').toString('base64')) - expect(secret.data.password).toBe(Buffer.from('secret123').toString('base64')) - expect(secret.data.json).toBe(Buffer.from(JSON.stringify({ key: 'value' })).toString('base64')) - }) + expect(result.current.data?.items).toHaveLength(1); + const secret = result.current.data?.items[0]; + expect(secret.data.username).toBe(Buffer.from('admin').toString('base64')); + expect(secret.data.password).toBe(Buffer.from('secret123').toString('base64')); + expect(secret.data.json).toBe(Buffer.from(JSON.stringify({ key: 'value' })).toString('base64')); + }); it('should cache data between renders', async () => { - server.use(createSecretsList()) + server.use(createSecretsList()); - const { result, rerender } = renderHook(() => useSecrets('default')) + const { result, rerender } = renderHook(() => useSecrets('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - const firstData = result.current.data + const firstData = result.current.data; - rerender() + rerender(); - expect(result.current.data).toBe(firstData) - }) + expect(result.current.data).toBe(firstData); + }); it('should refetch when namespace changes', async () => { - server.use(createSecretsList()) + server.use(createSecretsList()); const { result, rerender } = renderHook( ({ namespace }) => useSecrets(namespace), { initialProps: { namespace: 'default' } } - ) + ); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - const firstData = result.current.data + const firstData = result.current.data; - rerender({ namespace: 'kube-system' }) + rerender({ namespace: 'kube-system' }); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).not.toBe(firstData) - }) -}) + expect(result.current.data).not.toBe(firstData); + }); +}); // ============================================================================ // MUTATION HOOKS TESTS @@ -326,119 +325,119 @@ describe('useSecret', () => { metadata: { name: 'test-secret', namespace: 'default', uid: 'secret-1' }, type: 'Opaque', data: { username: 'dGVzdA==', password: 'cGFzcw==' } - } + }; - server.use(getSecret(mockSecret)) + server.use(getSecret(mockSecret)); - const { result } = renderHook(() => useSecret('test-secret', 'default')) + const { result } = renderHook(() => useSecret('test-secret', 'default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).toEqual(mockSecret) - }) + expect(result.current.data).toEqual(mockSecret); + }); it('should handle secret not found', async () => { const handler = http.get('http://localhost:8001/api/v1/namespaces/:namespace/secrets/:name', () => { - return HttpResponse.json({ error: 'Secret not found' }, { status: 404 }) - }) + return HttpResponse.json({ error: 'Secret not found' }, { status: 404 }); + }); - server.use(handler) + server.use(handler); - const { result } = renderHook(() => useSecret('non-existent', 'default')) + const { result } = renderHook(() => useSecret('non-existent', 'default')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - }) -}) + expect(result.current.error).toBeDefined(); + }); +}); describe('useCreateSecret', () => { const mockSecret = { metadata: { name: 'new-secret', namespace: 'default', uid: 'secret-new' }, type: 'Opaque', data: { username: 'dGVzdA==', password: 'cGFzcw==' } - } + }; it('should create secret successfully', async () => { - server.use(createSecretHandler(mockSecret)) + server.use(createSecretHandler(mockSecret)); - const { result } = renderHook(() => useCreateSecret()) + const { result } = renderHook(() => useCreateSecret()); await act(async () => { await result.current.mutateAsync({ secret: mockSecret, namespace: 'default' - }) - }) + }); + }); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) - }) + expect(result.current.isSuccess).toBe(true); + }); + }); it('should handle creation errors', async () => { const handler = http.post('http://localhost:8001/api/v1/namespaces/:namespace/secrets', () => { - return HttpResponse.json({ error: 'Creation failed' }, { status: 400 }) - }) + return HttpResponse.json({ error: 'Creation failed' }, { status: 400 }); + }); - server.use(handler) + server.use(handler); - const { result } = renderHook(() => useCreateSecret()) + const { result } = renderHook(() => useCreateSecret()); await act(async () => { try { await result.current.mutateAsync({ secret: {} as any, namespace: 'default' - }) + }); } catch (error) { // Expected to throw } - }) + }); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) - }) -}) + expect(result.current.isError).toBe(true); + }); + }); +}); describe('useUpdateSecret', () => { const mockSecret = { metadata: { name: 'updated-secret', namespace: 'default', uid: 'secret-updated' }, type: 'Opaque', data: { username: 'dXBkYXRlZA==', password: 'bmV3cGFzcw==' } - } + }; it('should update secret successfully', async () => { - server.use(updateSecret()) + server.use(updateSecret()); - const { result } = renderHook(() => useUpdateSecret()) + const { result } = renderHook(() => useUpdateSecret()); await act(async () => { await result.current.mutateAsync({ name: 'updated-secret', secret: mockSecret, namespace: 'default' - }) - }) + }); + }); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) - }) + expect(result.current.isSuccess).toBe(true); + }); + }); it('should handle update errors', async () => { const handler = http.put('http://localhost:8001/api/v1/namespaces/:namespace/secrets/:name', () => { - return HttpResponse.json({ error: 'Update failed' }, { status: 400 }) - }) + return HttpResponse.json({ error: 'Update failed' }, { status: 400 }); + }); - server.use(handler) + server.use(handler); - const { result } = renderHook(() => useUpdateSecret()) + const { result } = renderHook(() => useUpdateSecret()); await act(async () => { try { @@ -446,59 +445,59 @@ describe('useUpdateSecret', () => { name: 'updated-secret', secret: {} as any, namespace: 'default' - }) + }); } catch (error) { // Expected to throw } - }) + }); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) - }) -}) + expect(result.current.isError).toBe(true); + }); + }); +}); describe('useDeleteSecret', () => { it('should delete secret successfully', async () => { - server.use(deleteSecretHandler('test-secret', 'default')) + server.use(deleteSecretHandler('test-secret', 'default')); - const { result } = renderHook(() => useDeleteSecret()) + const { result } = renderHook(() => useDeleteSecret()); await act(async () => { await result.current.mutateAsync({ name: 'test-secret', namespace: 'default' - }) - }) + }); + }); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) - }) + expect(result.current.isSuccess).toBe(true); + }); + }); it('should handle deletion errors', async () => { const handler = http.delete('http://localhost:8001/api/v1/namespaces/:namespace/secrets/:name', () => { - return HttpResponse.json({ error: 'Deletion failed' }, { status: 404 }) - }) + return HttpResponse.json({ error: 'Deletion failed' }, { status: 404 }); + }); - server.use(handler) + server.use(handler); - const { result } = renderHook(() => useDeleteSecret()) + const { result } = renderHook(() => useDeleteSecret()); await act(async () => { try { await result.current.mutateAsync({ name: 'non-existent-secret', namespace: 'default' - }) + }); } catch (error) { // Expected to throw } - }) + }); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) - }) -}) + expect(result.current.isError).toBe(true); + }); + }); +}); diff --git a/apps/ops-dashboard/__tests__/hooks/useServices.test.tsx b/apps/ops-dashboard/__tests__/hooks/useServices.test.tsx index 0fe1258..62b2d03 100644 --- a/apps/ops-dashboard/__tests__/hooks/useServices.test.tsx +++ b/apps/ops-dashboard/__tests__/hooks/useServices.test.tsx @@ -1,166 +1,165 @@ +import { http, HttpResponse } from 'msw'; + import { - useServices, - useService, - useCreateService, - useUpdateService, - useDeleteService -} from '../../hooks/useServices' -import { server } from '../../__mocks__/server' -import { http, HttpResponse } from 'msw' -import { renderHook, waitFor, act } from '../utils/test-utils' -import { - createServicesList, createAllServicesList, + createAllServicesListError, + createServiceHandler, + createServicesList, createServicesListData, createServicesListError, - createAllServicesListError, createServicesListNetworkError, createServicesListSlow, + deleteServiceHandler, getService, - createServiceHandler, - updateService, - deleteServiceHandler -} from '../../__mocks__/handlers/services' + updateService} from '../../__mocks__/handlers/services'; +import { server } from '../../__mocks__/server'; +import { + useCreateService, + useDeleteService, + useService, + useServices, + useUpdateService} from '../../hooks/useServices'; +import { act,renderHook, waitFor } from '../utils/test-utils'; describe('useServices', () => { it('should successfully fetch services list', async () => { - server.use(createServicesList()) + server.use(createServicesList()); - const { result } = renderHook(() => useServices('default')) + const { result } = renderHook(() => useServices('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).toBeDefined() - expect(result.current.data?.items).toHaveLength(2) - expect(result.current.data?.items[0].metadata.name).toBe('test-service-1') - expect(result.current.data?.items[1].metadata.name).toBe('test-service-2') - }) + expect(result.current.data).toBeDefined(); + expect(result.current.data?.items).toHaveLength(2); + expect(result.current.data?.items[0].metadata.name).toBe('test-service-1'); + expect(result.current.data?.items[1].metadata.name).toBe('test-service-2'); + }); it('should handle empty services list', async () => { - server.use(createServicesList([])) + server.use(createServicesList([])); - const { result } = renderHook(() => useServices('default')) + const { result } = renderHook(() => useServices('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(0) - }) + expect(result.current.data?.items).toHaveLength(0); + }); it('should support _all namespace', async () => { - const mock = createServicesListData() - server.use(createAllServicesList(mock)) + const mock = createServicesListData(); + server.use(createAllServicesList(mock)); - const { result } = renderHook(() => useServices('_all')) + const { result } = renderHook(() => useServices('_all')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(3) - expect(result.current.data?.items[0].metadata.name).toBe(mock[0]?.metadata?.name) - expect(result.current.data?.items[1].metadata.name).toBe(mock[1]?.metadata?.name) - expect(result.current.data?.items[2].metadata.name).toBe(mock[2]?.metadata?.name) - }) + expect(result.current.data?.items).toHaveLength(3); + expect(result.current.data?.items[0].metadata.name).toBe(mock[0]?.metadata?.name); + expect(result.current.data?.items[1].metadata.name).toBe(mock[1]?.metadata?.name); + expect(result.current.data?.items[2].metadata.name).toBe(mock[2]?.metadata?.name); + }); it('should complete loading successfully', async () => { - server.use(createServicesList()) + server.use(createServicesList()); - const { result } = renderHook(() => useServices('default')) + const { result } = renderHook(() => useServices('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.isLoading).toBe(false) - expect(result.current.data).toBeDefined() - }) + expect(result.current.isLoading).toBe(false); + expect(result.current.data).toBeDefined(); + }); it('should show loading state initially', async () => { - server.use(createServicesListSlow([], 100)) + server.use(createServicesListSlow([], 100)); - const { result } = renderHook(() => useServices('default')) + const { result } = renderHook(() => useServices('default')); - expect(result.current.isLoading).toBe(true) - expect(result.current.data).toBeUndefined() + expect(result.current.isLoading).toBe(true); + expect(result.current.data).toBeUndefined(); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.isLoading).toBe(false) - expect(result.current.data).toBeDefined() - }) + expect(result.current.isLoading).toBe(false); + expect(result.current.data).toBeDefined(); + }); it('should handle slow responses', async () => { - server.use(createServicesListSlow(createServicesListData(), 200)) + server.use(createServicesListSlow(createServicesListData(), 200)); - const { result } = renderHook(() => useServices('default')) + const { result } = renderHook(() => useServices('default')); - expect(result.current.isLoading).toBe(true) + expect(result.current.isLoading).toBe(true); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }, { timeout: 1000 }) + expect(result.current.isSuccess).toBe(true); + }, { timeout: 1000 }); - expect(result.current.isLoading).toBe(false) - expect(result.current.data?.items).toHaveLength(2) - }) + expect(result.current.isLoading).toBe(false); + expect(result.current.data?.items).toHaveLength(2); + }); it('should handle API errors (500)', async () => { - server.use(createServicesListError(500, 'Internal Server Error')) + server.use(createServicesListError(500, 'Internal Server Error')); - const { result } = renderHook(() => useServices('default')) + const { result } = renderHook(() => useServices('default')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); it('should handle API errors (404)', async () => { - server.use(createServicesListError(404, 'Not Found')) + server.use(createServicesListError(404, 'Not Found')); - const { result } = renderHook(() => useServices('default')) + const { result } = renderHook(() => useServices('default')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); it('should handle network errors', async () => { - server.use(createServicesListNetworkError()) + server.use(createServicesListNetworkError()); - const { result } = renderHook(() => useServices('default')) + const { result } = renderHook(() => useServices('default')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); it('should handle _all namespace API errors', async () => { - server.use(createAllServicesListError(500, 'Server Error')) + server.use(createAllServicesListError(500, 'Server Error')); - const { result } = renderHook(() => useServices('_all')) + const { result } = renderHook(() => useServices('_all')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - expect(result.current.data).toBeUndefined() - }) + expect(result.current.error).toBeDefined(); + expect(result.current.data).toBeUndefined(); + }); it('should correctly transform service data', async () => { const customServices = [ @@ -182,21 +181,21 @@ describe('useServices', () => { loadBalancer: {} } } - ] + ]; - server.use(createServicesList(customServices)) + server.use(createServicesList(customServices)); - const { result } = renderHook(() => useServices('default')) + const { result } = renderHook(() => useServices('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(1) - expect(result.current.data?.items[0].metadata.name).toBe('test-service') - expect(result.current.data?.items[0].spec.type).toBe('NodePort') - expect(result.current.data?.items[0].spec.ports[0].nodePort).toBe(30080) - }) + expect(result.current.data?.items).toHaveLength(1); + expect(result.current.data?.items[0].metadata.name).toBe('test-service'); + expect(result.current.data?.items[0].spec.type).toBe('NodePort'); + expect(result.current.data?.items[0].spec.ports[0].nodePort).toBe(30080); + }); it('should handle different service types correctly', async () => { const multiTypeServices = [ @@ -222,60 +221,60 @@ describe('useServices', () => { } } } - ] + ]; - server.use(createServicesList(multiTypeServices)) + server.use(createServicesList(multiTypeServices)); - const { result } = renderHook(() => useServices('default')) + const { result } = renderHook(() => useServices('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data?.items).toHaveLength(2) - expect(result.current.data?.items[0].spec.type).toBe('ClusterIP') - expect(result.current.data?.items[1].spec.type).toBe('LoadBalancer') - }) + expect(result.current.data?.items).toHaveLength(2); + expect(result.current.data?.items[0].spec.type).toBe('ClusterIP'); + expect(result.current.data?.items[1].spec.type).toBe('LoadBalancer'); + }); it('should cache data between renders', async () => { - server.use(createServicesList()) + server.use(createServicesList()); - const { result, rerender } = renderHook(() => useServices('default')) + const { result, rerender } = renderHook(() => useServices('default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - const firstData = result.current.data + const firstData = result.current.data; - rerender() + rerender(); - expect(result.current.data).toBe(firstData) - }) + expect(result.current.data).toBe(firstData); + }); it('should refetch when namespace changes', async () => { - server.use(createServicesList()) + server.use(createServicesList()); const { result, rerender } = renderHook( ({ namespace }) => useServices(namespace), { initialProps: { namespace: 'default' } } - ) + ); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - const firstData = result.current.data + const firstData = result.current.data; - rerender({ namespace: 'kube-system' }) + rerender({ namespace: 'kube-system' }); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).not.toBe(firstData) - }) -}) + expect(result.current.data).not.toBe(firstData); + }); +}); // ============================================================================ // MUTATION HOOKS TESTS @@ -287,119 +286,119 @@ describe('useService', () => { metadata: { name: 'test-service', namespace: 'default', uid: 'svc-1' }, spec: { type: 'ClusterIP', ports: [{ port: 80, targetPort: 80 }] }, status: { loadBalancer: {} } - } + }; - server.use(getService(mockService)) + server.use(getService(mockService)); - const { result } = renderHook(() => useService('test-service', 'default')) + const { result } = renderHook(() => useService('test-service', 'default')); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) + expect(result.current.isSuccess).toBe(true); + }); - expect(result.current.data).toEqual(mockService) - }) + expect(result.current.data).toEqual(mockService); + }); it('should handle service not found', async () => { const handler = http.get('http://localhost:8001/api/v1/namespaces/:namespace/services/:name', () => { - return HttpResponse.json({ error: 'Service not found' }, { status: 404 }) - }) + return HttpResponse.json({ error: 'Service not found' }, { status: 404 }); + }); - server.use(handler) + server.use(handler); - const { result } = renderHook(() => useService('non-existent', 'default')) + const { result } = renderHook(() => useService('non-existent', 'default')); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) + expect(result.current.isError).toBe(true); + }); - expect(result.current.error).toBeDefined() - }) -}) + expect(result.current.error).toBeDefined(); + }); +}); describe('useCreateService', () => { const mockService = { metadata: { name: 'new-service', namespace: 'default', uid: 'svc-new' }, spec: { type: 'ClusterIP', ports: [{ port: 80, targetPort: 80 }] }, status: { loadBalancer: {} } - } + }; it('should create service successfully', async () => { - server.use(createServiceHandler(mockService)) + server.use(createServiceHandler(mockService)); - const { result } = renderHook(() => useCreateService()) + const { result } = renderHook(() => useCreateService()); await act(async () => { await result.current.mutateAsync({ service: mockService, namespace: 'default' - }) - }) + }); + }); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) - }) + expect(result.current.isSuccess).toBe(true); + }); + }); it('should handle creation errors', async () => { const handler = http.post('http://localhost:8001/api/v1/namespaces/:namespace/services', () => { - return HttpResponse.json({ error: 'Creation failed' }, { status: 400 }) - }) + return HttpResponse.json({ error: 'Creation failed' }, { status: 400 }); + }); - server.use(handler) + server.use(handler); - const { result } = renderHook(() => useCreateService()) + const { result } = renderHook(() => useCreateService()); await act(async () => { try { await result.current.mutateAsync({ service: {} as any, namespace: 'default' - }) + }); } catch (error) { // Expected to throw } - }) + }); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) - }) -}) + expect(result.current.isError).toBe(true); + }); + }); +}); describe('useUpdateService', () => { const mockService = { metadata: { name: 'updated-service', namespace: 'default', uid: 'svc-updated' }, spec: { type: 'NodePort', ports: [{ port: 80, targetPort: 80, nodePort: 30080 }] }, status: { loadBalancer: {} } - } + }; it('should update service successfully', async () => { - server.use(updateService()) + server.use(updateService()); - const { result } = renderHook(() => useUpdateService()) + const { result } = renderHook(() => useUpdateService()); await act(async () => { await result.current.mutateAsync({ name: 'updated-service', service: mockService, namespace: 'default' - }) - }) + }); + }); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) - }) + expect(result.current.isSuccess).toBe(true); + }); + }); it('should handle update errors', async () => { const handler = http.put('http://localhost:8001/api/v1/namespaces/:namespace/services/:name', () => { - return HttpResponse.json({ error: 'Update failed' }, { status: 400 }) - }) + return HttpResponse.json({ error: 'Update failed' }, { status: 400 }); + }); - server.use(handler) + server.use(handler); - const { result } = renderHook(() => useUpdateService()) + const { result } = renderHook(() => useUpdateService()); await act(async () => { try { @@ -407,59 +406,59 @@ describe('useUpdateService', () => { name: 'updated-service', service: {} as any, namespace: 'default' - }) + }); } catch (error) { // Expected to throw } - }) + }); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) - }) -}) + expect(result.current.isError).toBe(true); + }); + }); +}); describe('useDeleteService', () => { it('should delete service successfully', async () => { - server.use(deleteServiceHandler('test-service', 'default')) + server.use(deleteServiceHandler('test-service', 'default')); - const { result } = renderHook(() => useDeleteService()) + const { result } = renderHook(() => useDeleteService()); await act(async () => { await result.current.mutateAsync({ name: 'test-service', namespace: 'default' - }) - }) + }); + }); await waitFor(() => { - expect(result.current.isSuccess).toBe(true) - }) - }) + expect(result.current.isSuccess).toBe(true); + }); + }); it('should handle deletion errors', async () => { const handler = http.delete('http://localhost:8001/api/v1/namespaces/:namespace/services/:name', () => { - return HttpResponse.json({ error: 'Deletion failed' }, { status: 404 }) - }) + return HttpResponse.json({ error: 'Deletion failed' }, { status: 404 }); + }); - server.use(handler) + server.use(handler); - const { result } = renderHook(() => useDeleteService()) + const { result } = renderHook(() => useDeleteService()); await act(async () => { try { await result.current.mutateAsync({ name: 'non-existent-service', namespace: 'default' - }) + }); } catch (error) { // Expected to throw } - }) + }); await waitFor(() => { - expect(result.current.isError).toBe(true) - }) - }) -}) + expect(result.current.isError).toBe(true); + }); + }); +}); diff --git a/apps/ops-dashboard/__tests__/lib/agents/bradie.test.ts b/apps/ops-dashboard/__tests__/lib/agents/bradie.test.ts index f7ab814..7757377 100644 --- a/apps/ops-dashboard/__tests__/lib/agents/bradie.test.ts +++ b/apps/ops-dashboard/__tests__/lib/agents/bradie.test.ts @@ -1,4 +1,4 @@ -import BradieClient, { BradieSession, BradieActRequest, BradieActResponse } from '@/lib/agents/bradie'; +import BradieClient, { BradieActRequest } from '@/lib/agents/bradie'; // Use the global mockFetch from setup const mockFetch = (global as any).mockFetch; diff --git a/apps/ops-dashboard/__tests__/lib/agents/index.test.ts b/apps/ops-dashboard/__tests__/lib/agents/index.test.ts index 30a989d..fd76145 100644 --- a/apps/ops-dashboard/__tests__/lib/agents/index.test.ts +++ b/apps/ops-dashboard/__tests__/lib/agents/index.test.ts @@ -1,4 +1,4 @@ -import { OllamaClient, BradieClient } from '@/lib/agents/index'; +import { BradieClient,OllamaClient } from '@/lib/agents/index'; describe('lib/agents/index', () => { it('should export OllamaClient', () => { diff --git a/apps/ops-dashboard/__tests__/lib/agents/types.test.ts b/apps/ops-dashboard/__tests__/lib/agents/types.test.ts index 14bdc10..10271dd 100644 --- a/apps/ops-dashboard/__tests__/lib/agents/types.test.ts +++ b/apps/ops-dashboard/__tests__/lib/agents/types.test.ts @@ -1,4 +1,4 @@ -import { Session, Message, AgentConfig } from '@/lib/agents/types'; +import { AgentConfig,Message, Session } from '@/lib/agents/types'; describe('lib/agents/types', () => { describe('Session interface', () => { diff --git a/apps/ops-dashboard/__tests__/lib/agents/utils-simple.test.ts b/apps/ops-dashboard/__tests__/lib/agents/utils-simple.test.ts index 4f2e992..3269f5b 100644 --- a/apps/ops-dashboard/__tests__/lib/agents/utils-simple.test.ts +++ b/apps/ops-dashboard/__tests__/lib/agents/utils-simple.test.ts @@ -1,12 +1,12 @@ import { + AgentType, + clearAgentConfig, + getAgentConfig, + getBradieDomain, getCurrentAgent, setAgent, - getBradieDomain, - setBradieDomain, - getAgentConfig, setAgentConfig, - clearAgentConfig, - AgentType, + setBradieDomain, } from '@/lib/agents/utils'; // Mock localStorage diff --git a/apps/ops-dashboard/__tests__/lib/agents/utils.test.ts b/apps/ops-dashboard/__tests__/lib/agents/utils.test.ts index 6f22623..6cca2f1 100644 --- a/apps/ops-dashboard/__tests__/lib/agents/utils.test.ts +++ b/apps/ops-dashboard/__tests__/lib/agents/utils.test.ts @@ -1,12 +1,12 @@ import { + AgentType, + clearAgentConfig, + getAgentConfig, + getBradieDomain, getCurrentAgent, setAgent, - getBradieDomain, - setBradieDomain, - getAgentConfig, setAgentConfig, - clearAgentConfig, - AgentType, + setBradieDomain, } from '@/lib/agents/utils'; // Mock localStorage diff --git a/apps/ops-dashboard/__tests__/lib/color.test.ts b/apps/ops-dashboard/__tests__/lib/color.test.ts index 66bee15..76104ee 100644 --- a/apps/ops-dashboard/__tests__/lib/color.test.ts +++ b/apps/ops-dashboard/__tests__/lib/color.test.ts @@ -1,4 +1,4 @@ -import { isLightColor, extractColorsFromString } from '@/lib/color'; +import { extractColorsFromString,isLightColor } from '@/lib/color'; describe('lib/color', () => { describe('isLightColor', () => { diff --git a/apps/ops-dashboard/__tests__/lib/format.test.ts b/apps/ops-dashboard/__tests__/lib/format.test.ts index 5d57150..29fd57f 100644 --- a/apps/ops-dashboard/__tests__/lib/format.test.ts +++ b/apps/ops-dashboard/__tests__/lib/format.test.ts @@ -1,13 +1,13 @@ import { - trimPath, - formatDuration, - getTotalDuration, - formatBlogDate, - getFilenameFromPath, + capitalize, capitalToKebabCase, + formatBlogDate, + formatDuration, getChildrenString, + getFilenameFromPath, getHeadingId, - capitalize, + getTotalDuration, + trimPath, } from '@/lib/format'; // Mock dayjs diff --git a/apps/ops-dashboard/__tests__/lib/markdown.test.ts b/apps/ops-dashboard/__tests__/lib/markdown.test.ts index 734d8bf..ce5e2c7 100644 --- a/apps/ops-dashboard/__tests__/lib/markdown.test.ts +++ b/apps/ops-dashboard/__tests__/lib/markdown.test.ts @@ -1,12 +1,13 @@ import fs from 'fs'; import path from 'path'; + import { - extractMarkdownData, - isFileExists, extractCodeFromMd, + extractMarkdownData, getFileNames, - getPostsMetadata, getPostsInfo, + getPostsMetadata, + isFileExists, } from '@/lib/markdown'; // Mock fs module @@ -201,7 +202,7 @@ interface Props { }); callback({ type: 'code', - value: "interface Props {\n title: string;\n}", + value: 'interface Props {\n title: string;\n}', lang: 'typescript', meta: 'component' }); @@ -219,7 +220,7 @@ interface Props { expect(result[1]).toEqual({ id: 'component', lang: 'typescript', - value: "interface Props {\n title: string;\n}", + value: 'interface Props {\n title: string;\n}', }); }); diff --git a/apps/ops-dashboard/__tests__/lib/utils.test.ts b/apps/ops-dashboard/__tests__/lib/utils.test.ts index 232cb19..671f961 100644 --- a/apps/ops-dashboard/__tests__/lib/utils.test.ts +++ b/apps/ops-dashboard/__tests__/lib/utils.test.ts @@ -1,16 +1,16 @@ import { cn, - isExternalImage, - truncateString, - getCookie, - isMacOS, - safeJSONParse, formatBytes, formatDuration, formatRelativeTime, + getCookie, + isExternalImage, + isMacOS, + parseResourceQuantity, + safeJSONParse, + truncateString, validateKubernetesName, validateNamespace, - parseResourceQuantity, } from '@/lib/utils'; // Mock document for getCookie tests diff --git a/apps/ops-dashboard/__tests__/msw-basic.test.ts b/apps/ops-dashboard/__tests__/msw-basic.test.ts index 2e9252f..a7289fd 100644 --- a/apps/ops-dashboard/__tests__/msw-basic.test.ts +++ b/apps/ops-dashboard/__tests__/msw-basic.test.ts @@ -1,47 +1,47 @@ -import { server } from "@/__mocks__/server" -import { baseHandlers } from "@/__mocks__/handlers" +import { baseHandlers } from '@/__mocks__/handlers'; +import { server } from '@/__mocks__/server'; // Test MSW basic functionality describe('MSW Basic Setup', () => { it('should have server configured', () => { - expect(server).toBeDefined() - expect(server.listHandlers()).toHaveLength(4) // We have 4 handlers - }) + expect(server).toBeDefined(); + expect(server.listHandlers()).toHaveLength(4); // We have 4 handlers + }); it('should have handlers exported', () => { - expect(baseHandlers).toBeDefined() - expect(Array.isArray(baseHandlers)).toBe(true) - expect(baseHandlers).toHaveLength(4) - }) + expect(baseHandlers).toBeDefined(); + expect(Array.isArray(baseHandlers)).toBe(true); + expect(baseHandlers).toHaveLength(4); + }); it('should handle GET /api/test request', async () => { - const response = await fetch('http://127.0.0.1:8001/api/test') - const data = await response.json() + const response = await fetch('http://127.0.0.1:8001/api/test'); + const data = await response.json(); - expect(response.status).toBe(200) - expect(data).toEqual({ message: 'Hello from MSW!' }) - }) + expect(response.status).toBe(200); + expect(data).toEqual({ message: 'Hello from MSW!' }); + }); it('should handle GET /health request', async () => { - const response = await fetch('http://127.0.0.1:8001/health') - const data = await response.json() + const response = await fetch('http://127.0.0.1:8001/health'); + const data = await response.json(); - expect(response.status).toBe(200) - expect(data.status).toBe('ok') - expect(data.timestamp).toBeDefined() - }) + expect(response.status).toBe(200); + expect(data.status).toBe('ok'); + expect(data.timestamp).toBeDefined(); + }); it('should handle error responses', async () => { - const response = await fetch('http://127.0.0.1:8001/api/error') - const data = await response.json() + const response = await fetch('http://127.0.0.1:8001/api/error'); + const data = await response.json(); - expect(response.status).toBe(500) - expect(data).toEqual({ error: 'Test error' }) - }) + expect(response.status).toBe(500); + expect(data).toEqual({ error: 'Test error' }); + }); it('should handle POST requests', async () => { - const testData = { name: 'test', value: 123 } + const testData = { name: 'test', value: 123 }; const response = await fetch('http://127.0.0.1:8001/api/test', { method: 'POST', @@ -49,23 +49,23 @@ describe('MSW Basic Setup', () => { 'Content-Type': 'application/json' }, body: JSON.stringify(testData) - }) + }); - const data = await response.json() + const data = await response.json(); - expect(response.status).toBe(200) - expect(data.message).toBe('POST request received') - expect(data.receivedData).toEqual(testData) - }) + expect(response.status).toBe(200); + expect(data.message).toBe('POST request received'); + expect(data.receivedData).toEqual(testData); + }); it('should reset handlers between tests', async () => { // This test verifies that handlers are reset between tests - const response = await fetch('http://127.0.0.1:8001/api/test') - const data = await response.json() + const response = await fetch('http://127.0.0.1:8001/api/test'); + const data = await response.json(); - expect(response.status).toBe(200) - expect(data).toEqual({ message: 'Hello from MSW!' }) - }) -}) + expect(response.status).toBe(200); + expect(data).toEqual({ message: 'Hello from MSW!' }); + }); +}); diff --git a/apps/ops-dashboard/__tests__/setup.test.ts b/apps/ops-dashboard/__tests__/setup.test.ts index ca78f89..d8dd287 100644 --- a/apps/ops-dashboard/__tests__/setup.test.ts +++ b/apps/ops-dashboard/__tests__/setup.test.ts @@ -2,32 +2,33 @@ * @jest-environment jsdom */ -import { render, screen } from '@testing-library/react' -import '@testing-library/jest-dom' -import React from 'react' +import '@testing-library/jest-dom'; + +import { render, screen } from '@testing-library/react'; +import React from 'react'; // Simple test to verify Jest configuration is working describe('Jest Setup', () => { it('should render a simple component', () => { - const TestComponent = () => React.createElement('div', { 'data-testid': 'test-element' }, 'Hello World') + const TestComponent = () => React.createElement('div', { 'data-testid': 'test-element' }, 'Hello World'); - render(React.createElement(TestComponent)) + render(React.createElement(TestComponent)); - expect(screen.getByTestId('test-element')).toBeInTheDocument() - expect(screen.getByText('Hello World')).toBeInTheDocument() - }) + expect(screen.getByTestId('test-element')).toBeInTheDocument(); + expect(screen.getByText('Hello World')).toBeInTheDocument(); + }); it('should have jsdom environment', () => { - expect(typeof window).toBe('object') - expect(typeof document).toBe('object') - }) + expect(typeof window).toBe('object'); + expect(typeof document).toBe('object'); + }); it('should have Next.js mocks available', () => { // Test that Next.js router mock is working - const { useRouter } = require('next/router') - const router = useRouter() + const { useRouter } = require('next/router'); + const router = useRouter(); - expect(router).toBeDefined() - expect(typeof router.push).toBe('function') - }) -}) + expect(router).toBeDefined(); + expect(typeof router.push).toBe('function'); + }); +}); diff --git a/apps/ops-dashboard/__tests__/setup.test.tsx b/apps/ops-dashboard/__tests__/setup.test.tsx index affa7db..66723c3 100644 --- a/apps/ops-dashboard/__tests__/setup.test.tsx +++ b/apps/ops-dashboard/__tests__/setup.test.tsx @@ -2,32 +2,33 @@ * @jest-environment jsdom */ -import { render, screen } from '@testing-library/react' -import '@testing-library/jest-dom' -import React from 'react' +import '@testing-library/jest-dom'; + +import { render, screen } from '@testing-library/react'; +import React from 'react'; // Simple test to verify Jest configuration is working describe('Jest Setup', () => { it('should render a simple component', () => { - const TestComponent = () =>
Hello World
+ const TestComponent = () =>
Hello World
; - render() + render(); - expect(screen.getByTestId('test-element')).toBeInTheDocument() - expect(screen.getByText('Hello World')).toBeInTheDocument() - }) + expect(screen.getByTestId('test-element')).toBeInTheDocument(); + expect(screen.getByText('Hello World')).toBeInTheDocument(); + }); it('should have jsdom environment', () => { - expect(typeof window).toBe('object') - expect(typeof document).toBe('object') - }) + expect(typeof window).toBe('object'); + expect(typeof document).toBe('object'); + }); it('should have Next.js mocks available', () => { // Test that Next.js router mock is working - const { useRouter } = require('next/router') - const router = useRouter() + const { useRouter } = require('next/router'); + const router = useRouter(); - expect(router).toBeDefined() - expect(typeof router.push).toBe('function') - }) -}) \ No newline at end of file + expect(router).toBeDefined(); + expect(typeof router.push).toBe('function'); + }); +}); \ No newline at end of file diff --git a/apps/ops-dashboard/__tests__/utils/test-utils.tsx b/apps/ops-dashboard/__tests__/utils/test-utils.tsx index 03c1966..1f04603 100644 --- a/apps/ops-dashboard/__tests__/utils/test-utils.tsx +++ b/apps/ops-dashboard/__tests__/utils/test-utils.tsx @@ -1,12 +1,13 @@ -import React, { ReactElement } from 'react' -import { render, renderHook, RenderOptions } from '@testing-library/react' -import { QueryClient, QueryClientProvider } from '@tanstack/react-query' -import { ThemeProvider } from 'next-themes' -import { KubernetesProvider } from '../../k8s/context' -import { NamespaceProvider } from '../../contexts/NamespaceContext' -import { AppProvider } from '../../contexts/AppContext' +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { render, renderHook, RenderOptions } from '@testing-library/react'; +import { ThemeProvider } from 'next-themes'; +import React, { ReactElement } from 'react'; + +import { AppProvider } from '../../contexts/AppContext'; +import { NamespaceProvider } from '../../contexts/NamespaceContext'; // import { ConfirmProvider } from '@/hooks' -import { ConfirmProvider } from '../../hooks/useConfirm' +import { ConfirmProvider } from '../../hooks/useConfirm'; +import { KubernetesProvider } from '../../k8s/context'; // Create a custom render function that includes providers const AllTheProviders = ({ children }: { children: React.ReactNode }) => { @@ -19,7 +20,7 @@ const AllTheProviders = ({ children }: { children: React.ReactNode }) => { retry: false, }, }, - }) + }); return ( @@ -40,25 +41,25 @@ const AllTheProviders = ({ children }: { children: React.ReactNode }) => { - ) -} + ); +}; const customRender = ( ui: ReactElement, options?: RenderOptions, -) => render(ui, { wrapper: AllTheProviders, ...options }) +) => render(ui, { wrapper: AllTheProviders, ...options }); const customRenderHook = ( hook: () => T, options?: RenderOptions, -) => renderHook(hook, { wrapper: AllTheProviders, ...options }) +) => renderHook(hook, { wrapper: AllTheProviders, ...options }); // Re-export everything -export * from '@testing-library/react' +export * from '@testing-library/react'; export { customRender as render, customRenderHook as renderHook, -} +}; diff --git a/apps/ops-dashboard/app/admin/backups/page.tsx b/apps/ops-dashboard/app/admin/backups/page.tsx index e30ae15..6c83d81 100644 --- a/apps/ops-dashboard/app/admin/backups/page.tsx +++ b/apps/ops-dashboard/app/admin/backups/page.tsx @@ -1,32 +1,33 @@ -'use client' +'use client'; -import { Button } from "@/components/ui/button"; -import { Card, CardHeader, CardTitle, CardContent, CardDescription } from "@/components/ui/card"; -import { TableHeader, TableRow, TableHead, TableBody, TableCell } from "@/components/ui/table"; -import { useQueryBackups } from "@/hooks/useDatabases"; -import { RefreshCw, Plus, AlertCircle, Table, Eye, Terminal, Trash2 } from "lucide-react"; -import { useState } from "react"; +import { AlertCircle, Eye, RefreshCw, Table, Terminal, Trash2 } from 'lucide-react'; +import { useState } from 'react'; + +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription,CardHeader, CardTitle } from '@/components/ui/card'; +import { TableBody, TableCell,TableHead, TableHeader, TableRow } from '@/components/ui/table'; +import { useQueryBackups } from '@/hooks/useDatabases'; export default function AdminBackupView() { - const namespace = 'postgres-db' + const namespace = 'postgres-db'; - const { data, isLoading ,error, refetch } = useQueryBackups(namespace, 'postgres-cluster') + const { data, isLoading ,error, refetch } = useQueryBackups(namespace, 'postgres-cluster'); const handleRefresh = () => { - refetch() - } + refetch(); + }; - const backups = data?.backups || [] + const backups = data?.backups || []; - const [selectedBackup, setSelectedBackup] = useState(null) + const [selectedBackup, setSelectedBackup] = useState(null); const handleViewLogs = (backup: any) => { - console.log(backup) - } + console.log(backup); + }; const handleDelete = (backup: any) => { - console.log(backup) - } + console.log(backup); + }; return (
@@ -193,5 +194,5 @@ export default function AdminBackupView() {
- ) + ); } \ No newline at end of file diff --git a/apps/ops-dashboard/app/admin/databases/page.tsx b/apps/ops-dashboard/app/admin/databases/page.tsx index 042ad8d..886808f 100644 --- a/apps/ops-dashboard/app/admin/databases/page.tsx +++ b/apps/ops-dashboard/app/admin/databases/page.tsx @@ -1,16 +1,17 @@ 'use client'; -import { useDatabaseStatus } from '@/hooks/use-database-status'; -import { useState } from 'react'; import { useQueryClient } from '@tanstack/react-query'; -import { Button } from '@/components/ui/button'; -import { CreateDatabasesDialog } from '@/components/create-databases-dialog'; -import { CreateDatabaseParams, useCreateBackup, useCreateDatabases, useQueryBackups } from '@/hooks/useDatabases'; import { AlertCircle, CheckCircle, Eye, Plus, RefreshCw } from 'lucide-react'; -import { Badge } from '@/components/ui/badge'; -import { Card, CardHeader, CardTitle, CardDescription, CardContent } from '@/components/ui/card'; -import { TableHeader, TableRow, TableHead, TableBody, TableCell,Table } from '@/components/ui/table'; +import { useState } from 'react'; + import { CreateBackupDialog } from '@/components/create-backup-dialog'; +import { CreateDatabasesDialog } from '@/components/create-databases-dialog'; +import { Badge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent,CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { Table,TableBody, TableCell,TableHead, TableHeader, TableRow } from '@/components/ui/table'; +import { useDatabaseStatus } from '@/hooks/use-database-status'; +import { CreateDatabaseParams, useCreateBackup, useCreateDatabases, useQueryBackups } from '@/hooks/useDatabases'; export default function DatabasesPage() { // For now default to the standard ns/name; later we can add list + picker @@ -26,11 +27,11 @@ export default function DatabasesPage() { const [showCreateBackup, setShowCreateBackup] = useState(false); - const createDb = useCreateDatabases() + const createDb = useCreateDatabases(); - const backups = useQueryBackups(ns, name) + const backups = useQueryBackups(ns, name); - const createBackup = useCreateBackup() + const createBackup = useCreateBackup(); const handleCreateDb = async (data: CreateDatabaseParams) =>{ return createDb.mutateAsync(data,{ @@ -38,12 +39,12 @@ export default function DatabasesPage() { refetch(); qc.invalidateQueries({ queryKey: ['db-status', ns, name] }); } - }) - } + }); + }; const openBackupDialog = () => { - setShowCreateBackup(true) - } + setShowCreateBackup(true); + }; const handleCreateBackUp = (method?: string) =>{ return createBackup.mutateAsync({ @@ -52,24 +53,24 @@ export default function DatabasesPage() { method },{ onSuccess: () => qc.invalidateQueries({ queryKey: ['db-backups', ns, name] }), - }) - } + }); + }; const getStatusBadge = (status: string) => { switch (status) { - case 'Cluster in healthy state': - return - + case 'Cluster in healthy state': + return + running - - default: - return {status} + ; + default: + return {status}; } - } + }; const handleRefresh = () => { - refetch() - } + refetch(); + }; return (
diff --git a/apps/ops-dashboard/app/admin/operators/page.tsx b/apps/ops-dashboard/app/admin/operators/page.tsx index efb0cd2..f3f2599 100644 --- a/apps/ops-dashboard/app/admin/operators/page.tsx +++ b/apps/ops-dashboard/app/admin/operators/page.tsx @@ -1,11 +1,12 @@ 'use client'; -import { useState } from 'react'; -import { Card, CardContent } from '@/components/ui/card'; import { RefreshCw } from 'lucide-react'; +import { useState } from 'react'; + +import { OperatorCard } from '@/components/admin/operator-card'; import { OperatorFilters } from '@/components/admin/operator-filters'; +import { Card, CardContent } from '@/components/ui/card'; import { useOperators } from '@/hooks/use-operators'; -import { OperatorCard } from '@/components/admin/operator-card'; export default function OperatorsPage() { const [searchTerm, setSearchTerm] = useState(''); diff --git a/apps/ops-dashboard/app/admin/pods/page.tsx b/apps/ops-dashboard/app/admin/pods/page.tsx index 4aa4054..8e9b25f 100644 --- a/apps/ops-dashboard/app/admin/pods/page.tsx +++ b/apps/ops-dashboard/app/admin/pods/page.tsx @@ -1,5 +1,5 @@ -import { PodsView } from "@/components/resources/pods"; +import { PodsView } from '@/components/resources/pods'; export default function AdminPodsPage() { - return + return ; } \ No newline at end of file diff --git a/apps/ops-dashboard/app/admin/services/page.tsx b/apps/ops-dashboard/app/admin/services/page.tsx index ed73551..6b570c5 100644 --- a/apps/ops-dashboard/app/admin/services/page.tsx +++ b/apps/ops-dashboard/app/admin/services/page.tsx @@ -1,5 +1,5 @@ -import { ServicesView } from "@/components/resources/services"; +import { ServicesView } from '@/components/resources/services'; export default function AdminServicesPage() { - return + return ; } \ No newline at end of file diff --git a/apps/ops-dashboard/app/admin/templates/page.tsx b/apps/ops-dashboard/app/admin/templates/page.tsx index 47bafd0..9e34397 100644 --- a/apps/ops-dashboard/app/admin/templates/page.tsx +++ b/apps/ops-dashboard/app/admin/templates/page.tsx @@ -1,38 +1,39 @@ -'use client' +'use client'; -import { useState, useMemo, useCallback } from 'react' -import { Card, CardContent } from '@/components/ui/card' -import { TemplateFilters } from '@/components/admin/template-filters' -import { templates, type Template } from '@/components/templates/templates' -import { TemplateCard } from '@/components/admin/template-card' +import { useCallback,useMemo, useState } from 'react'; + +import { TemplateCard } from '@/components/admin/template-card'; +import { TemplateFilters } from '@/components/admin/template-filters'; +import { type Template,templates } from '@/components/templates/templates'; +import { Card, CardContent } from '@/components/ui/card'; type TemplateStatus = 'all' | 'installed' | 'not-installed' | 'installing' | 'error' export default function AdminTemplatesPage() { - const [searchTerm, setSearchTerm] = useState('') - const [globalStatusFilter, setGlobalStatusFilter] = useState('all') - const [templateStatuses, setTemplateStatuses] = useState>(new Map()) + const [searchTerm, setSearchTerm] = useState(''); + const [globalStatusFilter, setGlobalStatusFilter] = useState('all'); + const [templateStatuses, setTemplateStatuses] = useState>(new Map()); const filteredTemplates = useMemo(() => { - const term = searchTerm.toLowerCase() + const term = searchTerm.toLowerCase(); return templates.filter((tpl) => { - const matchesSearch = tpl.name.toLowerCase().includes(term) || tpl.description.toLowerCase().includes(term) + const matchesSearch = tpl.name.toLowerCase().includes(term) || tpl.description.toLowerCase().includes(term); // Apply global status filter if not 'all' if (globalStatusFilter !== 'all') { - const templateStatus = templateStatuses.get(tpl.id) || 'not-installed' + const templateStatus = templateStatuses.get(tpl.id) || 'not-installed'; if (templateStatus !== globalStatusFilter) { - return false + return false; } } - return matchesSearch - }) - }, [searchTerm, globalStatusFilter, templateStatuses]) + return matchesSearch; + }); + }, [searchTerm, globalStatusFilter, templateStatuses]); const updateTemplateStatus = useCallback((templateId: string, status: TemplateStatus) => { - setTemplateStatuses(prev => new Map(prev).set(templateId, status)) - }, []) + setTemplateStatuses(prev => new Map(prev).set(templateId, status)); + }, []); return (
@@ -71,5 +72,5 @@ export default function AdminTemplatesPage() { )}
- ) + ); } \ No newline at end of file diff --git a/apps/ops-dashboard/app/api/databases/[namespace]/[name]/backups/route.ts b/apps/ops-dashboard/app/api/databases/[namespace]/[name]/backups/route.ts index cdf8ddf..afb74b5 100644 --- a/apps/ops-dashboard/app/api/databases/[namespace]/[name]/backups/route.ts +++ b/apps/ops-dashboard/app/api/databases/[namespace]/[name]/backups/route.ts @@ -1,7 +1,7 @@ -import { NextRequest, NextResponse } from 'next/server'; -import { InterwebClient as InterwebKubernetesClient } from '@kubernetesjs/ops'; import { SetupClient } from '@kubernetesjs/client'; import { PostgresDeployer } from '@kubernetesjs/client'; +import { InterwebClient as InterwebKubernetesClient } from '@kubernetesjs/ops'; +import { NextRequest, NextResponse } from 'next/server'; export const dynamic = 'force-dynamic'; @@ -85,7 +85,7 @@ export async function POST( if (type === 'onDemand') { // Auto-select method if none provided if (!method) { - const cluster: any = await (kube as any).readPostgresqlCnpgIoV1NamespacedCluster({ path: { namespace: ns, name } }).catch(() => null); + const cluster: any = await (kube as any).readPostgresqlCnpgIoV1NamespacedCluster({ path: { namespace: ns, name } }).catch(() => null); const hasBarman = Boolean(cluster?.spec?.backup?.barmanObjectStore); if (hasBarman) { method = 'barmanObjectStore'; diff --git a/apps/ops-dashboard/app/api/databases/[namespace]/[name]/deploy/route.ts b/apps/ops-dashboard/app/api/databases/[namespace]/[name]/deploy/route.ts index 35bd88a..9b36bad 100644 --- a/apps/ops-dashboard/app/api/databases/[namespace]/[name]/deploy/route.ts +++ b/apps/ops-dashboard/app/api/databases/[namespace]/[name]/deploy/route.ts @@ -1,5 +1,5 @@ -import { NextRequest, NextResponse } from 'next/server'; import { Client } from '@kubernetesjs/client'; +import { NextRequest, NextResponse } from 'next/server'; export const dynamic = 'force-dynamic'; diff --git a/apps/ops-dashboard/app/api/databases/[namespace]/[name]/status/route.ts b/apps/ops-dashboard/app/api/databases/[namespace]/[name]/status/route.ts index 25b12b9..e59530f 100644 --- a/apps/ops-dashboard/app/api/databases/[namespace]/[name]/status/route.ts +++ b/apps/ops-dashboard/app/api/databases/[namespace]/[name]/status/route.ts @@ -1,5 +1,5 @@ -import { NextResponse } from 'next/server'; import { InterwebClient as InterwebKubernetesClient } from '@kubernetesjs/ops'; +import { NextResponse } from 'next/server'; export const dynamic = 'force-dynamic'; diff --git a/apps/ops-dashboard/app/api/init/route.ts b/apps/ops-dashboard/app/api/init/route.ts index 8a3df5a..daaf3b9 100644 --- a/apps/ops-dashboard/app/api/init/route.ts +++ b/apps/ops-dashboard/app/api/init/route.ts @@ -1,17 +1,17 @@ -import { NextRequest, NextResponse } from 'next/server' -import { randomUUID } from 'crypto' +import { randomUUID } from 'crypto'; +import { NextRequest, NextResponse } from 'next/server'; export async function POST(request: NextRequest) { try { - const body = await request.json() - const { projectName, projectPath, instanceId } = body + const body = await request.json(); + const { projectName, projectPath, instanceId } = body; // Validate required fields if (!projectName || !projectPath || !instanceId) { return NextResponse.json( { error: 'Missing required fields: projectName, projectPath, or instanceId' }, { status: 400 } - ) + ); } // In a real implementation, this would: @@ -21,8 +21,8 @@ export async function POST(request: NextRequest) { // 4. Create a session for the user // For now, we'll simulate project initialization - const sessionId = randomUUID() - const projectId = randomUUID() + const sessionId = randomUUID(); + const projectId = randomUUID(); console.log('Initializing project:', { projectName, @@ -30,7 +30,7 @@ export async function POST(request: NextRequest) { instanceId, sessionId, projectId - }) + }); // Return the session and project IDs return NextResponse.json({ @@ -38,12 +38,12 @@ export async function POST(request: NextRequest) { projectId, projectName, projectPath - }) + }); } catch (error) { - console.error('Failed to initialize project:', error) + console.error('Failed to initialize project:', error); return NextResponse.json( { error: 'Failed to initialize project' }, { status: 500 } - ) + ); } } \ No newline at end of file diff --git a/apps/ops-dashboard/app/api/instance-id/route.ts b/apps/ops-dashboard/app/api/instance-id/route.ts index 4c68680..fbce08c 100644 --- a/apps/ops-dashboard/app/api/instance-id/route.ts +++ b/apps/ops-dashboard/app/api/instance-id/route.ts @@ -1,22 +1,22 @@ -import { NextResponse } from 'next/server' -import { randomUUID } from 'crypto' +import { randomUUID } from 'crypto'; +import { NextResponse } from 'next/server'; // In a real implementation, this would be stored in a database or retrieved from a service -let instanceId: string | null = null +let instanceId: string | null = null; export async function GET() { try { // Generate instance ID if not exists if (!instanceId) { - instanceId = randomUUID() + instanceId = randomUUID(); } - return NextResponse.json({ instanceId }) + return NextResponse.json({ instanceId }); } catch (error) { - console.error('Failed to get instance ID:', error) + console.error('Failed to get instance ID:', error); return NextResponse.json( { error: 'Failed to get instance ID' }, { status: 500 } - ) + ); } } \ No newline at end of file diff --git a/apps/ops-dashboard/app/api/k8s/[...path]/route.ts b/apps/ops-dashboard/app/api/k8s/[...path]/route.ts index 054cc48..55ee206 100644 --- a/apps/ops-dashboard/app/api/k8s/[...path]/route.ts +++ b/apps/ops-dashboard/app/api/k8s/[...path]/route.ts @@ -19,8 +19,8 @@ const resolvePath = async (context: any) => { const segments = Array.isArray(rawParams?.path) ? rawParams.path : rawParams?.path - ? [rawParams.path] - : []; + ? [rawParams.path] + : []; return segments.join('/'); }; @@ -37,7 +37,7 @@ export async function GET(request: NextRequest, context: any) { const response = await fetch(proxyUrl, { method: 'GET', headers: { - 'Accept': 'application/json', + Accept: 'application/json', }, }); @@ -73,7 +73,7 @@ export async function POST(request: NextRequest, context: any) { method: 'POST', headers: { 'Content-Type': 'application/json', - 'Accept': 'application/json', + Accept: 'application/json', }, body: JSON.stringify(body), }); @@ -108,7 +108,7 @@ export async function DELETE(request: NextRequest, context: any) { const response = await fetch(proxyUrl, { method: 'DELETE', headers: { - 'Accept': 'application/json', + Accept: 'application/json', }, }); @@ -144,7 +144,7 @@ export async function PUT(request: NextRequest, context: any) { method: 'PUT', headers: { 'Content-Type': 'application/json', - 'Accept': 'application/json', + Accept: 'application/json', }, body: JSON.stringify(body), }); @@ -181,7 +181,7 @@ export async function PATCH(request: NextRequest, context: any) { method: 'PATCH', headers: { 'Content-Type': 'application/strategic-merge-patch+json', - 'Accept': 'application/json', + Accept: 'application/json', }, body: JSON.stringify(body), }); diff --git a/apps/ops-dashboard/app/api/operators/[operator]/debug/route.ts b/apps/ops-dashboard/app/api/operators/[operator]/debug/route.ts index 16c3a4c..97a6981 100644 --- a/apps/ops-dashboard/app/api/operators/[operator]/debug/route.ts +++ b/apps/ops-dashboard/app/api/operators/[operator]/debug/route.ts @@ -1,4 +1,5 @@ import { NextResponse } from 'next/server'; + import { createSetupClient } from '@/k8s/client'; export const dynamic = 'force-dynamic'; diff --git a/apps/ops-dashboard/app/api/operators/[operator]/install/route.ts b/apps/ops-dashboard/app/api/operators/[operator]/install/route.ts index b031ccd..7eb79f6 100644 --- a/apps/ops-dashboard/app/api/operators/[operator]/install/route.ts +++ b/apps/ops-dashboard/app/api/operators/[operator]/install/route.ts @@ -1,9 +1,10 @@ -import { NextRequest, NextResponse } from 'next/server'; -import { createSetupClient } from '@/k8s/client'; -import { createRequire } from 'module'; import fs from 'fs'; +import { createRequire } from 'module'; +import { NextRequest, NextResponse } from 'next/server'; import path from 'path'; +import { createSetupClient } from '@/k8s/client'; + export async function POST( request: NextRequest, { params }: { params: Promise<{ operator: string }> } diff --git a/apps/ops-dashboard/app/api/operators/route.ts b/apps/ops-dashboard/app/api/operators/route.ts index fa22f1d..4f8550b 100644 --- a/apps/ops-dashboard/app/api/operators/route.ts +++ b/apps/ops-dashboard/app/api/operators/route.ts @@ -1,9 +1,10 @@ import { NextResponse } from 'next/server'; export const dynamic = 'force-dynamic'; -import { createRequire } from 'module'; import fs from 'fs'; +import { createRequire } from 'module'; import path from 'path'; + import { createSetupClient } from '@/k8s/client'; export async function GET() { diff --git a/apps/ops-dashboard/app/api/templates/[template]/route.ts b/apps/ops-dashboard/app/api/templates/[template]/route.ts index a83972d..dd4b66c 100644 --- a/apps/ops-dashboard/app/api/templates/[template]/route.ts +++ b/apps/ops-dashboard/app/api/templates/[template]/route.ts @@ -1,27 +1,27 @@ -import { NextRequest, NextResponse } from 'next/server' -import { Client, SetupClient } from '@kubernetesjs/client' -import { InterwebClient as InterwebKubernetesClient } from '@kubernetesjs/ops' +import { Client, SetupClient } from '@kubernetesjs/client'; +import { InterwebClient as InterwebKubernetesClient } from '@kubernetesjs/ops'; +import { NextRequest, NextResponse } from 'next/server'; // Initialize client with dashboard context function createClient() { - const restEndpoint = process.env.KUBERNETES_PROXY_URL || 'http://127.0.0.1:8001' + const restEndpoint = process.env.KUBERNETES_PROXY_URL || 'http://127.0.0.1:8001'; return new Client({ restEndpoint, - }) + }); } // GET - Check template status export async function GET(request: NextRequest, { params }: { params: Promise<{ template: string }> }) { try { - const { template } = await params - const url = new URL(request.url) - const namespace = url.searchParams.get('namespace') || 'default' - const name = url.searchParams.get('name') || template + const { template } = await params; + const url = new URL(request.url); + const namespace = url.searchParams.get('namespace') || 'default'; + const name = url.searchParams.get('name') || template; - const client = createClient() + const client = createClient(); - const isDeployed = await client.isTemplateDeployed(template, name, namespace) - const status = await client.getTemplateStatus(template, name, namespace) + const isDeployed = await client.isTemplateDeployed(template, name, namespace); + const status = await client.getTemplateStatus(template, name, namespace); return NextResponse.json({ templateId: template, @@ -29,75 +29,75 @@ export async function GET(request: NextRequest, { params }: { params: Promise<{ namespace, isDeployed, status, - }) + }); } catch (error) { - console.error('Failed to get template status:', error) + console.error('Failed to get template status:', error); return NextResponse.json( { error: 'Failed to get template status', message: error instanceof Error ? error.message : 'Unknown error' }, { status: 500 } - ) + ); } } // POST - Deploy template export async function POST(request: NextRequest, { params }: { params: Promise<{ template: string }> }) { try { - const { template } = await params - const body = await request.json() + const { template } = await params; + const body = await request.json(); const { name = template, namespace = 'default', config = {}, - } = body + } = body; // Ensure CloudNativePG operator is installed and ready before deploying Postgres if (template === 'postgres') { - const restEndpoint = process.env.KUBERNETES_PROXY_URL || 'http://127.0.0.1:8001' - const kube = new InterwebKubernetesClient({ restEndpoint } as any) - const setupClient = new SetupClient(kube, namespace) + const restEndpoint = process.env.KUBERNETES_PROXY_URL || 'http://127.0.0.1:8001'; + const kube = new InterwebKubernetesClient({ restEndpoint } as any); + const setupClient = new SetupClient(kube, namespace); - const connected = await setupClient.checkConnection() + const connected = await setupClient.checkConnection(); if (!connected) { return NextResponse.json( { error: 'Failed to deploy template', message: 'Unable to connect to Kubernetes cluster' }, { status: 500 } - ) + ); } try { - const installs = await setupClient.getOperatorInstallations('cloudnative-pg') - const cnpgInstalled = installs.some(i => i.status === 'installed') + const installs = await setupClient.getOperatorInstallations('cloudnative-pg'); + const cnpgInstalled = installs.some(i => i.status === 'installed'); if (!cnpgInstalled) { - await setupClient.installOperatorByName('cloudnative-pg') - await setupClient.waitForOperator('cloudnative-pg', 180_000, 5_000) + await setupClient.installOperatorByName('cloudnative-pg'); + await setupClient.waitForOperator('cloudnative-pg', 180_000, 5_000); } } catch (opErr) { - console.error('Failed to ensure CNPG operator:', opErr) + console.error('Failed to ensure CNPG operator:', opErr); return NextResponse.json( { error: 'Failed to deploy template', message: opErr instanceof Error ? opErr.message : 'Unable to install CloudNativePG operator' }, { status: 500 } - ) + ); } } - const client = createClient() + const client = createClient(); const result = await client.deployTemplate(template, { name, namespace, config, - }) + }); if (result.status === 'deployed') { return NextResponse.json({ success: true, message: `Template ${template} deployed successfully`, result, - }) + }); } else { return NextResponse.json( { @@ -106,50 +106,50 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{ result, }, { status: 500 } - ) + ); } } catch (error) { - console.error('Failed to deploy template:', error) + console.error('Failed to deploy template:', error); return NextResponse.json( { error: 'Failed to deploy template', message: error instanceof Error ? error.message : 'Unknown error' }, { status: 500 } - ) + ); } } // DELETE - Uninstall template export async function DELETE(request: NextRequest, { params }: { params: Promise<{ template: string }> }) { try { - const { template } = await params - const url = new URL(request.url) + const { template } = await params; + const url = new URL(request.url); // Prefer values from JSON body if provided; fallback to query params - let body: any = undefined + let body: any = undefined; try { - body = await request.json() + body = await request.json(); } catch {} - const namespace = (body?.namespace as string) || url.searchParams.get('namespace') || 'default' - const name = (body?.name as string) || url.searchParams.get('name') || template - const force = Boolean(body?.force) || url.searchParams.get('force') === 'true' + const namespace = (body?.namespace as string) || url.searchParams.get('namespace') || 'default'; + const name = (body?.name as string) || url.searchParams.get('name') || template; + const force = Boolean(body?.force) || url.searchParams.get('force') === 'true'; - const client = createClient() + const client = createClient(); const result = await client.uninstallTemplate(template, { name, namespace, force, - }) + }); if (result.status === 'uninstalled') { return NextResponse.json({ success: true, message: `Template ${template} uninstalled successfully`, result, - }) + }); } else { return NextResponse.json( { @@ -158,16 +158,16 @@ export async function DELETE(request: NextRequest, { params }: { params: Promise result, }, { status: 500 } - ) + ); } } catch (error) { - console.error('Failed to uninstall template:', error) + console.error('Failed to uninstall template:', error); return NextResponse.json( { error: 'Failed to uninstall template', message: error instanceof Error ? error.message : 'Unknown error' }, { status: 500 } - ) + ); } } \ No newline at end of file diff --git a/apps/ops-dashboard/app/d/chains/page.tsx b/apps/ops-dashboard/app/d/chains/page.tsx index 3b6b84a..f6f1d64 100644 --- a/apps/ops-dashboard/app/d/chains/page.tsx +++ b/apps/ops-dashboard/app/d/chains/page.tsx @@ -1,8 +1,9 @@ -'use client' +'use client'; -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Link, Plus, Activity, Globe, Zap } from 'lucide-react' -import { Button } from '@/components/ui/button' +import { Activity, Globe, Link, Plus, Zap } from 'lucide-react'; + +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; export default function ChainsPage() { return ( @@ -81,5 +82,5 @@ export default function ChainsPage() {
- ) + ); } \ No newline at end of file diff --git a/apps/ops-dashboard/app/d/databases/page.tsx b/apps/ops-dashboard/app/d/databases/page.tsx index e2aa28c..06f30f4 100644 --- a/apps/ops-dashboard/app/d/databases/page.tsx +++ b/apps/ops-dashboard/app/d/databases/page.tsx @@ -1,8 +1,9 @@ -'use client' +'use client'; -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Database, Plus, Activity, Users, HardDrive } from 'lucide-react' -import { Button } from '@/components/ui/button' +import { Activity, Database, HardDrive,Plus, Users } from 'lucide-react'; + +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; export default function DatabasesPage() { return ( @@ -81,5 +82,5 @@ export default function DatabasesPage() { - ) + ); } \ No newline at end of file diff --git a/apps/ops-dashboard/app/d/functions/page.tsx b/apps/ops-dashboard/app/d/functions/page.tsx index ac9c559..1a16418 100644 --- a/apps/ops-dashboard/app/d/functions/page.tsx +++ b/apps/ops-dashboard/app/d/functions/page.tsx @@ -1,8 +1,9 @@ -'use client' +'use client'; -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Zap, Plus, Activity, Clock, TrendingUp } from 'lucide-react' -import { Button } from '@/components/ui/button' +import { Activity, Clock, Plus, TrendingUp,Zap } from 'lucide-react'; + +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; export default function FunctionsPage() { return ( @@ -81,5 +82,5 @@ export default function FunctionsPage() { - ) + ); } \ No newline at end of file diff --git a/apps/ops-dashboard/app/d/page.tsx b/apps/ops-dashboard/app/d/page.tsx index aaee298..e177b31 100644 --- a/apps/ops-dashboard/app/d/page.tsx +++ b/apps/ops-dashboard/app/d/page.tsx @@ -1,8 +1,9 @@ 'use client'; -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { Activity, ArrowRight, Database, Globe, Link as LinkIcon, TrendingUp,Zap } from 'lucide-react'; import Link from 'next/link'; -import { Database, Zap, Link as LinkIcon, Globe, Settings, ArrowRight, Activity, TrendingUp, Users } from 'lucide-react'; + +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; const smartObjects = [ { diff --git a/apps/ops-dashboard/app/d/registry/page.tsx b/apps/ops-dashboard/app/d/registry/page.tsx index 1c6f8ce..7551dbb 100644 --- a/apps/ops-dashboard/app/d/registry/page.tsx +++ b/apps/ops-dashboard/app/d/registry/page.tsx @@ -1,8 +1,9 @@ -'use client' +'use client'; -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Database, Plus, Search, Tag, FileCode2 } from 'lucide-react' -import { Button } from '@/components/ui/button' +import { Database, FileCode2,Plus, Search, Tag } from 'lucide-react'; + +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; export default function RegistryPage() { return ( @@ -81,5 +82,5 @@ export default function RegistryPage() { - ) + ); } \ No newline at end of file diff --git a/apps/ops-dashboard/app/d/relayers/page.tsx b/apps/ops-dashboard/app/d/relayers/page.tsx index fe2cb0d..db7bab4 100644 --- a/apps/ops-dashboard/app/d/relayers/page.tsx +++ b/apps/ops-dashboard/app/d/relayers/page.tsx @@ -1,8 +1,9 @@ -'use client' +'use client'; -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Globe, Plus, Activity, ArrowRightLeft, Zap } from 'lucide-react' -import { Button } from '@/components/ui/button' +import { Activity, ArrowRightLeft, Globe, Plus, Zap } from 'lucide-react'; + +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; export default function RelayersPage() { return ( @@ -81,5 +82,5 @@ export default function RelayersPage() { - ) + ); } \ No newline at end of file diff --git a/apps/ops-dashboard/app/d/settings/page.tsx b/apps/ops-dashboard/app/d/settings/page.tsx index 0e8d0a2..8fcf3a8 100644 --- a/apps/ops-dashboard/app/d/settings/page.tsx +++ b/apps/ops-dashboard/app/d/settings/page.tsx @@ -1,8 +1,8 @@ -'use client' +'use client'; -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Settings, User, Key, Bell, Shield } from 'lucide-react' -import { Button } from '@/components/ui/button' +import { Bell, Key, Shield,User } from 'lucide-react'; + +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; export default function SettingsPage() { return ( @@ -85,5 +85,5 @@ export default function SettingsPage() { - ) + ); } \ No newline at end of file diff --git a/apps/ops-dashboard/app/databases/page.tsx b/apps/ops-dashboard/app/databases/page.tsx index b282a24..c7b45c7 100644 --- a/apps/ops-dashboard/app/databases/page.tsx +++ b/apps/ops-dashboard/app/databases/page.tsx @@ -1,7 +1,8 @@ -'use client' +'use client'; -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Database } from 'lucide-react' +import { Database } from 'lucide-react'; + +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; export default function DatabasesPage() { return ( @@ -34,5 +35,5 @@ export default function DatabasesPage() { - ) + ); } \ No newline at end of file diff --git a/apps/ops-dashboard/app/functions/page.tsx b/apps/ops-dashboard/app/functions/page.tsx index 4889631..a7ba99e 100644 --- a/apps/ops-dashboard/app/functions/page.tsx +++ b/apps/ops-dashboard/app/functions/page.tsx @@ -1,7 +1,8 @@ -'use client' +'use client'; -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Zap } from 'lucide-react' +import { Zap } from 'lucide-react'; + +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; export default function FunctionsPage() { return ( @@ -34,5 +35,5 @@ export default function FunctionsPage() { - ) + ); } \ No newline at end of file diff --git a/apps/ops-dashboard/app/i/all/page.tsx b/apps/ops-dashboard/app/i/all/page.tsx index a746662..58d47e3 100644 --- a/apps/ops-dashboard/app/i/all/page.tsx +++ b/apps/ops-dashboard/app/i/all/page.tsx @@ -1,5 +1,5 @@ -import { AllResourcesView } from '@/components/resources/all-resources' +import { AllResourcesView } from '@/components/resources/all-resources'; export default function AllResourcesPage() { - return + return ; } diff --git a/apps/ops-dashboard/app/i/configmaps/page.tsx b/apps/ops-dashboard/app/i/configmaps/page.tsx index 440e31e..db4041c 100644 --- a/apps/ops-dashboard/app/i/configmaps/page.tsx +++ b/apps/ops-dashboard/app/i/configmaps/page.tsx @@ -1,5 +1,5 @@ -import { ConfigMapsView } from '@/components/resources/configmaps' +import { ConfigMapsView } from '@/components/resources/configmaps'; export default function ConfigMapsPage() { - return + return ; } \ No newline at end of file diff --git a/apps/ops-dashboard/app/i/cronjobs/page.tsx b/apps/ops-dashboard/app/i/cronjobs/page.tsx index e777832..487c3d2 100644 --- a/apps/ops-dashboard/app/i/cronjobs/page.tsx +++ b/apps/ops-dashboard/app/i/cronjobs/page.tsx @@ -1,5 +1,5 @@ -import { CronJobsView } from '@/components/resources/cronjobs' +import { CronJobsView } from '@/components/resources/cronjobs'; export default function CronJobsPage() { - return + return ; } diff --git a/apps/ops-dashboard/app/i/daemonsets/page.tsx b/apps/ops-dashboard/app/i/daemonsets/page.tsx index a3595f9..2c7b8cd 100644 --- a/apps/ops-dashboard/app/i/daemonsets/page.tsx +++ b/apps/ops-dashboard/app/i/daemonsets/page.tsx @@ -1,5 +1,5 @@ -import { DaemonSetsView } from '@/components/resources/daemonsets' +import { DaemonSetsView } from '@/components/resources/daemonsets'; export default function DaemonSetsPage() { - return + return ; } diff --git a/apps/ops-dashboard/app/i/deployments/page.tsx b/apps/ops-dashboard/app/i/deployments/page.tsx index 251b5dd..ac81723 100644 --- a/apps/ops-dashboard/app/i/deployments/page.tsx +++ b/apps/ops-dashboard/app/i/deployments/page.tsx @@ -1,5 +1,5 @@ -import { DeploymentsView } from '@/components/resources/deployments' +import { DeploymentsView } from '@/components/resources/deployments'; export default function DeploymentsPage() { - return + return ; } \ No newline at end of file diff --git a/apps/ops-dashboard/app/i/endpoints/page.tsx b/apps/ops-dashboard/app/i/endpoints/page.tsx index 88b1972..62f8c82 100644 --- a/apps/ops-dashboard/app/i/endpoints/page.tsx +++ b/apps/ops-dashboard/app/i/endpoints/page.tsx @@ -1,5 +1,5 @@ -import { EndpointsView } from '@/components/resources/endpoints' +import { EndpointsView } from '@/components/resources/endpoints'; export default function EndpointsPage() { - return + return ; } diff --git a/apps/ops-dashboard/app/i/endpointslices/page.tsx b/apps/ops-dashboard/app/i/endpointslices/page.tsx index 887d06a..ea036fd 100644 --- a/apps/ops-dashboard/app/i/endpointslices/page.tsx +++ b/apps/ops-dashboard/app/i/endpointslices/page.tsx @@ -1,5 +1,5 @@ -import { EndpointSlicesView } from '@/components/resources/endpointslices' +import { EndpointSlicesView } from '@/components/resources/endpointslices'; export default function EndpointSlicesPage() { - return + return ; } diff --git a/apps/ops-dashboard/app/i/events/page.tsx b/apps/ops-dashboard/app/i/events/page.tsx index 0b2cfb5..36e4c7d 100644 --- a/apps/ops-dashboard/app/i/events/page.tsx +++ b/apps/ops-dashboard/app/i/events/page.tsx @@ -1,5 +1,5 @@ -import { EventsView } from '@/components/resources/events' +import { EventsView } from '@/components/resources/events'; export default function EventsPage() { - return + return ; } diff --git a/apps/ops-dashboard/app/i/hpas/page.tsx b/apps/ops-dashboard/app/i/hpas/page.tsx index 8c86dba..a688f8f 100644 --- a/apps/ops-dashboard/app/i/hpas/page.tsx +++ b/apps/ops-dashboard/app/i/hpas/page.tsx @@ -1,5 +1,5 @@ -import { HPAsView } from '@/components/resources/hpas' +import { HPAsView } from '@/components/resources/hpas'; export default function HPAsPage() { - return + return ; } diff --git a/apps/ops-dashboard/app/i/ingresses/page.tsx b/apps/ops-dashboard/app/i/ingresses/page.tsx index e228dcc..cf46c36 100644 --- a/apps/ops-dashboard/app/i/ingresses/page.tsx +++ b/apps/ops-dashboard/app/i/ingresses/page.tsx @@ -1,5 +1,5 @@ -import { IngressesView } from '@/components/resources/ingresses' +import { IngressesView } from '@/components/resources/ingresses'; export default function IngressesPage() { - return + return ; } diff --git a/apps/ops-dashboard/app/i/jobs/page.tsx b/apps/ops-dashboard/app/i/jobs/page.tsx index e43f5d5..b4f3554 100644 --- a/apps/ops-dashboard/app/i/jobs/page.tsx +++ b/apps/ops-dashboard/app/i/jobs/page.tsx @@ -1,5 +1,5 @@ -import { JobsView } from '@/components/resources/jobs' +import { JobsView } from '@/components/resources/jobs'; export default function JobsPage() { - return + return ; } diff --git a/apps/ops-dashboard/app/i/networkpolicies/page.tsx b/apps/ops-dashboard/app/i/networkpolicies/page.tsx index aa5bad2..521a07f 100644 --- a/apps/ops-dashboard/app/i/networkpolicies/page.tsx +++ b/apps/ops-dashboard/app/i/networkpolicies/page.tsx @@ -1,5 +1,5 @@ -import { NetworkPoliciesView } from '@/components/resources/networkpolicies' +import { NetworkPoliciesView } from '@/components/resources/networkpolicies'; export default function NetworkPoliciesPage() { - return + return ; } diff --git a/apps/ops-dashboard/app/i/page.tsx b/apps/ops-dashboard/app/i/page.tsx index 0c46883..445dee2 100644 --- a/apps/ops-dashboard/app/i/page.tsx +++ b/apps/ops-dashboard/app/i/page.tsx @@ -1,9 +1,9 @@ 'use client'; -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; -import { Suspense } from 'react'; +import { Activity, ArrowRight, Copy, Key, Layers,Package, Server, Settings } from 'lucide-react'; import Link from 'next/link'; -import { Package, Server, Key, Settings, Copy, Activity, ArrowRight, Layers } from 'lucide-react'; + +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; const resources = [ { diff --git a/apps/ops-dashboard/app/i/pdbs/page.tsx b/apps/ops-dashboard/app/i/pdbs/page.tsx index ba94619..178c010 100644 --- a/apps/ops-dashboard/app/i/pdbs/page.tsx +++ b/apps/ops-dashboard/app/i/pdbs/page.tsx @@ -1,5 +1,5 @@ -import { PDBsView } from '@/components/resources/pdbs' +import { PDBsView } from '@/components/resources/pdbs'; export default function PDBsPage() { - return + return ; } diff --git a/apps/ops-dashboard/app/i/pods/page.tsx b/apps/ops-dashboard/app/i/pods/page.tsx index 16aa3d0..3f1085f 100644 --- a/apps/ops-dashboard/app/i/pods/page.tsx +++ b/apps/ops-dashboard/app/i/pods/page.tsx @@ -1,5 +1,5 @@ -import { PodsView } from '@/components/resources/pods' +import { PodsView } from '@/components/resources/pods'; export default function PodsPage() { - return + return ; } \ No newline at end of file diff --git a/apps/ops-dashboard/app/i/priorityclasses/page.tsx b/apps/ops-dashboard/app/i/priorityclasses/page.tsx index c8f3b18..ab62f46 100644 --- a/apps/ops-dashboard/app/i/priorityclasses/page.tsx +++ b/apps/ops-dashboard/app/i/priorityclasses/page.tsx @@ -1,5 +1,5 @@ -import { PriorityClassesView } from '@/components/resources/priorityclasses' +import { PriorityClassesView } from '@/components/resources/priorityclasses'; export default function PriorityClassesPage() { - return + return ; } diff --git a/apps/ops-dashboard/app/i/pvcs/page.tsx b/apps/ops-dashboard/app/i/pvcs/page.tsx index b10ea5c..7beff65 100644 --- a/apps/ops-dashboard/app/i/pvcs/page.tsx +++ b/apps/ops-dashboard/app/i/pvcs/page.tsx @@ -1,5 +1,5 @@ -import { PVCsView } from '@/components/resources/pvcs' +import { PVCsView } from '@/components/resources/pvcs'; export default function PVCsPage() { - return + return ; } diff --git a/apps/ops-dashboard/app/i/pvs/page.tsx b/apps/ops-dashboard/app/i/pvs/page.tsx index a4f84d4..98bfe7d 100644 --- a/apps/ops-dashboard/app/i/pvs/page.tsx +++ b/apps/ops-dashboard/app/i/pvs/page.tsx @@ -1,5 +1,5 @@ -import { PVsView } from '@/components/resources/pvs' +import { PVsView } from '@/components/resources/pvs'; export default function PVsPage() { - return + return ; } diff --git a/apps/ops-dashboard/app/i/replicasets/page.tsx b/apps/ops-dashboard/app/i/replicasets/page.tsx index d01880f..3b0e3d0 100644 --- a/apps/ops-dashboard/app/i/replicasets/page.tsx +++ b/apps/ops-dashboard/app/i/replicasets/page.tsx @@ -1,5 +1,5 @@ -import { ReplicaSetsView } from '@/components/resources/replicasets' +import { ReplicaSetsView } from '@/components/resources/replicasets'; export default function ReplicaSetsPage() { - return + return ; } \ No newline at end of file diff --git a/apps/ops-dashboard/app/i/resourcequotas/page.tsx b/apps/ops-dashboard/app/i/resourcequotas/page.tsx index 4ce8ff3..034edc3 100644 --- a/apps/ops-dashboard/app/i/resourcequotas/page.tsx +++ b/apps/ops-dashboard/app/i/resourcequotas/page.tsx @@ -1,5 +1,5 @@ -import { ResourceQuotasView } from '@/components/resources/resourcequotas' +import { ResourceQuotasView } from '@/components/resources/resourcequotas'; export default function ResourceQuotasPage() { - return + return ; } diff --git a/apps/ops-dashboard/app/i/rolebindings/page.tsx b/apps/ops-dashboard/app/i/rolebindings/page.tsx index a1d3e41..c9ec803 100644 --- a/apps/ops-dashboard/app/i/rolebindings/page.tsx +++ b/apps/ops-dashboard/app/i/rolebindings/page.tsx @@ -1,5 +1,5 @@ -import { RoleBindingsView } from '@/components/resources/rolebindings' +import { RoleBindingsView } from '@/components/resources/rolebindings'; export default function RoleBindingsPage() { - return + return ; } diff --git a/apps/ops-dashboard/app/i/roles/page.tsx b/apps/ops-dashboard/app/i/roles/page.tsx index 719cd19..b84a034 100644 --- a/apps/ops-dashboard/app/i/roles/page.tsx +++ b/apps/ops-dashboard/app/i/roles/page.tsx @@ -1,5 +1,5 @@ -import { RolesView } from '@/components/resources/roles' +import { RolesView } from '@/components/resources/roles'; export default function RolesPage() { - return + return ; } diff --git a/apps/ops-dashboard/app/i/runtimeclasses/page.tsx b/apps/ops-dashboard/app/i/runtimeclasses/page.tsx index deddc20..93e8753 100644 --- a/apps/ops-dashboard/app/i/runtimeclasses/page.tsx +++ b/apps/ops-dashboard/app/i/runtimeclasses/page.tsx @@ -1,5 +1,5 @@ -import { RuntimeClassesView } from '@/components/resources/runtimeclasses' +import { RuntimeClassesView } from '@/components/resources/runtimeclasses'; export default function RuntimeClassesPage() { - return + return ; } diff --git a/apps/ops-dashboard/app/i/secrets/page.tsx b/apps/ops-dashboard/app/i/secrets/page.tsx index 53efaa6..8a8ade1 100644 --- a/apps/ops-dashboard/app/i/secrets/page.tsx +++ b/apps/ops-dashboard/app/i/secrets/page.tsx @@ -1,5 +1,5 @@ -import { SecretsView } from '@/components/resources/secrets' +import { SecretsView } from '@/components/resources/secrets'; export default function SecretsPage() { - return + return ; } \ No newline at end of file diff --git a/apps/ops-dashboard/app/i/serviceaccounts/page.tsx b/apps/ops-dashboard/app/i/serviceaccounts/page.tsx index d408a2e..867abde 100644 --- a/apps/ops-dashboard/app/i/serviceaccounts/page.tsx +++ b/apps/ops-dashboard/app/i/serviceaccounts/page.tsx @@ -1,5 +1,5 @@ -import { ServiceAccountsView } from '@/components/resources/serviceaccounts' +import { ServiceAccountsView } from '@/components/resources/serviceaccounts'; export default function ServiceAccountsPage() { - return + return ; } diff --git a/apps/ops-dashboard/app/i/services/page.tsx b/apps/ops-dashboard/app/i/services/page.tsx index 0ab7eef..7c0aa42 100644 --- a/apps/ops-dashboard/app/i/services/page.tsx +++ b/apps/ops-dashboard/app/i/services/page.tsx @@ -1,5 +1,5 @@ -import { ServicesView } from '@/components/resources/services' +import { ServicesView } from '@/components/resources/services'; export default function ServicesPage() { - return + return ; } \ No newline at end of file diff --git a/apps/ops-dashboard/app/i/statefulsets/page.tsx b/apps/ops-dashboard/app/i/statefulsets/page.tsx index 3c3c8b9..23480c9 100644 --- a/apps/ops-dashboard/app/i/statefulsets/page.tsx +++ b/apps/ops-dashboard/app/i/statefulsets/page.tsx @@ -1,5 +1,5 @@ -import { StatefulSetsView } from '@/components/resources/statefulsets' +import { StatefulSetsView } from '@/components/resources/statefulsets'; export default function StatefulSetsPage() { - return + return ; } diff --git a/apps/ops-dashboard/app/i/storageclasses/page.tsx b/apps/ops-dashboard/app/i/storageclasses/page.tsx index 2dfb39e..dfd4ec3 100644 --- a/apps/ops-dashboard/app/i/storageclasses/page.tsx +++ b/apps/ops-dashboard/app/i/storageclasses/page.tsx @@ -1,5 +1,5 @@ -import { StorageClassesView } from '@/components/resources/storageclasses' +import { StorageClassesView } from '@/components/resources/storageclasses'; export default function StorageClassesPage() { - return + return ; } diff --git a/apps/ops-dashboard/app/i/volumeattachments/page.tsx b/apps/ops-dashboard/app/i/volumeattachments/page.tsx index 340db99..835d749 100644 --- a/apps/ops-dashboard/app/i/volumeattachments/page.tsx +++ b/apps/ops-dashboard/app/i/volumeattachments/page.tsx @@ -1,5 +1,5 @@ -import { VolumeAttachmentsView } from '@/components/resources/volumeattachments' +import { VolumeAttachmentsView } from '@/components/resources/volumeattachments'; export default function VolumeAttachmentsPage() { - return + return ; } diff --git a/apps/ops-dashboard/app/layout.tsx b/apps/ops-dashboard/app/layout.tsx index 8994ed9..382aa0d 100644 --- a/apps/ops-dashboard/app/layout.tsx +++ b/apps/ops-dashboard/app/layout.tsx @@ -1,10 +1,13 @@ +import './globals.css'; + import type { Metadata } from 'next'; import { Inter } from 'next/font/google'; -import './globals.css'; -import { Providers } from './providers'; -import { AppLayout } from '@/components/app-layout'; import { NuqsAdapter } from 'nuqs/adapters/next/app'; +import { AppLayout } from '@/components/app-layout'; + +import { Providers } from './providers'; + const inter = Inter({ subsets: ['latin'] }); export const metadata: Metadata = { diff --git a/apps/ops-dashboard/app/page.tsx b/apps/ops-dashboard/app/page.tsx index 25c0dc9..02c62bf 100644 --- a/apps/ops-dashboard/app/page.tsx +++ b/apps/ops-dashboard/app/page.tsx @@ -1,14 +1,14 @@ -'use client' +'use client'; -import { useEffect } from 'react' -import { useRouter } from 'next/navigation' +import { useRouter } from 'next/navigation'; +import { useEffect } from 'react'; export default function HomePage() { - const router = useRouter() + const router = useRouter(); useEffect(() => { - router.replace('/d') - }, [router]) + router.replace('/d'); + }, [router]); - return null + return null; } \ No newline at end of file diff --git a/apps/ops-dashboard/app/providers.tsx b/apps/ops-dashboard/app/providers.tsx index 4a16169..2114f20 100644 --- a/apps/ops-dashboard/app/providers.tsx +++ b/apps/ops-dashboard/app/providers.tsx @@ -1,11 +1,13 @@ 'use client'; import { ThemeProvider } from 'next-themes'; -import { KubernetesProvider } from '../k8s/context'; -import { NamespaceProvider } from '@/contexts/NamespaceContext'; + import { AppProvider } from '@/contexts/AppContext'; +import { NamespaceProvider } from '@/contexts/NamespaceContext'; import { ConfirmProvider } from '@/hooks/useConfirm'; +import { KubernetesProvider } from '../k8s/context'; + interface ProvidersProps { children: React.ReactNode; } diff --git a/apps/ops-dashboard/components/adaptive-layout.tsx b/apps/ops-dashboard/components/adaptive-layout.tsx index 54cef6d..e12e044 100644 --- a/apps/ops-dashboard/components/adaptive-layout.tsx +++ b/apps/ops-dashboard/components/adaptive-layout.tsx @@ -1,6 +1,7 @@ 'use client'; import { usePathname } from 'next/navigation'; + import { DashboardLayout } from './dashboard-layout'; interface AdaptiveLayoutProps { diff --git a/apps/ops-dashboard/components/admin/cluster-overview.tsx b/apps/ops-dashboard/components/admin/cluster-overview.tsx index 07a56f6..a37208d 100644 --- a/apps/ops-dashboard/components/admin/cluster-overview.tsx +++ b/apps/ops-dashboard/components/admin/cluster-overview.tsx @@ -1,9 +1,10 @@ 'use client'; -import { useClusterStatus } from '@/hooks/use-cluster-status'; +import { RefreshCw } from 'lucide-react'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; -import { RefreshCw } from 'lucide-react'; +import { useClusterStatus } from '@/hooks/use-cluster-status'; + import { StatusIndicator } from './status-indicator'; export function ClusterOverview() { diff --git a/apps/ops-dashboard/components/admin/operator-card.tsx b/apps/ops-dashboard/components/admin/operator-card.tsx index 9955786..15f0312 100644 --- a/apps/ops-dashboard/components/admin/operator-card.tsx +++ b/apps/ops-dashboard/components/admin/operator-card.tsx @@ -1,18 +1,17 @@ 'use client'; -import { useState } from 'react'; +import type { OperatorInfo } from '@kubernetesjs/client'; +import { ExternalLink, Loader2,Settings } from 'lucide-react'; import Link from 'next/link'; +import { useState } from 'react'; +import { Button } from '@/components/ui/button'; import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card'; - - -import { Settings, ExternalLink, Loader2 } from 'lucide-react'; +import { Switch } from '@/components/ui/switch'; +import { useOperatorMutation } from '@/hooks/use-operators'; import { cn } from '@/lib/utils'; + import { StatusIndicator } from './status-indicator'; -import { Switch } from '@/components/ui/switch' -import type { OperatorInfo } from '@kubernetesjs/client'; -import { useOperatorMutation } from '@/hooks/use-operators'; -import { Button } from '@/components/ui/button'; interface OperatorCardProps { operator: OperatorInfo; diff --git a/apps/ops-dashboard/components/admin/operator-filters.tsx b/apps/ops-dashboard/components/admin/operator-filters.tsx index 2f71da6..1310d71 100644 --- a/apps/ops-dashboard/components/admin/operator-filters.tsx +++ b/apps/ops-dashboard/components/admin/operator-filters.tsx @@ -1,6 +1,7 @@ 'use client'; -import { Search, Filter } from 'lucide-react'; +import { Filter,Search } from 'lucide-react'; + import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; diff --git a/apps/ops-dashboard/components/admin/operator-grid.tsx b/apps/ops-dashboard/components/admin/operator-grid.tsx index d456ef4..c1992f4 100644 --- a/apps/ops-dashboard/components/admin/operator-grid.tsx +++ b/apps/ops-dashboard/components/admin/operator-grid.tsx @@ -1,11 +1,12 @@ 'use client'; +import { ArrowRight,RefreshCw } from 'lucide-react'; import Link from 'next/link'; -import { useOperators } from '@/hooks/use-operators'; + import { OperatorCard } from '@/components/admin/operator-card'; -import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; -import { RefreshCw, ArrowRight } from 'lucide-react'; +import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; +import { useOperators } from '@/hooks/use-operators'; export function OperatorGrid() { const { data: operators, isLoading, error } = useOperators(); diff --git a/apps/ops-dashboard/components/admin/quick-actions.tsx b/apps/ops-dashboard/components/admin/quick-actions.tsx index 11a0d55..e03ed19 100644 --- a/apps/ops-dashboard/components/admin/quick-actions.tsx +++ b/apps/ops-dashboard/components/admin/quick-actions.tsx @@ -1,9 +1,10 @@ 'use client'; +import { Database, Key, Rocket } from 'lucide-react'; import Link from 'next/link'; -import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; + import { Button } from '@/components/ui/button'; -import { Plus, Database, Key, Rocket } from 'lucide-react'; +import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; export function QuickActions() { const actions = [ diff --git a/apps/ops-dashboard/components/admin/recent-activity.tsx b/apps/ops-dashboard/components/admin/recent-activity.tsx index 90fac3d..14ccc1d 100644 --- a/apps/ops-dashboard/components/admin/recent-activity.tsx +++ b/apps/ops-dashboard/components/admin/recent-activity.tsx @@ -1,8 +1,9 @@ 'use client'; +import { AlertCircle, CheckCircle, Clock, XCircle } from 'lucide-react'; + import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { formatRelativeTime } from '@/lib/utils'; -import { Clock, CheckCircle, AlertCircle, XCircle } from 'lucide-react'; // Mock data for now - in a real implementation, this would come from Kubernetes events const mockActivities = [ diff --git a/apps/ops-dashboard/components/admin/status-indicator.tsx b/apps/ops-dashboard/components/admin/status-indicator.tsx index 9741f73..46a78e7 100644 --- a/apps/ops-dashboard/components/admin/status-indicator.tsx +++ b/apps/ops-dashboard/components/admin/status-indicator.tsx @@ -1,6 +1,7 @@ +import { AlertCircle, CheckCircle, Circle,Clock, XCircle } from 'lucide-react'; import * as React from 'react'; + import { cn } from '@/lib/utils'; -import { CheckCircle, AlertCircle, Clock, XCircle, Circle } from 'lucide-react'; export interface StatusIndicatorProps { status: 'ready' | 'installed' | 'creating' | 'installing' | 'pending' | 'error' | 'not-installed' | 'unknown'; diff --git a/apps/ops-dashboard/components/admin/template-card.tsx b/apps/ops-dashboard/components/admin/template-card.tsx index dbd7820..7f8b9d0 100644 --- a/apps/ops-dashboard/components/admin/template-card.tsx +++ b/apps/ops-dashboard/components/admin/template-card.tsx @@ -1,16 +1,18 @@ -'use client' - -import { useState, useEffect } from 'react' -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card' -import { Switch } from '@/components/ui/switch' -import { Button } from '@/components/ui/button' -import { Loader2, Settings, ExternalLink, Database } from 'lucide-react' -import { cn } from '@/lib/utils' -import { StatusIndicator } from './status-indicator' -import { TemplateDialog } from '@/components/templates/template-dialog' -import { useTemplateInstalled } from '@/hooks/use-templates' -import type { Template } from '@/components/templates/templates' -import { ConfirmDialog } from '@/components/ui/confirm-dialog' +'use client'; + +import { Database, Loader2, Settings } from 'lucide-react'; +import { useEffect,useState } from 'react'; + +import { TemplateDialog } from '@/components/templates/template-dialog'; +import type { Template } from '@/components/templates/templates'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card'; +import { ConfirmDialog } from '@/components/ui/confirm-dialog'; +import { Switch } from '@/components/ui/switch'; +import { useTemplateInstalled } from '@/hooks/use-templates'; +import { cn } from '@/lib/utils'; + +import { StatusIndicator } from './status-indicator'; type TemplateStatus = 'all' | 'installed' | 'not-installed' | 'installing' | 'error' @@ -20,86 +22,86 @@ interface TemplateCardProps { } export function TemplateCard({ template, onStatusChange }: TemplateCardProps) { - const [showDialog, setShowDialog] = useState(false) - const [isToggling, setIsToggling] = useState(false) - const { isInstalled, isLoading, status, refetch, namespace } = useTemplateInstalled(template.id) - const [confirmOpen, setConfirmOpen] = useState(false) - const [confirmAction, setConfirmAction] = useState<'install' | 'uninstall' | null>(null) + const [showDialog, setShowDialog] = useState(false); + const [isToggling, setIsToggling] = useState(false); + const { isInstalled, isLoading, status, refetch, namespace } = useTemplateInstalled(template.id); + const [confirmOpen, setConfirmOpen] = useState(false); + const [confirmAction, setConfirmAction] = useState<'install' | 'uninstall' | null>(null); // Notify parent component of status changes useEffect(() => { if (onStatusChange && status) { - onStatusChange(template.id, status) + onStatusChange(template.id, status); } - }, [status, template.id]) // Remove onStatusChange from dependencies to prevent infinite loop + }, [status, template.id]); // Remove onStatusChange from dependencies to prevent infinite loop const handleToggle = async (checked: boolean) => { - console.log(`[TemplateCard] ${template.id} - Toggle clicked:`, { checked, isInstalled, isToggling }) - if (isToggling) return + console.log(`[TemplateCard] ${template.id} - Toggle clicked:`, { checked, isInstalled, isToggling }); + if (isToggling) return; // Removed pendingChecked to avoid unused variable if (checked && !isInstalled) { // Ask for confirmation before opening deployment dialog - setConfirmAction('install') - setConfirmOpen(true) + setConfirmAction('install'); + setConfirmOpen(true); } else if (!checked && isInstalled) { // Ask for confirmation before uninstalling - setConfirmAction('uninstall') - setConfirmOpen(true) + setConfirmAction('uninstall'); + setConfirmOpen(true); } - } + }; const handleConfirm = async () => { - if (!confirmAction) return + if (!confirmAction) return; try { if (confirmAction === 'install') { // Show a brief processing state and then open the setup dialog - setIsToggling(true) - setShowDialog(true) - await new Promise(resolve => setTimeout(resolve, 300)) - setIsToggling(false) + setIsToggling(true); + setShowDialog(true); + await new Promise(resolve => setTimeout(resolve, 300)); + setIsToggling(false); } else if (confirmAction === 'uninstall' && isInstalled) { - setIsToggling(true) - console.log(`[TemplateCard] ${template.id} - Starting uninstall`) - const deploymentName = `${template.id}-deployment` + setIsToggling(true); + console.log(`[TemplateCard] ${template.id} - Starting uninstall`); + const deploymentName = `${template.id}-deployment`; const response = await fetch(`/api/templates/${template.id}?namespace=${namespace}&name=${deploymentName}`, { method: 'DELETE', - }) + }); if (response.ok) { - console.log(`[TemplateCard] ${template.id} - Uninstall successful, refetching status`) - await new Promise(resolve => setTimeout(resolve, 1000)) - await refetch() + console.log(`[TemplateCard] ${template.id} - Uninstall successful, refetching status`); + await new Promise(resolve => setTimeout(resolve, 1000)); + await refetch(); } else { - console.error(`[TemplateCard] ${template.id} - Uninstall failed:`, response.status, response.statusText) - const errorData = await response.json().catch(() => ({})) - throw new Error(errorData.message || 'Failed to uninstall template') + console.error(`[TemplateCard] ${template.id} - Uninstall failed:`, response.status, response.statusText); + const errorData = await response.json().catch(() => ({})); + throw new Error(errorData.message || 'Failed to uninstall template'); } } } catch (error) { - console.error(`[TemplateCard] ${template.id} - Confirmation action failed:`, error) - await new Promise(resolve => setTimeout(resolve, 500)) + console.error(`[TemplateCard] ${template.id} - Confirmation action failed:`, error); + await new Promise(resolve => setTimeout(resolve, 500)); } finally { - setConfirmOpen(false) - setConfirmAction(null) - setIsToggling(false) + setConfirmOpen(false); + setConfirmAction(null); + setIsToggling(false); } - } + }; const getStatusText = () => { switch (status) { - case 'installed': return 'installed' - case 'installing': return 'installing' - case 'not-installed': return 'not-installed' - default: return 'error' + case 'installed': return 'installed'; + case 'installing': return 'installing'; + case 'not-installed': return 'not-installed'; + default: return 'error'; } - } + }; // Determine states similar to operator card - const isInstalling = status === 'installing' || isToggling - const hasError = false // Templates don't have error state like operators + const isInstalling = status === 'installing' || isToggling; + const hasError = false; // Templates don't have error state like operators - const Icon = template?.icon || Database + const Icon = template?.icon || Database; return ( <> @@ -166,9 +168,9 @@ export function TemplateCard({ template, onStatusChange }: TemplateCardProps) { template={template} open={showDialog} onOpenChange={(open) => { - setShowDialog(open) + setShowDialog(open); if (!open) { - refetch() + refetch(); } }} /> @@ -182,5 +184,5 @@ export function TemplateCard({ template, onStatusChange }: TemplateCardProps) { onConfirm={handleConfirm} /> - ) + ); } \ No newline at end of file diff --git a/apps/ops-dashboard/components/admin/template-filters.tsx b/apps/ops-dashboard/components/admin/template-filters.tsx index f990dc5..fd31eb0 100644 --- a/apps/ops-dashboard/components/admin/template-filters.tsx +++ b/apps/ops-dashboard/components/admin/template-filters.tsx @@ -1,8 +1,9 @@ -'use client' +'use client'; -import { Search, Filter } from 'lucide-react' -import { Input } from '@/components/ui/input' -import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select' +import { Filter,Search } from 'lucide-react'; + +import { Input } from '@/components/ui/input'; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; interface TemplateFiltersProps { searchTerm: string @@ -45,5 +46,5 @@ export function TemplateFilters({ - ) + ); } \ No newline at end of file diff --git a/apps/ops-dashboard/components/agent-manager-agentic.tsx b/apps/ops-dashboard/components/agent-manager-agentic.tsx index cd5a4e3..1fea82f 100644 --- a/apps/ops-dashboard/components/agent-manager-agentic.tsx +++ b/apps/ops-dashboard/components/agent-manager-agentic.tsx @@ -1,6 +1,22 @@ -'use client' +'use client'; -import { useState, useEffect } from 'react' +import OllamaClient from '@agentic-kit/ollama'; +import { AgentKit } from 'agentic-kit'; +import { + AlertCircle, + Brain, + CheckCircle, + Download, + FolderOpen, + Loader2, + Plus, + Server, + Sparkles, + Trash2} from 'lucide-react'; +import { useEffect,useState } from 'react'; + +import { Alert, AlertDescription } from '@/components/ui/alert'; +import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, @@ -8,35 +24,19 @@ import { DialogFooter, DialogHeader, DialogTitle, -} from '@/components/ui/dialog' -import { Button } from '@/components/ui/button' -import { Input } from '@/components/ui/input' -import { Label } from '@/components/ui/label' -import { Alert, AlertDescription } from '@/components/ui/alert' -import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs' +} from '@/components/ui/dialog'; +import { Input } from '@/components/ui/input'; +import { Label } from '@/components/ui/label'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, -} from '@/components/ui/select' -import { - Loader2, - Download, - Trash2, - CheckCircle, - AlertCircle, - Server, - Settings, - Plus, - FolderOpen, - Brain, - Sparkles -} from 'lucide-react' -import { AgentKit } from 'agentic-kit' -import OllamaClient from '@agentic-kit/ollama' -import type { AgentProvider } from './ai-chat-agentic' +} from '@/components/ui/select'; +import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; + +import type { AgentProvider } from './ai-chat-agentic'; interface AgentManagerAgenticProps { isOpen: boolean @@ -54,164 +54,164 @@ export function AgentManagerAgentic({ onProviderChange }: AgentManagerAgenticProps) { // Connection states - const [ollamaStatus, setOllamaStatus] = useState<'checking' | 'online' | 'offline'>('checking') - const [bradieStatus, setBradieStatus] = useState<'checking' | 'online' | 'offline'>('checking') + const [ollamaStatus, setOllamaStatus] = useState<'checking' | 'online' | 'offline'>('checking'); + const [bradieStatus, setBradieStatus] = useState<'checking' | 'online' | 'offline'>('checking'); // Model management - const [ollamaModels, setOllamaModels] = useState([]) - const [isLoadingModels, setIsLoadingModels] = useState(false) - const [isPulling, setIsPulling] = useState(false) - const [isDeleting, setIsDeleting] = useState(false) - const [pullModel, setPullModel] = useState('') + const [ollamaModels, setOllamaModels] = useState([]); + const [isLoadingModels, setIsLoadingModels] = useState(false); + const [isPulling, setIsPulling] = useState(false); + const [isDeleting, setIsDeleting] = useState(false); + const [pullModel, setPullModel] = useState(''); // Endpoints - const [ollamaEndpoint, setOllamaEndpoint] = useState('http://localhost:11434') - const [bradieEndpoint, setBradieEndpoint] = useState('http://localhost:3001') + const [ollamaEndpoint, setOllamaEndpoint] = useState('http://localhost:11434'); + const [bradieEndpoint, setBradieEndpoint] = useState('http://localhost:3001'); // Bradie project management - const [projectName, setProjectName] = useState('') - const [projectPath, setProjectPath] = useState('') - const [isCreatingProject, setIsCreatingProject] = useState(false) + const [projectName, setProjectName] = useState(''); + const [projectPath, setProjectPath] = useState(''); + const [isCreatingProject, setIsCreatingProject] = useState(false); // UI state - const [error, setError] = useState(null) - const [success, setSuccess] = useState(null) - const [isTestingConnection, setIsTestingConnection] = useState(false) - const [selectedModel, setSelectedModel] = useState('') - const [sessionId, setSessionId] = useState(null) - const [projectId, setProjectId] = useState(null) + const [error, setError] = useState(null); + const [success, setSuccess] = useState(null); + const [isTestingConnection, setIsTestingConnection] = useState(false); + const [selectedModel, setSelectedModel] = useState(''); + const [sessionId, setSessionId] = useState(null); + const [projectId, setProjectId] = useState(null); - const ollamaClient = new OllamaClient(ollamaEndpoint) + const ollamaClient = new OllamaClient(ollamaEndpoint); // Test connections when dialog opens useEffect(() => { if (isOpen) { - testConnections() - loadOllamaModels() + testConnections(); + loadOllamaModels(); } - }, [isOpen]) + }, [isOpen]); const testConnections = async () => { - setOllamaStatus('checking') - setBradieStatus('checking') + setOllamaStatus('checking'); + setBradieStatus('checking'); try { - await ollamaClient.listModels() - setOllamaStatus('online') + await ollamaClient.listModels(); + setOllamaStatus('online'); } catch { - setOllamaStatus('offline') + setOllamaStatus('offline'); } try { - const response = await fetch(`${bradieEndpoint}/api/health`) - setBradieStatus(response.ok ? 'online' : 'offline') + const response = await fetch(`${bradieEndpoint}/api/health`); + setBradieStatus(response.ok ? 'online' : 'offline'); } catch { - setBradieStatus('offline') + setBradieStatus('offline'); } - } + }; const loadOllamaModels = async () => { if (ollamaStatus === 'offline') { - setOllamaModels([]) - return + setOllamaModels([]); + return; } - setIsLoadingModels(true) + setIsLoadingModels(true); try { - const models = await ollamaClient.listModels() - setOllamaModels(models || []) + const models = await ollamaClient.listModels(); + setOllamaModels(models || []); } catch (err) { - console.error('Failed to load Ollama models:', err) - setOllamaModels([]) + console.error('Failed to load Ollama models:', err); + setOllamaModels([]); } finally { - setIsLoadingModels(false) + setIsLoadingModels(false); } - } + }; const handlePullModel = async () => { - if (!pullModel.trim()) return + if (!pullModel.trim()) return; - setIsPulling(true) - setError(null) - setSuccess(null) + setIsPulling(true); + setError(null); + setSuccess(null); try { - await ollamaClient.pullModel(pullModel.trim()) - setSuccess(`Successfully pulled model: ${pullModel}`) - setPullModel('') - await loadOllamaModels() + await ollamaClient.pullModel(pullModel.trim()); + setSuccess(`Successfully pulled model: ${pullModel}`); + setPullModel(''); + await loadOllamaModels(); } catch (err) { - setError(`Failed to pull model: ${err}`) + setError(`Failed to pull model: ${err}`); } finally { - setIsPulling(false) + setIsPulling(false); } - } + }; const handleDeleteModel = async (model: string) => { - if (!confirm(`Are you sure you want to delete the model "${model}"?`)) return + if (!confirm(`Are you sure you want to delete the model "${model}"?`)) return; - setIsDeleting(true) - setError(null) - setSuccess(null) + setIsDeleting(true); + setError(null); + setSuccess(null); try { - await ollamaClient.deleteModel(model) - setSuccess(`Successfully deleted model: ${model}`) - await loadOllamaModels() + await ollamaClient.deleteModel(model); + setSuccess(`Successfully deleted model: ${model}`); + await loadOllamaModels(); } catch (err) { - setError(`Failed to delete model: ${err}`) + setError(`Failed to delete model: ${err}`); } finally { - setIsDeleting(false) + setIsDeleting(false); } - } + }; const handleTestConnection = async (provider: AgentProvider, endpoint: string) => { - setIsTestingConnection(true) + setIsTestingConnection(true); try { - let isOnline = false + let isOnline = false; if (provider === 'ollama') { - const testClient = new OllamaClient(endpoint) - await testClient.listModels() - isOnline = true - setOllamaStatus('online') + const testClient = new OllamaClient(endpoint); + await testClient.listModels(); + isOnline = true; + setOllamaStatus('online'); } else { - const response = await fetch(`${endpoint}/api/health`) - isOnline = response.ok - setBradieStatus(isOnline ? 'online' : 'offline') + const response = await fetch(`${endpoint}/api/health`); + isOnline = response.ok; + setBradieStatus(isOnline ? 'online' : 'offline'); } - setSuccess(`${provider} connection ${isOnline ? 'successful' : 'failed'}`) + setSuccess(`${provider} connection ${isOnline ? 'successful' : 'failed'}`); } catch (err) { if (provider === 'ollama') { - setOllamaStatus('offline') + setOllamaStatus('offline'); } else { - setBradieStatus('offline') + setBradieStatus('offline'); } - setError(`Failed to test ${provider} connection: ${err}`) + setError(`Failed to test ${provider} connection: ${err}`); } finally { - setIsTestingConnection(false) + setIsTestingConnection(false); } - } + }; const handleCreateBradieProject = async () => { if (!projectName.trim() || !projectPath.trim()) { - setError('Please fill in all fields') - return + setError('Please fill in all fields'); + return; } - setIsCreatingProject(true) - setError(null) + setIsCreatingProject(true); + setError(null); try { // This would need Bradie client implementation - setSuccess(`Project creation not yet implemented`) - setProjectName('') - setProjectPath('') + setSuccess(`Project creation not yet implemented`); + setProjectName(''); + setProjectPath(''); } catch (err) { - setError(`Failed to create project: ${err}`) + setError(`Failed to create project: ${err}`); } finally { - setIsCreatingProject(false) + setIsCreatingProject(false); } - } + }; return ( !open && onClose()}> @@ -278,8 +278,8 @@ export function AgentManagerAgentic({
{ollamaStatus === 'checking' ? ( @@ -317,8 +317,8 @@ export function AgentManagerAgentic({
{bradieStatus === 'checking' ? ( @@ -447,7 +447,7 @@ export function AgentManagerAgentic({ disabled={isPulling || ollamaStatus !== 'online'} onKeyDown={(e) => { if (e.key === 'Enter' && !isPulling) { - handlePullModel() + handlePullModel(); } }} /> @@ -562,5 +562,5 @@ export function AgentManagerAgentic({
- ) + ); } \ No newline at end of file diff --git a/apps/ops-dashboard/components/agent-manager-global.tsx b/apps/ops-dashboard/components/agent-manager-global.tsx index 1223793..8f3bc38 100644 --- a/apps/ops-dashboard/components/agent-manager-global.tsx +++ b/apps/ops-dashboard/components/agent-manager-global.tsx @@ -1,6 +1,20 @@ -'use client' +'use client'; -import { useState, useEffect } from 'react' +import { + AlertCircle, + Brain, + CheckCircle, + FolderOpen, + Globe, + Loader2, + Plus, + Server, + Sparkles, + Trash2} from 'lucide-react'; +import { useEffect,useState } from 'react'; + +import { Alert, AlertDescription } from '@/components/ui/alert'; +import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, @@ -8,33 +22,20 @@ import { DialogFooter, DialogHeader, DialogTitle, -} from '@/components/ui/dialog' -import { Button } from '@/components/ui/button' -import { Input } from '@/components/ui/input' -import { Label } from '@/components/ui/label' -import { Alert, AlertDescription } from '@/components/ui/alert' -import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs' +} from '@/components/ui/dialog'; +import { Input } from '@/components/ui/input'; +import { Label } from '@/components/ui/label'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, -} from '@/components/ui/select' -import { - Loader2, - CheckCircle, - AlertCircle, - Server, - Brain, - Sparkles, - Plus, - Trash2, - FolderOpen, - Globe -} from 'lucide-react' -import { OllamaClient, BradieClient, type Session } from '@/lib/agents' -import type { GlobalAgentConfig } from './ai-chat-global' +} from '@/components/ui/select'; +import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; +import { BradieClient, OllamaClient, type Session } from '@/lib/agents'; + +import type { GlobalAgentConfig } from './ai-chat-global'; interface AgentManagerGlobalProps { isOpen: boolean @@ -45,102 +46,102 @@ interface AgentManagerGlobalProps { export function AgentManagerGlobal({ isOpen, onClose, currentConfig, onConfigChange }: AgentManagerGlobalProps) { // Session Management State - const [sessions, setSessions] = useState([]) - const [showCreateSession, setShowCreateSession] = useState(false) - const [projectName, setProjectName] = useState('') - const [projectPath, setProjectPath] = useState('') + const [sessions, setSessions] = useState([]); + const [showCreateSession, setShowCreateSession] = useState(false); + const [projectName, setProjectName] = useState(''); + const [projectPath, setProjectPath] = useState(''); // Model Management State - const [ollamaModels, setOllamaModels] = useState(['llama2', 'mistral', 'mixtral']) - const [isLoadingModels, setIsLoadingModels] = useState(false) + const [ollamaModels, setOllamaModels] = useState(['llama2', 'mistral', 'mixtral']); + const [isLoadingModels, setIsLoadingModels] = useState(false); // Endpoint State - const [bradieDomain, setBradieDomain] = useState(currentConfig.bradieDomain || 'http://localhost:3001') - const [ollamaEndpoint, setOllamaEndpoint] = useState(currentConfig.endpoint || 'http://localhost:11434') - const [isTestingConnection, setIsTestingConnection] = useState(false) + const [bradieDomain, setBradieDomain] = useState(currentConfig.bradieDomain || 'http://localhost:3001'); + const [ollamaEndpoint, setOllamaEndpoint] = useState(currentConfig.endpoint || 'http://localhost:11434'); + const [isTestingConnection, setIsTestingConnection] = useState(false); // General State - const [error, setError] = useState(null) - const [success, setSuccess] = useState(null) - const [connectionStatus, setConnectionStatus] = useState>({}) + const [error, setError] = useState(null); + const [success, setSuccess] = useState(null); + const [connectionStatus, setConnectionStatus] = useState>({}); // Load sessions from localStorage useEffect(() => { - const savedSessions = localStorage.getItem('ai-chat-bradie-sessions') + const savedSessions = localStorage.getItem('ai-chat-bradie-sessions'); if (savedSessions) { try { - const parsed = JSON.parse(savedSessions) + const parsed = JSON.parse(savedSessions); setSessions(parsed.map((s: any) => ({ ...s, createdAt: new Date(s.createdAt) - }))) + }))); } catch (err) { - console.error('Failed to load sessions:', err) + console.error('Failed to load sessions:', err); } } - }, []) + }, []); // Save sessions to localStorage const saveSessions = (newSessions: Session[]) => { - setSessions(newSessions) - localStorage.setItem('ai-chat-bradie-sessions', JSON.stringify(newSessions)) - } + setSessions(newSessions); + localStorage.setItem('ai-chat-bradie-sessions', JSON.stringify(newSessions)); + }; // Test Ollama connection and load models const testOllamaConnection = async () => { - setIsTestingConnection(true) - setError(null) + setIsTestingConnection(true); + setError(null); try { - const client = new OllamaClient(ollamaEndpoint) - const models = await client.listModels() - setOllamaModels(models) - setConnectionStatus(prev => ({ ...prev, ollama: true })) - setSuccess('Successfully connected to Ollama') + const client = new OllamaClient(ollamaEndpoint); + const models = await client.listModels(); + setOllamaModels(models); + setConnectionStatus(prev => ({ ...prev, ollama: true })); + setSuccess('Successfully connected to Ollama'); } catch (err) { - console.error('Ollama connection error:', err) - setConnectionStatus(prev => ({ ...prev, ollama: false })) - setError('Failed to connect to Ollama. Please ensure Ollama is running.') + console.error('Ollama connection error:', err); + setConnectionStatus(prev => ({ ...prev, ollama: false })); + setError('Failed to connect to Ollama. Please ensure Ollama is running.'); } finally { - setIsTestingConnection(false) + setIsTestingConnection(false); } - } + }; // Test Bradie connection const testBradieConnection = async () => { - setIsTestingConnection(true) - setError(null) + setIsTestingConnection(true); + setError(null); try { - const client = new BradieClient(bradieDomain) - const isHealthy = await client.checkHealth() - setConnectionStatus(prev => ({ ...prev, bradie: isHealthy })) + const client = new BradieClient(bradieDomain); + const isHealthy = await client.checkHealth(); + setConnectionStatus(prev => ({ ...prev, bradie: isHealthy })); if (isHealthy) { - setSuccess('Successfully connected to Bradie') + setSuccess('Successfully connected to Bradie'); } else { - setError('Bradie backend is not responding') + setError('Bradie backend is not responding'); } } catch (err) { - console.error('Bradie connection error:', err) - setConnectionStatus(prev => ({ ...prev, bradie: false })) - setError('Failed to connect to Bradie backend') + console.error('Bradie connection error:', err); + setConnectionStatus(prev => ({ ...prev, bradie: false })); + setError('Failed to connect to Bradie backend'); } finally { - setIsTestingConnection(false) + setIsTestingConnection(false); } - } + }; // Create new Bradie session const createSession = async () => { if (!projectName || !projectPath) { - setError('Please provide both project name and path') - return + setError('Please provide both project name and path'); + return; } try { - const client = new BradieClient(bradieDomain) - const session = await client.createSession(projectName, projectPath) - const newSessions = [...sessions, session] - saveSessions(newSessions) + const client = new BradieClient(bradieDomain); + const session = await client.createSession(projectName, projectPath); + const newSessions = [...sessions, session]; + saveSessions(newSessions); // Update config with new session onConfigChange({ @@ -148,31 +149,31 @@ export function AgentManagerGlobal({ isOpen, onClose, currentConfig, onConfigCha agent: 'bradie', bradieDomain, session - }) + }); - setShowCreateSession(false) - setProjectName('') - setProjectPath('') - setSuccess('Session created successfully') + setShowCreateSession(false); + setProjectName(''); + setProjectPath(''); + setSuccess('Session created successfully'); } catch (err) { - console.error('Failed to create session:', err) - setError('Failed to create session') + console.error('Failed to create session:', err); + setError('Failed to create session'); } - } + }; // Delete session const deleteSession = (sessionId: string) => { - const newSessions = sessions.filter(s => s.id !== sessionId) - saveSessions(newSessions) + const newSessions = sessions.filter(s => s.id !== sessionId); + saveSessions(newSessions); // If deleted session was active, clear it if (currentConfig.session?.id === sessionId) { onConfigChange({ ...currentConfig, session: null - }) + }); } - } + }; // Apply configuration const applyConfig = () => { @@ -182,11 +183,11 @@ export function AgentManagerGlobal({ isOpen, onClose, currentConfig, onConfigCha model: currentConfig.model, bradieDomain: bradieDomain, session: currentConfig.session - } + }; - onConfigChange(newConfig) - onClose() - } + onConfigChange(newConfig); + onClose(); + }; return ( @@ -345,8 +346,8 @@ export function AgentManagerGlobal({ isOpen, onClose, currentConfig, onConfigCha variant="ghost" size="icon" onClick={(e) => { - e.stopPropagation() - deleteSession(session.id) + e.stopPropagation(); + deleteSession(session.id); }} > @@ -387,9 +388,9 @@ export function AgentManagerGlobal({ isOpen, onClose, currentConfig, onConfigCha variant="outline" size="sm" onClick={() => { - setShowCreateSession(false) - setProjectName('') - setProjectPath('') + setShowCreateSession(false); + setProjectName(''); + setProjectPath(''); }} > Cancel @@ -424,5 +425,5 @@ export function AgentManagerGlobal({ isOpen, onClose, currentConfig, onConfigCha - ) + ); } diff --git a/apps/ops-dashboard/components/ai-chat-agentic.tsx b/apps/ops-dashboard/components/ai-chat-agentic.tsx index 43a6ff7..7d8e77b 100644 --- a/apps/ops-dashboard/components/ai-chat-agentic.tsx +++ b/apps/ops-dashboard/components/ai-chat-agentic.tsx @@ -1,19 +1,19 @@ -'use client' - -import React, { useState, useRef, useEffect, KeyboardEvent } from 'react' -import ReactMarkdown from 'react-markdown' -import remarkGfm from 'remark-gfm' -import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter' -import { vscDarkPlus } from 'react-syntax-highlighter/dist/esm/styles/prism' -import { Button } from '@/components/ui/button' -import { Textarea } from '@/components/ui/textarea' -import { AgentManagerAgentic } from './agent-manager-agentic' +'use client'; + import { - AgentKit, - OllamaAdapter, BradieAdapter, - createMultiProviderKit -} from 'agentic-kit' + createMultiProviderKit, + OllamaAdapter} from 'agentic-kit'; +import React, { KeyboardEvent,useEffect, useRef, useState } from 'react'; +import ReactMarkdown from 'react-markdown'; +import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; +import { vscDarkPlus } from 'react-syntax-highlighter/dist/esm/styles/prism'; +import remarkGfm from 'remark-gfm'; + +import { Button } from '@/components/ui/button'; +import { Textarea } from '@/components/ui/textarea'; + +import { AgentManagerAgentic } from './agent-manager-agentic'; export type AgentProvider = 'ollama' | 'bradie' @@ -25,31 +25,30 @@ export interface ChatMessage { provider?: AgentProvider } import { - MoreVertical, - Send, - User, + AlertCircle, Bot, - Copy, + Brain, Check, ChevronRight, + Copy, + Loader2, MessageSquare, - Trash2, - Plus, + MoreVertical, Pin, PinOff, - Loader2, - AlertCircle, + Send, Settings2, - Brain, - Sparkles -} from 'lucide-react' + Sparkles, + Trash2, + User} from 'lucide-react'; + import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, - DropdownMenuTrigger, DropdownMenuSeparator, -} from '@/components/ui/dropdown-menu' + DropdownMenuTrigger, +} from '@/components/ui/dropdown-menu'; interface AIChatAgenticProps { isOpen: boolean @@ -68,70 +67,70 @@ export function AIChatAgentic({ layoutMode, onLayoutModeChange }: AIChatAgenticProps) { - const [messages, setMessages] = useState([]) - const [input, setInput] = useState('') - const [showTimestamps, setShowTimestamps] = useState(false) - const [copiedCode, setCopiedCode] = useState(null) - const [isResizing, setIsResizing] = useState(false) - const [isLoading, setIsLoading] = useState(false) - const [error, setError] = useState(null) - const [showAgentManager, setShowAgentManager] = useState(false) - const [streamingMessage, setStreamingMessage] = useState('') + const [messages, setMessages] = useState([]); + const [input, setInput] = useState(''); + const [showTimestamps, setShowTimestamps] = useState(false); + const [copiedCode, setCopiedCode] = useState(null); + const [isResizing, setIsResizing] = useState(false); + const [isLoading, setIsLoading] = useState(false); + const [error, setError] = useState(null); + const [showAgentManager, setShowAgentManager] = useState(false); + const [streamingMessage, setStreamingMessage] = useState(''); // Agent state - const [currentProvider, setCurrentProvider] = useState('ollama') + const [currentProvider, setCurrentProvider] = useState('ollama'); const [agentKit] = useState(() => { - const kit = createMultiProviderKit() - kit.addProvider(new OllamaAdapter('http://localhost:11434')) + const kit = createMultiProviderKit(); + kit.addProvider(new OllamaAdapter('http://localhost:11434')); kit.addProvider(new BradieAdapter({ domain: 'http://localhost:3001', onSystemMessage: () => {}, onAssistantReply: () => {} - })) - kit.setProvider('ollama') - return kit - }) + })); + kit.setProvider('ollama'); + return kit; + }); - const resizeRef = useRef(null) - const chatEndRef = useRef(null) + const resizeRef = useRef(null); + const chatEndRef = useRef(null); // Auto scroll to bottom on new messages useEffect(() => { - chatEndRef.current?.scrollIntoView({ behavior: 'smooth' }) - }, [messages, streamingMessage]) + chatEndRef.current?.scrollIntoView({ behavior: 'smooth' }); + }, [messages, streamingMessage]); // Load chat history from localStorage (use same key as global chat) useEffect(() => { - const savedMessages = localStorage.getItem('ai-chat-messages') + const savedMessages = localStorage.getItem('ai-chat-messages'); if (savedMessages) { try { - const parsed = JSON.parse(savedMessages) + const parsed = JSON.parse(savedMessages); setMessages(parsed.map((m: any) => ({ ...m, timestamp: new Date(m.timestamp) - }))) + }))); } catch (err) { - console.error('Failed to load chat history:', err) + console.error('Failed to load chat history:', err); } } - }, []) + }, []); // Save messages to localStorage (use same key as global chat) useEffect(() => { if (messages.length > 0) { - localStorage.setItem('ai-chat-messages', JSON.stringify(messages)) + localStorage.setItem('ai-chat-messages', JSON.stringify(messages)); } - }, [messages]) + }, [messages]); // Handle provider change const handleProviderChange = (provider: AgentProvider) => { - setCurrentProvider(provider) - agentKit.setProvider(provider) - } + setCurrentProvider(provider); + agentKit.setProvider(provider); + }; // Handle send message const handleSend = async () => { - if (!input.trim() || isLoading) return + if (!input.trim() || isLoading) return; const userMessage: ChatMessage = { id: Date.now().toString(), @@ -139,22 +138,22 @@ export function AIChatAgentic({ content: input.trim(), timestamp: new Date(), provider: currentProvider - } + }; - setMessages(prev => [...prev, userMessage]) - setInput('') - setIsLoading(true) - setError(null) - setStreamingMessage('') + setMessages(prev => [...prev, userMessage]); + setInput(''); + setIsLoading(true); + setError(null); + setStreamingMessage(''); try { - let fullResponse = '' + let fullResponse = ''; // Handle streaming const onChunk = (chunk: string) => { - fullResponse += chunk - setStreamingMessage(fullResponse) - } + fullResponse += chunk; + setStreamingMessage(fullResponse); + }; // Generate response await agentKit.generate( @@ -232,7 +231,7 @@ export default class HelloWorldContract { { onChunk } - ) + ); // After streaming completes, create the final message if (fullResponse.trim()) { @@ -242,74 +241,74 @@ export default class HelloWorldContract { content: fullResponse, timestamp: new Date(), provider: currentProvider - } - setMessages(prev => [...prev, assistantMessage]) + }; + setMessages(prev => [...prev, assistantMessage]); } // Clear streaming message - setStreamingMessage('') + setStreamingMessage(''); } catch (err) { - console.error('Error generating response:', err) - setError('An error occurred. Please try again.') - setStreamingMessage('') + console.error('Error generating response:', err); + setError('An error occurred. Please try again.'); + setStreamingMessage(''); } finally { - setIsLoading(false) + setIsLoading(false); } - } + }; const handleKeyDown = (e: KeyboardEvent) => { if (e.key === 'Enter' && !e.shiftKey) { - e.preventDefault() + e.preventDefault(); if (!isLoading) { - handleSend() + handleSend(); } } - } + }; const copyToClipboard = async (text: string) => { try { - await navigator.clipboard.writeText(text) - setCopiedCode(text) - setTimeout(() => setCopiedCode(null), 2000) + await navigator.clipboard.writeText(text); + setCopiedCode(text); + setTimeout(() => setCopiedCode(null), 2000); } catch (err) { - console.error('Failed to copy:', err) + console.error('Failed to copy:', err); } - } + }; const clearHistory = () => { - setMessages([]) - localStorage.removeItem('ai-chat-messages') - } + setMessages([]); + localStorage.removeItem('ai-chat-messages'); + }; // Handle resize useEffect(() => { const handleMouseMove = (e: MouseEvent) => { - if (!isResizing) return - const newWidth = window.innerWidth - e.clientX - onWidthChange(Math.max(300, Math.min(800, newWidth))) - } + if (!isResizing) return; + const newWidth = window.innerWidth - e.clientX; + onWidthChange(Math.max(300, Math.min(800, newWidth))); + }; const handleMouseUp = () => { - setIsResizing(false) - } + setIsResizing(false); + }; if (isResizing) { - document.addEventListener('mousemove', handleMouseMove) - document.addEventListener('mouseup', handleMouseUp) + document.addEventListener('mousemove', handleMouseMove); + document.addEventListener('mouseup', handleMouseUp); } return () => { - document.removeEventListener('mousemove', handleMouseMove) - document.removeEventListener('mouseup', handleMouseUp) - } - }, [isResizing, onWidthChange]) + document.removeEventListener('mousemove', handleMouseMove); + document.removeEventListener('mouseup', handleMouseUp); + }; + }, [isResizing, onWidthChange]); - if (!isOpen) return null + if (!isOpen) return null; const containerStyle = layoutMode === 'floating' ? 'fixed right-4 top-4 bottom-4 shadow-2xl rounded-lg border' - : 'fixed right-0 top-0 bottom-0 border-l' + : 'fixed right-0 top-0 bottom-0 border-l'; return ( <> @@ -397,13 +396,13 @@ export default class HelloWorldContract { remarkPlugins={[remarkGfm]} components={{ code({ node, inline, className, children, ...props }: any) { - const match = /language-(\w+)/.exec(className || '') + const match = /language-(\w+)/.exec(className || ''); return !inline && match ? (
{React.createElement(SyntaxHighlighter as any, { style: vscDarkPlus, language: match[1], - PreTag: "div", + PreTag: 'div', ...props }, String(children).replace(/\n$/, ''))}
- ) + ); } // Regular versions const containerClasses = variant === 'sidebar' - ? "px-4 pb-4 border-b" - : "" + ? 'px-4 pb-4 border-b' + : ''; const triggerClasses = variant === 'sidebar' - ? "w-full" - : "w-[180px]" + ? 'w-full' + : 'w-[180px]'; return (
@@ -110,7 +110,7 @@ export function ContextSwitcher({ variant = 'sidebar' }: ContextSwitcherProps) { {Object.entries(modeConfig).map(([key, config]) => { - const Icon = config.icon + const Icon = config.icon; return (
@@ -118,10 +118,10 @@ export function ContextSwitcher({ variant = 'sidebar' }: ContextSwitcherProps) { {config.label}
- ) + ); })}
- ) + ); } diff --git a/apps/ops-dashboard/components/create-backup-dialog.tsx b/apps/ops-dashboard/components/create-backup-dialog.tsx index 0f72411..fce943e 100644 --- a/apps/ops-dashboard/components/create-backup-dialog.tsx +++ b/apps/ops-dashboard/components/create-backup-dialog.tsx @@ -1,11 +1,11 @@ -import { AlertCircle, Brain, Sparkles } from "lucide-react"; -import { Alert, AlertDescription } from "@/components/ui/alert"; -import { Button } from "@/components/ui/button"; -import { DialogHeader, DialogFooter, Dialog, DialogContent, DialogTitle } from "@/components/ui/dialog"; -import { useState } from "react"; -import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; -import { AgentProvider } from "agentic-kit"; +import { AlertCircle } from 'lucide-react'; +import { useState } from 'react'; + +import { Alert, AlertDescription } from '@/components/ui/alert'; +import { Button } from '@/components/ui/button'; +import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog'; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; interface CreateBackupDialogProps { backups: any @@ -16,28 +16,28 @@ interface CreateBackupDialogProps { } export function CreateBackupDialog({backups, open, onOpenChange, onSubmit ,databaseStatus}: CreateBackupDialogProps) { - const [error, setError] = useState(null) - const [isSubmitting, setIsSubmitting] = useState(false) + const [error, setError] = useState(null); + const [isSubmitting, setIsSubmitting] = useState(false); const [methodChoice, setMethodChoice] = useState<'auto'|'barmanObjectStore'|'volumeSnapshot'>('auto'); const handleCancel = () => { - setError(null) - onOpenChange(false) - } + setError(null); + onOpenChange(false); + }; const handleSubmit = async (methodParam?: string) => { - setError(null) - setIsSubmitting(true) + setError(null); + setIsSubmitting(true); try { - await onSubmit(methodParam) + await onSubmit(methodParam); // Only close dialog on successful submission - onOpenChange(false) + onOpenChange(false); } catch (error) { - setError(error instanceof Error ? error.message : 'Failed to create backup') + setError(error instanceof Error ? error.message : 'Failed to create backup'); // Don't close dialog on error - let user see the error message } finally { - setIsSubmitting(false) + setIsSubmitting(false); } - } + }; return ( @@ -91,31 +91,31 @@ export function CreateBackupDialog({backups, open, onOpenChange, onSubmit ,datab Cancel + } + onClick={() => { + const methodParam = methodChoice === 'auto' ? undefined : methodChoice; + handleSubmit(methodParam); + }} + title={(() => { + if (!backups.isFetched) return 'Create on-demand backup'; + if (methodChoice === 'auto' && !(backups.data?.configured || backups.data?.snapshotSupported)) return 'Configure backups (barman) or install VolumeSnapshot CRDs'; + if (methodChoice === 'barmanObjectStore' && backups.data?.methodConfigured !== 'barmanObjectStore') return 'Cluster is not configured for barman backups'; + if (methodChoice === 'volumeSnapshot' && !backups.data?.snapshotSupported) return 'VolumeSnapshot CRDs/CSI not available'; + return 'Create on-demand backup'; + })()} + > + {isSubmitting ? 'Creating…' : 'Create Backup'} + - ) + ); } \ No newline at end of file diff --git a/apps/ops-dashboard/components/create-databases-dialog.tsx b/apps/ops-dashboard/components/create-databases-dialog.tsx index 69f8830..e8dc2f4 100644 --- a/apps/ops-dashboard/components/create-databases-dialog.tsx +++ b/apps/ops-dashboard/components/create-databases-dialog.tsx @@ -1,13 +1,14 @@ -'use client' +'use client'; -import React, { useState } from 'react' -import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from '@/components/ui/dialog' -import { Button } from '@/components/ui/button' -import { Input } from '@/components/ui/input' -import { Label } from '@/components/ui/label' -import { Checkbox } from '@/components/ui/checkbox' -import { AlertCircle } from 'lucide-react' -import { Alert, AlertDescription } from '@/components/ui/alert' +import { AlertCircle } from 'lucide-react'; +import React, { useState } from 'react'; + +import { Alert, AlertDescription } from '@/components/ui/alert'; +import { Button } from '@/components/ui/button'; +import { Checkbox } from '@/components/ui/checkbox'; +import { Dialog, DialogContent, DialogFooter,DialogHeader, DialogTitle } from '@/components/ui/dialog'; +import { Input } from '@/components/ui/input'; +import { Label } from '@/components/ui/label'; interface CreateDatabasesDialogProps { open: boolean @@ -28,8 +29,8 @@ interface CreateDatabasesDialogProps { export function CreateDatabasesDialog({ open, onOpenChange, onSubmit }: CreateDatabasesDialogProps) { - const [isSubmitting, setIsSubmitting] = useState(false) - const [error, setError] = useState(null) + const [isSubmitting, setIsSubmitting] = useState(false); + const [error, setError] = useState(null); // Create DB form state (required fields) @@ -45,22 +46,22 @@ export function CreateDatabasesDialog({ open, onOpenChange, onSubmit }: CreateDa const handleSubmit = async () => { - setError(null) - setIsSubmitting(true) + setError(null); + setIsSubmitting(true); try { // Basic validation if (!appUsername.trim()) { - setError('App username is required') - return + setError('App username is required'); + return; } if (!appPassword.trim()) { - setError('App password is required') - return + setError('App password is required'); + return; } if (!superuserPassword.trim()) { - setError('Superuser password is required') - return + setError('Superuser password is required'); + return; } await onSubmit({ @@ -73,29 +74,29 @@ export function CreateDatabasesDialog({ open, onOpenChange, onSubmit }: CreateDa enablePooler, poolerName, poolerInstances, - }) - onOpenChange(false) + }); + onOpenChange(false); } catch (err) { - setError(err instanceof Error ? err.message : 'Failed to create database') + setError(err instanceof Error ? err.message : 'Failed to create database'); } finally { - setIsSubmitting(false) + setIsSubmitting(false); } - } + }; const handleCancel = () => { - setError(null) - onOpenChange(false) + setError(null); + onOpenChange(false); // Reset form to defaults - setInstances(1) - setStorage('1Gi') - setStorageClass('') - setAppUsername('appuser') - setAppPassword('appuser123!') - setSuperuserPassword('postgres123!') - setEnablePooler(true) - setPoolerName('postgres-pooler') - setPoolerInstances(1) - } + setInstances(1); + setStorage('1Gi'); + setStorageClass(''); + setAppUsername('appuser'); + setAppPassword('appuser123!'); + setSuperuserPassword('postgres123!'); + setEnablePooler(true); + setPoolerName('postgres-pooler'); + setPoolerInstances(1); + }; return ( @@ -226,5 +227,5 @@ export function CreateDatabasesDialog({ open, onOpenChange, onSubmit }: CreateDa - ) + ); } diff --git a/apps/ops-dashboard/components/create-deployment-dialog.tsx b/apps/ops-dashboard/components/create-deployment-dialog.tsx index da5eeb7..937b8db 100644 --- a/apps/ops-dashboard/components/create-deployment-dialog.tsx +++ b/apps/ops-dashboard/components/create-deployment-dialog.tsx @@ -1,11 +1,12 @@ -'use client' +'use client'; -import React, { useState } from 'react' -import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogFooter } from '@/components/ui/dialog' -import { Button } from '@/components/ui/button' -import { YAMLEditor } from '@/components/yaml-editor' -import { AlertCircle } from 'lucide-react' -import { Alert, AlertDescription } from '@/components/ui/alert' +import { AlertCircle } from 'lucide-react'; +import React, { useState } from 'react'; + +import { Alert, AlertDescription } from '@/components/ui/alert'; +import { Button } from '@/components/ui/button'; +import { Dialog, DialogContent, DialogDescription, DialogFooter,DialogHeader, DialogTitle } from '@/components/ui/dialog'; +import { YAMLEditor } from '@/components/yaml-editor'; interface CreateDeploymentDialogProps { open: boolean @@ -40,40 +41,40 @@ spec: memory: "128Mi" requests: cpu: "50m" - memory: "64Mi"` + memory: "64Mi"`; export function CreateDeploymentDialog({ open, onOpenChange, onSubmit }: CreateDeploymentDialogProps) { - const [yaml, setYaml] = useState(DEFAULT_DEPLOYMENT_TEMPLATE) - const [isSubmitting, setIsSubmitting] = useState(false) - const [error, setError] = useState(null) + const [yaml, setYaml] = useState(DEFAULT_DEPLOYMENT_TEMPLATE); + const [isSubmitting, setIsSubmitting] = useState(false); + const [error, setError] = useState(null); const handleSubmit = async () => { - setError(null) - setIsSubmitting(true) + setError(null); + setIsSubmitting(true); try { // Basic YAML validation if (!yaml.trim()) { - throw new Error('YAML content cannot be empty') + throw new Error('YAML content cannot be empty'); } - await onSubmit(yaml) - onOpenChange(false) + await onSubmit(yaml); + onOpenChange(false); // Reset to template for next time - setYaml(DEFAULT_DEPLOYMENT_TEMPLATE) + setYaml(DEFAULT_DEPLOYMENT_TEMPLATE); } catch (err) { - setError(err instanceof Error ? err.message : 'Failed to create deployment') + setError(err instanceof Error ? err.message : 'Failed to create deployment'); } finally { - setIsSubmitting(false) + setIsSubmitting(false); } - } + }; const handleCancel = () => { - setError(null) - onOpenChange(false) + setError(null); + onOpenChange(false); // Reset to template - setYaml(DEFAULT_DEPLOYMENT_TEMPLATE) - } + setYaml(DEFAULT_DEPLOYMENT_TEMPLATE); + }; return ( @@ -110,5 +111,5 @@ export function CreateDeploymentDialog({ open, onOpenChange, onSubmit }: CreateD - ) + ); } diff --git a/apps/ops-dashboard/components/dashboard-layout.tsx b/apps/ops-dashboard/components/dashboard-layout.tsx index 42b78d0..b04d092 100644 --- a/apps/ops-dashboard/components/dashboard-layout.tsx +++ b/apps/ops-dashboard/components/dashboard-layout.tsx @@ -1,61 +1,52 @@ 'use client'; -import { useState, useCallback, useEffect } from 'react'; -import NextLink from 'next/link'; -import { usePathname } from 'next/navigation'; -import { Button } from '@/components/ui/button'; -import { NamespaceSwitcher } from '@/components/namespace-switcher'; -import { ContextSwitcher } from '@/components/context-switcher'; -import { ThemeToggle } from '@/components/ui/theme-toggle'; -import { InfraHeader } from '@/components/headers/infra-header'; -import { SmartObjectsHeader } from '@/components/headers/smart-objects-header'; -import { useKubernetes } from '../k8s/context'; import { - Package, - Server, - Shield, - Settings, - Key, - Copy, Activity, - Home, - Menu, - PanelLeftClose, - FileCode2, - Layers, + BarChart, + Bot, + Boxes, Calendar, + ChevronDown, + ChevronLeft, + ChevronRight, Clock, - Gauge, - ShieldCheck, - Star, + Copy, Cpu, + Database, + FileCode2, + Gauge, Globe, - Network, - Link, + Grid3x3, HardDrive, - Database, + Heart, + Home, + Key, + Layers, + LayoutDashboard, + Link, + LucideIcon, + Network, + Package, Paperclip, - Bot, + Server, + Settings, + Shield, + ShieldCheck, + Star, UserCheck, Users, Zap, - BarChart, - Grid3x3, - ChevronDown, - ChevronRight, - ChevronLeft, - Heart, - Code, - MessageSquare, - CloudIcon, - FunctionSquare, - Play, - Code2, - Boxes, - LayoutDashboard, - Rocket, - LucideIcon, } from 'lucide-react'; +import NextLink from 'next/link'; +import { usePathname } from 'next/navigation'; +import { useCallback, useEffect,useState } from 'react'; + +import { ContextSwitcher } from '@/components/context-switcher'; +import { InfraHeader } from '@/components/headers/infra-header'; +import { SmartObjectsHeader } from '@/components/headers/smart-objects-header'; +import { Button } from '@/components/ui/button'; + +import { useKubernetes } from '../k8s/context'; import { AdminHeader } from './headers/admin-header'; interface DashboardLayoutHeaderProps { @@ -69,15 +60,15 @@ interface DashboardLayoutHeaderProps { export function DashboardLayoutHeader(props: DashboardLayoutHeaderProps) { - const { mode,...restProps } = props + const { mode,...restProps } = props; if(mode === 'smart-objects') { - return + return ; } if(mode === 'infra') { - return + return ; } - return + return ; } @@ -232,8 +223,8 @@ export function DashboardLayout({ if(mode === 'infra') { return infraNavigation; } - return [] - } + return []; + }; // Choose navigation based on context const navigationItems = getNavigationItems(); diff --git a/apps/ops-dashboard/components/headers/admin-header.tsx b/apps/ops-dashboard/components/headers/admin-header.tsx index d4d7b10..f3ae97e 100644 --- a/apps/ops-dashboard/components/headers/admin-header.tsx +++ b/apps/ops-dashboard/components/headers/admin-header.tsx @@ -1,8 +1,9 @@ -'use client' +'use client'; -import { Button } from '@/components/ui/button' -import { ThemeToggle } from '@/components/ui/theme-toggle' -import { Menu, PanelLeftClose, MessageSquare } from 'lucide-react' +import { Menu, MessageSquare,PanelLeftClose } from 'lucide-react'; + +import { Button } from '@/components/ui/button'; +import { ThemeToggle } from '@/components/ui/theme-toggle'; interface AdminHeaderProps { sidebarOpen: boolean @@ -47,5 +48,5 @@ export function AdminHeader({ - ) + ); } \ No newline at end of file diff --git a/apps/ops-dashboard/components/headers/infra-header.tsx b/apps/ops-dashboard/components/headers/infra-header.tsx index 3d6c2cf..de08540 100644 --- a/apps/ops-dashboard/components/headers/infra-header.tsx +++ b/apps/ops-dashboard/components/headers/infra-header.tsx @@ -1,10 +1,11 @@ -'use client' +'use client'; -import { Button } from '@/components/ui/button' -import { NamespaceSwitcher } from '@/components/namespace-switcher' -import { ThemeToggle } from '@/components/ui/theme-toggle' -import { useKubernetes } from '@/k8s/context' -import { Menu, PanelLeftClose, MessageSquare } from 'lucide-react' +import { Menu, MessageSquare,PanelLeftClose } from 'lucide-react'; + +import { NamespaceSwitcher } from '@/components/namespace-switcher'; +import { Button } from '@/components/ui/button'; +import { ThemeToggle } from '@/components/ui/theme-toggle'; +import { useKubernetes } from '@/k8s/context'; interface InfraHeaderProps { sidebarOpen: boolean @@ -21,7 +22,7 @@ export function InfraHeader({ onChatToggle, chatVisible }: InfraHeaderProps) { - const { config } = useKubernetes() + const { config } = useKubernetes(); return (
@@ -53,5 +54,5 @@ export function InfraHeader({
- ) + ); } \ No newline at end of file diff --git a/apps/ops-dashboard/components/headers/smart-objects-header.tsx b/apps/ops-dashboard/components/headers/smart-objects-header.tsx index 4755d52..fbb6568 100644 --- a/apps/ops-dashboard/components/headers/smart-objects-header.tsx +++ b/apps/ops-dashboard/components/headers/smart-objects-header.tsx @@ -1,8 +1,9 @@ -'use client' +'use client'; -import { Button } from '@/components/ui/button' -import { ThemeToggle } from '@/components/ui/theme-toggle' -import { Menu, PanelLeftClose, MessageSquare } from 'lucide-react' +import { Menu, MessageSquare,PanelLeftClose } from 'lucide-react'; + +import { Button } from '@/components/ui/button'; +import { ThemeToggle } from '@/components/ui/theme-toggle'; interface SmartObjectsHeaderProps { sidebarOpen: boolean @@ -47,5 +48,5 @@ export function SmartObjectsHeader({ - ) + ); } \ No newline at end of file diff --git a/apps/ops-dashboard/components/namespace-switcher.tsx b/apps/ops-dashboard/components/namespace-switcher.tsx index 90acab2..557e8ed 100644 --- a/apps/ops-dashboard/components/namespace-switcher.tsx +++ b/apps/ops-dashboard/components/namespace-switcher.tsx @@ -1,23 +1,24 @@ -'use client' +'use client'; -import { useNamespaces } from '@/hooks' -import { usePreferredNamespace } from '@/contexts/NamespaceContext' +import { RefreshCw } from 'lucide-react'; + +import { Badge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, -} from '@/components/ui/select' -import { Badge } from '@/components/ui/badge' -import { RefreshCw } from 'lucide-react' -import { Button } from '@/components/ui/button' +} from '@/components/ui/select'; +import { usePreferredNamespace } from '@/contexts/NamespaceContext'; +import { useNamespaces } from '@/hooks'; export function NamespaceSwitcher() { - const { namespace, setNamespace } = usePreferredNamespace() - const { data, isLoading, error, refetch } = useNamespaces() + const { namespace, setNamespace } = usePreferredNamespace(); + const { data, isLoading, error, refetch } = useNamespaces(); - const namespaces = (data?.items as any[])?.map((item: any) => item.metadata?.name).filter(Boolean) || [] + const namespaces = (data?.items as any[])?.map((item: any) => item.metadata?.name).filter(Boolean) || []; return (
@@ -68,5 +69,5 @@ export function NamespaceSwitcher() {
- ) + ); } \ No newline at end of file diff --git a/apps/ops-dashboard/components/resources/all-resources.tsx b/apps/ops-dashboard/components/resources/all-resources.tsx index 4edb215..6655737 100644 --- a/apps/ops-dashboard/components/resources/all-resources.tsx +++ b/apps/ops-dashboard/components/resources/all-resources.tsx @@ -1,22 +1,22 @@ -'use client' +'use client'; -import { useState, useEffect, useDeferredValue } from 'react' -import { Button } from '@/components/ui/button' -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Badge } from '@/components/ui/badge' +import { type AppsV1DaemonSet as DaemonSet, type AppsV1Deployment as Deployment, type AppsV1ReplicaSet as ReplicaSet, type Pod, type Service } from '@kubernetesjs/ops'; import { + Activity, + AlertCircle, ChevronDown, ChevronRight, - RefreshCw, + Copy, Package, + RefreshCw, Server, - Activity, - Copy, - Settings, - AlertCircle -} from 'lucide-react' -import { useDeployments, useServices, usePods, useDaemonSets, useReplicaSets } from '@/hooks' -import { type AppsV1Deployment as Deployment, type AppsV1DaemonSet as DaemonSet, type AppsV1ReplicaSet as ReplicaSet, type Pod, type Service } from '@kubernetesjs/ops' + Settings} from 'lucide-react'; +import { useState } from 'react'; + +import { Badge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { useDaemonSets, useDeployments, usePods, useReplicaSets,useServices } from '@/hooks'; interface ResourceSectionProps { title: string @@ -30,7 +30,7 @@ interface ResourceSectionProps { } function ResourceSection({ title, icon: Icon, color, count, loading, error, children, onRefresh }: ResourceSectionProps) { - const [isExpanded, setIsExpanded] = useState(true) + const [isExpanded, setIsExpanded] = useState(true); return ( @@ -54,8 +54,8 @@ function ResourceSection({ title, icon: Icon, color, count, loading, error, chil variant="outline" size="sm" onClick={(e) => { - e.stopPropagation() - onRefresh() + e.stopPropagation(); + onRefresh(); }} disabled={loading} > @@ -76,24 +76,24 @@ function ResourceSection({ title, icon: Icon, color, count, loading, error, chil )} - ) + ); } export function AllResourcesView() { // Always call all hooks, but control their enabled state - const deployments = useDeployments() - const services = useServices() - const pods = usePods() - const daemonSets = useDaemonSets() - const replicaSets = useReplicaSets() + const deployments = useDeployments(); + const services = useServices(); + const pods = usePods(); + const daemonSets = useDaemonSets(); + const replicaSets = useReplicaSets(); const refreshAll = () => { - deployments.refetch() - services.refetch() - pods.refetch() - daemonSets.refetch() - replicaSets.refetch() - } + deployments.refetch(); + services.refetch(); + pods.refetch(); + daemonSets.refetch(); + replicaSets.refetch(); + }; return (
@@ -169,9 +169,9 @@ export function AllResourcesView() { >
{deployments.data?.items?.map((item: Deployment) => { - const replicas = item.spec?.replicas || 0 - const readyReplicas = item.status?.readyReplicas || 0 - const isReady = replicas === readyReplicas && replicas > 0 + const replicas = item.spec?.replicas || 0; + const readyReplicas = item.status?.readyReplicas || 0; + const isReady = replicas === readyReplicas && replicas > 0; return (
@@ -185,7 +185,7 @@ export function AllResourcesView() { {item.spec?.template?.spec?.containers[0]?.image || 'unknown'}
- ) + ); })}
@@ -202,8 +202,8 @@ export function AllResourcesView() { >
{services.data?.items?.map((item: Service) => { - const type = item.spec?.type || 'Unknown' - const ports = item.spec?.ports?.map(p => p.port).join(', ') || 'none' + const type = item.spec?.type || 'Unknown'; + const ports = item.spec?.ports?.map(p => p.port).join(', ') || 'none'; return (
@@ -215,7 +215,7 @@ export function AllResourcesView() { Ports: {ports}
- ) + ); })} @@ -232,10 +232,10 @@ export function AllResourcesView() { >
{pods.data?.items?.map((item: Pod) => { - const phase = item.status?.phase || 'Unknown' - const containerStatuses = item.status?.containerStatuses || [] - const readyContainers = containerStatuses.filter(cs => cs.ready).length - const totalContainers = containerStatuses.length + const phase = item.status?.phase || 'Unknown'; + const containerStatuses = item.status?.containerStatuses || []; + const readyContainers = containerStatuses.filter(cs => cs.ready).length; + const totalContainers = containerStatuses.length; return (
@@ -252,7 +252,7 @@ export function AllResourcesView() { Node: {item.spec?.nodeName || 'unassigned'}
- ) + ); })} @@ -269,9 +269,9 @@ export function AllResourcesView() { >
{daemonSets.data?.items?.map((item: DaemonSet) => { - const desired = item.status?.desiredNumberScheduled || 0 - const ready = item.status?.numberReady || 0 - const isReady = desired === ready && desired > 0 + const desired = item.status?.desiredNumberScheduled || 0; + const ready = item.status?.numberReady || 0; + const isReady = desired === ready && desired > 0; return (
@@ -285,7 +285,7 @@ export function AllResourcesView() { {item.spec?.template?.spec?.containers[0]?.image || 'unknown'}
- ) + ); })} @@ -302,13 +302,13 @@ export function AllResourcesView() { >
{replicaSets.data?.items?.map((item: ReplicaSet) => { - const replicas = item.spec?.replicas || 0 - const readyReplicas = item.status?.readyReplicas || 0 - const isReady = replicas === readyReplicas && replicas > 0 + const replicas = item.spec?.replicas || 0; + const readyReplicas = item.status?.readyReplicas || 0; + const isReady = replicas === readyReplicas && replicas > 0; // Check if owned by deployment - const ownerRefs = item.metadata?.ownerReferences || [] - const deploymentRef = ownerRefs.find(ref => ref.kind === 'Deployment') + const ownerRefs = item.metadata?.ownerReferences || []; + const deploymentRef = ownerRefs.find(ref => ref.kind === 'Deployment'); return (
@@ -327,11 +327,11 @@ export function AllResourcesView() { {item.spec?.template?.spec?.containers[0]?.image || 'unknown'}
- ) + ); })} - ) + ); } diff --git a/apps/ops-dashboard/components/resources/configmaps.tsx b/apps/ops-dashboard/components/resources/configmaps.tsx index 5dacefb..c3fe3c8 100644 --- a/apps/ops-dashboard/components/resources/configmaps.tsx +++ b/apps/ops-dashboard/components/resources/configmaps.tsx @@ -1,31 +1,30 @@ -'use client' +'use client'; -import { useState } from 'react' -import { Button } from '@/components/ui/button' -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' -import { Badge } from '@/components/ui/badge' -import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog' -import { Textarea } from '@/components/ui/textarea' -import { Label } from '@/components/ui/label' +import { type ConfigMap as K8sConfigMap } from '@kubernetesjs/ops'; import { - RefreshCw, - Plus, - Trash2, + AlertCircle, + ChevronDown, + ChevronRight, + Database, Edit, Eye, FileCode, FileText, - Database, + Plus, + RefreshCw, Save, - AlertCircle, - ChevronDown, - ChevronRight -} from 'lucide-react' -import { type ConfigMap as K8sConfigMap } from '@kubernetesjs/ops' -import { useConfigMaps, useDeleteConfigMap, useUpdateConfigMap } from '@/hooks' + Trash2} from 'lucide-react'; +import { useState } from 'react'; -import { confirmDialog } from '@/hooks/useConfirm' +import { Badge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog'; +import { Label } from '@/components/ui/label'; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; +import { Textarea } from '@/components/ui/textarea'; +import { useConfigMaps, useDeleteConfigMap, useUpdateConfigMap } from '@/hooks'; +import { confirmDialog } from '@/hooks/useConfirm'; interface ConfigMap { name: string @@ -38,18 +37,18 @@ interface ConfigMap { } export function ConfigMapsView() { - const [selectedConfigMap, setSelectedConfigMap] = useState(null) - const [editDialogOpen, setEditDialogOpen] = useState(false) - const [editingConfigMap, setEditingConfigMap] = useState(null) - const [editedData, setEditedData] = useState>({}) - const [expandedKeys, setExpandedKeys] = useState>(new Set()) - const [saving, setSaving] = useState(false) - const [createDialogOpen, setCreateDialogOpen] = useState(false) + const [selectedConfigMap, setSelectedConfigMap] = useState(null); + const [editDialogOpen, setEditDialogOpen] = useState(false); + const [editingConfigMap, setEditingConfigMap] = useState(null); + const [editedData, setEditedData] = useState>({}); + const [expandedKeys, setExpandedKeys] = useState>(new Set()); + const [saving, setSaving] = useState(false); + const [createDialogOpen, setCreateDialogOpen] = useState(false); // Use TanStack Query hooks - const { data, isLoading, error, refetch } = useConfigMaps() - const deleteConfigMapMutation = useDeleteConfigMap() - const updateConfigMapMutation = useUpdateConfigMap() + const { data, isLoading, error, refetch } = useConfigMaps(); + const deleteConfigMapMutation = useDeleteConfigMap(); + const updateConfigMapMutation = useUpdateConfigMap(); // Format configmaps from query data const configMaps: ConfigMap[] = (data?.items as any[])?.map((item: any) => ({ @@ -60,11 +59,11 @@ export function ConfigMapsView() { createdAt: item.metadata?.creationTimestamp || '', immutable: item.immutable, k8sData: item - })) || [] + })) || []; const handleRefresh = () => { - refetch() - } + refetch(); + }; const handleDelete = async (configMap: ConfigMap) => { const confirmed = await confirmDialog({ @@ -72,98 +71,98 @@ export function ConfigMapsView() { description: `Are you sure you want to delete ${configMap.name}?`, confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); if (confirmed) { try { await deleteConfigMapMutation.mutateAsync({ name: configMap.name, namespace: configMap.namespace - }) + }); } catch (err) { - console.error('Failed to delete configmap:', err) - alert(`Failed to delete configmap: ${err instanceof Error ? err.message : 'Unknown error'}`) + console.error('Failed to delete configmap:', err); + alert(`Failed to delete configmap: ${err instanceof Error ? err.message : 'Unknown error'}`); } } - } + }; const handleEdit = (configMap: ConfigMap) => { - setEditingConfigMap(configMap) - setEditedData((configMap.k8sData?.data as Record) || {}) - setExpandedKeys(new Set()) - setEditDialogOpen(true) - } + setEditingConfigMap(configMap); + setEditedData((configMap.k8sData?.data as Record) || {}); + setExpandedKeys(new Set()); + setEditDialogOpen(true); + }; const toggleKeyExpansion = (key: string) => { - const newExpanded = new Set(expandedKeys) + const newExpanded = new Set(expandedKeys); if (expandedKeys.has(key)) { - newExpanded.delete(key) + newExpanded.delete(key); } else { - newExpanded.add(key) + newExpanded.add(key); } - setExpandedKeys(newExpanded) - } + setExpandedKeys(newExpanded); + }; const handleSaveConfigMap = async () => { - if (!editingConfigMap || !editingConfigMap.k8sData) return + if (!editingConfigMap || !editingConfigMap.k8sData) return; - setSaving(true) + setSaving(true); try { const updatedConfigMap: K8sConfigMap = { ...editingConfigMap.k8sData, data: editedData - } + }; await updateConfigMapMutation.mutateAsync({ name: editingConfigMap.name, configMap: updatedConfigMap, namespace: editingConfigMap.namespace - }) + }); - setEditDialogOpen(false) + setEditDialogOpen(false); } catch (err) { - console.error('Failed to update configmap:', err) - alert(`Failed to update configmap: ${err instanceof Error ? err.message : 'Unknown error'}`) + console.error('Failed to update configmap:', err); + alert(`Failed to update configmap: ${err instanceof Error ? err.message : 'Unknown error'}`); } finally { - setSaving(false) + setSaving(false); } - } + }; const getDataTypeBadge = (key: string, isBinary: boolean = false) => { if (isBinary) { return Binary - + ; } - const extension = key.split('.').pop()?.toLowerCase() + const extension = key.split('.').pop()?.toLowerCase(); switch (extension) { - case 'yaml': - case 'yml': - case 'json': - case 'xml': - return - + case 'yaml': + case 'yml': + case 'json': + case 'xml': + return + Config - - case 'conf': - case 'properties': - case 'ini': - return - + ; + case 'conf': + case 'properties': + case 'ini': + return + Settings - - case 'sh': - case 'bash': - return - + ; + case 'sh': + case 'bash': + return + Script - - default: - return Text + ; + default: + return Text; } - } + }; return (
@@ -368,9 +367,9 @@ export function ConfigMapsView() {
{editingConfigMap && Object.entries(editedData).map(([key, value]) => { - const isExpanded = expandedKeys.has(key) - const lines = value.split('\n').length - const isLarge = lines > 3 || value.length > 200 + const isExpanded = expandedKeys.has(key); + const lines = value.split('\n').length; + const isLarge = lines > 3 || value.length > 200; return (
@@ -398,7 +397,7 @@ export function ConfigMapsView() { setEditedData(prev => ({ ...prev, [key]: e.target.value - })) + })); }} className={`font-mono text-sm ${ isLarge && !isExpanded ? 'h-20' : 'min-h-[100px]' @@ -408,7 +407,7 @@ export function ConfigMapsView() { }} />
- ) + ); })}
@@ -440,5 +439,5 @@ export function ConfigMapsView() {
- ) + ); } \ No newline at end of file diff --git a/apps/ops-dashboard/components/resources/cronjobs.tsx b/apps/ops-dashboard/components/resources/cronjobs.tsx index dc82018..4295ffc 100644 --- a/apps/ops-dashboard/components/resources/cronjobs.tsx +++ b/apps/ops-dashboard/components/resources/cronjobs.tsx @@ -1,78 +1,77 @@ -'use client' +'use client'; -import { useState } from 'react' -import { Button } from '@/components/ui/button' -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' -import { Badge } from '@/components/ui/badge' +import { type BatchV1CronJob as CronJob } from '@kubernetesjs/ops'; import { - RefreshCw, - Plus, - Trash2, - Eye, AlertCircle, CheckCircle, Clock, + Eye, Pause, - Play -} from 'lucide-react' + Play, + Plus, + RefreshCw, + Trash2} from 'lucide-react'; +import { useState } from 'react'; + +import { Badge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; +import { usePreferredNamespace } from '@/contexts/NamespaceContext'; +import { confirmDialog } from '@/hooks/useConfirm'; import { - useListBatchV1NamespacedCronJobQuery, - useListBatchV1CronJobForAllNamespacesQuery, useDeleteBatchV1NamespacedCronJob, + useListBatchV1CronJobForAllNamespacesQuery, + useListBatchV1NamespacedCronJobQuery, usePatchBatchV1NamespacedCronJob -} from '@/k8s' -import { usePreferredNamespace } from '@/contexts/NamespaceContext' -import { type BatchV1CronJob as CronJob } from '@kubernetesjs/ops' - -import { confirmDialog } from '@/hooks/useConfirm' +} from '@/k8s'; export function CronJobsView() { - const [selectedCronJob, setSelectedCronJob] = useState(null) - const { namespace } = usePreferredNamespace() + const [selectedCronJob, setSelectedCronJob] = useState(null); + const { namespace } = usePreferredNamespace(); // Use k8s hooks directly const query = namespace === '_all' ? useListBatchV1CronJobForAllNamespacesQuery({ query: {} }) - : useListBatchV1NamespacedCronJobQuery({ path: { namespace }, query: {} }) + : useListBatchV1NamespacedCronJobQuery({ path: { namespace }, query: {} }); - const { data, isLoading, error, refetch } = query - const deleteCronJob = useDeleteBatchV1NamespacedCronJob() - const patchCronJob = usePatchBatchV1NamespacedCronJob() + const { data, isLoading, error, refetch } = query; + const deleteCronJob = useDeleteBatchV1NamespacedCronJob(); + const patchCronJob = usePatchBatchV1NamespacedCronJob(); - const cronjobs = data?.items || [] + const cronjobs = data?.items || []; - const handleRefresh = () => refetch() + const handleRefresh = () => refetch(); const handleDelete = async (cronjob: CronJob) => { - const name = cronjob.metadata!.name! - const namespace = cronjob.metadata!.namespace! + const name = cronjob.metadata!.name!; + const namespace = cronjob.metadata!.namespace!; const confirmed = await confirmDialog({ title: 'Delete CronJob', description: `Are you sure you want to delete ${name}?`, confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); if (confirmed) { try { await deleteCronJob.mutateAsync({ path: { namespace, name }, query: {} - }) - refetch() + }); + refetch(); } catch (err) { - console.error('Failed to delete cronjob:', err) - alert(`Failed to delete cronjob: ${err instanceof Error ? err.message : 'Unknown error'}`) + console.error('Failed to delete cronjob:', err); + alert(`Failed to delete cronjob: ${err instanceof Error ? err.message : 'Unknown error'}`); } } - } + }; const handleToggleSuspend = async (cronjob: CronJob) => { - const name = cronjob.metadata!.name! - const namespace = cronjob.metadata!.namespace! - const suspend = !cronjob.spec?.suspend + const name = cronjob.metadata!.name!; + const namespace = cronjob.metadata!.namespace!; + const suspend = !cronjob.spec?.suspend; try { await patchCronJob.mutateAsync({ @@ -81,63 +80,63 @@ export function CronJobsView() { body: { spec: { suspend } } - }) - refetch() + }); + refetch(); } catch (err) { - console.error('Failed to update cronjob:', err) - alert(`Failed to update cronjob: ${err instanceof Error ? err.message : 'Unknown error'}`) + console.error('Failed to update cronjob:', err); + alert(`Failed to update cronjob: ${err instanceof Error ? err.message : 'Unknown error'}`); } - } + }; const getStatus = (cronjob: CronJob) => { if (cronjob.spec?.suspend) { - return 'Suspended' + return 'Suspended'; } - return cronjob.status?.active && cronjob.status.active.length > 0 ? 'Active' : 'Idle' - } + return cronjob.status?.active && cronjob.status.active.length > 0 ? 'Active' : 'Idle'; + }; const getStatusBadge = (status: string) => { switch (status) { - case 'Active': - return - - {status} - - case 'Idle': - return - - {status} - - case 'Suspended': - return - - {status} - - default: - return {status} + case 'Active': + return + + {status} + ; + case 'Idle': + return + + {status} + ; + case 'Suspended': + return + + {status} + ; + default: + return {status}; } - } + }; const getLastScheduleTime = (cronjob: CronJob) => { - if (!cronjob.status?.lastScheduleTime) return 'Never' - const lastTime = new Date(cronjob.status.lastScheduleTime) - const now = new Date() - const diff = now.getTime() - lastTime.getTime() + if (!cronjob.status?.lastScheduleTime) return 'Never'; + const lastTime = new Date(cronjob.status.lastScheduleTime); + const now = new Date(); + const diff = now.getTime() - lastTime.getTime(); - if (diff < 60000) return 'Just now' - if (diff < 3600000) return `${Math.floor(diff / 60000)}m ago` - if (diff < 86400000) return `${Math.floor(diff / 3600000)}h ago` - return lastTime.toLocaleDateString() - } + if (diff < 60000) return 'Just now'; + if (diff < 3600000) return `${Math.floor(diff / 60000)}m ago`; + if (diff < 86400000) return `${Math.floor(diff / 3600000)}h ago`; + return lastTime.toLocaleDateString(); + }; const getNextScheduleTime = (cronjob: CronJob) => { - if (cronjob.spec?.suspend) return 'Suspended' + if (cronjob.spec?.suspend) return 'Suspended'; if (!cronjob.status?.lastScheduleTime && !cronjob.status?.lastSuccessfulTime) { - return 'Soon' + return 'Soon'; } // Note: Actual next schedule calculation would require cron parsing - return 'Calculating...' - } + return 'Calculating...'; + }; return (
@@ -297,5 +296,5 @@ export function CronJobsView() {
- ) + ); } diff --git a/apps/ops-dashboard/components/resources/daemonsets.tsx b/apps/ops-dashboard/components/resources/daemonsets.tsx index 0b14b84..abfbdb9 100644 --- a/apps/ops-dashboard/components/resources/daemonsets.tsx +++ b/apps/ops-dashboard/components/resources/daemonsets.tsx @@ -1,23 +1,21 @@ -'use client' +'use client'; -import { useState } from 'react' -import { Button } from '@/components/ui/button' -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' -import { Badge } from '@/components/ui/badge' +import { type AppsV1DaemonSet as K8sDaemonSet } from '@kubernetesjs/ops'; import { - RefreshCw, - Plus, - Trash2, - Eye, AlertCircle, CheckCircle, - Server -} from 'lucide-react' -import { type AppsV1DaemonSet as K8sDaemonSet } from '@kubernetesjs/ops' -import { useDaemonSets, useDeleteDaemonSet } from '@/hooks/useDaemonSets' + Eye, + Plus, + RefreshCw, + Trash2} from 'lucide-react'; +import { useState } from 'react'; -import { confirmDialog } from '@/hooks/useConfirm' +import { Badge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; +import { confirmDialog } from '@/hooks/useConfirm'; +import { useDaemonSets, useDeleteDaemonSet } from '@/hooks/useDaemonSets'; interface DaemonSet { name: string @@ -33,23 +31,23 @@ interface DaemonSet { } export function DaemonSetsView() { - const [selectedDaemonSet, setSelectedDaemonSet] = useState(null) + const [selectedDaemonSet, setSelectedDaemonSet] = useState(null); // Use TanStack Query hooks - const { data, isLoading, error, refetch } = useDaemonSets() - const deleteDaemonSetMutation = useDeleteDaemonSet() + const { data, isLoading, error, refetch } = useDaemonSets(); + const deleteDaemonSetMutation = useDeleteDaemonSet(); // Helper function to determine daemon set status function determineDaemonSetStatus(ds: K8sDaemonSet): DaemonSet['status'] { - const status = ds.status - if (!status) return 'NotReady' + const status = ds.status; + if (!status) return 'NotReady'; if (status.desiredNumberScheduled === status.numberReady) { - return 'Ready' + return 'Ready'; } else if (status.updatedNumberScheduled && status.updatedNumberScheduled > 0) { - return 'Updating' + return 'Updating'; } else { - return 'NotReady' + return 'NotReady'; } } @@ -66,12 +64,12 @@ export function DaemonSetsView() { createdAt: item.metadata?.creationTimestamp || new Date().toISOString(), status: determineDaemonSetStatus(item), k8sData: item - } - }) || [] + }; + }) || []; const handleRefresh = () => { - refetch() - } + refetch(); + }; const handleDelete = async (daemonSet: DaemonSet) => { const confirmed = await confirmDialog({ @@ -79,42 +77,42 @@ export function DaemonSetsView() { description: `Are you sure you want to delete ${daemonSet.name}?`, confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); if (confirmed) { try { await deleteDaemonSetMutation.mutateAsync({ name: daemonSet.name, namespace: daemonSet.namespace - }) + }); } catch (err) { - console.error('Failed to delete daemonset:', err) - alert(`Failed to delete daemonset: ${err instanceof Error ? err.message : 'Unknown error'}`) + console.error('Failed to delete daemonset:', err); + alert(`Failed to delete daemonset: ${err instanceof Error ? err.message : 'Unknown error'}`); } } - } + }; const getStatusBadge = (status: DaemonSet['status']) => { switch (status) { - case 'Ready': - return - - {status} - - case 'Updating': - return - - {status} - - case 'NotReady': - return - - {status} - - default: - return {status} + case 'Ready': + return + + {status} + ; + case 'Updating': + return + + {status} + ; + case 'NotReady': + return + + {status} + ; + default: + return {status}; } - } + }; return (
@@ -267,5 +265,5 @@ export function DaemonSetsView() {
- ) + ); } diff --git a/apps/ops-dashboard/components/resources/deployments.tsx b/apps/ops-dashboard/components/resources/deployments.tsx index 1be4dad..1954403 100644 --- a/apps/ops-dashboard/components/resources/deployments.tsx +++ b/apps/ops-dashboard/components/resources/deployments.tsx @@ -1,31 +1,28 @@ -'use client' +'use client'; -import { useState } from 'react' -import { Button } from '@/components/ui/button' -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' -import { Badge } from '@/components/ui/badge' +import { type AppsV1Deployment as K8sDeployment } from '@kubernetesjs/ops'; +import yaml from 'js-yaml'; +import { load } from 'js-yaml'; import { - RefreshCw, - Plus, - Trash2, + AlertCircle, + CheckCircle, Edit, - Scale, Eye, - AlertCircle, - CheckCircle -} from 'lucide-react' -import { type AppsV1Deployment as K8sDeployment } from '@kubernetesjs/ops' -import { useDeployments, useDeleteDeployment, useScaleDeployment, useCreateDeployment, useUpdateDeployment } from '@/hooks' - -import { confirmDialog } from '@/hooks/useConfirm' - -import { CreateDeploymentDialog } from '@/components/create-deployment-dialog' + Plus, + RefreshCw, + Scale, + Trash2} from 'lucide-react'; +import { useState } from 'react'; -import { ViewEditDeploymentDialog } from '@/components/view-edit-deployment-dialog' -import { ScaleDeploymentDialog } from '@/components/scale-deployment-dialog' -import yaml from 'js-yaml' -import { load } from 'js-yaml' +import { CreateDeploymentDialog } from '@/components/create-deployment-dialog'; +import { ScaleDeploymentDialog } from '@/components/scale-deployment-dialog'; +import { Badge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; +import { ViewEditDeploymentDialog } from '@/components/view-edit-deployment-dialog'; +import { useCreateDeployment, useDeleteDeployment, useDeployments, useScaleDeployment, useUpdateDeployment } from '@/hooks'; +import { confirmDialog } from '@/hooks/useConfirm'; interface Deployment { name: string @@ -39,39 +36,39 @@ interface Deployment { } export function DeploymentsView() { - const [selectedDeployment, setSelectedDeployment] = useState(null) + const [selectedDeployment, setSelectedDeployment] = useState(null); - const [showCreateDialog, setShowCreateDialog] = useState(false) + const [showCreateDialog, setShowCreateDialog] = useState(false); - const [showViewEditDialog, setShowViewEditDialog] = useState(false) - const [viewEditMode, setViewEditMode] = useState<'view' | 'edit'>('view') - const [showScaleDialog, setShowScaleDialog] = useState(false) + const [showViewEditDialog, setShowViewEditDialog] = useState(false); + const [viewEditMode, setViewEditMode] = useState<'view' | 'edit'>('view'); + const [showScaleDialog, setShowScaleDialog] = useState(false); // Use TanStack Query hooks - const { data, isLoading, error, refetch } = useDeployments() - const deleteDeploymentMutation = useDeleteDeployment() - const scaleDeploymentMutation = useScaleDeployment() - const createDeploymentMutation = useCreateDeployment() - const updateDeploymentMutation = useUpdateDeployment() + const { data, isLoading, error, refetch } = useDeployments(); + const deleteDeploymentMutation = useDeleteDeployment(); + const scaleDeploymentMutation = useScaleDeployment(); + const createDeploymentMutation = useCreateDeployment(); + const updateDeploymentMutation = useUpdateDeployment(); // Helper function to determine deployment status function determineStatus(deployment: K8sDeployment): 'Running' | 'Pending' | 'Failed' { - const conditions = deployment.status!.conditions || [] - const progressingCondition = conditions.find(c => c.type === 'Progressing') - const availableCondition = conditions.find(c => c.type === 'Available') + const conditions = deployment.status!.conditions || []; + const progressingCondition = conditions.find(c => c.type === 'Progressing'); + const availableCondition = conditions.find(c => c.type === 'Available'); if (availableCondition?.status === 'True' && deployment.status!.availableReplicas === deployment.spec!.replicas!) { - return 'Running' + return 'Running'; } else if (progressingCondition?.status === 'True') { - return 'Pending' + return 'Pending'; } else { - return 'Failed' + return 'Failed'; } } // Format deployments from query data const deployments: Deployment[] = (data?.items as any[])?.map(item => { - const status = determineStatus(item) + const status = determineStatus(item); return { name: item.metadata?.name || 'unknown', namespace: item.metadata?.namespace || 'unknown', @@ -81,30 +78,30 @@ export function DeploymentsView() { createdAt: item.metadata?.creationTimestamp || new Date().toISOString(), status, k8sData: item - } - }) || [] + }; + }) || []; const handleRefresh = () => { - refetch() - } + refetch(); + }; const handleScale = (deployment: Deployment) => { - setSelectedDeployment(deployment) - setShowScaleDialog(true) - } + setSelectedDeployment(deployment); + setShowScaleDialog(true); + }; const handleView = (deployment: Deployment) => { - setSelectedDeployment(deployment) - setViewEditMode('view') - setShowViewEditDialog(true) - } + setSelectedDeployment(deployment); + setViewEditMode('view'); + setShowViewEditDialog(true); + }; const handleEdit = (deployment: Deployment) => { - setSelectedDeployment(deployment) - setViewEditMode('edit') - setShowViewEditDialog(true) - } + setSelectedDeployment(deployment); + setViewEditMode('edit'); + setShowViewEditDialog(true); + }; const handleDelete = async (deployment: Deployment) => { const confirmed = await confirmDialog({ @@ -112,43 +109,43 @@ export function DeploymentsView() { description: `Are you sure you want to delete ${deployment.name}?`, confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); if (confirmed) { try { await deleteDeploymentMutation.mutateAsync({ name: deployment.name, namespace: deployment.namespace - }) - refetch() + }); + refetch(); } catch (err) { - console.error('Failed to delete deployment:', err) - alert(`Failed to delete deployment: ${err instanceof Error ? err.message : 'Unknown error'}`) + console.error('Failed to delete deployment:', err); + alert(`Failed to delete deployment: ${err instanceof Error ? err.message : 'Unknown error'}`); } } - } + }; const getStatusBadge = (status: string) => { switch (status) { - case 'Running': - return - - {status} - - case 'Pending': - return - - {status} - - case 'Failed': - return - - {status} - - default: - return {status} + case 'Running': + return + + {status} + ; + case 'Pending': + return + + {status} + ; + case 'Failed': + return + + {status} + ; + default: + return {status}; } - } + }; return (
@@ -321,34 +318,34 @@ export function DeploymentsView() { onSubmit={async (yaml) => { try { // Parse YAML to extract namespace if provided - const yamlLines = yaml.split('\n') - let namespace = 'default' + const yamlLines = yaml.split('\n'); + let namespace = 'default'; // Look for namespace in metadata - const metadataIndex = yamlLines.findIndex(line => line.trim() === 'metadata:') + const metadataIndex = yamlLines.findIndex(line => line.trim() === 'metadata:'); if (metadataIndex !== -1) { for (let i = metadataIndex + 1; i < yamlLines.length; i++) { - const line = yamlLines[i].trim() + const line = yamlLines[i].trim(); if (line.startsWith('namespace:')) { - namespace = line.split(':')[1].trim() - break + namespace = line.split(':')[1].trim(); + break; } // Stop if we hit another top-level key if (!line.startsWith(' ') && !line.startsWith('\t') && line.includes(':')) { - break + break; } } } // Convert YAML string to JSON object - const deploymentObj = load(yaml) as any + const deploymentObj = load(yaml) as any; // Create deployment using hook - await createDeploymentMutation.mutateAsync({ deployment: deploymentObj, namespace }) + await createDeploymentMutation.mutateAsync({ deployment: deploymentObj, namespace }); // Refresh the deployments list - refetch() + refetch(); } catch (error) { - console.error('Failed to create deployment:', error) - throw error + console.error('Failed to create deployment:', error); + throw error; } }} /> @@ -361,24 +358,24 @@ export function DeploymentsView() { onOpenChange={setShowViewEditDialog} mode={viewEditMode} onSubmit={async (yamlContent) => { - if (!selectedDeployment) return + if (!selectedDeployment) return; try { // Parse the YAML to get the deployment object - const deploymentObj = yaml.load(yamlContent) as any + const deploymentObj = yaml.load(yamlContent) as any; // Update deployment using PUT request await updateDeploymentMutation.mutateAsync({ name: selectedDeployment.name, deployment: deploymentObj, namespace: selectedDeployment.namespace - }) + }); // Refresh the deployments list - refetch() + refetch(); } catch (error) { - console.error('Failed to update deployment:', error) - throw error + console.error('Failed to update deployment:', error); + throw error; } }} /> @@ -389,21 +386,21 @@ export function DeploymentsView() { open={showScaleDialog} onOpenChange={setShowScaleDialog} onScale={async (replicas) => { - if (!selectedDeployment) return + if (!selectedDeployment) return; try { await scaleDeploymentMutation.mutateAsync({ name: selectedDeployment.name, replicas: replicas, namespace: selectedDeployment.namespace - }) - refetch() + }); + refetch(); } catch (err) { - console.error('Failed to scale deployment:', err) - throw err + console.error('Failed to scale deployment:', err); + throw err; } }} />
- ) + ); } \ No newline at end of file diff --git a/apps/ops-dashboard/components/resources/endpoints.tsx b/apps/ops-dashboard/components/resources/endpoints.tsx index ca07d46..ac3ab4c 100644 --- a/apps/ops-dashboard/components/resources/endpoints.tsx +++ b/apps/ops-dashboard/components/resources/endpoints.tsx @@ -1,130 +1,126 @@ -'use client' +'use client'; -import { useState } from 'react' -import { Button } from '@/components/ui/button' -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' -import { Badge } from '@/components/ui/badge' +import type { Endpoints } from '@kubernetesjs/ops'; import { - RefreshCw, - Plus, - Trash2, - Eye, AlertCircle, CheckCircle, - Network, - Server -} from 'lucide-react' + Eye, + Network, + RefreshCw, + Trash2} from 'lucide-react'; +import { useState } from 'react'; + +import { Badge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; +import { usePreferredNamespace } from '@/contexts/NamespaceContext'; +import { confirmDialog } from '@/hooks/useConfirm'; import { - useListCoreV1NamespacedEndpointsQuery, + useDeleteCoreV1NamespacedEndpoints, useListCoreV1EndpointsForAllNamespacesQuery, - useDeleteCoreV1NamespacedEndpoints -} from '@/k8s' -import { usePreferredNamespace } from '@/contexts/NamespaceContext' -import type { Endpoints } from '@kubernetesjs/ops' - -import { confirmDialog } from '@/hooks/useConfirm' + useListCoreV1NamespacedEndpointsQuery} from '@/k8s'; export function EndpointsView() { - const [selectedEndpoint, setSelectedEndpoint] = useState(null) - const { namespace } = usePreferredNamespace() + const [selectedEndpoint, setSelectedEndpoint] = useState(null); + const { namespace } = usePreferredNamespace(); const query = namespace === '_all' ? useListCoreV1EndpointsForAllNamespacesQuery({ query: {} }) - : useListCoreV1NamespacedEndpointsQuery({ path: { namespace }, query: {} }) + : useListCoreV1NamespacedEndpointsQuery({ path: { namespace }, query: {} }); - const { data, isLoading, error, refetch } = query - const deleteEndpoint = useDeleteCoreV1NamespacedEndpoints() + const { data, isLoading, error, refetch } = query; + const deleteEndpoint = useDeleteCoreV1NamespacedEndpoints(); - const endpoints = data?.items || [] + const endpoints = data?.items || []; - const handleRefresh = () => refetch() + const handleRefresh = () => refetch(); const handleDelete = async (endpoint: Endpoints) => { - const name = endpoint.metadata!.name! - const namespace = endpoint.metadata!.namespace! + const name = endpoint.metadata!.name!; + const namespace = endpoint.metadata!.namespace!; const confirmed = await confirmDialog({ title: 'Delete Endpoint', description: `Are you sure you want to delete ${name}?`, confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); if (confirmed) { try { await deleteEndpoint.mutateAsync({ path: { namespace, name }, query: {} - }) - refetch() + }); + refetch(); } catch (err) { - console.error('Failed to delete endpoint:', err) - alert(`Failed to delete endpoint: ${err instanceof Error ? err.message : 'Unknown error'}`) + console.error('Failed to delete endpoint:', err); + alert(`Failed to delete endpoint: ${err instanceof Error ? err.message : 'Unknown error'}`); } } - } + }; const getAddressCount = (endpoint: Endpoints): number => { - const subsets = endpoint.subsets || [] + const subsets = endpoint.subsets || []; return subsets.reduce((sum, subset) => { - const addresses = subset.addresses || [] - return sum + addresses.length - }, 0) - } + const addresses = subset.addresses || []; + return sum + addresses.length; + }, 0); + }; const getPortCount = (endpoint: Endpoints): number => { - const subsets = endpoint.subsets || [] - const uniquePorts = new Set() + const subsets = endpoint.subsets || []; + const uniquePorts = new Set(); subsets.forEach(subset => { - const ports = subset.ports || [] + const ports = subset.ports || []; ports.forEach(port => { - uniquePorts.add(`${port.name || 'unnamed'}:${port.port}/${port.protocol || 'TCP'}`) - }) - }) - return uniquePorts.size - } + uniquePorts.add(`${port.name || 'unnamed'}:${port.port}/${port.protocol || 'TCP'}`); + }); + }); + return uniquePorts.size; + }; const getStatus = (endpoint: Endpoints) => { - const addressCount = getAddressCount(endpoint) + const addressCount = getAddressCount(endpoint); if (addressCount === 0) { - return 'No Endpoints' + return 'No Endpoints'; } - return 'Ready' - } + return 'Ready'; + }; const getStatusBadge = (status: string) => { switch (status) { - case 'Ready': - return - - {status} - - case 'No Endpoints': - return - - {status} - - default: - return {status} + case 'Ready': + return + + {status} + ; + case 'No Endpoints': + return + + {status} + ; + default: + return {status}; } - } + }; const getEndpointAddresses = (endpoint: Endpoints): string => { - const subsets = endpoint.subsets || [] - const addresses: string[] = [] + const subsets = endpoint.subsets || []; + const addresses: string[] = []; subsets.forEach(subset => { - const addrs = subset.addresses || [] + const addrs = subset.addresses || []; addrs.forEach(addr => { - addresses.push(addr.ip) - }) - }) + addresses.push(addr.ip); + }); + }); - if (addresses.length === 0) return 'None' - if (addresses.length <= 3) return addresses.join(', ') - return `${addresses.slice(0, 3).join(', ')} +${addresses.length - 3} more` - } + if (addresses.length === 0) return 'None'; + if (addresses.length <= 3) return addresses.join(', '); + return `${addresses.slice(0, 3).join(', ')} +${addresses.length - 3} more`; + }; return (
@@ -278,5 +274,5 @@ export function EndpointsView() {
- ) + ); } diff --git a/apps/ops-dashboard/components/resources/endpointslices.tsx b/apps/ops-dashboard/components/resources/endpointslices.tsx index 7adc98b..56d289a 100644 --- a/apps/ops-dashboard/components/resources/endpointslices.tsx +++ b/apps/ops-dashboard/components/resources/endpointslices.tsx @@ -1,125 +1,122 @@ -'use client' +'use client'; -import { useState } from 'react' -import { Button } from '@/components/ui/button' -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' -import { Badge } from '@/components/ui/badge' +import { type DiscoveryK8sIoV1EndpointSlice as EndpointSlice } from '@kubernetesjs/ops'; import { - RefreshCw, - Plus, - Trash2, - Eye, AlertCircle, CheckCircle, - Network, - Slice -} from 'lucide-react' + Eye, + Network, + RefreshCw, + Slice, + Trash2} from 'lucide-react'; +import { useState } from 'react'; + +import { Badge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; +import { usePreferredNamespace } from '@/contexts/NamespaceContext'; +import { confirmDialog } from '@/hooks/useConfirm'; import { - useListDiscoveryV1NamespacedEndpointSliceQuery, + useDeleteDiscoveryV1NamespacedEndpointSlice, useListDiscoveryV1EndpointSliceForAllNamespacesQuery, - useDeleteDiscoveryV1NamespacedEndpointSlice -} from '@/k8s' -import { usePreferredNamespace } from '@/contexts/NamespaceContext' -import { type DiscoveryK8sIoV1EndpointSlice as EndpointSlice } from '@kubernetesjs/ops' - -import { confirmDialog } from '@/hooks/useConfirm' + useListDiscoveryV1NamespacedEndpointSliceQuery} from '@/k8s'; export function EndpointSlicesView() { - const [selectedSlice, setSelectedSlice] = useState(null) - const { namespace } = usePreferredNamespace() + const [selectedSlice, setSelectedSlice] = useState(null); + const { namespace } = usePreferredNamespace(); const query = namespace === '_all' ? useListDiscoveryV1EndpointSliceForAllNamespacesQuery({ query: {} }) - : useListDiscoveryV1NamespacedEndpointSliceQuery({ path: { namespace }, query: {} }) + : useListDiscoveryV1NamespacedEndpointSliceQuery({ path: { namespace }, query: {} }); - const { data, isLoading, error, refetch } = query - const deleteSlice = useDeleteDiscoveryV1NamespacedEndpointSlice() + const { data, isLoading, error, refetch } = query; + const deleteSlice = useDeleteDiscoveryV1NamespacedEndpointSlice(); - const slices = data?.items || [] + const slices = data?.items || []; - const handleRefresh = () => refetch() + const handleRefresh = () => refetch(); const handleDelete = async (slice: EndpointSlice) => { - const name = slice.metadata!.name! - const namespace = slice.metadata!.namespace! + const name = slice.metadata!.name!; + const namespace = slice.metadata!.namespace!; const confirmed = await confirmDialog({ title: 'Delete Endpoint Slice', description: `Are you sure you want to delete ${name}?`, confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); if (confirmed) { try { await deleteSlice.mutateAsync({ path: { namespace, name }, query: {} - }) - refetch() + }); + refetch(); } catch (err) { - console.error('Failed to delete endpoint slice:', err) - alert(`Failed to delete endpoint slice: ${err instanceof Error ? err.message : 'Unknown error'}`) + console.error('Failed to delete endpoint slice:', err); + alert(`Failed to delete endpoint slice: ${err instanceof Error ? err.message : 'Unknown error'}`); } } - } + }; const getEndpointCount = (slice: EndpointSlice): number => { - return slice.endpoints?.length || 0 - } + return slice.endpoints?.length || 0; + }; const getReadyEndpoints = (slice: EndpointSlice): number => { - const endpoints = slice.endpoints || [] - return endpoints.filter(ep => ep.conditions?.ready === true).length - } + const endpoints = slice.endpoints || []; + return endpoints.filter(ep => ep.conditions?.ready === true).length; + }; const getServiceName = (slice: EndpointSlice): string => { const label = slice.metadata?.labels?.['kubernetes.io/service-name'] as string | undefined; return label?.trim() ? label : 'Unknown'; - } + }; const getAddressType = (slice: EndpointSlice): string => { return slice.addressType ?? 'Unknown'; - } + }; const getPorts = (slice: EndpointSlice): string => { - const ports = slice.ports || [] - if (ports.length === 0) return 'None' - return ports.map(p => `${p.name || 'unnamed'}:${p.port}/${p.protocol || 'TCP'}`).join(', ') - } + const ports = slice.ports || []; + if (ports.length === 0) return 'None'; + return ports.map(p => `${p.name || 'unnamed'}:${p.port}/${p.protocol || 'TCP'}`).join(', '); + }; const getStatus = (slice: EndpointSlice) => { - const total = getEndpointCount(slice) - const ready = getReadyEndpoints(slice) + const total = getEndpointCount(slice); + const ready = getReadyEndpoints(slice); - if (total === 0) return 'Empty' - if (ready === total) return 'All Ready' - if (ready === 0) return 'None Ready' - return 'Partial Ready' - } + if (total === 0) return 'Empty'; + if (ready === total) return 'All Ready'; + if (ready === 0) return 'None Ready'; + return 'Partial Ready'; + }; const getStatusBadge = (status: string) => { switch (status) { - case 'All Ready': - return - - {status} - - case 'Partial Ready': - return - - {status} - - case 'None Ready': - return - - {status} - - default: - return {status} + case 'All Ready': + return + + {status} + ; + case 'Partial Ready': + return + + {status} + ; + case 'None Ready': + return + + {status} + ; + default: + return {status}; } - } + }; return (
@@ -276,5 +273,5 @@ export function EndpointSlicesView() {
- ) + ); } diff --git a/apps/ops-dashboard/components/resources/events.tsx b/apps/ops-dashboard/components/resources/events.tsx index b80108f..6593e26 100644 --- a/apps/ops-dashboard/components/resources/events.tsx +++ b/apps/ops-dashboard/components/resources/events.tsx @@ -1,108 +1,107 @@ -'use client' +'use client'; -import { useState } from 'react' -import { Button } from '@/components/ui/button' -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' -import { Badge } from '@/components/ui/badge' +import type { Event } from '@kubernetesjs/ops'; import { - RefreshCw, + Activity, AlertCircle, - Info, AlertTriangle, - Filter, Clock, - Activity -} from 'lucide-react' + Filter, + Info, + RefreshCw} from 'lucide-react'; +import { useState } from 'react'; + +import { Badge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; +import { usePreferredNamespace } from '@/contexts/NamespaceContext'; import { - useListCoreV1NamespacedEventQuery, - useListCoreV1EventForAllNamespacesQuery -} from '@/k8s' -import { usePreferredNamespace } from '@/contexts/NamespaceContext' -import type { Event } from '@kubernetesjs/ops' + useListCoreV1EventForAllNamespacesQuery, + useListCoreV1NamespacedEventQuery} from '@/k8s'; export function EventsView() { - const [typeFilter, setTypeFilter] = useState('All') - const { namespace } = usePreferredNamespace() + const [typeFilter, setTypeFilter] = useState('All'); + const { namespace } = usePreferredNamespace(); // Note: Events API has changed in newer versions, using v1 events const query = namespace === '_all' ? useListCoreV1EventForAllNamespacesQuery({ query: {} }) - : useListCoreV1NamespacedEventQuery({ path: { namespace }, query: {} }) + : useListCoreV1NamespacedEventQuery({ path: { namespace }, query: {} }); - const { data, isLoading, error, refetch } = query + const { data, isLoading, error, refetch } = query; - const events = data?.items || [] + const events = data?.items || []; - const handleRefresh = () => refetch() + const handleRefresh = () => refetch(); const getEventType = (event: Event): string => { - return event.type || 'Normal' - } + return event.type || 'Normal'; + }; const getEventReason = (event: Event): string => { - return event.reason || 'Unknown' - } + return event.reason || 'Unknown'; + }; const getEventMessage = (event: Event): string => { - return event.message || 'No message' - } + return event.message || 'No message'; + }; const getEventObject = (event: Event): string => { - const obj = event.involvedObject - if (!obj) return 'Unknown' - return `${obj.kind}/${obj.name}` - } + const obj = event.involvedObject; + if (!obj) return 'Unknown'; + return `${obj.kind}/${obj.name}`; + }; const getEventTime = (event: Event): string => { - const timestamp = event.lastTimestamp || event.firstTimestamp - if (!timestamp) return 'Unknown' + const timestamp = event.lastTimestamp || event.firstTimestamp; + if (!timestamp) return 'Unknown'; - const date = new Date(timestamp) - const now = new Date() - const diff = now.getTime() - date.getTime() + const date = new Date(timestamp); + const now = new Date(); + const diff = now.getTime() - date.getTime(); - if (diff < 60000) return 'Just now' - if (diff < 3600000) return `${Math.floor(diff / 60000)}m ago` - if (diff < 86400000) return `${Math.floor(diff / 3600000)}h ago` - return date.toLocaleDateString() - } + if (diff < 60000) return 'Just now'; + if (diff < 3600000) return `${Math.floor(diff / 60000)}m ago`; + if (diff < 86400000) return `${Math.floor(diff / 3600000)}h ago`; + return date.toLocaleDateString(); + }; const getEventCount = (event: Event): number => { - return event.count || 1 - } + return event.count || 1; + }; const getTypeBadge = (type: string) => { switch (type) { - case 'Normal': - return - - {type} - - case 'Warning': - return - - {type} - - case 'Error': - return - - {type} - - default: - return {type} + case 'Normal': + return + + {type} + ; + case 'Warning': + return + + {type} + ; + case 'Error': + return + + {type} + ; + default: + return {type}; } - } + }; const filteredEvents = typeFilter === 'All' ? events - : events.filter((e: Event) => getEventType(e) === typeFilter) + : events.filter((e: Event) => getEventType(e) === typeFilter); const sortedEvents = [...filteredEvents].sort((a: Event, b: Event) => { - const timeA = new Date(a.lastTimestamp || a.firstTimestamp || 0).getTime() - const timeB = new Date(b.lastTimestamp || b.firstTimestamp || 0).getTime() - return timeB - timeA // Most recent first - }) + const timeA = new Date(a.lastTimestamp || a.firstTimestamp || 0).getTime(); + const timeB = new Date(b.lastTimestamp || b.firstTimestamp || 0).getTime(); + return timeB - timeA; // Most recent first + }); return (
@@ -273,5 +272,5 @@ export function EventsView() {
- ) + ); } diff --git a/apps/ops-dashboard/components/resources/hpas.tsx b/apps/ops-dashboard/components/resources/hpas.tsx index 9b96269..f190658 100644 --- a/apps/ops-dashboard/components/resources/hpas.tsx +++ b/apps/ops-dashboard/components/resources/hpas.tsx @@ -1,124 +1,122 @@ -'use client' +'use client'; -import { useState } from 'react' -import { Button } from '@/components/ui/button' -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' -import { Badge } from '@/components/ui/badge' +import { type AutoscalingV2HorizontalPodAutoscaler as HorizontalPodAutoscaler } from '@kubernetesjs/ops'; import { - RefreshCw, - Plus, - Trash2, - Eye, AlertCircle, CheckCircle, - TrendingUp, + Eye, + Minus, + Plus, + RefreshCw, + Trash2, TrendingDown, - Minus -} from 'lucide-react' + TrendingUp} from 'lucide-react'; +import { useState } from 'react'; + +import { Badge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; +import { usePreferredNamespace } from '@/contexts/NamespaceContext'; +import { confirmDialog } from '@/hooks/useConfirm'; import { - useListAutoscalingV2NamespacedHorizontalPodAutoscalerQuery, + useDeleteAutoscalingV2NamespacedHorizontalPodAutoscaler, useListAutoscalingV2HorizontalPodAutoscalerForAllNamespacesQuery, - useDeleteAutoscalingV2NamespacedHorizontalPodAutoscaler -} from '@/k8s' -import { usePreferredNamespace } from '@/contexts/NamespaceContext' -import { type AutoscalingV2HorizontalPodAutoscaler as HorizontalPodAutoscaler } from '@kubernetesjs/ops' - -import { confirmDialog } from '@/hooks/useConfirm' + useListAutoscalingV2NamespacedHorizontalPodAutoscalerQuery} from '@/k8s'; export function HPAsView() { - const [selectedHPA, setSelectedHPA] = useState(null) - const { namespace } = usePreferredNamespace() + const [selectedHPA, setSelectedHPA] = useState(null); + const { namespace } = usePreferredNamespace(); const query = namespace === '_all' ? useListAutoscalingV2HorizontalPodAutoscalerForAllNamespacesQuery({ query: {} }) - : useListAutoscalingV2NamespacedHorizontalPodAutoscalerQuery({ path: { namespace }, query: {} }) + : useListAutoscalingV2NamespacedHorizontalPodAutoscalerQuery({ path: { namespace }, query: {} }); - const { data, isLoading, error, refetch } = query - const deleteHPA = useDeleteAutoscalingV2NamespacedHorizontalPodAutoscaler() + const { data, isLoading, error, refetch } = query; + const deleteHPA = useDeleteAutoscalingV2NamespacedHorizontalPodAutoscaler(); - const hpas = data?.items || [] + const hpas = data?.items || []; - const handleRefresh = () => refetch() + const handleRefresh = () => refetch(); const handleDelete = async (hpa: HorizontalPodAutoscaler) => { - const name = hpa.metadata!.name! - const namespace = hpa.metadata!.namespace! + const name = hpa.metadata!.name!; + const namespace = hpa.metadata!.namespace!; const confirmed = await confirmDialog({ title: 'Delete Horizontal Pod Autoscaler', description: `Are you sure you want to delete ${name}?`, confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); if (confirmed) { try { await deleteHPA.mutateAsync({ path: { namespace, name }, query: {} - }) - refetch() + }); + refetch(); } catch (err) { - console.error('Failed to delete HPA:', err) - alert(`Failed to delete HPA: ${err instanceof Error ? err.message : 'Unknown error'}`) + console.error('Failed to delete HPA:', err); + alert(`Failed to delete HPA: ${err instanceof Error ? err.message : 'Unknown error'}`); } } - } + }; const getScaleDirection = (current: number, desired: number) => { - if (current < desired) return 'up' - if (current > desired) return 'down' - return 'stable' - } + if (current < desired) return 'up'; + if (current > desired) return 'down'; + return 'stable'; + }; const getScaleIcon = (direction: string) => { switch (direction) { - case 'up': - return - case 'down': - return - default: - return + case 'up': + return ; + case 'down': + return ; + default: + return ; } - } + }; const getStatus = (hpa: HorizontalPodAutoscaler) => { - const conditions = hpa.status?.conditions || [] - const ableToScale = conditions.find(c => c.type === 'AbleToScale') - const scalingActive = conditions.find(c => c.type === 'ScalingActive') + const conditions = hpa.status?.conditions || []; + const ableToScale = conditions.find(c => c.type === 'AbleToScale'); + const scalingActive = conditions.find(c => c.type === 'ScalingActive'); - if (ableToScale?.status === 'False') return 'Unable to Scale' - if (scalingActive?.status === 'True') return 'Active' - return 'Idle' - } + if (ableToScale?.status === 'False') return 'Unable to Scale'; + if (scalingActive?.status === 'True') return 'Active'; + return 'Idle'; + }; const getStatusBadge = (status: string) => { switch (status) { - case 'Active': - return - - {status} - - case 'Unable to Scale': - return - - {status} - - default: - return {status} + case 'Active': + return + + {status} + ; + case 'Unable to Scale': + return + + {status} + ; + default: + return {status}; } - } + }; const getMetrics = (hpa: HorizontalPodAutoscaler) => { - const metrics = hpa.spec?.metrics || [] + const metrics = hpa.spec?.metrics || []; return metrics.map(m => { if (m.type === 'Resource' && m.resource) { - return `${m.resource.name} (${m.resource.target?.averageUtilization || 'N/A'}%)` + return `${m.resource.name} (${m.resource.target?.averageUtilization || 'N/A'}%)`; } - return m.type || 'Unknown' - }).join(', ') || 'No metrics' - } + return m.type || 'Unknown'; + }).join(', ') || 'No metrics'; + }; return (
@@ -171,9 +169,9 @@ export function HPAsView() {
{hpas.filter(h => { - const current = h.status?.currentReplicas || 0 - const desired = h.status?.desiredReplicas || 0 - return current < desired + const current = h.status?.currentReplicas || 0; + const desired = h.status?.desiredReplicas || 0; + return current < desired; }).length}
@@ -235,9 +233,9 @@ export function HPAsView() { {hpas.map((hpa) => { - const current = hpa.status?.currentReplicas || 0 - const desired = hpa.status?.desiredReplicas || 0 - const direction = getScaleDirection(current, desired) + const current = hpa.status?.currentReplicas || 0; + const desired = hpa.status?.desiredReplicas || 0; + const direction = getScaleDirection(current, desired); return ( @@ -276,7 +274,7 @@ export function HPAsView() {
- ) + ); })} @@ -284,5 +282,5 @@ export function HPAsView() { - ) + ); } diff --git a/apps/ops-dashboard/components/resources/ingresses.tsx b/apps/ops-dashboard/components/resources/ingresses.tsx index 0b560ec..d715357 100644 --- a/apps/ops-dashboard/components/resources/ingresses.tsx +++ b/apps/ops-dashboard/components/resources/ingresses.tsx @@ -1,114 +1,112 @@ -'use client' +'use client'; -import { useState } from 'react' -import { Button } from '@/components/ui/button' -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' -import { Badge } from '@/components/ui/badge' +import { type NetworkingK8sIoV1Ingress as Ingress } from '@kubernetesjs/ops'; import { - RefreshCw, - Plus, - Trash2, - Eye, AlertCircle, CheckCircle, + Eye, Globe, + Link, Lock, - Link -} from 'lucide-react' + Plus, + RefreshCw, + Trash2} from 'lucide-react'; +import { useState } from 'react'; + +import { Badge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; +import { usePreferredNamespace } from '@/contexts/NamespaceContext'; +import { confirmDialog } from '@/hooks/useConfirm'; import { - useListNetworkingV1NamespacedIngressQuery, + useDeleteNetworkingV1NamespacedIngress, useListNetworkingV1IngressForAllNamespacesQuery, - useDeleteNetworkingV1NamespacedIngress -} from '@/k8s' -import { usePreferredNamespace } from '@/contexts/NamespaceContext' -import { type NetworkingK8sIoV1Ingress as Ingress } from '@kubernetesjs/ops' - -import { confirmDialog } from '@/hooks/useConfirm' + useListNetworkingV1NamespacedIngressQuery} from '@/k8s'; export function IngressesView() { - const [selectedIngress, setSelectedIngress] = useState(null) - const { namespace } = usePreferredNamespace() + const [selectedIngress, setSelectedIngress] = useState(null); + const { namespace } = usePreferredNamespace(); const query = namespace === '_all' ? useListNetworkingV1IngressForAllNamespacesQuery({ query: {} }) - : useListNetworkingV1NamespacedIngressQuery({ path: { namespace }, query: {} }) + : useListNetworkingV1NamespacedIngressQuery({ path: { namespace }, query: {} }); - const { data, isLoading, error, refetch } = query - const deleteIngress = useDeleteNetworkingV1NamespacedIngress() + const { data, isLoading, error, refetch } = query; + const deleteIngress = useDeleteNetworkingV1NamespacedIngress(); - const ingresses = data?.items || [] + const ingresses = data?.items || []; - const handleRefresh = () => refetch() + const handleRefresh = () => refetch(); const handleDelete = async (ingress: Ingress) => { - const name = ingress.metadata!.name! - const namespace = ingress.metadata!.namespace! + const name = ingress.metadata!.name!; + const namespace = ingress.metadata!.namespace!; const confirmed = await confirmDialog({ title: 'Delete Ingress', description: `Are you sure you want to delete ${name}?`, confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); if (confirmed) { try { await deleteIngress.mutateAsync({ path: { namespace, name }, query: {} - }) - refetch() + }); + refetch(); } catch (err) { - console.error('Failed to delete ingress:', err) - alert(`Failed to delete ingress: ${err instanceof Error ? err.message : 'Unknown error'}`) + console.error('Failed to delete ingress:', err); + alert(`Failed to delete ingress: ${err instanceof Error ? err.message : 'Unknown error'}`); } } - } + }; const getHosts = (ingress: Ingress): string[] => { - const rules = ingress.spec?.rules || [] - return rules.map(rule => rule.host || '*').filter((v, i, a) => a.indexOf(v) === i) - } + const rules = ingress.spec?.rules || []; + return rules.map(rule => rule.host || '*').filter((v, i, a) => a.indexOf(v) === i); + }; const getPaths = (ingress: Ingress): number => { - const rules = ingress.spec?.rules || [] + const rules = ingress.spec?.rules || []; return rules.reduce((sum, rule) => { - const paths = rule.http?.paths || [] - return sum + paths.length - }, 0) - } + const paths = rule.http?.paths || []; + return sum + paths.length; + }, 0); + }; const getIngressClass = (ingress: Ingress): string => { const className = ingress.spec?.ingressClassName as string | undefined; const annotation = ingress.metadata?.annotations?.['kubernetes.io/ingress.class'] as string | undefined; return className?.trim() || annotation?.trim() || 'default'; - } + }; const hasTLS = (ingress: Ingress): boolean => { - return (ingress.spec?.tls?.length || 0) > 0 - } + return (ingress.spec?.tls?.length || 0) > 0; + }; const getStatus = (ingress: Ingress) => { - const loadBalancers = ingress.status?.loadBalancer?.ingress || [] + const loadBalancers = ingress.status?.loadBalancer?.ingress || []; if (loadBalancers.length > 0) { - return 'Active' + return 'Active'; } - return 'Pending' - } + return 'Pending'; + }; const getStatusBadge = (status: string) => { switch (status) { - case 'Active': - return - - {status} - - default: - return {status} + case 'Active': + return + + {status} + ; + default: + return {status}; } - } + }; return (
@@ -221,8 +219,8 @@ export function IngressesView() { {ingresses.map((ingress) => { - const hosts = getHosts(ingress) - const lbIngresses = ingress.status?.loadBalancer?.ingress || [] + const hosts = getHosts(ingress); + const lbIngresses = ingress.status?.loadBalancer?.ingress || []; return ( @@ -287,7 +285,7 @@ export function IngressesView() {
- ) + ); })} @@ -295,5 +293,5 @@ export function IngressesView() { - ) + ); } diff --git a/apps/ops-dashboard/components/resources/jobs.tsx b/apps/ops-dashboard/components/resources/jobs.tsx index cc46973..1eb79b9 100644 --- a/apps/ops-dashboard/components/resources/jobs.tsx +++ b/apps/ops-dashboard/components/resources/jobs.tsx @@ -1,122 +1,121 @@ -'use client' +'use client'; -import { useState } from 'react' -import { Button } from '@/components/ui/button' -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' -import { Badge } from '@/components/ui/badge' +import { type BatchV1Job as Job } from '@kubernetesjs/ops'; import { - RefreshCw, - Plus, - Trash2, - Eye, AlertCircle, CheckCircle, Clock, + Eye, + Plus, + RefreshCw, + Trash2, XCircle -} from 'lucide-react' +} from 'lucide-react'; +import { useState } from 'react'; + +import { Badge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; +import { usePreferredNamespace } from '@/contexts/NamespaceContext'; +import { confirmDialog } from '@/hooks/useConfirm'; import { - useListBatchV1NamespacedJobQuery, + useDeleteBatchV1NamespacedJob, useListBatchV1JobForAllNamespacesQuery, - useDeleteBatchV1NamespacedJob -} from '@/k8s' -import { usePreferredNamespace } from '@/contexts/NamespaceContext' -import { type BatchV1Job as Job } from '@kubernetesjs/ops' - -import { confirmDialog } from '@/hooks/useConfirm' + useListBatchV1NamespacedJobQuery} from '@/k8s'; export function JobsView() { - const [selectedJob, setSelectedJob] = useState(null) - const { namespace } = usePreferredNamespace() + const [selectedJob, setSelectedJob] = useState(null); + const { namespace } = usePreferredNamespace(); // Use k8s hooks directly const query = namespace === '_all' ? useListBatchV1JobForAllNamespacesQuery({ query: {} }) - : useListBatchV1NamespacedJobQuery({ path: { namespace }, query: {} }) + : useListBatchV1NamespacedJobQuery({ path: { namespace }, query: {} }); - const { data, isLoading, error, refetch } = query - const deleteJob = useDeleteBatchV1NamespacedJob() + const { data, isLoading, error, refetch } = query; + const deleteJob = useDeleteBatchV1NamespacedJob(); - const jobs = data?.items || [] + const jobs = data?.items || []; - const handleRefresh = () => refetch() + const handleRefresh = () => refetch(); const handleDelete = async (job: Job) => { - const name = job.metadata!.name! - const namespace = job.metadata!.namespace! + const name = job.metadata!.name!; + const namespace = job.metadata!.namespace!; const confirmed = await confirmDialog({ title: 'Delete Job', description: `Are you sure you want to delete ${name}?`, confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); if (confirmed) { try { await deleteJob.mutateAsync({ path: { namespace, name }, query: {} - }) - refetch() + }); + refetch(); } catch (err) { - console.error('Failed to delete job:', err) - alert(`Failed to delete job: ${err instanceof Error ? err.message : 'Unknown error'}`) + console.error('Failed to delete job:', err); + alert(`Failed to delete job: ${err instanceof Error ? err.message : 'Unknown error'}`); } } - } + }; const getStatus = (job: Job) => { - const conditions = job.status?.conditions || [] - const succeeded = job.status?.succeeded || 0 - const failed = job.status?.failed || 0 - const active = job.status?.active || 0 + const conditions = job.status?.conditions || []; + const succeeded = job.status?.succeeded || 0; + const failed = job.status?.failed || 0; + const active = job.status?.active || 0; if (conditions.find(c => c.type === 'Complete' && c.status === 'True')) { - return 'Completed' + return 'Completed'; } else if (conditions.find(c => c.type === 'Failed' && c.status === 'True')) { - return 'Failed' + return 'Failed'; } else if (active > 0) { - return 'Running' + return 'Running'; } else { - return 'Pending' + return 'Pending'; } - } + }; const getStatusBadge = (status: string) => { switch (status) { - case 'Completed': - return - - {status} - - case 'Running': - return - - {status} - - case 'Failed': - return - - {status} - - default: - return {status} + case 'Completed': + return + + {status} + ; + case 'Running': + return + + {status} + ; + case 'Failed': + return + + {status} + ; + default: + return {status}; } - } + }; const getDuration = (job: Job) => { - if (!job.status?.startTime) return 'Not started' - const start = new Date(job.status.startTime).getTime() + if (!job.status?.startTime) return 'Not started'; + const start = new Date(job.status.startTime).getTime(); const end = job.status.completionTime ? new Date(job.status.completionTime).getTime() - : Date.now() - const duration = Math.floor((end - start) / 1000) + : Date.now(); + const duration = Math.floor((end - start) / 1000); - if (duration < 60) return `${duration}s` - if (duration < 3600) return `${Math.floor(duration / 60)}m ${duration % 60}s` - return `${Math.floor(duration / 3600)}h ${Math.floor((duration % 3600) / 60)}m` - } + if (duration < 60) return `${duration}s`; + if (duration < 3600) return `${Math.floor(duration / 60)}m ${duration % 60}s`; + return `${Math.floor(duration / 3600)}h ${Math.floor((duration % 3600) / 60)}m`; + }; return (
@@ -275,5 +274,5 @@ export function JobsView() {
- ) + ); } diff --git a/apps/ops-dashboard/components/resources/networkpolicies.tsx b/apps/ops-dashboard/components/resources/networkpolicies.tsx index 0f54a18..e213541 100644 --- a/apps/ops-dashboard/components/resources/networkpolicies.tsx +++ b/apps/ops-dashboard/components/resources/networkpolicies.tsx @@ -1,103 +1,101 @@ -'use client' +'use client'; -import { useState } from 'react' -import { Button } from '@/components/ui/button' -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' -import { Badge } from '@/components/ui/badge' +import { type NetworkingK8sIoV1NetworkPolicy as NetworkPolicy } from '@kubernetesjs/ops'; import { - RefreshCw, - Plus, - Trash2, - Eye, AlertCircle, - Shield, - ArrowRight, ArrowLeft, - ArrowUpDown -} from 'lucide-react' + ArrowRight, + ArrowUpDown, + Eye, + Plus, + RefreshCw, + Shield, + Trash2} from 'lucide-react'; +import { useState } from 'react'; + +import { Badge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; +import { usePreferredNamespace } from '@/contexts/NamespaceContext'; +import { confirmDialog } from '@/hooks/useConfirm'; import { + useDeleteNetworkingV1NamespacedNetworkPolicy, useListNetworkingV1NamespacedNetworkPolicyQuery, - useListNetworkingV1NetworkPolicyForAllNamespacesQuery, - useDeleteNetworkingV1NamespacedNetworkPolicy -} from '@/k8s' -import { usePreferredNamespace } from '@/contexts/NamespaceContext' -import { type NetworkingK8sIoV1NetworkPolicy as NetworkPolicy } from '@kubernetesjs/ops' - -import { confirmDialog } from '@/hooks/useConfirm' + useListNetworkingV1NetworkPolicyForAllNamespacesQuery} from '@/k8s'; export function NetworkPoliciesView() { - const [selectedPolicy, setSelectedPolicy] = useState(null) - const { namespace } = usePreferredNamespace() + const [selectedPolicy, setSelectedPolicy] = useState(null); + const { namespace } = usePreferredNamespace(); const query = namespace === '_all' ? useListNetworkingV1NetworkPolicyForAllNamespacesQuery({ query: {} }) - : useListNetworkingV1NamespacedNetworkPolicyQuery({ path: { namespace }, query: {} }) + : useListNetworkingV1NamespacedNetworkPolicyQuery({ path: { namespace }, query: {} }); - const { data, isLoading, error, refetch } = query - const deletePolicy = useDeleteNetworkingV1NamespacedNetworkPolicy() + const { data, isLoading, error, refetch } = query; + const deletePolicy = useDeleteNetworkingV1NamespacedNetworkPolicy(); - const policies = data?.items || [] + const policies = data?.items || []; - const handleRefresh = () => refetch() + const handleRefresh = () => refetch(); const handleDelete = async (policy: NetworkPolicy) => { - const name = policy.metadata!.name! - const namespace = policy.metadata!.namespace! + const name = policy.metadata!.name!; + const namespace = policy.metadata!.namespace!; const confirmed = await confirmDialog({ title: 'Delete Network Policy', description: `Are you sure you want to delete ${name}?`, confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); if (confirmed) { try { await deletePolicy.mutateAsync({ path: { namespace, name }, query: {} - }) - refetch() + }); + refetch(); } catch (err) { - console.error('Failed to delete network policy:', err) - alert(`Failed to delete network policy: ${err instanceof Error ? err.message : 'Unknown error'}`) + console.error('Failed to delete network policy:', err); + alert(`Failed to delete network policy: ${err instanceof Error ? err.message : 'Unknown error'}`); } } - } + }; const getPolicyTypes = (policy: NetworkPolicy): string[] => { - return policy.spec?.policyTypes || ['Ingress'] - } + return policy.spec?.policyTypes || ['Ingress']; + }; const getSelector = (policy: NetworkPolicy): string => { - const selector = policy.spec?.podSelector + const selector = policy.spec?.podSelector; if (!selector || !selector.matchLabels || Object.keys(selector.matchLabels).length === 0) { - return 'All pods' + return 'All pods'; } return Object.entries(selector.matchLabels) .map(([k, v]) => `${k}=${v}`) - .join(', ') - } + .join(', '); + }; const getIngressRules = (policy: NetworkPolicy): number => { - return policy.spec?.ingress?.length || 0 - } + return policy.spec?.ingress?.length || 0; + }; const getEgressRules = (policy: NetworkPolicy): number => { - return policy.spec?.egress?.length || 0 - } + return policy.spec?.egress?.length || 0; + }; const getPolicyDirection = (types: string[]) => { if (types.includes('Ingress') && types.includes('Egress')) { - return { icon: ArrowUpDown, label: 'Both' } + return { icon: ArrowUpDown, label: 'Both' }; } else if (types.includes('Ingress')) { - return { icon: ArrowLeft, label: 'Ingress' } + return { icon: ArrowLeft, label: 'Ingress' }; } else if (types.includes('Egress')) { - return { icon: ArrowRight, label: 'Egress' } + return { icon: ArrowRight, label: 'Egress' }; } - return { icon: Shield, label: 'Unknown' } - } + return { icon: Shield, label: 'Unknown' }; + }; return (
@@ -210,9 +208,9 @@ export function NetworkPoliciesView() { {policies.map((policy) => { - const types = getPolicyTypes(policy) - const direction = getPolicyDirection(types) - const DirectionIcon = direction.icon + const types = getPolicyTypes(policy); + const direction = getPolicyDirection(types); + const DirectionIcon = direction.icon; return ( @@ -260,7 +258,7 @@ export function NetworkPoliciesView() {
- ) + ); })} @@ -268,5 +266,5 @@ export function NetworkPoliciesView() { - ) + ); } diff --git a/apps/ops-dashboard/components/resources/pdbs.tsx b/apps/ops-dashboard/components/resources/pdbs.tsx index b4ae0a2..44fa210 100644 --- a/apps/ops-dashboard/components/resources/pdbs.tsx +++ b/apps/ops-dashboard/components/resources/pdbs.tsx @@ -1,118 +1,116 @@ -'use client' +'use client'; -import { useState } from 'react' -import { Button } from '@/components/ui/button' -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' -import { Badge } from '@/components/ui/badge' +import { type PolicyV1PodDisruptionBudget as PodDisruptionBudget } from '@kubernetesjs/ops'; import { - RefreshCw, - Plus, - Trash2, - Eye, AlertCircle, CheckCircle, + Eye, + Plus, + RefreshCw, Shield, - ShieldOff -} from 'lucide-react' + ShieldOff, + Trash2} from 'lucide-react'; +import { useState } from 'react'; + +import { Badge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; +import { usePreferredNamespace } from '@/contexts/NamespaceContext'; +import { confirmDialog } from '@/hooks/useConfirm'; import { + useDeletePolicyV1NamespacedPodDisruptionBudget, useListPolicyV1NamespacedPodDisruptionBudgetQuery, - useListPolicyV1PodDisruptionBudgetForAllNamespacesQuery, - useDeletePolicyV1NamespacedPodDisruptionBudget -} from '@/k8s' -import { usePreferredNamespace } from '@/contexts/NamespaceContext' -import { type PolicyV1PodDisruptionBudget as PodDisruptionBudget } from '@kubernetesjs/ops' - -import { confirmDialog } from '@/hooks/useConfirm' + useListPolicyV1PodDisruptionBudgetForAllNamespacesQuery} from '@/k8s'; export function PDBsView() { - const [selectedPDB, setSelectedPDB] = useState(null) - const { namespace } = usePreferredNamespace() + const [selectedPDB, setSelectedPDB] = useState(null); + const { namespace } = usePreferredNamespace(); const query = namespace === '_all' ? useListPolicyV1PodDisruptionBudgetForAllNamespacesQuery({ query: {} }) - : useListPolicyV1NamespacedPodDisruptionBudgetQuery({ path: { namespace }, query: {} }) + : useListPolicyV1NamespacedPodDisruptionBudgetQuery({ path: { namespace }, query: {} }); - const { data, isLoading, error, refetch } = query - const deletePDB = useDeletePolicyV1NamespacedPodDisruptionBudget() + const { data, isLoading, error, refetch } = query; + const deletePDB = useDeletePolicyV1NamespacedPodDisruptionBudget(); - const pdbs = data?.items || [] + const pdbs = data?.items || []; - const handleRefresh = () => refetch() + const handleRefresh = () => refetch(); const handleDelete = async (pdb: PodDisruptionBudget) => { - const name = pdb.metadata!.name! - const namespace = pdb.metadata!.namespace! + const name = pdb.metadata!.name!; + const namespace = pdb.metadata!.namespace!; const confirmed = await confirmDialog({ title: 'Delete Pod Disruption Budget', description: `Are you sure you want to delete ${name}?`, confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); if (confirmed) { try { await deletePDB.mutateAsync({ path: { namespace, name }, query: {} - }) - refetch() + }); + refetch(); } catch (err) { - console.error('Failed to delete PDB:', err) - alert(`Failed to delete PDB: ${err instanceof Error ? err.message : 'Unknown error'}`) + console.error('Failed to delete PDB:', err); + alert(`Failed to delete PDB: ${err instanceof Error ? err.message : 'Unknown error'}`); } } - } + }; const getStatus = (pdb: PodDisruptionBudget) => { - const currentHealthy = pdb.status?.currentHealthy || 0 - const desiredHealthy = pdb.status?.desiredHealthy || 0 - const disruptionsAllowed = pdb.status?.disruptionsAllowed || 0 + const currentHealthy = pdb.status?.currentHealthy || 0; + const desiredHealthy = pdb.status?.desiredHealthy || 0; + const disruptionsAllowed = pdb.status?.disruptionsAllowed || 0; if (currentHealthy >= desiredHealthy && disruptionsAllowed > 0) { - return 'Ready' + return 'Ready'; } else if (currentHealthy >= desiredHealthy) { - return 'Protected' + return 'Protected'; } else { - return 'Not Ready' + return 'Not Ready'; } - } + }; const getStatusBadge = (status: string) => { switch (status) { - case 'Ready': - return - - {status} - - case 'Protected': - return - - {status} - - case 'Not Ready': - return - - {status} - - default: - return {status} + case 'Ready': + return + + {status} + ; + case 'Protected': + return + + {status} + ; + case 'Not Ready': + return + + {status} + ; + default: + return {status}; } - } + }; const getSelector = (pdb: PodDisruptionBudget) => { - const selector = pdb.spec?.selector - if (!selector) return 'No selector' + const selector = pdb.spec?.selector; + if (!selector) return 'No selector'; if (selector.matchLabels) { return Object.entries(selector.matchLabels) .map(([k, v]) => `${k}=${v}`) - .join(', ') + .join(', '); } - return 'Complex selector' - } + return 'Complex selector'; + }; return (
@@ -274,5 +272,5 @@ export function PDBsView() {
- ) + ); } diff --git a/apps/ops-dashboard/components/resources/pods.tsx b/apps/ops-dashboard/components/resources/pods.tsx index 6968254..50de888 100644 --- a/apps/ops-dashboard/components/resources/pods.tsx +++ b/apps/ops-dashboard/components/resources/pods.tsx @@ -1,26 +1,26 @@ -'use client' +'use client'; -import { useState } from 'react' -import { Button } from '@/components/ui/button' -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' -import { Badge } from '@/components/ui/badge' +import { type Pod as K8sPod } from '@kubernetesjs/ops'; import { - RefreshCw, - Plus, - Trash2, - Eye, - Terminal, AlertCircle, CheckCircle, Clock, + Eye, + Plus, + RefreshCw, + Terminal, + Trash2, XCircle -} from 'lucide-react' -import { type Pod as K8sPod } from '@kubernetesjs/ops' -import { usePods, useDeletePod, usePodLogs } from '@/hooks' +} from 'lucide-react'; +import { useState } from 'react'; -import { confirmDialog } from '@/hooks/useConfirm' -import { usePreferredNamespace } from '@/contexts/NamespaceContext' +import { Badge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; +import { usePreferredNamespace } from '@/contexts/NamespaceContext'; +import { useDeletePod,usePods } from '@/hooks'; +import { confirmDialog } from '@/hooks/useConfirm'; interface Pod { name: string @@ -34,29 +34,29 @@ interface Pod { } export function PodsView({ namespace:defaultNamespace }: { namespace?: string }) { - const [selectedPod, setSelectedPod] = useState(null) + const [selectedPod, setSelectedPod] = useState(null); // Use TanStack Query hooks - const { namespace } = usePreferredNamespace() - const { data, isLoading, error, refetch } = usePods(defaultNamespace) - const deletePodMutation = useDeletePod() + const { namespace } = usePreferredNamespace(); + const { data, isLoading, error, refetch } = usePods(defaultNamespace); + const deletePodMutation = useDeletePod(); // Helper function to determine pod status function determinePodStatus(pod: K8sPod): Pod['status'] { - const phase = pod.status?.phase - if (phase === 'Running') return 'Running' - if (phase === 'Pending') return 'Pending' - if (phase === 'Failed') return 'Failed' - if (phase === 'Succeeded') return 'Succeeded' - return 'Unknown' + const phase = pod.status?.phase; + if (phase === 'Running') return 'Running'; + if (phase === 'Pending') return 'Pending'; + if (phase === 'Failed') return 'Failed'; + if (phase === 'Succeeded') return 'Succeeded'; + return 'Unknown'; } // Format pods from query data const pods: Pod[] = data?.items?.map(item => { - const containerStatuses = item.status?.containerStatuses || [] - const readyContainers = containerStatuses.filter(cs => cs.ready).length - const totalContainers = containerStatuses.length - const totalRestarts = containerStatuses.reduce((sum, cs) => sum + (cs.restartCount || 0), 0) + const containerStatuses = item.status?.containerStatuses || []; + const readyContainers = containerStatuses.filter(cs => cs.ready).length; + const totalContainers = containerStatuses.length; + const totalRestarts = containerStatuses.reduce((sum, cs) => sum + (cs.restartCount || 0), 0); return { name: item.metadata!.name!, @@ -67,12 +67,12 @@ export function PodsView({ namespace:defaultNamespace }: { namespace?: string }) age: getAge(item.metadata!.creationTimestamp!), nodeName: item.spec?.nodeName || 'unassigned', k8sData: item - } - }) || [] + }; + }) || []; const handleRefresh = () => { - refetch() - } + refetch(); + }; const handleDelete = async (pod: Pod) => { const confirmed = await confirmDialog({ @@ -80,65 +80,65 @@ export function PodsView({ namespace:defaultNamespace }: { namespace?: string }) description: `Are you sure you want to delete pod ${pod.name}?`, confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); if (confirmed) { try { await deletePodMutation.mutateAsync({ name: pod.name, namespace: pod.namespace - }) + }); } catch (err) { - console.error('Failed to delete pod:', err) - alert(`Failed to delete pod: ${err instanceof Error ? err.message : 'Unknown error'}`) + console.error('Failed to delete pod:', err); + alert(`Failed to delete pod: ${err instanceof Error ? err.message : 'Unknown error'}`); } } - } + }; const handleViewLogs = (pod: Pod) => { // This would open a logs viewer - for now just alert - alert(`View logs functionality for ${pod.name} coming soon!\n\nUse kubectl for now:\nkubectl logs ${pod.name} -n ${pod.namespace}`) - } + alert(`View logs functionality for ${pod.name} coming soon!\n\nUse kubectl for now:\nkubectl logs ${pod.name} -n ${pod.namespace}`); + }; const getStatusBadge = (status: Pod['status']) => { switch (status) { - case 'Running': - return - - {status} - - case 'Pending': - return - - {status} - - case 'Failed': - return - - {status} - - case 'Succeeded': - return - - {status} - - default: - return {status} + case 'Running': + return + + {status} + ; + case 'Pending': + return + + {status} + ; + case 'Failed': + return + + {status} + ; + case 'Succeeded': + return + + {status} + ; + default: + return {status}; } - } + }; function getAge(timestamp: string): string { - const created = new Date(timestamp) - const now = new Date() - const diff = now.getTime() - created.getTime() + const created = new Date(timestamp); + const now = new Date(); + const diff = now.getTime() - created.getTime(); - const days = Math.floor(diff / (1000 * 60 * 60 * 24)) - const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)) - const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)) + const days = Math.floor(diff / (1000 * 60 * 60 * 24)); + const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); + const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)); - if (days > 0) return `${days}d${hours}h` - if (hours > 0) return `${hours}h${minutes}m` - return `${minutes}m` + if (days > 0) return `${days}d${hours}h`; + if (hours > 0) return `${hours}h${minutes}m`; + return `${minutes}m`; } return ( @@ -308,5 +308,5 @@ export function PodsView({ namespace:defaultNamespace }: { namespace?: string }) - ) + ); } diff --git a/apps/ops-dashboard/components/resources/priorityclasses.tsx b/apps/ops-dashboard/components/resources/priorityclasses.tsx index 2083932..e08d3e0 100644 --- a/apps/ops-dashboard/components/resources/priorityclasses.tsx +++ b/apps/ops-dashboard/components/resources/priorityclasses.tsx @@ -1,83 +1,81 @@ -'use client' +'use client'; -import { useState } from 'react' -import { Button } from '@/components/ui/button' -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' -import { Badge } from '@/components/ui/badge' +import { type SchedulingK8sIoV1PriorityClass as PriorityClass } from '@kubernetesjs/ops'; import { - RefreshCw, - Plus, - Trash2, - Eye, AlertCircle, + Eye, + Plus, + RefreshCw, Star, - StarOff -} from 'lucide-react' -import { - useListSchedulingV1PriorityClassQuery, - useDeleteSchedulingV1PriorityClass -} from '@/k8s' -import { type SchedulingK8sIoV1PriorityClass as PriorityClass } from '@kubernetesjs/ops' + StarOff, + Trash2} from 'lucide-react'; +import { useState } from 'react'; -import { confirmDialog } from '@/hooks/useConfirm' +import { Badge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; +import { confirmDialog } from '@/hooks/useConfirm'; +import { + useDeleteSchedulingV1PriorityClass, + useListSchedulingV1PriorityClassQuery} from '@/k8s'; export function PriorityClassesView() { - const [selectedPriorityClass, setSelectedPriorityClass] = useState(null) + const [selectedPriorityClass, setSelectedPriorityClass] = useState(null); - const { data, isLoading, error, refetch } = useListSchedulingV1PriorityClassQuery({ query: {} }) - const deletePriorityClass = useDeleteSchedulingV1PriorityClass() + const { data, isLoading, error, refetch } = useListSchedulingV1PriorityClassQuery({ query: {} }); + const deletePriorityClass = useDeleteSchedulingV1PriorityClass(); - const priorityClasses = data?.items || [] + const priorityClasses = data?.items || []; - const handleRefresh = () => refetch() + const handleRefresh = () => refetch(); const handleDelete = async (pc: PriorityClass) => { - const name = pc.metadata!.name! + const name = pc.metadata!.name!; const confirmed = await confirmDialog({ title: 'Delete Priority Class', description: `Are you sure you want to delete ${name}?`, confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); if (confirmed) { try { await deletePriorityClass.mutateAsync({ path: { name }, query: {} - }) - refetch() + }); + refetch(); } catch (err) { - console.error('Failed to delete priority class:', err) - alert(`Failed to delete priority class: ${err instanceof Error ? err.message : 'Unknown error'}`) + console.error('Failed to delete priority class:', err); + alert(`Failed to delete priority class: ${err instanceof Error ? err.message : 'Unknown error'}`); } } - } + }; const getPriorityBadge = (value: number) => { if (value >= 1000000000) { return System Critical - + ; } else if (value >= 900000000) { return Cluster Critical - + ; } else if (value > 0) { return Priority {value} - + ; } else { return Default - + ; } - } + }; return (
@@ -228,5 +226,5 @@ export function PriorityClassesView() {
- ) + ); } diff --git a/apps/ops-dashboard/components/resources/pvcs.tsx b/apps/ops-dashboard/components/resources/pvcs.tsx index 6a22c89..cf1e13b 100644 --- a/apps/ops-dashboard/components/resources/pvcs.tsx +++ b/apps/ops-dashboard/components/resources/pvcs.tsx @@ -1,128 +1,126 @@ -'use client' +'use client'; -import { useState } from 'react' -import { Button } from '@/components/ui/button' -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' -import { Badge } from '@/components/ui/badge' +import type { PersistentVolumeClaim } from '@kubernetesjs/ops'; import { - RefreshCw, - Plus, - Trash2, - Eye, AlertCircle, CheckCircle, + Database, + Eye, HardDrive, - Database -} from 'lucide-react' + Plus, + RefreshCw, + Trash2} from 'lucide-react'; +import { useState } from 'react'; + +import { Badge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; +import { usePreferredNamespace } from '@/contexts/NamespaceContext'; +import { confirmDialog } from '@/hooks/useConfirm'; import { + useDeleteCoreV1NamespacedPersistentVolumeClaim, useListCoreV1NamespacedPersistentVolumeClaimQuery, - useListCoreV1PersistentVolumeClaimForAllNamespacesQuery, - useDeleteCoreV1NamespacedPersistentVolumeClaim -} from '@/k8s' -import { usePreferredNamespace } from '@/contexts/NamespaceContext' -import type { PersistentVolumeClaim } from '@kubernetesjs/ops' - -import { confirmDialog } from '@/hooks/useConfirm' + useListCoreV1PersistentVolumeClaimForAllNamespacesQuery} from '@/k8s'; export function PVCsView() { - const [selectedPVC, setSelectedPVC] = useState(null) - const { namespace } = usePreferredNamespace() + const [selectedPVC, setSelectedPVC] = useState(null); + const { namespace } = usePreferredNamespace(); const query = namespace === '_all' ? useListCoreV1PersistentVolumeClaimForAllNamespacesQuery({ query: {} }) - : useListCoreV1NamespacedPersistentVolumeClaimQuery({ path: { namespace }, query: {} }) + : useListCoreV1NamespacedPersistentVolumeClaimQuery({ path: { namespace }, query: {} }); - const { data, isLoading, error, refetch } = query - const deletePVC = useDeleteCoreV1NamespacedPersistentVolumeClaim() + const { data, isLoading, error, refetch } = query; + const deletePVC = useDeleteCoreV1NamespacedPersistentVolumeClaim(); - const pvcs = data?.items || [] + const pvcs = data?.items || []; - const handleRefresh = () => refetch() + const handleRefresh = () => refetch(); const coerceString = (value: unknown): string | undefined => { if (typeof value === 'string') { - const trimmed = value.trim() - return trimmed.length > 0 ? trimmed : undefined + const trimmed = value.trim(); + return trimmed.length > 0 ? trimmed : undefined; } - return undefined - } + return undefined; + }; const handleDelete = async (pvc: PersistentVolumeClaim) => { - const name = pvc.metadata!.name! - const namespace = pvc.metadata!.namespace! + const name = pvc.metadata!.name!; + const namespace = pvc.metadata!.namespace!; const confirmed = await confirmDialog({ title: 'Delete Persistent Volume Claim', description: `Are you sure you want to delete ${name}? This may cause data loss.`, confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); if (confirmed) { try { await deletePVC.mutateAsync({ path: { namespace, name }, query: {} - }) - refetch() + }); + refetch(); } catch (err) { - console.error('Failed to delete PVC:', err) - alert(`Failed to delete PVC: ${err instanceof Error ? err.message : 'Unknown error'}`) + console.error('Failed to delete PVC:', err); + alert(`Failed to delete PVC: ${err instanceof Error ? err.message : 'Unknown error'}`); } } - } + }; const getPhase = (pvc: PersistentVolumeClaim): string => { - return pvc.status?.phase || 'Unknown' - } + return pvc.status?.phase || 'Unknown'; + }; const getStatusBadge = (phase: string) => { switch (phase) { - case 'Bound': - return - - {phase} - - case 'Pending': - return - - {phase} - - case 'Lost': - return - - {phase} - - default: - return {phase} + case 'Bound': + return + + {phase} + ; + case 'Pending': + return + + {phase} + ; + case 'Lost': + return + + {phase} + ; + default: + return {phase}; } - } + }; const getAccessModes = (pvc: PersistentVolumeClaim): string => { - const modes = pvc.spec?.accessModes || [] + const modes = pvc.spec?.accessModes || []; const modeMap: Record = { - 'ReadWriteOnce': 'RWO', - 'ReadOnlyMany': 'ROX', - 'ReadWriteMany': 'RWX', - 'ReadWriteOncePod': 'RWOP' - } - return modes.map(m => modeMap[m] || m).join(', ') || 'None' - } + ReadWriteOnce: 'RWO', + ReadOnlyMany: 'ROX', + ReadWriteMany: 'RWX', + ReadWriteOncePod: 'RWOP' + }; + return modes.map(m => modeMap[m] || m).join(', ') || 'None'; + }; const getStorageSize = (pvc: PersistentVolumeClaim): string => { - const storage = coerceString(pvc.spec?.resources?.requests?.storage) - const capacity = coerceString(pvc.status?.capacity?.storage) - return capacity || storage || 'Unknown' - } + const storage = coerceString(pvc.spec?.resources?.requests?.storage); + const capacity = coerceString(pvc.status?.capacity?.storage); + return capacity || storage || 'Unknown'; + }; const getStorageClass = (pvc: PersistentVolumeClaim): string => { - return coerceString(pvc.spec?.storageClassName) || 'default' - } + return coerceString(pvc.spec?.storageClassName) || 'default'; + }; const getVolumeName = (pvc: PersistentVolumeClaim): string => { - return coerceString(pvc.spec?.volumeName) || 'Not bound' - } + return coerceString(pvc.spec?.volumeName) || 'Not bound'; + }; return (
@@ -184,16 +182,16 @@ export function PVCsView() {
{pvcs.reduce((sum, pvc) => { - const size = getStorageSize(pvc) - const match = size.match(/(\d+)([GMK]i)?/) + const size = getStorageSize(pvc); + const match = size.match(/(\d+)([GMK]i)?/); if (match) { - const value = parseInt(match[1]) - const unit = match[2] || 'Gi' - if (unit === 'Gi') return sum + value - if (unit === 'Mi') return sum + value / 1024 - if (unit === 'Ki') return sum + value / (1024 * 1024) + const value = parseInt(match[1]); + const unit = match[2] || 'Gi'; + if (unit === 'Gi') return sum + value; + if (unit === 'Mi') return sum + value / 1024; + if (unit === 'Ki') return sum + value / (1024 * 1024); } - return sum + return sum; }, 0).toFixed(1)} GB
diff --git a/apps/ops-dashboard/components/resources/pvs.tsx b/apps/ops-dashboard/components/resources/pvs.tsx index c5a20ec..995e129 100644 --- a/apps/ops-dashboard/components/resources/pvs.tsx +++ b/apps/ops-dashboard/components/resources/pvs.tsx @@ -1,136 +1,134 @@ -'use client' +'use client'; -import { useState } from 'react' -import { Button } from '@/components/ui/button' -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' -import { Badge } from '@/components/ui/badge' +import type { PersistentVolume } from '@kubernetesjs/ops'; import { - RefreshCw, - Plus, - Trash2, - Eye, AlertCircle, CheckCircle, + Eye, HardDrive, Link, - Link2Off -} from 'lucide-react' -import { - useListCoreV1PersistentVolumeQuery, - useDeleteCoreV1PersistentVolume -} from '@/k8s' -import type { PersistentVolume } from '@kubernetesjs/ops' + Link2Off, + Plus, + RefreshCw, + Trash2} from 'lucide-react'; +import { useState } from 'react'; -import { confirmDialog } from '@/hooks/useConfirm' +import { Badge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; +import { confirmDialog } from '@/hooks/useConfirm'; +import { + useDeleteCoreV1PersistentVolume, + useListCoreV1PersistentVolumeQuery} from '@/k8s'; export function PVsView() { - const [selectedPV, setSelectedPV] = useState(null) + const [selectedPV, setSelectedPV] = useState(null); - const { data, isLoading, error, refetch } = useListCoreV1PersistentVolumeQuery({ query: {} }) - const deletePV = useDeleteCoreV1PersistentVolume() + const { data, isLoading, error, refetch } = useListCoreV1PersistentVolumeQuery({ query: {} }); + const deletePV = useDeleteCoreV1PersistentVolume(); - const pvs = data?.items || [] + const pvs = data?.items || []; - const handleRefresh = () => refetch() + const handleRefresh = () => refetch(); const coerceString = (value: unknown): string | undefined => { if (typeof value === 'string') { - const trimmed = value.trim() - return trimmed.length > 0 ? trimmed : undefined + const trimmed = value.trim(); + return trimmed.length > 0 ? trimmed : undefined; } - return undefined - } + return undefined; + }; const handleDelete = async (pv: PersistentVolume) => { - const name = pv.metadata!.name! + const name = pv.metadata!.name!; const confirmed = await confirmDialog({ title: 'Delete Persistent Volume', description: `Are you sure you want to delete ${name}? This may cause data loss.`, confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); if (confirmed) { try { await deletePV.mutateAsync({ path: { name }, query: {} - }) - refetch() + }); + refetch(); } catch (err) { - console.error('Failed to delete PV:', err) - alert(`Failed to delete PV: ${err instanceof Error ? err.message : 'Unknown error'}`) + console.error('Failed to delete PV:', err); + alert(`Failed to delete PV: ${err instanceof Error ? err.message : 'Unknown error'}`); } } - } + }; const getPhase = (pv: PersistentVolume): string => { - return pv.status?.phase || 'Unknown' - } + return pv.status?.phase || 'Unknown'; + }; const getStatusBadge = (phase: string) => { switch (phase) { - case 'Available': - return - - {phase} - - case 'Bound': - return - - {phase} - - case 'Released': - return - - {phase} - - case 'Failed': - return - - {phase} - - default: - return {phase} + case 'Available': + return + + {phase} + ; + case 'Bound': + return + + {phase} + ; + case 'Released': + return + + {phase} + ; + case 'Failed': + return + + {phase} + ; + default: + return {phase}; } - } + }; const getAccessModes = (pv: PersistentVolume): string => { - const modes = pv.spec?.accessModes || [] + const modes = pv.spec?.accessModes || []; const modeMap: Record = { - 'ReadWriteOnce': 'RWO', - 'ReadOnlyMany': 'ROX', - 'ReadWriteMany': 'RWX', - 'ReadWriteOncePod': 'RWOP' - } - return modes.map(m => modeMap[m] || m).join(', ') || 'None' - } + ReadWriteOnce: 'RWO', + ReadOnlyMany: 'ROX', + ReadWriteMany: 'RWX', + ReadWriteOncePod: 'RWOP' + }; + return modes.map(m => modeMap[m] || m).join(', ') || 'None'; + }; const getCapacity = (pv: PersistentVolume): string => { - return coerceString(pv.spec?.capacity?.storage) || 'Unknown' - } + return coerceString(pv.spec?.capacity?.storage) || 'Unknown'; + }; const getStorageClass = (pv: PersistentVolume): string => { - return coerceString(pv.spec?.storageClassName) || 'None' - } + return coerceString(pv.spec?.storageClassName) || 'None'; + }; const getReclaimPolicy = (pv: PersistentVolume): string => { - return coerceString(pv.spec?.persistentVolumeReclaimPolicy) || 'Retain' - } + return coerceString(pv.spec?.persistentVolumeReclaimPolicy) || 'Retain'; + }; const getClaimRef = (pv: PersistentVolume): string => { - const ref = pv.spec?.claimRef - if (!ref) return 'Unbound' - const namespace = coerceString(ref.namespace) || 'unknown' - const name = coerceString(ref.name) || 'unknown' - return `${namespace}/${name}` - } + const ref = pv.spec?.claimRef; + if (!ref) return 'Unbound'; + const namespace = coerceString(ref.namespace) || 'unknown'; + const name = coerceString(ref.name) || 'unknown'; + return `${namespace}/${name}`; + }; const getVolumeMode = (pv: PersistentVolume): string => { - return coerceString(pv.spec?.volumeMode) || 'Filesystem' - } + return coerceString(pv.spec?.volumeMode) || 'Filesystem'; + }; return (
@@ -192,17 +190,17 @@ export function PVsView() {
{pvs.reduce((sum, pv) => { - const size = getCapacity(pv) - const match = size.match(/(\d+)([GMK]i)?/) + const size = getCapacity(pv); + const match = size.match(/(\d+)([GMK]i)?/); if (match) { - const value = parseInt(match[1]) - const unit = match[2] || 'Gi' - if (unit === 'Gi') return sum + value - if (unit === 'Mi') return sum + value / 1024 - if (unit === 'Ki') return sum + value / (1024 * 1024) - if (unit === 'Ti') return sum + value * 1024 + const value = parseInt(match[1]); + const unit = match[2] || 'Gi'; + if (unit === 'Gi') return sum + value; + if (unit === 'Mi') return sum + value / 1024; + if (unit === 'Ki') return sum + value / (1024 * 1024); + if (unit === 'Ti') return sum + value * 1024; } - return sum + return sum; }, 0).toFixed(1)} GB
diff --git a/apps/ops-dashboard/components/resources/replicasets.tsx b/apps/ops-dashboard/components/resources/replicasets.tsx index bb8bf41..9a5a747 100644 --- a/apps/ops-dashboard/components/resources/replicasets.tsx +++ b/apps/ops-dashboard/components/resources/replicasets.tsx @@ -1,25 +1,22 @@ -'use client' +'use client'; -import { useState } from 'react' -import { Button } from '@/components/ui/button' -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' -import { Badge } from '@/components/ui/badge' +import { type AppsV1ReplicaSet as K8sReplicaSet } from '@kubernetesjs/ops'; import { - RefreshCw, + AlertCircle, + CheckCircle, + Eye, Plus, - Trash2, - Edit, + RefreshCw, Scale, - Eye, - AlertCircle, - CheckCircle, - Copy -} from 'lucide-react' -import { type AppsV1ReplicaSet as K8sReplicaSet } from '@kubernetesjs/ops' -import { useReplicaSets, useDeleteReplicaSet, useScaleReplicaSet } from '@/hooks/useReplicaSets' + Trash2} from 'lucide-react'; +import { useState } from 'react'; -import { confirmDialog } from '@/hooks/useConfirm' +import { Badge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; +import { confirmDialog } from '@/hooks/useConfirm'; +import { useDeleteReplicaSet, useReplicaSets, useScaleReplicaSet } from '@/hooks/useReplicaSets'; interface ReplicaSet { name: string @@ -35,35 +32,35 @@ interface ReplicaSet { } export function ReplicaSetsView() { - const [selectedReplicaSet, setSelectedReplicaSet] = useState(null) + const [selectedReplicaSet, setSelectedReplicaSet] = useState(null); // Use TanStack Query hooks - const { data, isLoading, error, refetch } = useReplicaSets() - const deleteReplicaSetMutation = useDeleteReplicaSet() - const scaleReplicaSetMutation = useScaleReplicaSet() + const { data, isLoading, error, refetch } = useReplicaSets(); + const deleteReplicaSetMutation = useDeleteReplicaSet(); + const scaleReplicaSetMutation = useScaleReplicaSet(); // Helper function to determine replica set status function determineReplicaSetStatus(rs: K8sReplicaSet): ReplicaSet['status'] { - const status = rs.status - if (!status) return 'NotReady' + const status = rs.status; + if (!status) return 'NotReady'; - const replicas = rs.spec?.replicas || 0 - const readyReplicas = status.readyReplicas || 0 + const replicas = rs.spec?.replicas || 0; + const readyReplicas = status.readyReplicas || 0; if (readyReplicas === replicas && replicas > 0) { - return 'Ready' + return 'Ready'; } else if (readyReplicas !== replicas) { - return 'Scaling' + return 'Scaling'; } else { - return 'NotReady' + return 'NotReady'; } } // Helper to extract deployment name from owner references function getDeploymentName(rs: K8sReplicaSet): string | undefined { - const ownerRefs = rs.metadata?.ownerReferences || [] - const deploymentRef = ownerRefs.find(ref => ref.kind === 'Deployment') - return deploymentRef?.name + const ownerRefs = rs.metadata?.ownerReferences || []; + const deploymentRef = ownerRefs.find(ref => ref.kind === 'Deployment'); + return deploymentRef?.name; } // Format replica sets from query data @@ -79,28 +76,28 @@ export function ReplicaSetsView() { status: determineReplicaSetStatus(item), deployment: getDeploymentName(item), k8sData: item - } - }) || [] + }; + }) || []; const handleRefresh = () => { - refetch() - } + refetch(); + }; const handleScale = async (replicaSet: ReplicaSet) => { - const newReplicas = prompt(`Scale ${replicaSet.name} to how many replicas?`, replicaSet.replicas.toString()) + const newReplicas = prompt(`Scale ${replicaSet.name} to how many replicas?`, replicaSet.replicas.toString()); if (newReplicas && !isNaN(Number(newReplicas))) { try { await scaleReplicaSetMutation.mutateAsync({ name: replicaSet.name, replicas: Number(newReplicas), namespace: replicaSet.namespace - }) + }); } catch (err) { - console.error('Failed to scale replicaset:', err) - alert(`Failed to scale replicaset: ${err instanceof Error ? err.message : 'Unknown error'}`) + console.error('Failed to scale replicaset:', err); + alert(`Failed to scale replicaset: ${err instanceof Error ? err.message : 'Unknown error'}`); } } - } + }; const handleDelete = async (replicaSet: ReplicaSet) => { const confirmed = await confirmDialog({ @@ -108,42 +105,42 @@ export function ReplicaSetsView() { description: `Are you sure you want to delete ${replicaSet.name}?`, confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); if (confirmed) { try { await deleteReplicaSetMutation.mutateAsync({ name: replicaSet.name, namespace: replicaSet.namespace - }) + }); } catch (err) { - console.error('Failed to delete replicaset:', err) - alert(`Failed to delete replicaset: ${err instanceof Error ? err.message : 'Unknown error'}`) + console.error('Failed to delete replicaset:', err); + alert(`Failed to delete replicaset: ${err instanceof Error ? err.message : 'Unknown error'}`); } } - } + }; const getStatusBadge = (status: ReplicaSet['status']) => { switch (status) { - case 'Ready': - return - - {status} - - case 'Scaling': - return - - {status} - - case 'NotReady': - return - - {status} - - default: - return {status} + case 'Ready': + return + + {status} + ; + case 'Scaling': + return + + {status} + ; + case 'NotReady': + return + + {status} + ; + default: + return {status}; } - } + }; return (
@@ -312,5 +309,5 @@ export function ReplicaSetsView() {
- ) + ); } diff --git a/apps/ops-dashboard/components/resources/resourcequotas.tsx b/apps/ops-dashboard/components/resources/resourcequotas.tsx index 477cb51..e3de3a4 100644 --- a/apps/ops-dashboard/components/resources/resourcequotas.tsx +++ b/apps/ops-dashboard/components/resources/resourcequotas.tsx @@ -1,94 +1,92 @@ -'use client' +'use client'; -import { useState } from 'react' -import { Button } from '@/components/ui/button' -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' -import { Badge } from '@/components/ui/badge' +import type { ResourceQuota } from '@kubernetesjs/ops'; import { - RefreshCw, - Plus, - Trash2, - Eye, AlertCircle, + AlertTriangle, CheckCircle, - AlertTriangle -} from 'lucide-react' + Eye, + Plus, + RefreshCw, + Trash2} from 'lucide-react'; +import { useState } from 'react'; + +import { Badge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; +import { usePreferredNamespace } from '@/contexts/NamespaceContext'; +import { confirmDialog } from '@/hooks/useConfirm'; import { + useDeleteCoreV1NamespacedResourceQuota, useListCoreV1NamespacedResourceQuotaQuery, - useListCoreV1ResourceQuotaForAllNamespacesQuery, - useDeleteCoreV1NamespacedResourceQuota -} from '@/k8s' -import { usePreferredNamespace } from '@/contexts/NamespaceContext' -import type { ResourceQuota } from '@kubernetesjs/ops' - -import { confirmDialog } from '@/hooks/useConfirm' + useListCoreV1ResourceQuotaForAllNamespacesQuery} from '@/k8s'; export function ResourceQuotasView() { - const [selectedQuota, setSelectedQuota] = useState(null) - const { namespace } = usePreferredNamespace() + const [selectedQuota, setSelectedQuota] = useState(null); + const { namespace } = usePreferredNamespace(); const query = namespace === '_all' ? useListCoreV1ResourceQuotaForAllNamespacesQuery({ query: {} }) - : useListCoreV1NamespacedResourceQuotaQuery({ path: { namespace }, query: {} }) + : useListCoreV1NamespacedResourceQuotaQuery({ path: { namespace }, query: {} }); - const { data, isLoading, error, refetch } = query - const deleteQuota = useDeleteCoreV1NamespacedResourceQuota() + const { data, isLoading, error, refetch } = query; + const deleteQuota = useDeleteCoreV1NamespacedResourceQuota(); - const quotas = data?.items || [] + const quotas = data?.items || []; - const handleRefresh = () => refetch() + const handleRefresh = () => refetch(); const handleDelete = async (quota: ResourceQuota) => { - const name = quota.metadata!.name! - const namespace = quota.metadata!.namespace! + const name = quota.metadata!.name!; + const namespace = quota.metadata!.namespace!; const confirmed = await confirmDialog({ title: 'Delete Resource Quota', description: `Are you sure you want to delete ${name}?`, confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); if (confirmed) { try { await deleteQuota.mutateAsync({ path: { namespace, name }, query: {} - }) - refetch() + }); + refetch(); } catch (err) { - console.error('Failed to delete resource quota:', err) - alert(`Failed to delete resource quota: ${err instanceof Error ? err.message : 'Unknown error'}`) + console.error('Failed to delete resource quota:', err); + alert(`Failed to delete resource quota: ${err instanceof Error ? err.message : 'Unknown error'}`); } } - } + }; const getUsagePercentage = (used: string, hard: string) => { - const usedNum = parseInt(used) || 0 - const hardNum = parseInt(hard) || 0 - if (hardNum === 0) return 0 - return Math.round((usedNum / hardNum) * 100) - } + const usedNum = parseInt(used) || 0; + const hardNum = parseInt(hard) || 0; + if (hardNum === 0) return 0; + return Math.round((usedNum / hardNum) * 100); + }; const getUsageBadge = (percentage: number) => { if (percentage >= 90) { return {percentage}% - + ; } else if (percentage >= 75) { return {percentage}% - + ; } else { return {percentage}% - + ; } - } + }; return (
@@ -141,11 +139,11 @@ export function ResourceQuotasView() {
{quotas.filter(q => { - const used = q.status?.used || {} - const hard = q.status?.hard || {} + const used = q.status?.used || {}; + const hard = q.status?.hard || {}; return Object.keys(hard).some((key) => getUsagePercentage(String(used[key] ?? '0'), String(hard[key] ?? '0')) >= 75 - ) + ); }).length}
@@ -196,9 +194,9 @@ export function ResourceQuotasView() { {quotas.map((quota) => { - const hard = quota.status?.hard || {} - const used = quota.status?.used || {} - const resources = Object.keys(hard) + const hard = quota.status?.hard || {}; + const used = quota.status?.used || {}; + const resources = Object.keys(hard); return resources.map((resource, idx) => ( @@ -245,7 +243,7 @@ export function ResourceQuotasView() { )} - )) + )); })} @@ -253,5 +251,5 @@ export function ResourceQuotasView() {
- ) + ); } diff --git a/apps/ops-dashboard/components/resources/rolebindings.tsx b/apps/ops-dashboard/components/resources/rolebindings.tsx index addb80e..bfc57c5 100644 --- a/apps/ops-dashboard/components/resources/rolebindings.tsx +++ b/apps/ops-dashboard/components/resources/rolebindings.tsx @@ -1,65 +1,63 @@ -'use client' +'use client'; -import { useState } from 'react' -import { Button } from '@/components/ui/button' -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' -import { Badge } from '@/components/ui/badge' +import { type RbacAuthorizationK8sIoV1ClusterRoleBinding as ClusterRoleBinding,type RbacAuthorizationK8sIoV1RoleBinding as RoleBinding } from '@kubernetesjs/ops'; import { - RefreshCw, + AlertCircle, + Bot, + Eye, Plus, + RefreshCw, Trash2, - Eye, - AlertCircle, - UserCheck, - Users, User, - Bot -} from 'lucide-react' + UserCheck, + Users} from 'lucide-react'; +import { useState } from 'react'; + +import { Badge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; +import { usePreferredNamespace } from '@/contexts/NamespaceContext'; +import { confirmDialog } from '@/hooks/useConfirm'; import { - useListRbacAuthorizationV1NamespacedRoleBindingQuery, - useListRbacAuthorizationV1RoleBindingForAllNamespacesQuery, + useDeleteRbacAuthorizationV1ClusterRoleBinding, useDeleteRbacAuthorizationV1NamespacedRoleBinding, useListRbacAuthorizationV1ClusterRoleBindingQuery, - useDeleteRbacAuthorizationV1ClusterRoleBinding -} from '@/k8s' -import { usePreferredNamespace } from '@/contexts/NamespaceContext' -import { type RbacAuthorizationK8sIoV1RoleBinding as RoleBinding, type RbacAuthorizationK8sIoV1ClusterRoleBinding as ClusterRoleBinding } from '@kubernetesjs/ops' - -import { confirmDialog } from '@/hooks/useConfirm' + useListRbacAuthorizationV1NamespacedRoleBindingQuery, + useListRbacAuthorizationV1RoleBindingForAllNamespacesQuery} from '@/k8s'; export function RoleBindingsView() { - const [selectedBinding, setSelectedBinding] = useState(null) - const [showClusterBindings, setShowClusterBindings] = useState(false) - const { namespace } = usePreferredNamespace() + const [selectedBinding, setSelectedBinding] = useState(null); + const [showClusterBindings, setShowClusterBindings] = useState(false); + const { namespace } = usePreferredNamespace(); // Namespace role bindings const nsQuery = namespace === '_all' ? useListRbacAuthorizationV1RoleBindingForAllNamespacesQuery({ query: {} }) - : useListRbacAuthorizationV1NamespacedRoleBindingQuery({ path: { namespace }, query: {} }) + : useListRbacAuthorizationV1NamespacedRoleBindingQuery({ path: { namespace }, query: {} }); // Cluster role bindings - const clusterQuery = useListRbacAuthorizationV1ClusterRoleBindingQuery({ query: {} }) + const clusterQuery = useListRbacAuthorizationV1ClusterRoleBindingQuery({ query: {} }); - const query = showClusterBindings ? clusterQuery : nsQuery - const { data, isLoading, error, refetch } = query + const query = showClusterBindings ? clusterQuery : nsQuery; + const { data, isLoading, error, refetch } = query; - const deleteNsBinding = useDeleteRbacAuthorizationV1NamespacedRoleBinding() - const deleteClusterBinding = useDeleteRbacAuthorizationV1ClusterRoleBinding() + const deleteNsBinding = useDeleteRbacAuthorizationV1NamespacedRoleBinding(); + const deleteClusterBinding = useDeleteRbacAuthorizationV1ClusterRoleBinding(); - const bindings = data?.items || [] + const bindings = data?.items || []; - const handleRefresh = () => refetch() + const handleRefresh = () => refetch(); const handleDelete = async (binding: RoleBinding | ClusterRoleBinding) => { - const name = binding.metadata!.name! + const name = binding.metadata!.name!; const confirmed = await confirmDialog({ title: 'Delete Role Binding', description: `Are you sure you want to delete ${name}?`, confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); if (confirmed) { try { @@ -67,53 +65,53 @@ export function RoleBindingsView() { await deleteClusterBinding.mutateAsync({ path: { name }, query: {} - }) + }); } else { - const namespace = binding.metadata!.namespace! + const namespace = binding.metadata!.namespace!; await deleteNsBinding.mutateAsync({ path: { namespace, name }, query: {} - }) + }); } - refetch() + refetch(); } catch (err) { - console.error('Failed to delete role binding:', err) - alert(`Failed to delete role binding: ${err instanceof Error ? err.message : 'Unknown error'}`) + console.error('Failed to delete role binding:', err); + alert(`Failed to delete role binding: ${err instanceof Error ? err.message : 'Unknown error'}`); } } - } + }; const getRoleRef = (binding: RoleBinding | ClusterRoleBinding): string => { - const ref = binding.roleRef - return `${ref.kind}/${ref.name}` - } + const ref = binding.roleRef; + return `${ref.kind}/${ref.name}`; + }; const getSubjects = (binding: RoleBinding | ClusterRoleBinding): string => { - const subjects = binding.subjects || [] - if (subjects.length === 0) return 'None' + const subjects = binding.subjects || []; + if (subjects.length === 0) return 'None'; if (subjects.length === 1) { - const s = subjects[0] - return `${s.kind}/${s.name}` + const s = subjects[0]; + return `${s.kind}/${s.name}`; } - return `${subjects.length} subjects` - } + return `${subjects.length} subjects`; + }; const getSubjectTypes = (binding: RoleBinding | ClusterRoleBinding): string[] => { - const subjects = binding.subjects || [] - const types = new Set(subjects.map(s => s.kind)) - return Array.from(types) - } + const subjects = binding.subjects || []; + const types = new Set(subjects.map(s => s.kind)); + return Array.from(types); + }; const getSubjectIcon = (types: string[]) => { - if (types.includes('ServiceAccount')) return Bot - if (types.includes('Group')) return Users - if (types.includes('User')) return User - return UserCheck - } + if (types.includes('ServiceAccount')) return Bot; + if (types.includes('Group')) return Users; + if (types.includes('User')) return User; + return UserCheck; + }; const isClusterRole = (binding: RoleBinding | ClusterRoleBinding): boolean => { - return binding.roleRef.kind === 'ClusterRole' - } + return binding.roleRef.kind === 'ClusterRole'; + }; return (
@@ -243,8 +241,8 @@ export function RoleBindingsView() { {bindings.map((binding) => { - const subjectTypes = getSubjectTypes(binding) - const SubjectIcon = getSubjectIcon(subjectTypes) + const subjectTypes = getSubjectTypes(binding); + const SubjectIcon = getSubjectIcon(subjectTypes); return ( @@ -289,7 +287,7 @@ export function RoleBindingsView() {
- ) + ); })} @@ -297,5 +295,5 @@ export function RoleBindingsView() {
- ) + ); } diff --git a/apps/ops-dashboard/components/resources/roles.tsx b/apps/ops-dashboard/components/resources/roles.tsx index ecafbcb..8b1439c 100644 --- a/apps/ops-dashboard/components/resources/roles.tsx +++ b/apps/ops-dashboard/components/resources/roles.tsx @@ -1,64 +1,62 @@ -'use client' +'use client'; -import { useState } from 'react' -import { Button } from '@/components/ui/button' -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' -import { Badge } from '@/components/ui/badge' +import { type RbacAuthorizationK8sIoV1ClusterRole as ClusterRole,type RbacAuthorizationK8sIoV1Role as Role } from '@kubernetesjs/ops'; import { - RefreshCw, - Plus, - Trash2, - Eye, AlertCircle, - Shield, + Eye, + Globe, Key, - Globe -} from 'lucide-react' + Plus, + RefreshCw, + Shield, + Trash2} from 'lucide-react'; +import { useState } from 'react'; + +import { Badge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; +import { usePreferredNamespace } from '@/contexts/NamespaceContext'; +import { confirmDialog } from '@/hooks/useConfirm'; import { - useListRbacAuthorizationV1NamespacedRoleQuery, - useListRbacAuthorizationV1RoleForAllNamespacesQuery, + useDeleteRbacAuthorizationV1ClusterRole, useDeleteRbacAuthorizationV1NamespacedRole, useListRbacAuthorizationV1ClusterRoleQuery, - useDeleteRbacAuthorizationV1ClusterRole -} from '@/k8s' -import { usePreferredNamespace } from '@/contexts/NamespaceContext' -import { type RbacAuthorizationK8sIoV1Role as Role, type RbacAuthorizationK8sIoV1ClusterRole as ClusterRole } from '@kubernetesjs/ops' - -import { confirmDialog } from '@/hooks/useConfirm' + useListRbacAuthorizationV1NamespacedRoleQuery, + useListRbacAuthorizationV1RoleForAllNamespacesQuery} from '@/k8s'; export function RolesView() { - const [selectedRole, setSelectedRole] = useState(null) - const [showClusterRoles, setShowClusterRoles] = useState(false) - const { namespace } = usePreferredNamespace() + const [selectedRole, setSelectedRole] = useState(null); + const [showClusterRoles, setShowClusterRoles] = useState(false); + const { namespace } = usePreferredNamespace(); // Namespace roles const nsQuery = namespace === '_all' ? useListRbacAuthorizationV1RoleForAllNamespacesQuery({ query: {} }) - : useListRbacAuthorizationV1NamespacedRoleQuery({ path: { namespace }, query: {} }) + : useListRbacAuthorizationV1NamespacedRoleQuery({ path: { namespace }, query: {} }); // Cluster roles - const clusterQuery = useListRbacAuthorizationV1ClusterRoleQuery({ query: {} }) + const clusterQuery = useListRbacAuthorizationV1ClusterRoleQuery({ query: {} }); - const query = showClusterRoles ? clusterQuery : nsQuery - const { data, isLoading, error, refetch } = query + const query = showClusterRoles ? clusterQuery : nsQuery; + const { data, isLoading, error, refetch } = query; - const deleteNsRole = useDeleteRbacAuthorizationV1NamespacedRole() - const deleteClusterRole = useDeleteRbacAuthorizationV1ClusterRole() + const deleteNsRole = useDeleteRbacAuthorizationV1NamespacedRole(); + const deleteClusterRole = useDeleteRbacAuthorizationV1ClusterRole(); - const roles = data?.items || [] + const roles = data?.items || []; - const handleRefresh = () => refetch() + const handleRefresh = () => refetch(); const handleDelete = async (role: Role | ClusterRole) => { - const name = role.metadata!.name! + const name = role.metadata!.name!; const confirmed = await confirmDialog({ title: 'Delete Role', description: `Are you sure you want to delete ${name}?`, confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); if (confirmed) { try { @@ -66,81 +64,81 @@ export function RolesView() { await deleteClusterRole.mutateAsync({ path: { name }, query: {} - }) + }); } else { - const namespace = role.metadata!.namespace! + const namespace = role.metadata!.namespace!; await deleteNsRole.mutateAsync({ path: { namespace, name }, query: {} - }) + }); } - refetch() + refetch(); } catch (err) { - console.error('Failed to delete role:', err) - alert(`Failed to delete role: ${err instanceof Error ? err.message : 'Unknown error'}`) + console.error('Failed to delete role:', err); + alert(`Failed to delete role: ${err instanceof Error ? err.message : 'Unknown error'}`); } } - } + }; const getRuleCount = (role: Role | ClusterRole): number => { - return role.rules?.length || 0 - } + return role.rules?.length || 0; + }; const getResourceCount = (role: Role | ClusterRole): number => { - const rules = role.rules || [] - const resources = new Set() + const rules = role.rules || []; + const resources = new Set(); rules.forEach(rule => { (rule.resources || []).forEach(resource => { - resources.add(resource) - }) - }) - return resources.size - } + resources.add(resource); + }); + }); + return resources.size; + }; const getVerbCount = (role: Role | ClusterRole): number => { - const rules = role.rules || [] - const verbs = new Set() + const rules = role.rules || []; + const verbs = new Set(); rules.forEach(rule => { (rule.verbs || []).forEach(verb => { - verbs.add(verb) - }) - }) - return verbs.size - } + verbs.add(verb); + }); + }); + return verbs.size; + }; const hasWildcardAccess = (role: Role | ClusterRole): boolean => { - const rules = role.rules || [] + const rules = role.rules || []; return rules.some(rule => rule.verbs?.includes('*') || rule.resources?.includes('*') || rule.apiGroups?.includes('*') - ) - } + ); + }; const getTopResources = (role: Role | ClusterRole): string => { - const rules = role.rules || [] - const resources: string[] = [] + const rules = role.rules || []; + const resources: string[] = []; rules.forEach(rule => { (rule.resources || []).forEach(resource => { if (!resources.includes(resource)) { - resources.push(resource) + resources.push(resource); } - }) - }) + }); + }); - if (resources.length === 0) return 'None' - if (resources.length <= 3) return resources.join(', ') - return `${resources.slice(0, 3).join(', ')} +${resources.length - 3} more` - } + if (resources.length === 0) return 'None'; + if (resources.length <= 3) return resources.join(', '); + return `${resources.slice(0, 3).join(', ')} +${resources.length - 3} more`; + }; const isSystemRole = (role: Role | ClusterRole): boolean => { - const name = role.metadata?.name || '' + const name = role.metadata?.name || ''; return name.startsWith('system:') || name.startsWith('kubernetes-') || name.includes(':system:') || - (role.metadata?.labels?.['kubernetes.io/bootstrapping'] === 'rbac-defaults') - } + (role.metadata?.labels?.['kubernetes.io/bootstrapping'] === 'rbac-defaults'); + }; return (
@@ -271,8 +269,8 @@ export function RolesView() { {roles.map((role) => { - const isSystem = isSystemRole(role) - const hasWildcard = hasWildcardAccess(role) + const isSystem = isSystemRole(role); + const hasWildcard = hasWildcardAccess(role); return ( @@ -332,7 +330,7 @@ export function RolesView() {
- ) + ); })} @@ -340,5 +338,5 @@ export function RolesView() {
- ) + ); } diff --git a/apps/ops-dashboard/components/resources/runtimeclasses.tsx b/apps/ops-dashboard/components/resources/runtimeclasses.tsx index 829cb0d..01bc11d 100644 --- a/apps/ops-dashboard/components/resources/runtimeclasses.tsx +++ b/apps/ops-dashboard/components/resources/runtimeclasses.tsx @@ -1,80 +1,78 @@ -'use client' +'use client'; -import { useState } from 'react' -import { Button } from '@/components/ui/button' -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' -import { Badge } from '@/components/ui/badge' +import { type NodeK8sIoV1RuntimeClass as RuntimeClass } from '@kubernetesjs/ops'; import { - RefreshCw, - Plus, - Trash2, - Eye, AlertCircle, + Box, Cpu, - Box -} from 'lucide-react' -import { - useListNodeV1RuntimeClassQuery, - useDeleteNodeV1RuntimeClass -} from '@/k8s' -import { type NodeK8sIoV1RuntimeClass as RuntimeClass } from '@kubernetesjs/ops' + Eye, + Plus, + RefreshCw, + Trash2} from 'lucide-react'; +import { useState } from 'react'; -import { confirmDialog } from '@/hooks/useConfirm' +import { Badge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; +import { confirmDialog } from '@/hooks/useConfirm'; +import { + useDeleteNodeV1RuntimeClass, + useListNodeV1RuntimeClassQuery} from '@/k8s'; export function RuntimeClassesView() { - const [selectedRuntimeClass, setSelectedRuntimeClass] = useState(null) + const [selectedRuntimeClass, setSelectedRuntimeClass] = useState(null); - const { data, isLoading, error, refetch } = useListNodeV1RuntimeClassQuery({ query: {} }) - const deleteRuntimeClass = useDeleteNodeV1RuntimeClass() + const { data, isLoading, error, refetch } = useListNodeV1RuntimeClassQuery({ query: {} }); + const deleteRuntimeClass = useDeleteNodeV1RuntimeClass(); - const runtimeClasses = data?.items || [] + const runtimeClasses = data?.items || []; - const handleRefresh = () => refetch() + const handleRefresh = () => refetch(); const coerceString = (value: unknown): string | undefined => { if (typeof value === 'string') { - const trimmed = value.trim() - return trimmed.length > 0 ? trimmed : undefined + const trimmed = value.trim(); + return trimmed.length > 0 ? trimmed : undefined; } - return undefined - } + return undefined; + }; const handleDelete = async (rc: RuntimeClass) => { - const name = rc.metadata!.name! + const name = rc.metadata!.name!; const confirmed = await confirmDialog({ title: 'Delete Runtime Class', description: `Are you sure you want to delete ${name}?`, confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); if (confirmed) { try { await deleteRuntimeClass.mutateAsync({ path: { name }, query: {} - }) - refetch() + }); + refetch(); } catch (err) { - console.error('Failed to delete runtime class:', err) - alert(`Failed to delete runtime class: ${err instanceof Error ? err.message : 'Unknown error'}`) + console.error('Failed to delete runtime class:', err); + alert(`Failed to delete runtime class: ${err instanceof Error ? err.message : 'Unknown error'}`); } } - } + }; const getHandlerBadge = (handler: string) => { - const knownHandlers = ['runc', 'nvidia', 'gvisor', 'kata-containers', 'crun'] - const isKnown = knownHandlers.some(h => handler.toLowerCase().includes(h)) + const knownHandlers = ['runc', 'nvidia', 'gvisor', 'kata-containers', 'crun']; + const isKnown = knownHandlers.some(h => handler.toLowerCase().includes(h)); return ( {handler} - ) - } + ); + }; return (
@@ -239,5 +237,5 @@ export function RuntimeClassesView() {
- ) + ); } diff --git a/apps/ops-dashboard/components/resources/secrets.tsx b/apps/ops-dashboard/components/resources/secrets.tsx index 5a592df..dbdb70e 100644 --- a/apps/ops-dashboard/components/resources/secrets.tsx +++ b/apps/ops-dashboard/components/resources/secrets.tsx @@ -1,29 +1,28 @@ -'use client' +'use client'; -import { useState } from 'react' -import { Button } from '@/components/ui/button' -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' -import { Badge } from '@/components/ui/badge' -import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog' -import { Input } from '@/components/ui/input' -import { Label } from '@/components/ui/label' -import { Textarea } from '@/components/ui/textarea' +import { type Secret as K8sSecret } from '@kubernetesjs/ops'; import { - RefreshCw, - Plus, - Trash2, + AlertCircle, Edit, - Key, FileText, + Key, Lock, - Upload, - AlertCircle -} from 'lucide-react' -import { type Secret as K8sSecret } from '@kubernetesjs/ops' -import { useSecrets, useDeleteSecret, useCreateSecret } from '@/hooks' + Plus, + RefreshCw, + Trash2, + Upload} from 'lucide-react'; +import { useState } from 'react'; -import { confirmDialog } from '@/hooks/useConfirm' +import { Badge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog'; +import { Input } from '@/components/ui/input'; +import { Label } from '@/components/ui/label'; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; +import { Textarea } from '@/components/ui/textarea'; +import { useCreateSecret,useDeleteSecret, useSecrets } from '@/hooks'; +import { confirmDialog } from '@/hooks/useConfirm'; interface Secret { name: string @@ -36,20 +35,20 @@ interface Secret { } export function SecretsView() { - const [selectedSecret, setSelectedSecret] = useState(null) - const [createDialogOpen, setCreateDialogOpen] = useState(false) - const [editDialogOpen, setEditDialogOpen] = useState(false) - const [editingSecret, setEditingSecret] = useState(null) - const [secretName, setSecretName] = useState('') - const [secretContent, setSecretContent] = useState('') - const [uploadMethod, setUploadMethod] = useState<'text' | 'file'>('text') - const [creating, setCreating] = useState(false) - const [editing, setEditing] = useState(false) + const [selectedSecret, setSelectedSecret] = useState(null); + const [createDialogOpen, setCreateDialogOpen] = useState(false); + const [editDialogOpen, setEditDialogOpen] = useState(false); + const [editingSecret, setEditingSecret] = useState(null); + const [secretName, setSecretName] = useState(''); + const [secretContent, setSecretContent] = useState(''); + const [uploadMethod, setUploadMethod] = useState<'text' | 'file'>('text'); + const [creating, setCreating] = useState(false); + const [editing, setEditing] = useState(false); // Use TanStack Query hooks - const { data, isLoading, error, refetch } = useSecrets() - const deleteSecretMutation = useDeleteSecret() - const createSecretMutation = useCreateSecret() + const { data, isLoading, error, refetch } = useSecrets(); + const deleteSecretMutation = useDeleteSecret(); + const createSecretMutation = useCreateSecret(); // Format secrets from query data const secrets: Secret[] = data?.items @@ -62,11 +61,11 @@ export function SecretsView() { createdAt: item.metadata!.creationTimestamp!, immutable: item.immutable, k8sData: item - })) || [] + })) || []; const handleRefresh = () => { - refetch() - } + refetch(); + }; const handleDelete = async (secret: Secret) => { const confirmed = await confirmDialog({ @@ -74,71 +73,71 @@ export function SecretsView() { description: `Are you sure you want to delete ${secret.name}? This action cannot be undone.`, confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); if (confirmed) { try { await deleteSecretMutation.mutateAsync({ name: secret.name, namespace: secret.namespace - }) + }); } catch (err) { - console.error('Failed to delete secret:', err) - alert(`Failed to delete secret: ${err instanceof Error ? err.message : 'Unknown error'}`) + console.error('Failed to delete secret:', err); + alert(`Failed to delete secret: ${err instanceof Error ? err.message : 'Unknown error'}`); } } - } + }; const parseEnvContent = (content: string): Record => { - const result: Record = {} - const lines = content.split('\n') + const result: Record = {}; + const lines = content.split('\n'); for (const line of lines) { - const trimmed = line.trim() - if (!trimmed || trimmed.startsWith('#')) continue + const trimmed = line.trim(); + if (!trimmed || trimmed.startsWith('#')) continue; - const index = trimmed.indexOf('=') + const index = trimmed.indexOf('='); if (index > 0) { - const key = trimmed.substring(0, index).trim() - let value = trimmed.substring(index + 1).trim() + const key = trimmed.substring(0, index).trim(); + let value = trimmed.substring(index + 1).trim(); // Remove quotes if present if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) { - value = value.slice(1, -1) + value = value.slice(1, -1); } - result[key] = value + result[key] = value; } } - return result - } + return result; + }; const handleCreateSecret = async () => { if (!secretName.trim()) { - alert('Please provide a secret name') - return + alert('Please provide a secret name'); + return; } if (!secretContent.trim()) { - alert('Please provide secret content') - return + alert('Please provide secret content'); + return; } - setCreating(true) + setCreating(true); try { - const parsedData = parseEnvContent(secretContent) + const parsedData = parseEnvContent(secretContent); if (Object.keys(parsedData).length === 0) { - alert('No valid key-value pairs found in the content') - return + alert('No valid key-value pairs found in the content'); + return; } // Convert to base64 for Kubernetes - const data: Record = {} + const data: Record = {}; for (const [key, value] of Object.entries(parsedData)) { - data[key] = btoa(value) // Base64 encode + data[key] = btoa(value); // Base64 encode } const secret: K8sSecret = { @@ -149,57 +148,57 @@ export function SecretsView() { }, type: 'Opaque', data - } + }; await createSecretMutation.mutateAsync({ secret, namespace: 'default' - }) + }); // Reset form and close dialog - setSecretName('') - setSecretContent('') - setCreateDialogOpen(false) + setSecretName(''); + setSecretContent(''); + setCreateDialogOpen(false); } catch (err) { - console.error('Failed to create secret:', err) - alert(`Failed to create secret: ${err instanceof Error ? err.message : 'Unknown error'}`) + console.error('Failed to create secret:', err); + alert(`Failed to create secret: ${err instanceof Error ? err.message : 'Unknown error'}`); } finally { - setCreating(false) + setCreating(false); } - } + }; const handleEditSecret = async () => { - if (!editingSecret) return + if (!editingSecret) return; if (!secretName.trim()) { - alert('Please provide a secret name') - return + alert('Please provide a secret name'); + return; } if (!secretContent.trim()) { - alert('Please provide secret content') - return + alert('Please provide secret content'); + return; } - setEditing(true) + setEditing(true); try { - const parsedData = parseEnvContent(secretContent) + const parsedData = parseEnvContent(secretContent); if (Object.keys(parsedData).length === 0) { - alert('No valid key-value pairs found in the content') - return + alert('No valid key-value pairs found in the content'); + return; } // First delete the old secret await deleteSecretMutation.mutateAsync({ name: editingSecret.name, namespace: editingSecret.namespace - }) + }); // Convert to base64 for Kubernetes - const data: Record = {} + const data: Record = {}; for (const [key, value] of Object.entries(parsedData)) { - data[key] = btoa(value) // Base64 encode + data[key] = btoa(value); // Base64 encode } // Then create the new secret with the same name @@ -211,72 +210,72 @@ export function SecretsView() { }, type: 'Opaque', data - } + }; await createSecretMutation.mutateAsync({ secret, namespace: editingSecret.namespace - }) + }); // Reset form and close dialog - setSecretName('') - setSecretContent('') - setEditDialogOpen(false) - setEditingSecret(null) + setSecretName(''); + setSecretContent(''); + setEditDialogOpen(false); + setEditingSecret(null); } catch (err) { - console.error('Failed to edit secret:', err) - alert(`Failed to edit secret: ${err instanceof Error ? err.message : 'Unknown error'}`) + console.error('Failed to edit secret:', err); + alert(`Failed to edit secret: ${err instanceof Error ? err.message : 'Unknown error'}`); } finally { - setEditing(false) + setEditing(false); } - } + }; const handleOpenEditDialog = (secret: Secret) => { - setEditingSecret(secret) - setSecretName(secret.name) - setSecretContent('') // Start with empty content for security - setUploadMethod('text') - setEditDialogOpen(true) - } + setEditingSecret(secret); + setSecretName(secret.name); + setSecretContent(''); // Start with empty content for security + setUploadMethod('text'); + setEditDialogOpen(true); + }; const handleFileUpload = (event: React.ChangeEvent) => { - const file = event.target.files?.[0] + const file = event.target.files?.[0]; if (file) { - const reader = new FileReader() + const reader = new FileReader(); reader.onload = (e) => { - const content = e.target?.result as string - setSecretContent(content) - } - reader.readAsText(file) + const content = e.target?.result as string; + setSecretContent(content); + }; + reader.readAsText(file); } - } + }; const getTypeBadge = (type: string) => { switch (type) { - case 'Opaque': - return - + case 'Opaque': + return + Generic - - case 'kubernetes.io/tls': - return - + ; + case 'kubernetes.io/tls': + return + TLS - - case 'kubernetes.io/dockerconfigjson': - return - + ; + case 'kubernetes.io/dockerconfigjson': + return + Docker - - case 'kubernetes.io/service-account-token': - return - + ; + case 'kubernetes.io/service-account-token': + return + Service Account - - default: - return {type} + ; + default: + return {type}; } - } + }; return (
@@ -647,5 +646,5 @@ export function SecretsView() {
- ) + ); } diff --git a/apps/ops-dashboard/components/resources/serviceaccounts.tsx b/apps/ops-dashboard/components/resources/serviceaccounts.tsx index 6262a12..4faf6d8 100644 --- a/apps/ops-dashboard/components/resources/serviceaccounts.tsx +++ b/apps/ops-dashboard/components/resources/serviceaccounts.tsx @@ -1,128 +1,127 @@ -'use client' +'use client'; -import { useState } from 'react' -import { Button } from '@/components/ui/button' -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' -import { Badge } from '@/components/ui/badge' +import type { ServiceAccount } from '@kubernetesjs/ops'; import { - RefreshCw, - Plus, - Trash2, - Eye, AlertCircle, Bot, + Eye, Key, Lock, + Plus, + RefreshCw, + Trash2, Unlock -} from 'lucide-react' +} from 'lucide-react'; +import { useState } from 'react'; + +import { Badge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; +import { usePreferredNamespace } from '@/contexts/NamespaceContext'; +import { confirmDialog } from '@/hooks/useConfirm'; import { + useDeleteCoreV1NamespacedServiceAccount, useListCoreV1NamespacedServiceAccountQuery, - useListCoreV1ServiceAccountForAllNamespacesQuery, - useDeleteCoreV1NamespacedServiceAccount -} from '@/k8s' -import { usePreferredNamespace } from '@/contexts/NamespaceContext' -import type { ServiceAccount } from '@kubernetesjs/ops' - -import { confirmDialog } from '@/hooks/useConfirm' + useListCoreV1ServiceAccountForAllNamespacesQuery} from '@/k8s'; export function ServiceAccountsView() { - const [selectedAccount, setSelectedAccount] = useState(null) - const { namespace } = usePreferredNamespace() + const [selectedAccount, setSelectedAccount] = useState(null); + const { namespace } = usePreferredNamespace(); const query = namespace === '_all' ? useListCoreV1ServiceAccountForAllNamespacesQuery({ query: {} }) - : useListCoreV1NamespacedServiceAccountQuery({ path: { namespace }, query: {} }) + : useListCoreV1NamespacedServiceAccountQuery({ path: { namespace }, query: {} }); - const { data, isLoading, error, refetch } = query - const deleteAccount = useDeleteCoreV1NamespacedServiceAccount() + const { data, isLoading, error, refetch } = query; + const deleteAccount = useDeleteCoreV1NamespacedServiceAccount(); - const accounts = data?.items || [] + const accounts = data?.items || []; - const handleRefresh = () => refetch() + const handleRefresh = () => refetch(); const handleDelete = async (account: ServiceAccount) => { - const name = account.metadata!.name! - const namespace = account.metadata!.namespace! + const name = account.metadata!.name!; + const namespace = account.metadata!.namespace!; const confirmed = await confirmDialog({ title: 'Delete Service Account', description: `Are you sure you want to delete ${name}? This may affect pods using this service account.`, confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); if (confirmed) { try { await deleteAccount.mutateAsync({ path: { namespace, name }, query: {} - }) - refetch() + }); + refetch(); } catch (err) { - console.error('Failed to delete service account:', err) - alert(`Failed to delete service account: ${err instanceof Error ? err.message : 'Unknown error'}`) + console.error('Failed to delete service account:', err); + alert(`Failed to delete service account: ${err instanceof Error ? err.message : 'Unknown error'}`); } } - } + }; const getSecretCount = (account: ServiceAccount): number => { - return account.secrets?.length || 0 - } + return account.secrets?.length || 0; + }; const getImagePullSecrets = (account: ServiceAccount): number => { - return account.imagePullSecrets?.length || 0 - } + return account.imagePullSecrets?.length || 0; + }; const hasAutomountToken = (account: ServiceAccount): boolean => { - return account.automountServiceAccountToken !== false - } + return account.automountServiceAccountToken !== false; + }; const isDefaultAccount = (account: ServiceAccount): boolean => { - return account.metadata?.name === 'default' - } + return account.metadata?.name === 'default'; + }; const isSystemAccount = (account: ServiceAccount): boolean => { - const name = account.metadata?.name || '' - const namespace = account.metadata?.namespace || '' + const name = account.metadata?.name || ''; + const namespace = account.metadata?.namespace || ''; return namespace.startsWith('kube-') || name.startsWith('system:') || name.includes('controller') || - name.includes('operator') - } + name.includes('operator'); + }; const getSecretNames = (account: ServiceAccount): string => { - const secrets = account.secrets || [] - if (secrets.length === 0) return 'None' - if (secrets.length === 1) return secrets[0].name || 'Unknown' - return `${secrets.length} secrets` - } + const secrets = account.secrets || []; + if (secrets.length === 0) return 'None'; + if (secrets.length === 1) return secrets[0].name || 'Unknown'; + return `${secrets.length} secrets`; + }; const getAccountType = (account: ServiceAccount) => { - if (isDefaultAccount(account)) return 'Default' - if (isSystemAccount(account)) return 'System' - return 'User' - } + if (isDefaultAccount(account)) return 'Default'; + if (isSystemAccount(account)) return 'System'; + return 'User'; + }; const getAccountBadge = (type: string) => { switch (type) { - case 'Default': - return - - {type} - - case 'System': - return - - {type} - - default: - return - - {type} - + case 'Default': + return + + {type} + ; + case 'System': + return + + {type} + ; + default: + return + + {type} + ; } - } + }; return (
@@ -235,9 +234,9 @@ export function ServiceAccountsView() { {accounts.map((account) => { - const accountType = getAccountType(account) - const isSystem = accountType === 'System' - const isDefault = accountType === 'Default' + const accountType = getAccountType(account); + const isSystem = accountType === 'System'; + const isDefault = accountType === 'Default'; return ( @@ -296,7 +295,7 @@ export function ServiceAccountsView() {
- ) + ); })} @@ -304,5 +303,5 @@ export function ServiceAccountsView() { - ) + ); } diff --git a/apps/ops-dashboard/components/resources/services.tsx b/apps/ops-dashboard/components/resources/services.tsx index 50b60d4..393db4b 100644 --- a/apps/ops-dashboard/components/resources/services.tsx +++ b/apps/ops-dashboard/components/resources/services.tsx @@ -1,25 +1,24 @@ -'use client' +'use client'; -import { useState } from 'react' -import { Button } from '@/components/ui/button' -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' -import { Badge } from '@/components/ui/badge' +import { type Service as K8sService } from '@kubernetesjs/ops'; import { - RefreshCw, - Plus, - Trash2, + AlertCircle, Edit, Eye, Globe, - Shield, + Plus, + RefreshCw, Server, - AlertCircle -} from 'lucide-react' -import { type Service as K8sService } from '@kubernetesjs/ops' -import { useServices, useDeleteService } from '@/hooks' + Shield, + Trash2} from 'lucide-react'; +import { useState } from 'react'; -import { confirmDialog } from '@/hooks/useConfirm' +import { Badge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; +import { useDeleteService,useServices } from '@/hooks'; +import { confirmDialog } from '@/hooks/useConfirm'; interface Service { name: string @@ -35,15 +34,15 @@ interface Service { } export function ServicesView({ namespace:defaultNamespace }: { namespace?: string }) { - const [selectedService, setSelectedService] = useState(null) + const [selectedService, setSelectedService] = useState(null); // Use TanStack Query hooks - const { data, isLoading, error, refetch } = useServices(defaultNamespace) - const deleteServiceMutation = useDeleteService() + const { data, isLoading, error, refetch } = useServices(defaultNamespace); + const deleteServiceMutation = useDeleteService(); // Format services from query data const services: Service[] = data?.items?.map(item => { - const loadBalancerIngress = item.status?.loadBalancer?.ingress?.[0] + const loadBalancerIngress = item.status?.loadBalancer?.ingress?.[0]; return { name: item.metadata!.name!, namespace: item.metadata!.namespace!, @@ -61,12 +60,12 @@ export function ServicesView({ namespace:defaultNamespace }: { namespace?: strin externalIPs: item.spec!.externalIPs, loadBalancerIP: loadBalancerIngress?.ip || loadBalancerIngress?.hostname, k8sData: item, - } - }) || [] + }; + }) || []; const handleRefresh = () => { - refetch() - } + refetch(); + }; const handleDelete = async (service: Service) => { const confirmed = await confirmDialog({ @@ -74,60 +73,60 @@ export function ServicesView({ namespace:defaultNamespace }: { namespace?: strin description: `Are you sure you want to delete ${service.name}?`, confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); if (confirmed) { try { await deleteServiceMutation.mutateAsync({ name: service.name, namespace: service.namespace - }) + }); refetch(); } catch (err) { - console.error('Failed to delete service:', err) - alert(`Failed to delete service: ${err instanceof Error ? err.message : 'Unknown error'}`) + console.error('Failed to delete service:', err); + alert(`Failed to delete service: ${err instanceof Error ? err.message : 'Unknown error'}`); } } - } + }; const getTypeBadge = (type: string) => { switch (type) { - case 'LoadBalancer': - return - - {type} - - case 'NodePort': - return - - {type} - - case 'ClusterIP': - return - - {type} - - default: - return {type} + case 'LoadBalancer': + return + + {type} + ; + case 'NodePort': + return + + {type} + ; + case 'ClusterIP': + return + + {type} + ; + default: + return {type}; } - } + }; const formatPorts = (ports: Service['ports']) => { return ports.map(p => { - let portStr = `${p.port}` + let portStr = `${p.port}`; if (p.targetPort !== p.port) { - portStr += `:${p.targetPort}` + portStr += `:${p.targetPort}`; } if (p.nodePort) { - portStr += `:${p.nodePort}` + portStr += `:${p.nodePort}`; } - return `${portStr}/${p.protocol}` - }).join(', ') - } + return `${portStr}/${p.protocol}`; + }).join(', '); + }; const formatSelector = (selector: Record) => { - return Object.entries(selector).map(([k, v]) => `${k}=${v}`).join(', ') - } + return Object.entries(selector).map(([k, v]) => `${k}=${v}`).join(', '); + }; return (
@@ -307,5 +306,5 @@ export function ServicesView({ namespace:defaultNamespace }: { namespace?: strin
- ) + ); } \ No newline at end of file diff --git a/apps/ops-dashboard/components/resources/statefulsets.tsx b/apps/ops-dashboard/components/resources/statefulsets.tsx index 1337ae8..3d264b9 100644 --- a/apps/ops-dashboard/components/resources/statefulsets.tsx +++ b/apps/ops-dashboard/components/resources/statefulsets.tsx @@ -1,54 +1,53 @@ -'use client' +'use client'; -import { useState } from 'react' -import { Button } from '@/components/ui/button' -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' -import { Badge } from '@/components/ui/badge' +import { type AppsV1StatefulSet as StatefulSet } from '@kubernetesjs/ops'; import { - RefreshCw, - Plus, - Trash2, + AlertCircle, + CheckCircle, Edit, - Scale, Eye, - AlertCircle, - CheckCircle -} from 'lucide-react' + Plus, + RefreshCw, + Scale, + Trash2} from 'lucide-react'; +import { useState } from 'react'; + +import { Badge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; +import { usePreferredNamespace } from '@/contexts/NamespaceContext'; +import { confirmDialog } from '@/hooks/useConfirm'; import { + useDeleteAppsV1NamespacedStatefulSet, useListAppsV1NamespacedStatefulSetQuery, useListAppsV1StatefulSetForAllNamespacesQuery, - useDeleteAppsV1NamespacedStatefulSet, useReplaceAppsV1NamespacedStatefulSetScale -} from '@/k8s' -import { usePreferredNamespace } from '@/contexts/NamespaceContext' -import { type AppsV1StatefulSet as StatefulSet } from '@kubernetesjs/ops' - -import { confirmDialog } from '@/hooks/useConfirm' +} from '@/k8s'; export function StatefulSetsView() { - const [selectedStatefulSet, setSelectedStatefulSet] = useState(null) - const { namespace } = usePreferredNamespace() + const [selectedStatefulSet, setSelectedStatefulSet] = useState(null); + const { namespace } = usePreferredNamespace(); // Use k8s hooks directly const query = namespace === '_all' ? useListAppsV1StatefulSetForAllNamespacesQuery({ query: {} }) - : useListAppsV1NamespacedStatefulSetQuery({ path: { namespace }, query: {} }) + : useListAppsV1NamespacedStatefulSetQuery({ path: { namespace }, query: {} }); - const { data, isLoading, error, refetch } = query - const deleteStatefulSet = useDeleteAppsV1NamespacedStatefulSet() - const scaleStatefulSet = useReplaceAppsV1NamespacedStatefulSetScale() + const { data, isLoading, error, refetch } = query; + const deleteStatefulSet = useDeleteAppsV1NamespacedStatefulSet(); + const scaleStatefulSet = useReplaceAppsV1NamespacedStatefulSetScale(); - const statefulsets = data?.items || [] + const statefulsets = data?.items || []; - const handleRefresh = () => refetch() + const handleRefresh = () => refetch(); const handleScale = async (ss: StatefulSet) => { - const name = ss.metadata!.name! - const namespace = ss.metadata!.namespace! - const currentReplicas = ss.spec!.replicas || 0 + const name = ss.metadata!.name!; + const namespace = ss.metadata!.namespace!; + const currentReplicas = ss.spec!.replicas || 0; - const newReplicas = prompt(`Scale ${name} to how many replicas?`, currentReplicas.toString()) + const newReplicas = prompt(`Scale ${name} to how many replicas?`, currentReplicas.toString()); if (newReplicas && !isNaN(Number(newReplicas))) { try { await scaleStatefulSet.mutateAsync({ @@ -60,69 +59,69 @@ export function StatefulSetsView() { spec: { replicas: Number(newReplicas) } }, query: {} - }) - refetch() + }); + refetch(); } catch (err) { - console.error('Failed to scale statefulset:', err) - alert(`Failed to scale statefulset: ${err instanceof Error ? err.message : 'Unknown error'}`) + console.error('Failed to scale statefulset:', err); + alert(`Failed to scale statefulset: ${err instanceof Error ? err.message : 'Unknown error'}`); } } - } + }; const handleDelete = async (ss: StatefulSet) => { - const name = ss.metadata!.name! - const namespace = ss.metadata!.namespace! + const name = ss.metadata!.name!; + const namespace = ss.metadata!.namespace!; const confirmed = await confirmDialog({ title: 'Delete StatefulSet', description: `Are you sure you want to delete ${name}?`, confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); if (confirmed) { try { await deleteStatefulSet.mutateAsync({ path: { namespace, name }, query: {} - }) - refetch() + }); + refetch(); } catch (err) { - console.error('Failed to delete statefulset:', err) - alert(`Failed to delete statefulset: ${err instanceof Error ? err.message : 'Unknown error'}`) + console.error('Failed to delete statefulset:', err); + alert(`Failed to delete statefulset: ${err instanceof Error ? err.message : 'Unknown error'}`); } } - } + }; const getStatus = (ss: StatefulSet) => { - const replicas = ss.spec?.replicas || 0 - const readyReplicas = ss.status?.readyReplicas || 0 + const replicas = ss.spec?.replicas || 0; + const readyReplicas = ss.status?.readyReplicas || 0; if (readyReplicas === replicas && replicas > 0) { - return 'Running' + return 'Running'; } else if (readyReplicas < replicas) { - return 'Updating' + return 'Updating'; } else { - return 'Pending' + return 'Pending'; } - } + }; const getStatusBadge = (status: string) => { switch (status) { - case 'Running': - return - - {status} - - case 'Updating': - return - - {status} - - default: - return {status} + case 'Running': + return + + {status} + ; + case 'Updating': + return + + {status} + ; + default: + return {status}; } - } + }; return (
@@ -283,5 +282,5 @@ export function StatefulSetsView() {
- ) + ); } diff --git a/apps/ops-dashboard/components/resources/storageclasses.tsx b/apps/ops-dashboard/components/resources/storageclasses.tsx index 7edca78..d547e93 100644 --- a/apps/ops-dashboard/components/resources/storageclasses.tsx +++ b/apps/ops-dashboard/components/resources/storageclasses.tsx @@ -1,84 +1,82 @@ -'use client' +'use client'; -import { useState } from 'react' -import { Button } from '@/components/ui/button' -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' -import { Badge } from '@/components/ui/badge' +import { type StorageK8sIoV1StorageClass as StorageClass } from '@kubernetesjs/ops'; import { - RefreshCw, - Plus, - Trash2, - Eye, AlertCircle, - Database, - Zap, Archive, - HardDrive -} from 'lucide-react' -import { - useListStorageV1StorageClassQuery, - useDeleteStorageV1StorageClass -} from '@/k8s' -import { type StorageK8sIoV1StorageClass as StorageClass } from '@kubernetesjs/ops' + Database, + Eye, + HardDrive, + Plus, + RefreshCw, + Trash2, + Zap} from 'lucide-react'; +import { useState } from 'react'; -import { confirmDialog } from '@/hooks/useConfirm' +import { Badge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; +import { confirmDialog } from '@/hooks/useConfirm'; +import { + useDeleteStorageV1StorageClass, + useListStorageV1StorageClassQuery} from '@/k8s'; export function StorageClassesView() { - const [selectedClass, setSelectedClass] = useState(null) + const [selectedClass, setSelectedClass] = useState(null); - const { data, isLoading, error, refetch } = useListStorageV1StorageClassQuery({ query: {} }) - const deleteClass = useDeleteStorageV1StorageClass() + const { data, isLoading, error, refetch } = useListStorageV1StorageClassQuery({ query: {} }); + const deleteClass = useDeleteStorageV1StorageClass(); - const storageClasses = data?.items || [] + const storageClasses = data?.items || []; - const handleRefresh = () => refetch() + const handleRefresh = () => refetch(); const handleDelete = async (sc: StorageClass) => { - const name = sc.metadata!.name! + const name = sc.metadata!.name!; const confirmed = await confirmDialog({ title: 'Delete Storage Class', description: `Are you sure you want to delete ${name}? PVs using this class won't be affected.`, confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); if (confirmed) { try { await deleteClass.mutateAsync({ path: { name }, query: {} - }) - refetch() + }); + refetch(); } catch (err) { - console.error('Failed to delete storage class:', err) - alert(`Failed to delete storage class: ${err instanceof Error ? err.message : 'Unknown error'}`) + console.error('Failed to delete storage class:', err); + alert(`Failed to delete storage class: ${err instanceof Error ? err.message : 'Unknown error'}`); } } - } + }; const getProvisioner = (sc: StorageClass): string => { - return sc.provisioner || 'Unknown' - } + return sc.provisioner || 'Unknown'; + }; const getReclaimPolicy = (sc: StorageClass): string => { - return sc.reclaimPolicy || 'Delete' - } + return sc.reclaimPolicy || 'Delete'; + }; const getVolumeBindingMode = (sc: StorageClass): string => { - return sc.volumeBindingMode || 'Immediate' - } + return sc.volumeBindingMode || 'Immediate'; + }; const isDefaultClass = (sc: StorageClass): boolean => { - const annotations = sc.metadata?.annotations || {} + const annotations = sc.metadata?.annotations || {}; return annotations['storageclass.kubernetes.io/is-default-class'] === 'true' || - annotations['storageclass.beta.kubernetes.io/is-default-class'] === 'true' - } + annotations['storageclass.beta.kubernetes.io/is-default-class'] === 'true'; + }; const getAllowVolumeExpansion = (sc: StorageClass): boolean => { - return sc.allowVolumeExpansion === true - } + return sc.allowVolumeExpansion === true; + }; const getProvisionerBadge = (provisioner: string) => { // Common provisioners @@ -86,30 +84,30 @@ export function StorageClassesView() { return AWS EBS - + ; } else if (provisioner.includes('azure-disk')) { return Azure Disk - + ; } else if (provisioner.includes('gce-pd')) { return GCE PD - + ; } else if (provisioner.includes('nfs')) { return NFS - + ; } else if (provisioner.includes('local')) { return Local - + ; } - return {provisioner} - } + return {provisioner}; + }; return (
@@ -277,5 +275,5 @@ export function StorageClassesView() {
- ) + ); } diff --git a/apps/ops-dashboard/components/resources/volumeattachments.tsx b/apps/ops-dashboard/components/resources/volumeattachments.tsx index 4f94101..0836835 100644 --- a/apps/ops-dashboard/components/resources/volumeattachments.tsx +++ b/apps/ops-dashboard/components/resources/volumeattachments.tsx @@ -1,107 +1,103 @@ -'use client' +'use client'; -import { useState } from 'react' -import { Button } from '@/components/ui/button' -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' -import { Badge } from '@/components/ui/badge' +import { type StorageK8sIoV1VolumeAttachment as VolumeAttachment } from '@kubernetesjs/ops'; import { - RefreshCw, - Plus, - Trash2, - Eye, AlertCircle, - CheckCircle, + Eye, Link, - Link2Off, - Server -} from 'lucide-react' -import { - useListStorageV1VolumeAttachmentQuery, - useDeleteStorageV1VolumeAttachment -} from '@/k8s' -import { type StorageK8sIoV1VolumeAttachment as VolumeAttachment } from '@kubernetesjs/ops' + Link2Off, + RefreshCw, + Server, + Trash2} from 'lucide-react'; +import { useState } from 'react'; -import { confirmDialog } from '@/hooks/useConfirm' +import { Badge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; +import { confirmDialog } from '@/hooks/useConfirm'; +import { + useDeleteStorageV1VolumeAttachment, + useListStorageV1VolumeAttachmentQuery} from '@/k8s'; export function VolumeAttachmentsView() { - const [selectedAttachment, setSelectedAttachment] = useState(null) + const [selectedAttachment, setSelectedAttachment] = useState(null); - const { data, isLoading, error, refetch } = useListStorageV1VolumeAttachmentQuery({ query: {} }) - const deleteAttachment = useDeleteStorageV1VolumeAttachment() + const { data, isLoading, error, refetch } = useListStorageV1VolumeAttachmentQuery({ query: {} }); + const deleteAttachment = useDeleteStorageV1VolumeAttachment(); - const attachments = data?.items || [] + const attachments = data?.items || []; - const handleRefresh = () => refetch() + const handleRefresh = () => refetch(); const handleDelete = async (va: VolumeAttachment) => { - const name = va.metadata!.name! + const name = va.metadata!.name!; const confirmed = await confirmDialog({ title: 'Delete Volume Attachment', description: `Are you sure you want to delete ${name}? This may disrupt attached volumes.`, confirmText: 'Delete', confirmVariant: 'destructive' - }) + }); if (confirmed) { try { await deleteAttachment.mutateAsync({ path: { name }, query: {} - }) - refetch() + }); + refetch(); } catch (err) { - console.error('Failed to delete volume attachment:', err) - alert(`Failed to delete volume attachment: ${err instanceof Error ? err.message : 'Unknown error'}`) + console.error('Failed to delete volume attachment:', err); + alert(`Failed to delete volume attachment: ${err instanceof Error ? err.message : 'Unknown error'}`); } } - } + }; const getAttachmentStatus = (va: VolumeAttachment): string => { - return va.status?.attached ? 'Attached' : 'Detached' - } + return va.status?.attached ? 'Attached' : 'Detached'; + }; const getStatusBadge = (status: string) => { switch (status) { - case 'Attached': - return - - {status} - - case 'Detached': - return - - {status} - - default: - return {status} + case 'Attached': + return + + {status} + ; + case 'Detached': + return + + {status} + ; + default: + return {status}; } - } + }; const getAttacher = (va: VolumeAttachment): string => { - return va.spec?.attacher || 'Unknown' - } + return va.spec?.attacher || 'Unknown'; + }; const getNodeName = (va: VolumeAttachment): string => { - return va.spec?.nodeName || 'Unknown' - } + return va.spec?.nodeName || 'Unknown'; + }; const getPVName = (va: VolumeAttachment): string => { - return va.spec?.source?.persistentVolumeName || 'Unknown' - } + return va.spec?.source?.persistentVolumeName || 'Unknown'; + }; const getAttachError = (va: VolumeAttachment): string | null => { - const error = va.status?.attachError - if (!error) return null - return error.message || 'Unknown error' - } + const error = va.status?.attachError; + if (!error) return null; + return error.message || 'Unknown error'; + }; const getDetachError = (va: VolumeAttachment): string | null => { - const error = va.status?.detachError - if (!error) return null - return error.message || 'Unknown error' - } + const error = va.status?.detachError; + if (!error) return null; + return error.message || 'Unknown error'; + }; return (
@@ -210,9 +206,9 @@ export function VolumeAttachmentsView() { {attachments.map((va) => { - const attachError = getAttachError(va) - const detachError = getDetachError(va) - const hasError = attachError || detachError + const attachError = getAttachError(va); + const detachError = getDetachError(va); + const hasError = attachError || detachError; return ( @@ -263,7 +259,7 @@ export function VolumeAttachmentsView() {
- ) + ); })} @@ -271,5 +267,5 @@ export function VolumeAttachmentsView() { - ) + ); } diff --git a/apps/ops-dashboard/components/scale-deployment-dialog.tsx b/apps/ops-dashboard/components/scale-deployment-dialog.tsx index ff36baa..705a61e 100644 --- a/apps/ops-dashboard/components/scale-deployment-dialog.tsx +++ b/apps/ops-dashboard/components/scale-deployment-dialog.tsx @@ -1,13 +1,14 @@ -'use client' +'use client'; -import React, { useState, useEffect } from 'react' -import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogFooter } from '@/components/ui/dialog' -import { Button } from '@/components/ui/button' -import { Input } from '@/components/ui/input' -import { Label } from '@/components/ui/label' -import { AlertCircle, Scale } from 'lucide-react' -import { Alert, AlertDescription } from '@/components/ui/alert' -import type { AppsV1Deployment as Deployment } from '@kubernetesjs/ops' +import type { AppsV1Deployment as Deployment } from '@kubernetesjs/ops'; +import { AlertCircle, Scale } from 'lucide-react'; +import React, { useEffect,useState } from 'react'; + +import { Alert, AlertDescription } from '@/components/ui/alert'; +import { Button } from '@/components/ui/button'; +import { Dialog, DialogContent, DialogDescription, DialogFooter,DialogHeader, DialogTitle } from '@/components/ui/dialog'; +import { Input } from '@/components/ui/input'; +import { Label } from '@/components/ui/label'; interface ScaleDeploymentDialogProps { deployment: Deployment | null @@ -22,63 +23,63 @@ export function ScaleDeploymentDialog({ onOpenChange, onScale }: ScaleDeploymentDialogProps) { - const currentReplicas = deployment?.spec?.replicas || 0 - const [replicas, setReplicas] = useState(currentReplicas.toString()) - const [isSubmitting, setIsSubmitting] = useState(false) - const [error, setError] = useState(null) + const currentReplicas = deployment?.spec?.replicas || 0; + const [replicas, setReplicas] = useState(currentReplicas.toString()); + const [isSubmitting, setIsSubmitting] = useState(false); + const [error, setError] = useState(null); useEffect(() => { if (deployment && open) { - setReplicas((deployment.spec?.replicas || 0).toString()) - setError(null) + setReplicas((deployment.spec?.replicas || 0).toString()); + setError(null); } - }, [deployment, open]) + }, [deployment, open]); const handleSubmit = async () => { - setError(null) + setError(null); - const replicaCount = parseInt(replicas, 10) + const replicaCount = parseInt(replicas, 10); if (isNaN(replicaCount) || replicaCount < 0) { - setError('Please enter a valid number of replicas (0 or greater)') - return + setError('Please enter a valid number of replicas (0 or greater)'); + return; } if (replicaCount > 100) { - setError('For safety, maximum replicas is limited to 100. Please contact admin for higher limits.') - return + setError('For safety, maximum replicas is limited to 100. Please contact admin for higher limits.'); + return; } - setIsSubmitting(true) + setIsSubmitting(true); try { - await onScale(replicaCount) + await onScale(replicaCount); // Only close dialog on successful scaling - onOpenChange(false) + onOpenChange(false); } catch (err) { - setError(err instanceof Error ? err.message : 'Failed to scale deployment') + setError(err instanceof Error ? err.message : 'Failed to scale deployment'); // Don't close dialog on error - let user see the error message } finally { - setIsSubmitting(false) + setIsSubmitting(false); } - } + }; const handleCancel = () => { - setError(null) - setReplicas(currentReplicas.toString()) - onOpenChange(false) - } + setError(null); + setReplicas(currentReplicas.toString()); + onOpenChange(false); + }; const handleKeyPress = (e: React.KeyboardEvent) => { if (e.key === 'Enter' && !isSubmitting) { - handleSubmit() + handleSubmit(); } - } + }; - if (!deployment) return null + if (!deployment) return null; - const deploymentName = deployment.metadata?.name || 'Unknown' - const namespace = deployment.metadata?.namespace || 'default' + const deploymentName = deployment.metadata?.name || 'Unknown'; + const namespace = deployment.metadata?.namespace || 'default'; return ( @@ -140,5 +141,5 @@ export function ScaleDeploymentDialog({ - ) + ); } diff --git a/apps/ops-dashboard/components/templates/template-dialog.tsx b/apps/ops-dashboard/components/templates/template-dialog.tsx index 5511e8a..f1b1ebe 100644 --- a/apps/ops-dashboard/components/templates/template-dialog.tsx +++ b/apps/ops-dashboard/components/templates/template-dialog.tsx @@ -1,7 +1,10 @@ -'use client' +'use client'; -import { useState, useEffect, useRef } from 'react' -import { Button } from '@/components/ui/button' +import { CheckCircle,Loader2, XCircle } from 'lucide-react'; +import { useEffect, useRef,useState } from 'react'; + +import { Alert, AlertDescription } from '@/components/ui/alert'; +import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, @@ -9,12 +12,10 @@ import { DialogFooter, DialogHeader, DialogTitle, -} from '@/components/ui/dialog' -import { Input } from '@/components/ui/input' -import { Label } from '@/components/ui/label' -import { Alert, AlertDescription } from '@/components/ui/alert' -import { Loader2, CheckCircle, XCircle, FileJson } from 'lucide-react' -import { usePreferredNamespace } from '@/contexts/NamespaceContext' +} from '@/components/ui/dialog'; +import { Input } from '@/components/ui/input'; +import { Label } from '@/components/ui/label'; +import { usePreferredNamespace } from '@/contexts/NamespaceContext'; interface Template { id: string @@ -35,7 +36,7 @@ interface TemplateDialogProps { } export function TemplateDialog({ template, open, onOpenChange }: TemplateDialogProps) { - const { namespace: contextNamespace } = usePreferredNamespace() + const { namespace: contextNamespace } = usePreferredNamespace(); // Deploy template function using new API const deployTemplate = async (params: { @@ -71,7 +72,7 @@ export function TemplateDialog({ template, open, onOpenChange }: TemplateDialogP const result = await response.json(); return result; - } + }; // Force uninstall template function using API const forceUninstallTemplate = async (params: { @@ -104,41 +105,41 @@ export function TemplateDialog({ template, open, onOpenChange }: TemplateDialogP const result = await response.json(); return result; - } - const [deploymentName, setDeploymentName] = useState(template.id) - const [namespace, setNamespace] = useState(contextNamespace === '_all' ? 'default' : contextNamespace) - const [isDeploying, setIsDeploying] = useState(false) - const [isUninstalling, setIsUninstalling] = useState(false) - const [deploymentStatus, setDeploymentStatus] = useState<'idle' | 'success' | 'error'>('idle') - const [successMessage, setSuccessMessage] = useState('') - const [errorMessage, setErrorMessage] = useState('') + }; + const [deploymentName, setDeploymentName] = useState(template.id); + const [namespace, setNamespace] = useState(contextNamespace === '_all' ? 'default' : contextNamespace); + const [isDeploying, setIsDeploying] = useState(false); + const [isUninstalling, setIsUninstalling] = useState(false); + const [deploymentStatus, setDeploymentStatus] = useState<'idle' | 'success' | 'error'>('idle'); + const [successMessage, setSuccessMessage] = useState(''); + const [errorMessage, setErrorMessage] = useState(''); // Prevent double deploy/uninstall clicks - const isDeployingRef = useRef(false) - const isUninstallingRef = useRef(false) + const isDeployingRef = useRef(false); + const isUninstallingRef = useRef(false); // Reset form state when dialog opens or template changes useEffect(() => { if (open) { - setDeploymentName(`${template.id}-deployment`) - setNamespace(contextNamespace === '_all' ? 'default' : contextNamespace) - setDeploymentStatus('idle') - setSuccessMessage('') - setErrorMessage('') + setDeploymentName(`${template.id}-deployment`); + setNamespace(contextNamespace === '_all' ? 'default' : contextNamespace); + setDeploymentStatus('idle'); + setSuccessMessage(''); + setErrorMessage(''); } - }, [open, template.id]) + }, [open, template.id]); const handleDeploy = async () => { - console.log(`[TemplateDialog] ${template.id} - Deploy button clicked`) + console.log(`[TemplateDialog] ${template.id} - Deploy button clicked`); if (isDeployingRef.current || isUninstallingRef.current) { - console.log(`[TemplateDialog] ${template.id} - Another operation in progress, ignoring click`) - return + console.log(`[TemplateDialog] ${template.id} - Another operation in progress, ignoring click`); + return; } - isDeployingRef.current = true - setIsDeploying(true) - setDeploymentStatus('idle') - setSuccessMessage('') - setErrorMessage('') + isDeployingRef.current = true; + setIsDeploying(true); + setDeploymentStatus('idle'); + setSuccessMessage(''); + setErrorMessage(''); try { console.log(`[TemplateDialog] ${template.id} - Starting deployment with params:`, { @@ -148,7 +149,7 @@ export function TemplateDialog({ template, open, onOpenChange }: TemplateDialogP image: template.details.image, ports: template.details.ports, environment: template.details.environment - }) + }); await deployTemplate({ templateId: template.id, @@ -157,70 +158,70 @@ export function TemplateDialog({ template, open, onOpenChange }: TemplateDialogP image: template.details.image, ports: template.details.ports, environment: template.details.environment - }) + }); - console.log(`[TemplateDialog] ${template.id} - Deployment successful`) - setDeploymentStatus('success') - setSuccessMessage(`${template.name} deployed successfully!`) + console.log(`[TemplateDialog] ${template.id} - Deployment successful`); + setDeploymentStatus('success'); + setSuccessMessage(`${template.name} deployed successfully!`); setTimeout(() => { - onOpenChange(false) - setDeploymentStatus('idle') - setDeploymentName(`${template.id}-deployment`) - setSuccessMessage('') - }, 2000) + onOpenChange(false); + setDeploymentStatus('idle'); + setDeploymentName(`${template.id}-deployment`); + setSuccessMessage(''); + }, 2000); } catch (error) { - console.error(`[TemplateDialog] ${template.id} - Deployment failed:`, error) - setDeploymentStatus('error') - setErrorMessage(error instanceof Error ? error.message : 'Failed to deploy template') + console.error(`[TemplateDialog] ${template.id} - Deployment failed:`, error); + setDeploymentStatus('error'); + setErrorMessage(error instanceof Error ? error.message : 'Failed to deploy template'); } finally { - setIsDeploying(false) - isDeployingRef.current = false + setIsDeploying(false); + isDeployingRef.current = false; } - } + }; const handleForceUninstall = async () => { - console.log(`[TemplateDialog] ${template.id} - Force Uninstall button clicked`) + console.log(`[TemplateDialog] ${template.id} - Force Uninstall button clicked`); if (isUninstallingRef.current || isDeployingRef.current) { - console.log(`[TemplateDialog] ${template.id} - Another operation in progress, ignoring click`) - return + console.log(`[TemplateDialog] ${template.id} - Another operation in progress, ignoring click`); + return; } - isUninstallingRef.current = true - setIsUninstalling(true) - setDeploymentStatus('idle') - setSuccessMessage('') - setErrorMessage('') + isUninstallingRef.current = true; + setIsUninstalling(true); + setDeploymentStatus('idle'); + setSuccessMessage(''); + setErrorMessage(''); try { console.log(`[TemplateDialog] ${template.id} - Starting force uninstall with params:`, { templateId: template.id, name: deploymentName, namespace, - }) + }); await forceUninstallTemplate({ templateId: template.id, name: deploymentName, namespace, - }) + }); - console.log(`[TemplateDialog] ${template.id} - Force uninstall successful`) - setDeploymentStatus('success') - setSuccessMessage(`${template.name} force uninstalled successfully!`) + console.log(`[TemplateDialog] ${template.id} - Force uninstall successful`); + setDeploymentStatus('success'); + setSuccessMessage(`${template.name} force uninstalled successfully!`); setTimeout(() => { - onOpenChange(false) - setDeploymentStatus('idle') - setDeploymentName(`${template.id}-deployment`) - setSuccessMessage('') - }, 2000) + onOpenChange(false); + setDeploymentStatus('idle'); + setDeploymentName(`${template.id}-deployment`); + setSuccessMessage(''); + }, 2000); } catch (error) { - console.error(`[TemplateDialog] ${template.id} - Force uninstall failed:`, error) - setDeploymentStatus('error') - setErrorMessage(error instanceof Error ? error.message : 'Failed to uninstall template') + console.error(`[TemplateDialog] ${template.id} - Force uninstall failed:`, error); + setDeploymentStatus('error'); + setErrorMessage(error instanceof Error ? error.message : 'Failed to uninstall template'); } finally { - setIsUninstalling(false) - isUninstallingRef.current = false + setIsUninstalling(false); + isUninstallingRef.current = false; } - } + }; return ( @@ -334,5 +335,5 @@ export function TemplateDialog({ template, open, onOpenChange }: TemplateDialogP - ) + ); } \ No newline at end of file diff --git a/apps/ops-dashboard/components/templates/templates.tsx b/apps/ops-dashboard/components/templates/templates.tsx index d3270e0..8913a5e 100644 --- a/apps/ops-dashboard/components/templates/templates.tsx +++ b/apps/ops-dashboard/components/templates/templates.tsx @@ -1,7 +1,7 @@ -'use client' +'use client'; -import { Database, Cloud, Cpu } from 'lucide-react' -import { allTemplates, type TemplateMetadata } from '@kubernetesjs/client/deployers/presets/metadata' +import { allTemplates, type TemplateMetadata } from '@kubernetesjs/client/deployers/presets/metadata'; +import { Cloud, Cpu,Database } from 'lucide-react'; export interface Template { id: string @@ -17,38 +17,38 @@ export interface Template { // Icon mapping for template metadata const iconMap: Record> = { - 'Database': Database, - 'Cloud': Cloud, - 'Cpu': Cpu, -} + Database: Database, + Cloud: Cloud, + Cpu: Cpu, +}; // Convert client template metadata to dashboard template format function convertTemplateMetadata(metadata: TemplateMetadata): Template { // Convert environment array to object with default values - const environment: { [key: string]: string } = {} + const environment: { [key: string]: string } = {}; metadata.details.environment.forEach(env => { // Set default values for common environment variables switch (env.name) { - case 'POSTGRES_DB': - environment[env.name] = 'postgres' - break - case 'POSTGRES_USER': - environment[env.name] = 'postgres' - break - case 'POSTGRES_PASSWORD': - environment[env.name] = 'postgres' - break - case 'MINIO_ROOT_USER': - environment[env.name] = 'minioadmin' - break - case 'MINIO_ROOT_PASSWORD': - environment[env.name] = 'minioadmin' - break - default: - environment[env.name] = '' + case 'POSTGRES_DB': + environment[env.name] = 'postgres'; + break; + case 'POSTGRES_USER': + environment[env.name] = 'postgres'; + break; + case 'POSTGRES_PASSWORD': + environment[env.name] = 'postgres'; + break; + case 'MINIO_ROOT_USER': + environment[env.name] = 'minioadmin'; + break; + case 'MINIO_ROOT_PASSWORD': + environment[env.name] = 'minioadmin'; + break; + default: + environment[env.name] = ''; } - }) + }); return { id: metadata.id, @@ -60,8 +60,8 @@ function convertTemplateMetadata(metadata: TemplateMetadata): Template { ports: metadata.details.ports, environment: Object.keys(environment).length > 0 ? environment : undefined, }, - } + }; } // Convert all client templates to dashboard format -export const templates: Template[] = allTemplates.map(convertTemplateMetadata) \ No newline at end of file +export const templates: Template[] = allTemplates.map(convertTemplateMetadata); \ No newline at end of file diff --git a/apps/ops-dashboard/components/ui/accordion.tsx b/apps/ops-dashboard/components/ui/accordion.tsx index bcb6706..db1c19b 100644 --- a/apps/ops-dashboard/components/ui/accordion.tsx +++ b/apps/ops-dashboard/components/ui/accordion.tsx @@ -1,6 +1,6 @@ -import * as React from 'react'; import * as AccordionPrimitive from '@radix-ui/react-accordion'; import { ChevronDown } from 'lucide-react'; +import * as React from 'react'; import { cn } from '@/lib/utils'; @@ -10,7 +10,7 @@ const AccordionItem = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )); AccordionItem.displayName = 'AccordionItem'; @@ -18,19 +18,19 @@ const AccordionTrigger = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( - - svg]:rotate-180', - className, - )} - {...props} - > - {children} - - - + + svg]:rotate-180', + className, + )} + {...props} + > + {children} + + + )); AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName; @@ -38,14 +38,14 @@ const AccordionContent = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( - -
{children}
-
+ +
{children}
+
)); AccordionContent.displayName = AccordionPrimitive.Content.displayName; -export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }; +export { Accordion, AccordionContent,AccordionItem, AccordionTrigger }; diff --git a/apps/ops-dashboard/components/ui/alert-dialog.tsx b/apps/ops-dashboard/components/ui/alert-dialog.tsx index 390fa89..953d452 100644 --- a/apps/ops-dashboard/components/ui/alert-dialog.tsx +++ b/apps/ops-dashboard/components/ui/alert-dialog.tsx @@ -1,8 +1,8 @@ -import * as React from 'react'; import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog'; +import * as React from 'react'; -import { cn } from '@/lib/utils'; import { buttonVariants } from '@/components/ui/button'; +import { cn } from '@/lib/utils'; const AlertDialog = AlertDialogPrimitive.Root; @@ -14,14 +14,14 @@ const AlertDialogOverlay = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )); AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName; @@ -29,27 +29,27 @@ const AlertDialogContent = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - - - - + + + + )); AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName; const AlertDialogHeader = ({ className, ...props }: React.HTMLAttributes) => ( -
+
); AlertDialogHeader.displayName = 'AlertDialogHeader'; const AlertDialogFooter = ({ className, ...props }: React.HTMLAttributes) => ( -
+
); AlertDialogFooter.displayName = 'AlertDialogFooter'; @@ -57,7 +57,7 @@ const AlertDialogTitle = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )); AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName; @@ -65,7 +65,7 @@ const AlertDialogDescription = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )); AlertDialogDescription.displayName = AlertDialogPrimitive.Description.displayName; @@ -73,7 +73,7 @@ const AlertDialogAction = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )); AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName; @@ -81,24 +81,24 @@ const AlertDialogCancel = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )); AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName; export { - AlertDialog, - AlertDialogPortal, - AlertDialogOverlay, - AlertDialogTrigger, - AlertDialogContent, - AlertDialogHeader, - AlertDialogFooter, - AlertDialogTitle, - AlertDialogDescription, - AlertDialogAction, - AlertDialogCancel, + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogOverlay, + AlertDialogPortal, + AlertDialogTitle, + AlertDialogTrigger, }; diff --git a/apps/ops-dashboard/components/ui/alert.tsx b/apps/ops-dashboard/components/ui/alert.tsx index 52979f4..27012c2 100644 --- a/apps/ops-dashboard/components/ui/alert.tsx +++ b/apps/ops-dashboard/components/ui/alert.tsx @@ -1,5 +1,6 @@ -import * as React from 'react'; import { cva, type VariantProps } from 'class-variance-authority'; +import * as React from 'react'; + import { cn } from '@/lib/utils'; const alertVariants = cva( @@ -39,4 +40,4 @@ const AlertDescription = React.forwardRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )); Avatar.displayName = AvatarPrimitive.Root.displayName; @@ -19,7 +19,7 @@ const AvatarImage = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )); AvatarImage.displayName = AvatarPrimitive.Image.displayName; @@ -27,12 +27,12 @@ const AvatarFallback = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )); AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName; -export { Avatar, AvatarImage, AvatarFallback }; +export { Avatar, AvatarFallback,AvatarImage }; diff --git a/apps/ops-dashboard/components/ui/badge.tsx b/apps/ops-dashboard/components/ui/badge.tsx index 9b84e18..d789f1a 100644 --- a/apps/ops-dashboard/components/ui/badge.tsx +++ b/apps/ops-dashboard/components/ui/badge.tsx @@ -1,5 +1,5 @@ -import * as React from 'react'; import { cva, type VariantProps } from 'class-variance-authority'; +import * as React from 'react'; import { cn } from '@/lib/utils'; diff --git a/apps/ops-dashboard/components/ui/breadcrumb.tsx b/apps/ops-dashboard/components/ui/breadcrumb.tsx index feb4185..b2ba4dd 100644 --- a/apps/ops-dashboard/components/ui/breadcrumb.tsx +++ b/apps/ops-dashboard/components/ui/breadcrumb.tsx @@ -1,6 +1,6 @@ -import * as React from 'react'; import { Slot } from '@radix-ui/react-slot'; import { ChevronRight, MoreHorizontal } from 'lucide-react'; +import * as React from 'react'; import { cn } from '@/lib/utils'; @@ -13,20 +13,20 @@ const Breadcrumb = React.forwardRef< Breadcrumb.displayName = 'Breadcrumb'; const BreadcrumbList = React.forwardRef>( - ({ className, ...props }, ref) => ( -
    - ), + ({ className, ...props }, ref) => ( +
      + ), ); BreadcrumbList.displayName = 'BreadcrumbList'; const BreadcrumbItem = React.forwardRef>( - ({ className, ...props }, ref) => ( -
    1. - ), + ({ className, ...props }, ref) => ( +
    2. + ), ); BreadcrumbItem.displayName = 'BreadcrumbItem'; @@ -36,54 +36,54 @@ const BreadcrumbLink = React.forwardRef< asChild?: boolean; } >(({ asChild, className, ...props }, ref) => { - const Comp = asChild ? Slot : 'a'; + const Comp = asChild ? Slot : 'a'; - return ( - - ); + return ( + + ); }); BreadcrumbLink.displayName = 'BreadcrumbLink'; const BreadcrumbPage = React.forwardRef>( - ({ className, ...props }, ref) => ( - - ), + ({ className, ...props }, ref) => ( + + ), ); BreadcrumbPage.displayName = 'BreadcrumbPage'; const BreadcrumbSeparator = ({ children, className, ...props }: React.ComponentProps<'li'>) => ( -
    3. + ); BreadcrumbSeparator.displayName = 'BreadcrumbSeparator'; const BreadcrumbEllipsis = ({ className, ...props }: React.ComponentProps<'span'>) => ( - + ); BreadcrumbEllipsis.displayName = 'BreadcrumbElipssis'; export { - Breadcrumb, - BreadcrumbList, - BreadcrumbItem, - BreadcrumbLink, - BreadcrumbPage, - BreadcrumbSeparator, - BreadcrumbEllipsis, + Breadcrumb, + BreadcrumbEllipsis, + BreadcrumbItem, + BreadcrumbLink, + BreadcrumbList, + BreadcrumbPage, + BreadcrumbSeparator, }; diff --git a/apps/ops-dashboard/components/ui/button.tsx b/apps/ops-dashboard/components/ui/button.tsx index e3b4e41..6dc4277 100644 --- a/apps/ops-dashboard/components/ui/button.tsx +++ b/apps/ops-dashboard/components/ui/button.tsx @@ -1,6 +1,6 @@ -import * as React from 'react'; import { Slot } from '@radix-ui/react-slot'; import { cva, type VariantProps } from 'class-variance-authority'; +import * as React from 'react'; import { cn } from '@/lib/utils'; diff --git a/apps/ops-dashboard/components/ui/card.tsx b/apps/ops-dashboard/components/ui/card.tsx index 15f323b..2606560 100644 --- a/apps/ops-dashboard/components/ui/card.tsx +++ b/apps/ops-dashboard/components/ui/card.tsx @@ -38,4 +38,4 @@ const CardFooter = React.forwardRef; @@ -30,200 +30,200 @@ type CarouselContextProps = { const CarouselContext = React.createContext(null); function useCarousel() { - const context = React.useContext(CarouselContext); + const context = React.useContext(CarouselContext); - if (!context) { - throw new Error('useCarousel must be used within a '); - } + if (!context) { + throw new Error('useCarousel must be used within a '); + } - return context; + return context; } const Carousel = React.forwardRef & CarouselProps>( - ({ orientation = 'horizontal', opts, setApi, plugins, className, children, slidesToScroll = 1, ...props }, ref) => { - const [carouselRef, api] = useEmblaCarousel( - { - ...opts, - axis: orientation === 'horizontal' ? 'x' : 'y', - }, - plugins, - ); - const [canScrollPrev, setCanScrollPrev] = React.useState(false); - const [canScrollNext, setCanScrollNext] = React.useState(false); - - const onSelect = React.useCallback((api: CarouselApi) => { - if (!api) { - return; - } - - setCanScrollPrev(api.canScrollPrev()); - setCanScrollNext(api.canScrollNext()); - }, []); - - const scrollPrev = React.useCallback(() => { - if (!api) return; - const currentIndex = api.selectedScrollSnap(); - api.scrollTo(Math.max(currentIndex - slidesToScroll, 0)); - }, [api, slidesToScroll]); - - const scrollNext = React.useCallback(() => { - if (!api) return; - const currentIndex = api.selectedScrollSnap(); - api.scrollTo(Math.min(currentIndex + slidesToScroll, api.scrollSnapList().length - 1)); - }, [api, slidesToScroll]); - - const handleKeyDown = React.useCallback( - (event: React.KeyboardEvent) => { - if (event.key === 'ArrowLeft') { - event.preventDefault(); - scrollPrev(); - } else if (event.key === 'ArrowRight') { - event.preventDefault(); - scrollNext(); - } - }, - [scrollPrev, scrollNext], - ); - - React.useEffect(() => { - if (!api || !setApi) { - return; - } - - setApi(api); - }, [api, setApi]); - - React.useEffect(() => { - if (!api) { - return; - } - - onSelect(api); - api.on('reInit', onSelect); - api.on('select', onSelect); - - return () => { - api?.off('select', onSelect); - }; - }, [api, onSelect]); - - return ( - -
      - {children} -
      -
      - ); - }, + ({ orientation = 'horizontal', opts, setApi, plugins, className, children, slidesToScroll = 1, ...props }, ref) => { + const [carouselRef, api] = useEmblaCarousel( + { + ...opts, + axis: orientation === 'horizontal' ? 'x' : 'y', + }, + plugins, + ); + const [canScrollPrev, setCanScrollPrev] = React.useState(false); + const [canScrollNext, setCanScrollNext] = React.useState(false); + + const onSelect = React.useCallback((api: CarouselApi) => { + if (!api) { + return; + } + + setCanScrollPrev(api.canScrollPrev()); + setCanScrollNext(api.canScrollNext()); + }, []); + + const scrollPrev = React.useCallback(() => { + if (!api) return; + const currentIndex = api.selectedScrollSnap(); + api.scrollTo(Math.max(currentIndex - slidesToScroll, 0)); + }, [api, slidesToScroll]); + + const scrollNext = React.useCallback(() => { + if (!api) return; + const currentIndex = api.selectedScrollSnap(); + api.scrollTo(Math.min(currentIndex + slidesToScroll, api.scrollSnapList().length - 1)); + }, [api, slidesToScroll]); + + const handleKeyDown = React.useCallback( + (event: React.KeyboardEvent) => { + if (event.key === 'ArrowLeft') { + event.preventDefault(); + scrollPrev(); + } else if (event.key === 'ArrowRight') { + event.preventDefault(); + scrollNext(); + } + }, + [scrollPrev, scrollNext], + ); + + React.useEffect(() => { + if (!api || !setApi) { + return; + } + + setApi(api); + }, [api, setApi]); + + React.useEffect(() => { + if (!api) { + return; + } + + onSelect(api); + api.on('reInit', onSelect); + api.on('select', onSelect); + + return () => { + api?.off('select', onSelect); + }; + }, [api, onSelect]); + + return ( + +
      + {children} +
      +
      + ); + }, ); Carousel.displayName = 'Carousel'; const CarouselContent = React.forwardRef>( - ({ className, ...props }, ref) => { - const { carouselRef, orientation } = useCarousel(); - - return ( -
      -
      -
      - ); - }, + ({ className, ...props }, ref) => { + const { carouselRef, orientation } = useCarousel(); + + return ( +
      +
      +
      + ); + }, ); CarouselContent.displayName = 'CarouselContent'; const CarouselItem = React.forwardRef>( - ({ className, ...props }, ref) => { - const { orientation } = useCarousel(); - - return ( -
      - ); - }, + ({ className, ...props }, ref) => { + const { orientation } = useCarousel(); + + return ( +
      + ); + }, ); CarouselItem.displayName = 'CarouselItem'; const CarouselPrevious = React.forwardRef>( - ({ className, variant = 'outline', size = 'icon', ...props }, ref) => { - const { orientation, scrollPrev, canScrollPrev } = useCarousel(); - - return ( - - ); - }, + ({ className, variant = 'outline', size = 'icon', ...props }, ref) => { + const { orientation, scrollPrev, canScrollPrev } = useCarousel(); + + return ( + + ); + }, ); CarouselPrevious.displayName = 'CarouselPrevious'; const CarouselNext = React.forwardRef>( - ({ className, variant = 'outline', size = 'icon', ...props }, ref) => { - const { orientation, scrollNext, canScrollNext } = useCarousel(); - - return ( - - ); - }, + ({ className, variant = 'outline', size = 'icon', ...props }, ref) => { + const { orientation, scrollNext, canScrollNext } = useCarousel(); + + return ( + + ); + }, ); CarouselNext.displayName = 'CarouselNext'; -export { type CarouselApi, Carousel, CarouselContent, CarouselItem, CarouselPrevious, CarouselNext }; +export { Carousel, type CarouselApi, CarouselContent, CarouselItem, CarouselNext,CarouselPrevious }; diff --git a/apps/ops-dashboard/components/ui/checkbox.tsx b/apps/ops-dashboard/components/ui/checkbox.tsx index 0fccd3b..d4549c6 100644 --- a/apps/ops-dashboard/components/ui/checkbox.tsx +++ b/apps/ops-dashboard/components/ui/checkbox.tsx @@ -1,6 +1,6 @@ -import * as React from 'react'; import * as CheckboxPrimitive from '@radix-ui/react-checkbox'; import { Check } from 'lucide-react'; +import * as React from 'react'; import { cn } from '@/lib/utils'; @@ -8,22 +8,22 @@ const Checkbox = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - - - - - + className, + )} + {...props} + > + + + + )); Checkbox.displayName = CheckboxPrimitive.Root.displayName; diff --git a/apps/ops-dashboard/components/ui/confirm-dialog.tsx b/apps/ops-dashboard/components/ui/confirm-dialog.tsx index addeb58..2d14649 100644 --- a/apps/ops-dashboard/components/ui/confirm-dialog.tsx +++ b/apps/ops-dashboard/components/ui/confirm-dialog.tsx @@ -1,6 +1,8 @@ 'use client'; import * as React from 'react'; + +import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, @@ -9,7 +11,6 @@ import { DialogHeader, DialogTitle, } from '@/components/ui/dialog'; -import { Button } from '@/components/ui/button'; export interface ConfirmDialogProps { open: boolean; diff --git a/apps/ops-dashboard/components/ui/context-menu.tsx b/apps/ops-dashboard/components/ui/context-menu.tsx index 397453d..59a158c 100644 --- a/apps/ops-dashboard/components/ui/context-menu.tsx +++ b/apps/ops-dashboard/components/ui/context-menu.tsx @@ -1,6 +1,6 @@ -import * as React from 'react'; import * as ContextMenuPrimitive from '@radix-ui/react-context-menu'; import { Check, ChevronRight, Circle } from 'lucide-react'; +import * as React from 'react'; import { cn } from '@/lib/utils'; @@ -22,18 +22,18 @@ const ContextMenuSubTrigger = React.forwardRef< inset?: boolean; } >(({ className, inset, children, ...props }, ref) => ( - - {children} - - + + {children} + + )); ContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName; @@ -41,14 +41,14 @@ const ContextMenuSubContent = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )); ContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName; @@ -56,16 +56,16 @@ const ContextMenuContent = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - - - + + + )); ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName; @@ -75,15 +75,15 @@ const ContextMenuItem = React.forwardRef< inset?: boolean; } >(({ className, inset, ...props }, ref) => ( - + )); ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName; @@ -91,22 +91,22 @@ const ContextMenuCheckboxItem = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, children, checked, ...props }, ref) => ( - - - - - - - {children} - + + + + + + + {children} + )); ContextMenuCheckboxItem.displayName = ContextMenuPrimitive.CheckboxItem.displayName; @@ -114,21 +114,21 @@ const ContextMenuRadioItem = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( - - - - - - - {children} - + + + + + + + {children} + )); ContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName; @@ -138,11 +138,11 @@ const ContextMenuLabel = React.forwardRef< inset?: boolean; } >(({ className, inset, ...props }, ref) => ( - + )); ContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName; @@ -150,29 +150,29 @@ const ContextMenuSeparator = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )); ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName; const ContextMenuShortcut = ({ className, ...props }: React.HTMLAttributes) => { - return ; + return ; }; ContextMenuShortcut.displayName = 'ContextMenuShortcut'; export { - ContextMenu, - ContextMenuTrigger, - ContextMenuContent, - ContextMenuItem, - ContextMenuCheckboxItem, - ContextMenuRadioItem, - ContextMenuLabel, - ContextMenuSeparator, - ContextMenuShortcut, - ContextMenuGroup, - ContextMenuPortal, - ContextMenuSub, - ContextMenuSubContent, - ContextMenuSubTrigger, - ContextMenuRadioGroup, + ContextMenu, + ContextMenuCheckboxItem, + ContextMenuContent, + ContextMenuGroup, + ContextMenuItem, + ContextMenuLabel, + ContextMenuPortal, + ContextMenuRadioGroup, + ContextMenuRadioItem, + ContextMenuSeparator, + ContextMenuShortcut, + ContextMenuSub, + ContextMenuSubContent, + ContextMenuSubTrigger, + ContextMenuTrigger, }; diff --git a/apps/ops-dashboard/components/ui/dialog.tsx b/apps/ops-dashboard/components/ui/dialog.tsx index 0f7720c..53fc428 100644 --- a/apps/ops-dashboard/components/ui/dialog.tsx +++ b/apps/ops-dashboard/components/ui/dialog.tsx @@ -1,6 +1,6 @@ -import * as React from 'react'; import * as DialogPrimitive from '@radix-ui/react-dialog'; import { X } from 'lucide-react'; +import * as React from 'react'; import { cn } from '@/lib/utils'; @@ -83,13 +83,13 @@ DialogDescription.displayName = DialogPrimitive.Description.displayName; export { Dialog, - DialogPortal, - DialogOverlay, DialogClose, - DialogTrigger, DialogContent, - DialogHeader, + DialogDescription, DialogFooter, + DialogHeader, + DialogOverlay, + DialogPortal, DialogTitle, - DialogDescription, + DialogTrigger, }; diff --git a/apps/ops-dashboard/components/ui/dropdown-menu.tsx b/apps/ops-dashboard/components/ui/dropdown-menu.tsx index b68f21f..95a6b80 100644 --- a/apps/ops-dashboard/components/ui/dropdown-menu.tsx +++ b/apps/ops-dashboard/components/ui/dropdown-menu.tsx @@ -1,8 +1,8 @@ 'use client'; -import * as React from 'react'; import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu'; import { Check, ChevronRight, Circle } from 'lucide-react'; +import * as React from 'react'; import { cn } from '@/lib/utils'; @@ -164,18 +164,18 @@ DropdownMenuShortcut.displayName = 'DropdownMenuShortcut'; export { DropdownMenu, - DropdownMenuTrigger, + DropdownMenuCheckboxItem, DropdownMenuContent, + DropdownMenuGroup, DropdownMenuItem, - DropdownMenuCheckboxItem, - DropdownMenuRadioItem, DropdownMenuLabel, + DropdownMenuPortal, + DropdownMenuRadioGroup, + DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, - DropdownMenuGroup, - DropdownMenuPortal, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, - DropdownMenuRadioGroup, + DropdownMenuTrigger, }; diff --git a/apps/ops-dashboard/components/ui/form.tsx b/apps/ops-dashboard/components/ui/form.tsx index 2c35ef9..f7bc7da 100644 --- a/apps/ops-dashboard/components/ui/form.tsx +++ b/apps/ops-dashboard/components/ui/form.tsx @@ -1,10 +1,10 @@ -import * as React from 'react'; import * as LabelPrimitive from '@radix-ui/react-label'; import { Slot } from '@radix-ui/react-slot'; +import * as React from 'react'; import { Controller, ControllerProps, FieldPath, FieldValues, FormProvider, useFormContext } from 'react-hook-form'; -import { cn } from '@/lib/utils'; import { Label } from '@/components/ui/label'; +import { cn } from '@/lib/utils'; const Form = FormProvider; @@ -21,36 +21,36 @@ const FormField = < TFieldValues extends FieldValues = FieldValues, TName extends FieldPath = FieldPath, >({ - ...props -}: ControllerProps) => { - return ( - - - - ); + ...props + }: ControllerProps) => { + return ( + + + + ); }; const useFormField = () => { - const fieldContext = React.useContext(FormFieldContext); - const itemContext = React.useContext(FormItemContext); - const { getFieldState, formState } = useFormContext(); - - const fieldState = getFieldState(fieldContext.name, formState); - - if (!fieldContext) { - throw new Error('useFormField should be used within '); - } - - const { id } = itemContext; - - return { - id, - name: fieldContext.name, - formItemId: `${id}-form-item`, - formDescriptionId: `${id}-form-item-description`, - formMessageId: `${id}-form-item-message`, - ...fieldState, - }; + const fieldContext = React.useContext(FormFieldContext); + const itemContext = React.useContext(FormItemContext); + const { getFieldState, formState } = useFormContext(); + + const fieldState = getFieldState(fieldContext.name, formState); + + if (!fieldContext) { + throw new Error('useFormField should be used within '); + } + + const { id } = itemContext; + + return { + id, + name: fieldContext.name, + formItemId: `${id}-form-item`, + formDescriptionId: `${id}-form-item-description`, + formMessageId: `${id}-form-item-message`, + ...fieldState, + }; }; type FormItemContextValue = { @@ -60,15 +60,15 @@ type FormItemContextValue = { const FormItemContext = React.createContext({} as FormItemContextValue); const FormItem = React.forwardRef>( - ({ className, ...props }, ref) => { - const id = React.useId(); - - return ( - -
      - - ); - }, + ({ className, ...props }, ref) => { + const id = React.useId(); + + return ( + +
      + + ); + }, ); FormItem.displayName = 'FormItem'; @@ -76,66 +76,66 @@ const FormLabel = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => { - const { formItemId } = useFormField(); + const { formItemId } = useFormField(); - return