diff --git a/AGENTS.md b/AGENTS.md index 052bb77..226a93f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -7,6 +7,12 @@ This is the project map. Read this first, every session. FaaS PoC UI for OpenShift Console — React + TypeScript + Webpack + PatternFly 6 + OCP Dynamic Plugin SDK. See `docs/design/` for full design specs. +## Communication + +- Ask before staring modifications of code. +- Ask before starting a new task or making a design decision. +- Once actively implementing, keep going without asking. Only stop to ask when blocked by sandbox, permissions, or ambiguous requirements. + ## Writing Style No em dashes (`—`). Use commas, periods, or parentheses instead. diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index a61e8bc..3fb68c5 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -39,13 +39,23 @@ Arrows mean "imports / depends on." - Services never import Components or Views - No circular dependencies -## Page / Component / Hook Rules +## React -**Components are simple** — they receive data via props, render it, and call callbacks to return data to the parent (or use context). No logic at the top of a component. +### Page / Component / Hook Rules -**Pages are smart** — they use central hooks (e.g. `useClusterService`, `useSourceControl`) to fetch, prepare, and transform all data needed for downstream components. +**Components are simple by default** — they receive data via props, render it, and call callbacks. No logic at the top of a component. -**Extract logic into hooks** — if a page or component has any logic (state management, data transformation, side effects), extract it into a co-named hook: `FunctionTable.tsx` → `useFunctionTable.ts`, `FunctionsListPage.tsx` → `useFunctionsListPage.ts`. If there is no logic, no hook is needed. +**A component may own its own data and state when it encapsulates a self-contained capability that is not specific to any one page** (e.g., forge connection, auth flows, notification subscriptions). The component becomes the single owner of that concern. Pages consume it without orchestrating its internals. + +**Pages are smart for page-specific data** — they use central hooks (e.g. `useClusterService`, `useSourceControl`) to fetch, prepare, and transform all data needed for downstream components. + +**Extract logic into hooks** — if a page or component has any logic (state management, data transformation, side effects), extract it into a custom hook. If the hook is reused by multiple components, put it in a separate file: `useFunctionTable.ts`. If the hook is only used by one component, keep it in the same file, do not export it. If there is no logic, no hook is needed. + +**File ordering** — within a file, put the exported component at the top, then its hook below, then helper functions at the bottom. Readers see the main thing first and can drill down. + +### Performance + +- **No speculative memoization**: Do not wrap every function in `useCallback` or every value in `useMemo` as a habit. Use them when there is a concrete reason: a `React.memo` child that depends on a stable reference, or a known re-render path (e.g., a sibling component re-rendering on every keystroke). Plain functions and derived values are the default. ## Architectural Guidance diff --git a/docs/STYLEGUIDE.md b/docs/STYLEGUIDE.md index 60820f2..caab021 100644 --- a/docs/STYLEGUIDE.md +++ b/docs/STYLEGUIDE.md @@ -17,11 +17,17 @@ - **No `any` type**: Use proper TypeScript types. - **No `console.log`**: Use structured approach if logging needed. - **Naming**: `use*` for hooks, `*Service` for services, PascalCase for components/types. +- **Co-locate helper functions**: Keep helper functions in the same file as the component or hook that uses them. Test them indirectly through the consumer's tests. Only extract to `utils/` when shared across multiple unrelated modules. ## Documentation - **No em dashes (`—`)**. Use commas, periods, or parentheses instead. +## CSS + +- **PatternFly first**: Use PatternFly component props for all layout and spacing. Only fall back to custom CSS when PatternFly does not cover the need. +- **Relative units only**: When custom CSS is necessary, use `rem` and `em` for all sizing. Never use `px`. + ## OCP Plugin Styling Constraints The `.stylelintrc.yaml` enforces strict rules to prevent breaking the OpenShift Console: diff --git a/docs/WORKFLOW.md b/docs/WORKFLOW.md index 67c6751..9ec8524 100644 --- a/docs/WORKFLOW.md +++ b/docs/WORKFLOW.md @@ -17,7 +17,7 @@ Every session, before doing any work: After [Startup Sequence](#startup-sequence), work through the picked feature: 1. **Plan** — read `docs/ARCHITECTURE.md` + `docs/STYLEGUIDE.md` + `docs/TESTING.md`, then use `/brainstorming` to design the chosen feature from `docs/features.json`, then use `/writing-plans` to create implementation plan → `docs/plans/active/--.md` -2. **Branch** — create feature branch per [Branching](#branching) convention +2. **Branch** — create feature branch per [Branching](#branching) convention. Immediately push and open a **draft PR** (`gh pr create --draft`) to reserve the PR number for other contributors' branch numbering. 3. **Implement** — using `/executing-plans` skill 4. **Review** — code review using `/requesting-code-review` skill, fix found issues 5. **Manual Test** — use browser automation and validate it works in the browser diff --git a/docs/claude-progress.txt b/docs/claude-progress.txt index cfe2b2f..f4e0d4b 100644 --- a/docs/claude-progress.txt +++ b/docs/claude-progress.txt @@ -1,6 +1,27 @@ # Claude Progress Log # Newest entries first. Agents: append your entry at the top after the header. +--- +## 2026-04-28 | Session: Function Edit Page +Worked on: Full Function Edit Page feature (plan 016) +Completed: +- Function Edit Page with FileTreeView file browser and SDK CodeEditor +- FileTreeView component: loading spinner state, empty placeholder, directories-before-files sorting, dirty dot indicators, fixed width with horizontal scroll +- SDK CodeEditor with empty state (code icon, "Start editing"), language label, auto-selected handler file based on func.yaml runtime +- EditToolbar with Back link (unsaved changes modal), Save & Deploy (success alert with 2s auto-dismiss, danger alert on error) +- SourceControlService: fetch(repo) via git.getTree recursive + blob fetches, updateRepo(repo) with local commit SHA cache for GitHub's eventual consistency +- Decomposed push() into push() (initial commits) and updateRepo() (subsequent commits) +- Migrated test runner from Jest to Vitest with MSW 2.x for GitHub API mocking +- Merged RepoInfo + SourceRepo into single RepoMetadata type +- Extracted parseNamespaceAndRuntime, getLanguageFromPath, handlerMap into shared utils +- Added CSP connect-src for GitHub API in dev mode (start-console.sh) +- Removed navigation state passing between pages (each page loads own data from URL params) +- Added CSS, co-location, React performance rules to style guide and architecture docs +- Added communication rules and draft PR step to workflow docs +- 12 test suites, 89 tests, all passing, zero lint errors +Left off: PR #16 ready for review. Missing test coverage for dirty tracking, save error alert, modal interactions, file selection. +Blockers: None + --- ## 2026-04-28 | Session: Runtime PAT entry and user avatar Worked on: Replace compile-time PAT injection with runtime modal entry, add user avatar to page headers diff --git a/docs/features.json b/docs/features.json index 1eae9b9..26bb702 100644 --- a/docs/features.json +++ b/docs/features.json @@ -96,6 +96,19 @@ ], "passes": true }, + { + "category": "technical", + "description": "CI/CD: GitHub Actions pipelines for PR checks and master publish to GHCR, plus lint fixes and README deployment instructions", + "steps": [ + "PR pipeline (.github/workflows/pr.yml): triggers on pull_request to master, runs yarn install --immutable, yarn lint, yarn test — branch cannot merge without passing checks and an approval", + "Publish pipeline (.github/workflows/publish.yml): triggers on push to master (merged PRs), runs yarn install --immutable, yarn lint, yarn test, then builds multi-arch container image via docker/build-push-action using existing Dockerfile and pushes to ghcr.io/twogiants/console-functions-plugin with :latest and :sha- tags", + "Both pipelines use actions/setup-node@v4 with node-version 22, corepack enable, and cache: yarn for Yarn install caching (GitHub runners ship Node 20 by default with corepack disabled)", + "Both pipelines authenticate to GHCR using GITHUB_TOKEN secret with packages:write permission (token added to repo's Actions secrets)", + "Add yarn lint script to package.json if missing, run it, and fix all lint errors in the codebase", + "Update README.md deployment section (lines 96-117) — replace generic Helm boilerplate, placeholder commands, and obsolete OCP 4.10 / i18n notes with concrete instructions: oc new-project console-functions-plugin, helm upgrade -i console-functions-plugin charts/openshift-console-plugin -n console-functions-plugin --create-namespace --set plugin.image=ghcr.io/twogiants/console-functions-plugin:latest@sha256:" + ], + "passes": true + }, { "category": "functional", "description": "GitHub PAT Avatar: session-wide PAT entry via modal + avatar component showing authenticated GitHub user", @@ -126,19 +139,6 @@ ], "passes": false }, - { - "category": "technical", - "description": "CI/CD: GitHub Actions pipelines for PR checks and master publish to GHCR, plus lint fixes and README deployment instructions", - "steps": [ - "PR pipeline (.github/workflows/pr.yml): triggers on pull_request to master, runs yarn install --immutable, yarn lint, yarn test — branch cannot merge without passing checks and an approval", - "Publish pipeline (.github/workflows/publish.yml): triggers on push to master (merged PRs), runs yarn install --immutable, yarn lint, yarn test, then builds multi-arch container image via docker/build-push-action using existing Dockerfile and pushes to ghcr.io/twogiants/console-functions-plugin with :latest and :sha- tags", - "Both pipelines use actions/setup-node@v4 with node-version 22, corepack enable, and cache: yarn for Yarn install caching (GitHub runners ship Node 20 by default with corepack disabled)", - "Both pipelines authenticate to GHCR using GITHUB_TOKEN secret with packages:write permission (token added to repo's Actions secrets)", - "Add yarn lint script to package.json if missing, run it, and fix all lint errors in the codebase", - "Update README.md deployment section (lines 96-117) — replace generic Helm boilerplate, placeholder commands, and obsolete OCP 4.10 / i18n notes with concrete instructions: oc new-project console-functions-plugin, helm upgrade -i console-functions-plugin charts/openshift-console-plugin -n console-functions-plugin --create-namespace --set plugin.image=ghcr.io/twogiants/console-functions-plugin:latest@sha256:" - ], - "passes": true - }, { "category": "functional", "description": "Set GitHub Secret (KUBECONFIG) on created function repos so GH Actions can deploy to the cluster", @@ -149,5 +149,23 @@ "GH Actions workflow can authenticate to the cluster and run func deploy" ], "passes": false + }, + { + "category": "functional", + "description": "Function Edit Page with TreeView file browser and CodeEditor for editing and deploying function code", + "steps": [ + "SourceControlService extended with fetch(repo) and updateRepo(repo) methods. fetch retrieves full repo tree via git.getTree recursive + blob fetches. updateRepo commits on existing branches with local commit SHA cache for GitHub's eventual consistency", + "Navigate to /faas/edit/:name loads files from GitHub via listFunctionRepos + fetch (each page loads its own data from URL params)", + "Page layout: toolbar at top (Back link left, success/danger Alert center, Save & Deploy button right), FileTreeView fixed-width left panel (16rem, horizontally scrollable), SDK CodeEditor fills remaining width (70vh height)", + "FileTreeView builds nested tree from flat FileEntry[] paths with loading spinner state, empty placeholder state, directories expand/collapse only, files are selectable and update CodeEditor content", + "SDK CodeEditor with empty state (code icon + 'Start editing' message) when no file selected, language label visible in header", + "CodeEditor language auto-detected from file extension via getLanguageFromPath utility", + "Handler file auto-selected on load based on runtime from func.yaml (no fallback selection if handler not found)", + "Modified files indicated in tree with dot indicator after filename, dirty state derived by comparing working content against original per file on every onChange", + "Save & Deploy button pushes all files to GitHub via updateRepo, resets dirty state on success, shows spinner and disables button during push, shows success alert with auto-dismiss after 2 seconds", + "Back to Functions link navigates to /faas directly if clean, shows unsaved changes confirmation modal if dirty", + "Empty tree with 'No files' placeholder and disabled Save & Deploy when repo not found, back link always visible" + ], + "passes": true } ] diff --git a/docs/plans/completed/016-feat-function-edit-page.md b/docs/plans/completed/016-feat-function-edit-page.md new file mode 100644 index 0000000..fb3ecbf --- /dev/null +++ b/docs/plans/completed/016-feat-function-edit-page.md @@ -0,0 +1,86 @@ +# Function Edit Page Implementation Plan + +**Status:** COMPLETED + +**Goal:** Build the Function Edit Page with a TreeView file browser and CodeEditor for editing and deploying function code to GitHub. + +**Architecture:** The page follows the project's layered architecture. A `useFunctionEditPage` hook (co-located in the view file, unexported) handles data loading, state management, and save logic. A `FileTreeView` component with a co-located `useFileTreeView` hook renders the file tree. An `EditToolbar` component with `useEditToolbar` hook manages save flow and navigation. The `SourceControlService` interface is extended with `fetch()` and `updateRepo()`. + +**Tech Stack:** React, PatternFly 6 (TreeView, Toolbar, Modal, Button, Alert, EmptyState), OCP Dynamic Plugin SDK (CodeEditor, DocumentTitle, ListPageHeader), Vitest + React Testing Library + MSW + +**Testing approach:** MSW for all GitHub API interactions. `vi.mock` only for `react-i18next` and OCP SDK components. + +--- + +## Completed Tasks + +### Task 1: Add fetch() to SourceControlService and GithubService + +- Added `fetch(repo)` using `git.getTree({ recursive: '1' })` + per-file `git.getBlob` +- Migrated all GithubService tests from `vi.mock('@octokit/rest')` to MSW handlers +- Renamed test file to `GithubService.test.ts` +- Merged `RepoInfo` + `SourceRepo` into single `RepoMetadata` type +- Added test for `fetchFileContent` error path + +### Task 2: Decompose push() into push() and updateRepo() + +- `push()` for initial commits (createRef, no parents) +- `updateRepo()` for subsequent commits with local commit SHA cache +- Cache handles GitHub's eventually consistent ref storage (stale getRef on rapid saves) +- Cache clears only on "not a fast forward" errors (external push), not on network errors +- 5 updateRepo tests: first push, second from cache, third from cache, stale cache recovery, network error preserves cache + +### Task 3: Add getLanguageFromPath utility + +- Maps file extensions and special filenames (Dockerfile, Makefile) to Monaco Language enum +- Extracted to shared `src/utils/utils.ts` along with `parseNamespaceAndRuntime` and `handlerMap` + +### Tasks 4+5: FileTreeView component + +- Builds `TreeViewDataItem[]` directly from flat `FileEntry[]` paths (no intermediate type) +- Separate handling for root files and nested files +- Directories render before files, sorted alphabetically +- Loading state with spinner and "Loading source..." text +- Empty state with "No files" placeholder (not clickable) +- Dirty indicator after filename (`func.yaml ●`) +- `React.memo` with `useMemo` (justified: parent re-renders on every CodeEditor keystroke) +- Fixed width (16rem) with horizontal scroll, vertical scroll for long file lists +- 11 test cases using realistic Node function file structure from knative/func templates + +### Task 6: FunctionEditPage view and hooks + +- Page component: toolbar + flex layout (FileTreeView left, SDK CodeEditor right) +- `Flex` with `direction: row`, `flexWrap: nowrap`, `alignItems: stretch` (fixes baseline alignment stacking issue) +- SDK CodeEditor with `height="70vh"`, empty state (code icon + "Start editing"), language label visible +- Handler file auto-selected based on runtime from func.yaml (function.go for Go, index.js for Node, function/func.py for Python) +- Each page loads its own data from URL params (no navigation state passing between pages) +- `resolveRepoContent` extracts API calls from state management +- Repo metadata stored in state after load for save without re-fetching + +### EditToolbar component + +- Back link (left), success/danger Alert (center), Save & Deploy button (right) +- `useEditToolbar` hook: save flow with isSaving/error/success state +- Success alert "Pushed to GitHub. Deployment running..." with 2-second auto-dismiss (tested with `vi.useFakeTimers`) +- Unsaved changes confirmation modal (LeaveModal) on back navigation when dirty +- Save & Deploy disabled when no changes + +### Infrastructure changes + +- Migrated from Jest to Vitest with MSW 2.x +- Custom jsdom environment removed (Vitest handles globals natively) +- CSP connect-src for GitHub API added to start-console.sh for dev mode +- Added CSS, co-location, React performance rules to style guide and architecture docs +- Added communication rules and draft PR step to workflow docs + +--- + +## Deviations from original plan + +- Used SDK CodeEditor instead of PatternFly CodeEditor (CSP blob URL issues with Monaco workers in OCP Console) +- Removed navigation state passing between list and edit page (each page is self-contained) +- Split `push()` into `push()` + `updateRepo()` (clearer separation of initial vs subsequent commits) +- Added local commit SHA cache (GitHub eventual consistency workaround) +- Added success alert after save (not in original plan) +- Editor empty state with code icon (not in original plan) +- `autoSelectHandler` renamed to `determineHandler` (pure function, returns path instead of calling setState) diff --git a/docs/potential-features.json b/docs/potential-features.json index ab8d84b..1e8985f 100644 --- a/docs/potential-features.json +++ b/docs/potential-features.json @@ -22,5 +22,16 @@ "Namespace column visible in admin perspective, hidden in dev perspective (redundant with project selector)" ], "passes": false + }, + { + "category": "technical", + "description": "Replace per-file blob fetching in GithubService.fetch() with single archive download (downloadTarballArchive) and extraction for better performance", + "steps": [ + "Download repo as tarball via octokit.repos.downloadTarballArchive()", + "Decompress gzip with DecompressionStream, parse tar format", + "Strip the prefix directory from extracted paths", + "Return FileEntry[] from extracted contents instead of N+1 getBlob calls" + ], + "passes": false } ] diff --git a/jest.config.ts b/jest.config.ts deleted file mode 100644 index 7893a2e..0000000 --- a/jest.config.ts +++ /dev/null @@ -1,14 +0,0 @@ -import type { Config } from 'jest'; - -const config: Config = { - testEnvironment: 'jsdom', - transform: { - '^.+\\.tsx?$': 'ts-jest', - }, - moduleNameMapper: { - '\\.css$': 'identity-obj-proxy', - }, - setupFilesAfterEnv: ['./src/test-setup.ts'], -}; - -export default config; diff --git a/locales/en/plugin__console-functions-plugin.json b/locales/en/plugin__console-functions-plugin.json index 5a1d2af..8541f68 100644 --- a/locales/en/plugin__console-functions-plugin.json +++ b/locales/en/plugin__console-functions-plugin.json @@ -13,6 +13,7 @@ "Delete": "Delete", "Edit": "Edit", "Enter your GitHub Personal Access Token to connect your repositories.": "Enter your GitHub Personal Access Token to connect your repositories.", + "Edit function": "Edit function", "Error creating function": "Error creating function", "Function Settings": "Function Settings", "FaaS": "FaaS", @@ -25,6 +26,7 @@ "No functions found": "No functions found", "Owner": "Owner", "Personal Access Token": "Personal Access Token", + "Pushed to GitHub. Deployment running...": "Pushed to GitHub. Deployment running...", "Registry": "Registry", "Replicas": "Replicas", "Repository": "Repository", @@ -32,5 +34,13 @@ "Serverless functions in your repository and deployed to your cluster. Manage lifecycle, monitor status, and scale on demand.": "Serverless functions in your repository and deployed to your cluster. Manage lifecycle, monitor status, and scale on demand.", "Status": "Status", "URL": "URL", - "Undeploy": "Undeploy" + "Undeploy": "Undeploy", + "Back to Functions": "Back to Functions", + "Save & Deploy": "Save & Deploy", + "Select a file from the tree view to start editing.": "Select a file from the tree view to start editing.", + "Start editing": "Start editing", + "Unsaved changes": "Unsaved changes", + "You have unsaved changes. Leave anyway?": "You have unsaved changes. Leave anyway?", + "Stay": "Stay", + "Leave": "Leave" } diff --git a/package.json b/package.json index a117f7c..6ade408 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "build-dev": "yarn clean && yarn webpack", "start": "yarn webpack serve --progress", "start-console": "./start-console.sh", - "test": "jest", + "test": "vitest run", "i18n": "./i18n-scripts/build-i18n.sh && node ./i18n-scripts/set-english-defaults.js", "lint": "yarn eslint src integration-tests --fix && stylelint 'src/**/*.css' --allow-empty-input --fix", "test-cypress": "cd integration-tests && cypress open", @@ -37,11 +37,10 @@ "@testing-library/jest-dom": "^6.9.1", "@testing-library/react": "^12.1.5", "@testing-library/user-event": "^14.6.1", - "@types/identity-obj-proxy": "^3", - "@types/jest": "^30.0.0", "@types/node": "^22.0.0", "@types/react": "^17.0.37", "@types/react-router-dom": "^5.3.3", + "@vitest/coverage-v8": "^4.1.5", "babel-loader": "^10.1.0", "copy-webpack-plugin": "^14.0.0", "css-loader": "^7.1.4", @@ -56,13 +55,12 @@ "globals": "^17.4.0", "i18next": "^23.11.5", "i18next-parser": "^9.4.0", - "identity-obj-proxy": "^3.0.0", - "jest": "^30.3.0", - "jest-environment-jsdom": "^30.3.0", + "jsdom": "^29.0.2", "mocha": "^11.7.5", "mocha-junit-reporter": "^2.2.1", "mochawesome": "^7.1.4", "mochawesome-merge": "^5.1.1", + "msw": "^2.13.6", "pluralize": "^8.0.0", "prettier": "^3.8.1", "prettier-stylelint": "^0.4.2", @@ -75,11 +73,11 @@ "style-loader": "^4.0.0", "stylelint": "^17.4.0", "stylelint-config-standard": "^40.0.0", - "ts-jest": "^29.4.6", "ts-loader": "^9.5.4", "ts-node": "^10.9.2", "typescript": "^5.9.3", "typescript-eslint": "^8.56.1", + "vitest": "^4.1.5", "webpack": "^5.100.0", "webpack-cli": "^6.0.1", "webpack-dev-server": "^5.2.3" @@ -100,6 +98,7 @@ }, "packageManager": "yarn@4.13.0", "dependencies": { - "@octokit/rest": "^22.0.1" + "@octokit/rest": "^22.0.1", + "@patternfly/react-code-editor": "^6.4.3" } } diff --git a/src/components/CreateFunctionForm.test.tsx b/src/components/CreateFunctionForm.test.tsx index 91e74cd..8d8be42 100644 --- a/src/components/CreateFunctionForm.test.tsx +++ b/src/components/CreateFunctionForm.test.tsx @@ -2,17 +2,17 @@ import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { CreateFunctionForm } from './CreateFunctionForm'; -jest.mock('react-i18next', () => ({ +vi.mock('react-i18next', () => ({ useTranslation: () => ({ t: (key: string) => key }), })); afterEach(() => { - jest.restoreAllMocks(); + vi.restoreAllMocks(); }); describe('CreateFunctionForm', () => { - const onSubmit = jest.fn(); - const onCancel = jest.fn(); + const onSubmit = vi.fn(); + const onCancel = vi.fn(); beforeEach(() => { onSubmit.mockClear(); diff --git a/src/components/EmptyState.test.tsx b/src/components/EmptyState.test.tsx index f516404..ebd26f2 100644 --- a/src/components/EmptyState.test.tsx +++ b/src/components/EmptyState.test.tsx @@ -2,12 +2,12 @@ import { render, screen } from '@testing-library/react'; import { MemoryRouter } from 'react-router-dom-v5-compat'; import { FunctionsEmptyState } from './EmptyState'; -jest.mock('react-i18next', () => ({ +vi.mock('react-i18next', () => ({ useTranslation: () => ({ t: (key: string) => key }), })); afterEach(() => { - jest.restoreAllMocks(); + vi.restoreAllMocks(); }); describe('FunctionsEmptyState', () => { diff --git a/src/components/FileTreeView.test.tsx b/src/components/FileTreeView.test.tsx new file mode 100644 index 0000000..32c5f9a --- /dev/null +++ b/src/components/FileTreeView.test.tsx @@ -0,0 +1,190 @@ +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { FileTreeView } from './FileTreeView'; +import { FileEntry } from '../services/types'; + +const nodeFuncFiles: FileEntry[] = [ + { path: '.github/workflows/func-deploy.yaml', mode: '100644', content: '', type: 'blob' }, + { path: '.gitignore', mode: '100644', content: '', type: 'blob' }, + { path: 'README.md', mode: '100644', content: '', type: 'blob' }, + { path: 'func.yaml', mode: '100644', content: '', type: 'blob' }, + { path: 'index.js', mode: '100644', content: '', type: 'blob' }, + { path: 'package.json', mode: '100644', content: '', type: 'blob' }, + { path: 'test/integration.js', mode: '100644', content: '', type: 'blob' }, + { path: 'test/unit.js', mode: '100644', content: '', type: 'blob' }, +]; + +describe('FileTreeView', () => { + it('renders all file and directory names', () => { + render( + , + ); + + expect(screen.getByText('.github')).toBeInTheDocument(); + expect(screen.getByText('test')).toBeInTheDocument(); + expect(screen.getByText('func.yaml')).toBeInTheDocument(); + expect(screen.getByText('index.js')).toBeInTheDocument(); + expect(screen.getByText('package.json')).toBeInTheDocument(); + }); + + it('renders directories before files', () => { + render( + , + ); + + const allText = document.body.textContent ?? ''; + const githubPos = allText.indexOf('.github'); + const testPos = allText.indexOf('test'); + const gitignorePos = allText.indexOf('.gitignore'); + + expect(githubPos).toBeLessThan(gitignorePos); + expect(testPos).toBeLessThan(gitignorePos); + }); + + it('renders nested files under their parent directory', () => { + render( + , + ); + + const testDir = screen.getByText('test').closest('[role="treeitem"]'); + const nestedItems = testDir?.querySelectorAll('[role="treeitem"]'); + const nestedNames = Array.from(nestedItems ?? []).map((el) => el.textContent?.trim()); + + expect(nestedNames).toContain('integration.js'); + expect(nestedNames).toContain('unit.js'); + }); + + it('renders deeply nested paths as nested directories', () => { + render( + , + ); + + expect(screen.getByText('.github')).toBeInTheDocument(); + expect(screen.getByText('workflows')).toBeInTheDocument(); + expect(screen.getByText('func-deploy.yaml')).toBeInTheDocument(); + }); + + it('renders multiple files under the same directory', () => { + render( + , + ); + + const testDir = screen.getByText('test'); + const testGroup = testDir.closest('[role="treeitem"]'); + const nested = testGroup?.querySelectorAll('[role="treeitem"]'); + + expect(nested?.length).toBe(2); + }); + + it('shows placeholder when no files provided', () => { + render( + , + ); + + expect(screen.getByText('No files')).toBeInTheDocument(); + expect(screen.getAllByRole('treeitem')).toHaveLength(1); + }); + + it('does not call onSelect when placeholder is clicked', async () => { + const user = userEvent.setup(); + const onSelect = vi.fn(); + + render( + , + ); + + await user.click(screen.getByText('No files')); + + expect(onSelect).not.toHaveBeenCalled(); + }); + + it('calls onSelect when a file is clicked', async () => { + const user = userEvent.setup(); + const onSelect = vi.fn(); + + render( + , + ); + + await user.click(screen.getByText('func.yaml')); + + expect(onSelect).toHaveBeenCalledWith('func.yaml'); + }); + + it('does not call onSelect when a directory is clicked', async () => { + const user = userEvent.setup(); + const onSelect = vi.fn(); + + render( + , + ); + + await user.click(screen.getByText('test')); + + expect(onSelect).not.toHaveBeenCalled(); + }); + + it('shows loading state with spinner', () => { + render( + , + ); + + expect(screen.getByText('Loading source...')).toBeInTheDocument(); + expect(screen.queryByText('No files')).not.toBeInTheDocument(); + }); + + it('shows dirty indicator for modified files', () => { + render( + , + ); + + expect(screen.getByText(/func\.yaml \u25CF/)).toBeInTheDocument(); + expect(screen.queryByText(/index\.js \u25CF/)).not.toBeInTheDocument(); + }); +}); diff --git a/src/components/FileTreeView.tsx b/src/components/FileTreeView.tsx new file mode 100644 index 0000000..29ceabb --- /dev/null +++ b/src/components/FileTreeView.tsx @@ -0,0 +1,165 @@ +import { useMemo } from 'react'; +import { Spinner, TreeView, TreeViewDataItem } from '@patternfly/react-core'; +import { FileEntry } from '../services/types'; +import * as React from 'react'; + +const emptyTreeData: TreeViewDataItem[] = [{ id: '__empty__', name: 'No files' }]; +const loadingTreeData: TreeViewDataItem[] = [ + { + id: '__loading__', + name: ( + <> + Loading source... + + ), + }, +]; + +interface FileTreeViewProps { + files: FileEntry[]; + selectedPath: string | null; + dirtyPaths: Set; + isLoading?: boolean; + onSelect: (path: string) => void; +} + +export const FileTreeView = React.memo(function FileTreeView({ + files, + selectedPath, + dirtyPaths, + isLoading = false, + onSelect, +}: FileTreeViewProps) { + const { treeData, activeItems, handleSelect, selectable } = useFileTreeView( + files, + selectedPath, + dirtyPaths, + isLoading, + onSelect, + ); + + return ( + + ); +}); + +// --- hook --- + +function useFileTreeView( + files: FileEntry[], + selectedPath: string | null, + dirtyPaths: Set, + isLoading: boolean = false, + onSelect: (path: string) => void, +): { + treeData: TreeViewDataItem[]; + activeItems: TreeViewDataItem[]; + handleSelect: (_: React.MouseEvent, item: TreeViewDataItem) => void; + selectable: boolean; +} { + const treeData = useMemo(() => buildFileTree(files, dirtyPaths), [files, dirtyPaths]); + + const activeItems = useMemo(() => { + if (!selectedPath) return []; + return findItemByPath(treeData, selectedPath); + }, [treeData, selectedPath]); + + const handleSelect = (_: React.MouseEvent, item: TreeViewDataItem) => { + if (!item.children) { + onSelect(item.id!); + } + }; + + let data: TreeViewDataItem[]; + if (isLoading) data = loadingTreeData; + else if (treeData.length > 0) data = treeData; + else data = emptyTreeData; + + const selectable = !isLoading && treeData.length > 0; + + return { treeData: data, activeItems, handleSelect, selectable }; +} + +// --- helpers --- +function findItemByPath(items: TreeViewDataItem[], path: string): TreeViewDataItem[] { + for (const item of items) { + if (item.id === path) return [item]; + if (item.children) { + const found = findItemByPath(item.children, path); + if (found.length > 0) return [item, ...found]; + } + } + return []; +} + +function buildFileTree(files: FileEntry[], dirtyPaths: Set): TreeViewDataItem[] { + const root: TreeViewDataItem[] = []; + + for (const file of files) { + if (isRootFile(file)) handleRootFile(file); + else handleNestedFile(file); + } + + sortTree(root); + return root; + + function isRootFile(file: FileEntry): boolean { + return file.path.split('/').length === 1; + } + + function handleRootFile(file: FileEntry) { + if (!root.find((item) => item.id === file.path)) createItem(file.path, file.path, root); + } + + function handleNestedFile(file: FileEntry) { + let items = root; + const filePathParts = file.path.split('/'); + for (let i = 0; i < filePathParts.length; i++) { + // e.g. with ['test/unit.js'] filePathPart is first 'test', then 'unit.js' + const filePathPart = filePathParts[i]; + // fullPath is used as id + const fullPath = filePathParts.slice(0, i + 1).join('/'); + // tells us if filePathPart we're working with is a dir or a file + const isDir = i < filePathParts.length - 1; + + const existing = items.find((item) => item.id === fullPath); + if (existing) { + // only true when it's a directory and then we step into it + items = existing.children!; + continue; + } + + createItem(fullPath, filePathPart, items, isDir); + if (isDir) items = items[items.length - 1].children!; + } + } + + function createItem(id: string, name: string, items: TreeViewDataItem[], isDir = false) { + const item: TreeViewDataItem = { + id, + name: dirtyPaths.has(id) ? `${name} \u25CF` : name, + defaultExpanded: true, + }; + if (isDir) item.children = []; + items.push(item); + } + + function sortTree(items: TreeViewDataItem[]) { + items.sort((a, b) => { + const aIsDir = !!a.children; + const bIsDir = !!b.children; + if (aIsDir && !bIsDir) return -1; + if (!aIsDir && bIsDir) return 1; + return String(a.name).localeCompare(String(b.name)); + }); + for (const item of items) { + if (item.children) sortTree(item.children); + } + } +} diff --git a/src/components/FunctionTable.test.tsx b/src/components/FunctionTable.test.tsx index d33cc58..684a3ce 100644 --- a/src/components/FunctionTable.test.tsx +++ b/src/components/FunctionTable.test.tsx @@ -3,13 +3,13 @@ import userEvent from '@testing-library/user-event'; import { MemoryRouter } from 'react-router-dom-v5-compat'; import { FunctionTable, FunctionTableItem } from './FunctionTable'; -jest.mock('react-i18next', () => ({ +vi.mock('react-i18next', () => ({ useTranslation: () => ({ t: (key: string) => key }), })); -const mockUseDeleteModal = jest.fn().mockReturnValue(jest.fn()); +const mockUseDeleteModal = vi.fn().mockReturnValue(vi.fn()); -jest.mock('@openshift-console/dynamic-plugin-sdk', () => ({ +vi.mock('@openshift-console/dynamic-plugin-sdk', () => ({ SuccessStatus: ({ title }: { title: string }) => `Success: ${title}`, ProgressStatus: ({ title }: { title: string }) => `Progress: ${title}`, ErrorStatus: ({ title }: { title: string }) => `Error: ${title}`, @@ -18,14 +18,14 @@ jest.mock('@openshift-console/dynamic-plugin-sdk', () => ({ useDeleteModal: (...args: unknown[]) => mockUseDeleteModal(...args), })); -jest.mock('@patternfly/react-icons', () => ({ +vi.mock('@patternfly/react-icons', () => ({ ExclamationTriangleIcon: () => 'WarningIcon', PencilAltIcon: () => 'EditIcon', TrashIcon: () => 'DeleteIcon', })); afterEach(() => { - jest.restoreAllMocks(); + vi.restoreAllMocks(); }); const mockDeployment = { @@ -61,7 +61,7 @@ describe('FunctionTable', () => { it('renders a row for each function', () => { render( - + , ); @@ -72,7 +72,7 @@ describe('FunctionTable', () => { it('renders namespace with dash for empty value', () => { render( - + , ); @@ -84,7 +84,7 @@ describe('FunctionTable', () => { it('renders SuccessStatus for Running functions', () => { render( - + , ); @@ -94,7 +94,7 @@ describe('FunctionTable', () => { it('renders InfoStatus for NotDeployed functions', () => { render( - + , ); @@ -104,7 +104,7 @@ describe('FunctionTable', () => { it('displays hostname-only link for URL', () => { render( - + , ); @@ -114,7 +114,7 @@ describe('FunctionTable', () => { }); it('calls onEdit when edit button is clicked', async () => { - const onEdit = jest.fn(); + const onEdit = vi.fn(); const user = userEvent.setup(); render( @@ -128,13 +128,13 @@ describe('FunctionTable', () => { }); it('launches delete modal when delete button is clicked', async () => { - const mockLauncher = jest.fn(); + const mockLauncher = vi.fn(); mockUseDeleteModal.mockReturnValue(mockLauncher); const user = userEvent.setup(); render( - + , ); @@ -151,7 +151,7 @@ describe('FunctionTable', () => { it('disables delete button for NotDeployed functions', () => { render( - + , ); diff --git a/src/components/UserAvatar.test.tsx b/src/components/UserAvatar.test.tsx index 017f29b..b817361 100644 --- a/src/components/UserAvatar.test.tsx +++ b/src/components/UserAvatar.test.tsx @@ -5,12 +5,12 @@ import { PAT_KEY, USER_KEY } from '../services/types'; import { ForgeConnectionContext } from '../context/ForgeConnectionProvider'; import { ReactNode } from 'react'; -jest.mock('react-i18next', () => ({ +vi.mock('react-i18next', () => ({ useTranslation: () => ({ t: (key: string) => key }), })); -const mockFetchUserInfo = jest.fn(); -jest.mock('../services/source-control/useSourceControlService', () => ({ +const mockFetchUserInfo = vi.fn(); +vi.mock('../services/source-control/useSourceControlService', () => ({ useSourceControlService: () => ({ fetchUserInfo: mockFetchUserInfo, }), @@ -20,7 +20,7 @@ const testUser = { name: 'twoGiants' }; function renderWithContext( ui: ReactNode, - contextValue = { isActive: false, connectToForge: jest.fn() }, + contextValue = { isActive: false, connectToForge: vi.fn() }, ) { return render( {ui}, @@ -33,7 +33,7 @@ describe('UserAvatar', () => { }); afterEach(() => { - jest.restoreAllMocks(); + vi.restoreAllMocks(); }); afterAll(() => { @@ -114,7 +114,7 @@ describe('UserAvatar', () => { it('calls fetchUserInfo with PAT and updates UI on successful connect', async () => { const user = userEvent.setup(); - const connectToForge = jest.fn(); + const connectToForge = vi.fn(); mockFetchUserInfo.mockResolvedValue(testUser); renderWithContext(, { isActive: false, connectToForge }); diff --git a/src/components/UserAvatar.tsx b/src/components/UserAvatar.tsx index b44ccbd..8f4b63e 100644 --- a/src/components/UserAvatar.tsx +++ b/src/components/UserAvatar.tsx @@ -15,7 +15,7 @@ import { ForgeUser, PAT_KEY, USER_KEY } from '../services/types'; import { useContext, useState } from 'react'; import { ForgeConnectionContext } from '../context/ForgeConnectionProvider'; import { useSourceControlService } from '../services/source-control/useSourceControlService'; -import { errorMessage } from '../utils/errorMessage'; +import { errorMessage } from '../utils/utils'; interface UserAvatarProps { enableReconnect: boolean; diff --git a/src/services/cluster/useClusterService.test.tsx b/src/services/cluster/useClusterService.test.tsx index e7b6215..6f5b115 100644 --- a/src/services/cluster/useClusterService.test.tsx +++ b/src/services/cluster/useClusterService.test.tsx @@ -1,16 +1,16 @@ import { render, screen } from '@testing-library/react'; import { useClusterService } from './useClusterService'; -const mockUseK8sWatchResource = jest.fn(); -const mockUseActiveNamespace = jest.fn(); +const mockUseK8sWatchResource = vi.fn(); +const mockUseActiveNamespace = vi.fn(); -jest.mock('@openshift-console/dynamic-plugin-sdk', () => ({ +vi.mock('@openshift-console/dynamic-plugin-sdk', () => ({ useK8sWatchResource: (...args: unknown[]) => mockUseK8sWatchResource(...args), useActiveNamespace: () => mockUseActiveNamespace(), })); afterEach(() => { - jest.restoreAllMocks(); + vi.restoreAllMocks(); }); const mockDeployment = { diff --git a/src/services/function/FunctionService.test.ts b/src/services/function/FunctionService.test.ts index a7b5739..4ff63b2 100644 --- a/src/services/function/FunctionService.test.ts +++ b/src/services/function/FunctionService.test.ts @@ -2,14 +2,14 @@ import { consoleFetchJSON } from '@openshift-console/dynamic-plugin-sdk'; import { FunctionBackendService } from './FunctionBackendService'; import { FileEntry, FunctionConfig } from '../types'; -jest.mock('@openshift-console/dynamic-plugin-sdk', () => ({ +vi.mock('@openshift-console/dynamic-plugin-sdk', () => ({ consoleFetchJSON: { - post: jest.fn(), + post: vi.fn(), }, })); afterEach(() => { - jest.restoreAllMocks(); + vi.restoreAllMocks(); }); const config: FunctionConfig = { @@ -27,7 +27,7 @@ const files: FileEntry[] = [ describe('FunctionBackendService', () => { it('calls consoleFetchJSON.post with the proxy URL and returns generated files', async () => { - (consoleFetchJSON.post as jest.Mock).mockResolvedValue(files); + vi.mocked(consoleFetchJSON.post).mockResolvedValue(files); const service = new FunctionBackendService(); const result = await service.generateFunction(config); @@ -40,9 +40,7 @@ describe('FunctionBackendService', () => { }); it('throws when consoleFetchJSON.post rejects', async () => { - (consoleFetchJSON.post as jest.Mock).mockRejectedValue( - new Error('failed to initialize function'), - ); + vi.mocked(consoleFetchJSON.post).mockRejectedValue(new Error('failed to initialize function')); const service = new FunctionBackendService(); diff --git a/src/services/source-control/GithubService.test.ts b/src/services/source-control/GithubService.test.ts new file mode 100644 index 0000000..2f3ae41 --- /dev/null +++ b/src/services/source-control/GithubService.test.ts @@ -0,0 +1,398 @@ +import { http, HttpResponse } from 'msw'; +import { server } from '../../../testing/msw/server'; +import { GithubService } from './GithubService'; +import { FileEntry, RepoMetadata } from '../types'; + +const GITHUB_API = 'https://api.github.com'; +const GH_SEARCH_REPOS = `${GITHUB_API}/search/repositories`; + +describe('GithubService', () => { + describe('listFunctionRepos', () => { + it('lists function repos tagged with serverless-function topic', async () => { + setupGithubSearchReposResponse(); + + const svc = new GithubService(() => 'pat'); + const repos: RepoMetadata[] = await svc.listFunctionRepos(); + + expect(repos).toEqual([ + { + owner: 'twoGiants', + name: 'my-func', + url: 'https://github.com/twoGiants/my-func', + defaultBranch: 'main', + }, + ]); + + function setupGithubSearchReposResponse() { + server.use( + http.get(GH_SEARCH_REPOS, ({ request }) => { + const url = new URL(request.url); + expect(url.searchParams.get('q')).toBe('topic:serverless-function user:twoGiants'); + return HttpResponse.json({ + total_count: 1, + items: [ + { + owner: { login: 'twoGiants' }, + name: 'my-func', + html_url: 'https://github.com/twoGiants/my-func', + default_branch: 'main', + }, + ], + }); + }), + ); + } + }); + }); + + describe('fetchFileContent', () => { + it('fetches file content from a repo', async () => { + setupFileContentResponse(); + + const svc = new GithubService(() => 'pat'); + const content = await svc.fetchFileContent( + { + owner: 'twoGiants', + name: 'my-func', + url: 'https://github.com/twoGiants/my-func', + defaultBranch: 'main', + }, + 'func.yaml', + ); + + expect(content).toBe('name: my-func\nruntime: go\n'); + + function setupFileContentResponse() { + server.use( + http.get(`${GITHUB_API}/repos/twoGiants/my-func/contents/func.yaml`, () => + HttpResponse.json({ + content: btoa('name: my-func\nruntime: go\n'), + encoding: 'base64', + }), + ), + ); + } + }); + + it('throws when path is not a file', async () => { + setupDirectoryResponse(); + + const svc = new GithubService(() => 'pat'); + + await expect( + svc.fetchFileContent( + { owner: 'twoGiants', name: 'my-func', url: '', defaultBranch: 'main' }, + 'src', + ), + ).rejects.toThrow('src is not a file'); + + function setupDirectoryResponse() { + server.use( + http.get(`${GITHUB_API}/repos/twoGiants/my-func/contents/src`, () => + HttpResponse.json([{ name: 'index.js', type: 'file' }]), + ), + ); + } + }); + }); + + describe('push', () => { + const repoInfo: RepoMetadata = { + owner: 'twoGiants', + name: 'my-func', + url: '', + defaultBranch: 'main', + }; + const files: FileEntry[] = [ + { path: 'func.yaml', mode: '100644', content: 'name: my-func', type: 'blob' }, + ]; + + it('creates a new branch ref when branch does not exist', async () => { + const { refCreated } = setupPushHandlers(); + + const svc = new GithubService(() => 'pat'); + await svc.push(repoInfo, files, 'Initial commit'); + + expect(refCreated()).toBe(true); + }); + + it('throws when the API fails', async () => { + setupPushHandlers({ treeError: true }); + + const svc = new GithubService(() => 'pat'); + + await expect(svc.push(repoInfo, files, 'Fail')).rejects.toThrow(); + }); + + function setupPushHandlers({ treeError = false }: { treeError?: boolean } = {}) { + let _refCreated = false; + + server.use( + http.post(`${GITHUB_API}/repos/twoGiants/my-func/git/blobs`, () => + HttpResponse.json({ sha: 'blob-sha' }), + ), + http.post(`${GITHUB_API}/repos/twoGiants/my-func/git/trees`, () => + treeError + ? HttpResponse.json({ message: 'Validation Failed' }, { status: 422 }) + : HttpResponse.json({ sha: 'tree-sha' }), + ), + http.post(`${GITHUB_API}/repos/twoGiants/my-func/git/commits`, () => + HttpResponse.json({ sha: 'commit-sha' }), + ), + http.post(`${GITHUB_API}/repos/twoGiants/my-func/git/refs`, () => { + _refCreated = true; + return HttpResponse.json({}); + }), + ); + + return { refCreated: () => _refCreated }; + } + }); + + describe('updateRepo', () => { + const repoInfo: RepoMetadata = { + owner: 'twoGiants', + name: 'my-func', + url: '', + defaultBranch: 'main', + }; + const files: FileEntry[] = [ + { path: 'func.yaml', mode: '100644', content: 'name: my-func', type: 'blob' }, + ]; + + it('updates existing branch ref first time by loading last commit sha from GitHub', async () => { + const result = setupUpdateRepoHandlers({ commitSha: 'commit-1' }); + + const svc = new GithubService(() => 'pat'); + await svc.updateRepo(repoInfo, files, 'Update'); + + expect(result.updateRefSha()).toBe('commit-1'); + expect(result.getRefCalled()).toBe(true); + }); + + function setupUpdateRepoHandlers({ + commitSha, + updateRefError, + }: { + commitSha: string; + updateRefError?: string; + }) { + let _updateRefSha = ''; + let _getRefCalled = false; + + server.use( + // createBlob + http.post(`${GITHUB_API}/repos/twoGiants/my-func/git/blobs`, () => + HttpResponse.json({ sha: 'blob-sha' }), + ), + // getRef + http.get(`${GITHUB_API}/repos/twoGiants/my-func/git/ref/:ref+`, () => { + _getRefCalled = true; + return HttpResponse.json({ object: { sha: 'head-sha' } }); + }), + // getCommit + http.get(`${GITHUB_API}/repos/twoGiants/my-func/git/commits/:sha`, () => + HttpResponse.json({ tree: { sha: 'tree-sha' } }), + ), + // createTree + http.post(`${GITHUB_API}/repos/twoGiants/my-func/git/trees`, () => + HttpResponse.json({ sha: 'new-tree-sha' }), + ), + // createCommit + http.post(`${GITHUB_API}/repos/twoGiants/my-func/git/commits`, () => + HttpResponse.json({ sha: commitSha }), + ), + // updateRef + http.patch(`${GITHUB_API}/repos/twoGiants/my-func/git/refs/:ref+`, async ({ request }) => { + if (updateRefError === 'fast forward') + return HttpResponse.json({ message: 'Update is not a fast forward' }, { status: 422 }); + + if (updateRefError === 'network') + return HttpResponse.json({ message: 'Server Error' }, { status: 500 }); + + const body = (await request.json()) as { sha: string }; + _updateRefSha = body.sha; + + return HttpResponse.json({}); + }), + ); + + return { getRefCalled: () => _getRefCalled, updateRefSha: () => _updateRefSha }; + } + + it('updates existing branch ref second time by loading last commit sha from cache', async () => { + let result = setupUpdateRepoHandlers({ commitSha: 'commit-1' }); + + const svc = new GithubService(() => 'pat'); + await svc.updateRepo(repoInfo, files, 'First update'); + + expect(result.updateRefSha()).toBe('commit-1'); + expect(result.getRefCalled()).toBe(true); + + result = setupUpdateRepoHandlers({ commitSha: 'commit-2' }); + await svc.updateRepo(repoInfo, files, 'Second update'); + + expect(result.updateRefSha()).toBe('commit-2'); + expect(result.getRefCalled()).toBe(false); + }); + + it('updates existing branch ref third time by loading last commit sha from cache', async () => { + let result = setupUpdateRepoHandlers({ commitSha: 'commit-1' }); + + const svc = new GithubService(() => 'pat'); + await svc.updateRepo(repoInfo, files, 'First update'); + + expect(result.updateRefSha()).toBe('commit-1'); + expect(result.getRefCalled()).toBe(true); + + result = setupUpdateRepoHandlers({ commitSha: 'commit-2' }); + await svc.updateRepo(repoInfo, files, 'Second update'); + + expect(result.updateRefSha()).toBe('commit-2'); + expect(result.getRefCalled()).toBe(false); + + result = setupUpdateRepoHandlers({ commitSha: 'commit-3' }); + await svc.updateRepo(repoInfo, files, 'Third update'); + + expect(result.updateRefSha()).toBe('commit-3'); + expect(result.getRefCalled()).toBe(false); + }); + + it('fails to update existing branch ref because of a stale sha, cleans cache and throws error', async () => { + // GIVEN: first commit succeeds + let result = setupUpdateRepoHandlers({ + commitSha: 'commit-1', + }); + const svc = new GithubService(() => 'pat'); + + // WHEN + await svc.updateRepo(repoInfo, files, 'First update'); + + // THEN + expect(result.updateRefSha()).toBe('commit-1'); + expect(result.getRefCalled()).toBe(true); + + // GIVEN: second commit fails because of a stale sha => clears cache entry + result = setupUpdateRepoHandlers({ + commitSha: 'commit-2', + updateRefError: 'fast forward', + }); + + await expect( + // WHEN + svc.updateRepo(repoInfo, files, 'Stale (Second) update'), + // THEN + ).rejects.toThrow(); + expect(result.getRefCalled()).toBe(false); + expect(result.updateRefSha()).toBe(''); + + // GIVEN: third commit succeeds and goes through getRef because cache was cleared + result = setupUpdateRepoHandlers({ + commitSha: 'commit-3', + }); + + // WHEN + await svc.updateRepo(repoInfo, files, 'Third update'); + + // THEN + expect(result.updateRefSha()).toBe('commit-3'); + expect(result.getRefCalled()).toBe(true); + }); + + it('fails to update existing branch ref because of a network error, does not clean cache and throws error', async () => { + // GIVEN: first commit succeeds + let result = setupUpdateRepoHandlers({ + commitSha: 'commit-1', + }); + const svc = new GithubService(() => 'pat'); + + // WHEN + await svc.updateRepo(repoInfo, files, 'First update'); + + // THEN + expect(result.updateRefSha()).toBe('commit-1'); + expect(result.getRefCalled()).toBe(true); + + // GIVEN: second commit fails because of a network error -> cache NOT cleared + result = setupUpdateRepoHandlers({ + commitSha: 'commit-2', + updateRefError: 'network', + }); + + await expect( + // WHEN + svc.updateRepo(repoInfo, files, 'Network fail (Second) update'), + // THEN + ).rejects.toThrow(); + expect(result.getRefCalled()).toBe(false); + expect(result.updateRefSha()).toBe(''); + + // GIVEN: third commit succeeds and goes through cache + result = setupUpdateRepoHandlers({ + commitSha: 'commit-3', + }); + + // WHEN + await svc.updateRepo(repoInfo, files, 'Third update'); + + // THEN + expect(result.updateRefSha()).toBe('commit-3'); + expect(result.getRefCalled()).toBe(false); + }); + }); + + describe('fetch', () => { + const repo: RepoMetadata = { + owner: 'twoGiants', + name: 'my-func', + url: 'https://github.com/twoGiants/my-func', + defaultBranch: 'main', + }; + + it('fetches all files from a repo', async () => { + setupRepoTreeAndBlobs(); + + const svc = new GithubService(() => 'pat'); + const files = await svc.fetch(repo); + + expect(files).toEqual([ + { + path: 'func.yaml', + mode: '100644', + content: 'name: my-func\nruntime: node', + type: 'blob', + }, + { path: 'index.js', mode: '100644', content: 'module.exports = {}', type: 'blob' }, + ]); + + function setupRepoTreeAndBlobs() { + server.use( + http.get(`${GITHUB_API}/repos/twoGiants/my-func/git/trees/main`, ({ request }) => { + const url = new URL(request.url); + expect(url.searchParams.get('recursive')).toBe('1'); + return HttpResponse.json({ + sha: 'tree-sha', + tree: [ + { path: 'src', type: 'tree', mode: '040000', sha: 'dir-sha' }, + { path: 'func.yaml', type: 'blob', mode: '100644', sha: 'blob-1' }, + { path: 'index.js', type: 'blob', mode: '100644', sha: 'blob-2' }, + ], + }); + }), + http.get(`${GITHUB_API}/repos/twoGiants/my-func/git/blobs/blob-1`, () => + HttpResponse.json({ + content: btoa('name: my-func\nruntime: node'), + encoding: 'base64', + }), + ), + http.get(`${GITHUB_API}/repos/twoGiants/my-func/git/blobs/blob-2`, () => + HttpResponse.json({ + content: btoa('module.exports = {}'), + encoding: 'base64', + }), + ), + ); + } + }); + }); +}); diff --git a/src/services/source-control/GithubService.ts b/src/services/source-control/GithubService.ts index 3133af9..9410582 100644 --- a/src/services/source-control/GithubService.ts +++ b/src/services/source-control/GithubService.ts @@ -1,11 +1,12 @@ import { Octokit } from '@octokit/rest'; -import { FileEntry, ForgeUser, RepoInfo, SourceRepo } from '../types'; +import { FileEntry, ForgeUser, RepoMetadata } from '../types'; import { SourceControlService } from './SourceControlService'; export class GithubService implements SourceControlService { private getToken: () => string; private cachedOctokit: Octokit | null = null; private cachedToken: string = ''; + private lastCommitSha = new Map(); constructor(getToken: () => string) { this.getToken = getToken; @@ -26,7 +27,7 @@ export class GithubService implements SourceControlService { return { name: data.login }; } - async listFunctionRepos(): Promise { + async listFunctionRepos(): Promise { const { data: user } = await this.octokit.users.getAuthenticated(); const { data } = await this.octokit.search.repos({ @@ -41,8 +42,8 @@ export class GithubService implements SourceControlService { })); } - async push(repo: RepoInfo, files: FileEntry[], message: string): Promise { - const { owner, repo: repoName, branch } = repo; + async push(repo: RepoMetadata, files: FileEntry[], message: string): Promise { + const { owner, name: repoName, defaultBranch: branch } = repo; const treeEntries = await Promise.all( files.map(async (file) => { @@ -83,7 +84,110 @@ export class GithubService implements SourceControlService { }); } - async fetchFileContent(repo: SourceRepo, path: string): Promise { + async updateRepo(repo: RepoMetadata, files: FileEntry[], message: string): Promise { + const { owner, name: repoName, defaultBranch: branch } = repo; + const refKey = `${owner}/${repoName}/${branch}`; + + const treeEntries = await Promise.all( + files.map(async (file) => { + const { data: blob } = await this.octokit.git.createBlob({ + owner, + repo: repoName, + content: file.content, + encoding: 'utf-8', + }); + return { + path: file.path, + mode: file.mode, + type: file.type as 'blob', + sha: blob.sha, + }; + }), + ); + + // GitHub's ref storage is eventually consistent. After a successful + // updateRef, a subsequent getRef may return a stale SHA. Use the + // locally cached commit SHA from the previous push when available. + // Fall back to getRef only on first push or if the cache is stale + // (someone else pushed, causing a "not a fast forward" error). + let parentCommitSha = this.lastCommitSha.get(refKey); + if (!parentCommitSha) { + const { data: ref } = await this.octokit.git.getRef({ + owner, + repo: repoName, + ref: `heads/${branch}`, + }); + parentCommitSha = ref.object.sha; + } + + const { data: parentCommit } = await this.octokit.git.getCommit({ + owner, + repo: repoName, + commit_sha: parentCommitSha, + }); + + const { data: tree } = await this.octokit.git.createTree({ + owner, + repo: repoName, + tree: treeEntries, + base_tree: parentCommit.tree.sha, + }); + + const { data: commit } = await this.octokit.git.createCommit({ + owner, + repo: repoName, + message, + tree: tree.sha, + parents: [parentCommitSha], + }); + + try { + await this.octokit.git.updateRef({ + owner, + repo: repoName, + ref: `heads/${branch}`, + sha: commit.sha, + }); + this.lastCommitSha.set(refKey, commit.sha); + } catch (err) { + // If cache was stale (someone else pushed). Clear and let next + // attempt use getRef for the fresh SHA. + const isStaleRef = err instanceof Error && err.message.includes('fast forward'); + if (isStaleRef) this.lastCommitSha.delete(refKey); + throw err; + } + } + + async fetch(repo: RepoMetadata): Promise { + const { data: repoContent } = await this.octokit.git.getTree({ + owner: repo.owner, + repo: repo.name, + tree_sha: repo.defaultBranch, + recursive: '1', + }); + + const filesAsBlobs = repoContent.tree.filter((entry) => entry.type === 'blob'); + + const files = await Promise.all( + filesAsBlobs.map(async (fileAsBlob) => { + const { data: file } = await this.octokit.git.getBlob({ + owner: repo.owner, + repo: repo.name, + file_sha: fileAsBlob.sha!, + }); + return { + path: fileAsBlob.path!, + mode: (fileAsBlob.mode ?? '100644') as FileEntry['mode'], + content: base64ToUtf8(file.content), + type: 'blob' as const, + }; + }), + ); + + return files; + } + + async fetchFileContent(repo: RepoMetadata, path: string): Promise { const { data } = await this.octokit.repos.getContent({ owner: repo.owner, repo: repo.name, @@ -93,6 +197,14 @@ export class GithubService implements SourceControlService { if (!('content' in data)) { throw new Error(`${path} is not a file`); } - return atob(data.content); + return base64ToUtf8(data.content); } } + +/** + * Decodes base64 to UTF-8. Unlike plain atob, handles multi-byte characters. + */ +function base64ToUtf8(base64: string): string { + const bytes = Uint8Array.from(atob(base64), (c) => c.charCodeAt(0)); + return new TextDecoder().decode(bytes); +} diff --git a/src/services/source-control/SourceControlService.test.ts b/src/services/source-control/SourceControlService.test.ts deleted file mode 100644 index 33a8037..0000000 --- a/src/services/source-control/SourceControlService.test.ts +++ /dev/null @@ -1,157 +0,0 @@ -import { GithubService } from './GithubService'; -import { FileEntry, RepoInfo, SourceRepo } from '../types'; - -const mockGetAuthenticated = jest.fn(); -const mockSearch = jest.fn(); -const mockGetContent = jest.fn(); -const mockCreateBlob = jest.fn(); -const mockCreateTree = jest.fn(); -const mockCreateCommit = jest.fn(); -const mockCreateRef = jest.fn(); - -jest.mock('@octokit/rest', () => ({ - Octokit: jest.fn().mockImplementation(() => ({ - users: { getAuthenticated: mockGetAuthenticated }, - search: { repos: mockSearch }, - repos: { getContent: mockGetContent }, - git: { - createBlob: mockCreateBlob, - createTree: mockCreateTree, - createCommit: mockCreateCommit, - createRef: mockCreateRef, - }, - })), -})); - -afterEach(() => { - jest.restoreAllMocks(); -}); - -describe('GithubService', () => { - beforeEach(() => { - mockGetAuthenticated.mockResolvedValue({ - data: { login: 'twoGiants', avatar_url: 'https://avatars.githubusercontent.com/u/123' }, - }); - }); - - it('lists function repos tagged with serverless-function topic', async () => { - mockSearch.mockResolvedValue({ - data: { - items: [ - { - owner: { login: 'twoGiants' }, - name: 'my-func', - html_url: 'https://github.com/twoGiants/my-func', - default_branch: 'main', - }, - ], - }, - }); - - const svc = new GithubService(() => 'fake-token'); - const repos: SourceRepo[] = await svc.listFunctionRepos(); - - expect(repos).toEqual([ - { - owner: 'twoGiants', - name: 'my-func', - url: 'https://github.com/twoGiants/my-func', - defaultBranch: 'main', - }, - ]); - expect(mockSearch).toHaveBeenCalledWith({ q: 'topic:serverless-function user:twoGiants' }); - }); - - it('fetches file content from a repo', async () => { - mockGetContent.mockResolvedValue({ - data: { content: btoa('name: my-func\nruntime: go\n'), encoding: 'base64' }, - }); - - const svc = new GithubService(() => 'fake-token'); - const content = await svc.fetchFileContent( - { - owner: 'twoGiants', - name: 'my-func', - url: 'https://github.com/twoGiants/my-func', - defaultBranch: 'main', - }, - 'func.yaml', - ); - - expect(content).toBe('name: my-func\nruntime: go\n'); - expect(mockGetContent).toHaveBeenCalledWith({ - owner: 'twoGiants', - repo: 'my-func', - path: 'func.yaml', - }); - }); - - describe('push', () => { - const repoInfo: RepoInfo = { owner: 'twoGiants', repo: 'my-func', branch: 'main' }; - const files: FileEntry[] = [ - { path: 'func.yaml', mode: '100644', content: 'name: my-func', type: 'blob' }, - ]; - - beforeEach(() => { - mockCreateBlob.mockResolvedValue({ data: { sha: 'blob-sha-123' } }); - mockCreateTree.mockResolvedValue({ data: { sha: 'tree-sha-123' } }); - mockCreateCommit.mockResolvedValue({ data: { sha: 'commit-sha-123' } }); - mockCreateRef.mockResolvedValue({}); - }); - - it('creates an initial commit with the provided files', async () => { - const svc = new GithubService(() => 'fake-token'); - await svc.push(repoInfo, files, 'Initialize function'); - - expect(mockCreateBlob).toHaveBeenCalledWith({ - owner: 'twoGiants', - repo: 'my-func', - content: 'name: my-func', - encoding: 'utf-8', - }); - expect(mockCreateTree).toHaveBeenCalledWith({ - owner: 'twoGiants', - repo: 'my-func', - tree: [{ path: 'func.yaml', mode: '100644', type: 'blob', sha: 'blob-sha-123' }], - }); - expect(mockCreateCommit).toHaveBeenCalledWith({ - owner: 'twoGiants', - repo: 'my-func', - message: 'Initialize function', - tree: 'tree-sha-123', - parents: [], - }); - expect(mockCreateRef).toHaveBeenCalledWith({ - owner: 'twoGiants', - repo: 'my-func', - ref: 'refs/heads/main', - sha: 'commit-sha-123', - }); - }); - - it('propagates errors from intermediate API calls', async () => { - mockCreateTree.mockRejectedValue(new Error('Validation Failed')); - const svc = new GithubService(() => 'fake-token'); - - await expect(svc.push(repoInfo, files, 'Initialize function')).rejects.toThrow( - 'Validation Failed', - ); - }); - }); - - describe('fetchUserInfo', () => { - it('returns ForgeUser on valid token', async () => { - const svc = new GithubService(() => ''); - const user = await svc.fetchUserInfo('valid-token'); - - expect(user).toEqual({ name: 'twoGiants' }); - }); - - it('throws on invalid token', async () => { - mockGetAuthenticated.mockRejectedValue(new Error('Bad credentials')); - const svc = new GithubService(() => ''); - - await expect(svc.fetchUserInfo('bad-token')).rejects.toThrow('Bad credentials'); - }); - }); -}); diff --git a/src/services/source-control/SourceControlService.ts b/src/services/source-control/SourceControlService.ts index c7555d8..6264d42 100644 --- a/src/services/source-control/SourceControlService.ts +++ b/src/services/source-control/SourceControlService.ts @@ -1,8 +1,10 @@ -import { FileEntry, ForgeUser as ForgeUserInfo, RepoInfo, SourceRepo } from '../types'; +import { FileEntry, ForgeUser, RepoMetadata } from '../types'; export interface SourceControlService { - listFunctionRepos(): Promise; - fetchFileContent(repo: SourceRepo, path: string): Promise; - push(repo: RepoInfo, files: FileEntry[], message: string): Promise; - fetchUserInfo(pat: string): Promise; + listFunctionRepos(): Promise; + fetchFileContent(repo: RepoMetadata, path: string): Promise; + push(repo: RepoMetadata, files: FileEntry[], message: string): Promise; + updateRepo(repo: RepoMetadata, files: FileEntry[], message: string): Promise; + fetch(repo: RepoMetadata): Promise; + fetchUserInfo(pat: string): Promise; } diff --git a/src/services/types.ts b/src/services/types.ts index f7cb21d..27802ed 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -18,13 +18,7 @@ export interface FunctionConfig { export type FunctionRuntime = 'node' | 'python' | 'go' | 'quarkus'; -export interface RepoInfo { - owner: string; - repo: string; - branch: string; -} - -export interface SourceRepo { +export interface RepoMetadata { owner: string; name: string; url: string; diff --git a/src/test-setup.ts b/src/test-setup.ts deleted file mode 100644 index 7b0828b..0000000 --- a/src/test-setup.ts +++ /dev/null @@ -1 +0,0 @@ -import '@testing-library/jest-dom'; diff --git a/src/utils/errorMessage.ts b/src/utils/errorMessage.ts deleted file mode 100644 index 7db4add..0000000 --- a/src/utils/errorMessage.ts +++ /dev/null @@ -1,3 +0,0 @@ -export function errorMessage(err: unknown): string { - return err instanceof Error ? err.message : String(err); -} diff --git a/src/utils/utils.test.ts b/src/utils/utils.test.ts new file mode 100644 index 0000000..1156f31 --- /dev/null +++ b/src/utils/utils.test.ts @@ -0,0 +1,20 @@ +import { getLanguageFromPath } from './utils'; + +describe('getLanguageFromPath', () => { + it.each([ + ['index.js', 'javascript'], + ['handler.ts', 'typescript'], + ['main.go', 'go'], + ['app.py', 'python'], + ['func.yaml', 'yaml'], + ['config.yml', 'yaml'], + ['package.json', 'json'], + ['README.md', 'markdown'], + ['Dockerfile', 'dockerfile'], + ['.gitignore', 'plaintext'], + ['Makefile', 'plaintext'], + ['', 'plaintext'], + ])('returns correct language for %s', (path, expected) => { + expect(getLanguageFromPath(path)).toBe(expected); + }); +}); diff --git a/src/utils/utils.ts b/src/utils/utils.ts new file mode 100644 index 0000000..99bae26 --- /dev/null +++ b/src/utils/utils.ts @@ -0,0 +1,55 @@ +import { Language } from '@patternfly/react-code-editor'; + +const extensionMap: Record = { + js: 'javascript', + jsx: 'javascript', + ts: 'typescript', + tsx: 'typescript', + go: 'go', + py: 'python', + yaml: 'yaml', + yml: 'yaml', + json: 'json', + md: 'markdown', + sh: 'shell', + bash: 'shell', + html: 'html', + css: 'css', + xml: 'xml', + toml: 'plaintext', + txt: 'plaintext', +}; + +const filenameMap: Record = { + Dockerfile: 'dockerfile', + Makefile: 'plaintext', +}; + +export function getLanguageFromPath(path: string): Language { + const filename = path.split('/').pop() ?? ''; + if (filenameMap[filename]) return filenameMap[filename] as Language; + + const ext = filename.split('.').pop() ?? ''; + return (extensionMap[ext] as Language) ?? Language.plaintext; +} + +export function parseNamespaceAndRuntime(funcYaml: string): { + namespace: string; + runtime: string; +} { + const runtimeMatch = funcYaml.match(/^runtime:\s*(.+)$/m); + const namespaceMatch = funcYaml.match(/^namespace:\s*(.+)$/m); + if (!runtimeMatch) throw new Error(`func.yaml missing runtime field`); + return { namespace: namespaceMatch?.[1]?.trim() ?? '', runtime: runtimeMatch[1].trim() }; +} + +export const handlerMap: Record = { + node: 'index.js', + python: 'function/func.py', + go: 'handle.go', + quarkus: 'src/main/java/functions/Function.java', +}; + +export function errorMessage(err: unknown): string { + return err instanceof Error ? err.message : String(err); +} diff --git a/src/views/FunctionCreatePage.test.tsx b/src/views/FunctionCreatePage.test.tsx index 7d57ffe..d7ace7a 100644 --- a/src/views/FunctionCreatePage.test.tsx +++ b/src/views/FunctionCreatePage.test.tsx @@ -4,15 +4,15 @@ import { MemoryRouter } from 'react-router-dom'; import FunctionCreatePage from './FunctionCreatePage'; import { PAT_KEY } from '../services/types'; -const mockGenerateFunction = jest.fn(); -const mockPush = jest.fn(); -const mockNavigate = jest.fn(); +const mockGenerateFunction = vi.fn(); +const mockPush = vi.fn(); +const mockNavigate = vi.fn(); -jest.mock('react-i18next', () => ({ +vi.mock('react-i18next', () => ({ useTranslation: () => ({ t: (key: string) => key }), })); -jest.mock('@openshift-console/dynamic-plugin-sdk', () => ({ +vi.mock('@openshift-console/dynamic-plugin-sdk', () => ({ DocumentTitle: ({ children }: { children: string }) => children, ListPageHeader: ({ title, children }: { title: string; children?: React.ReactNode }) => ( <> @@ -22,23 +22,23 @@ jest.mock('@openshift-console/dynamic-plugin-sdk', () => ({ ), })); -jest.mock('../services/function/useFunctionService', () => ({ +vi.mock('../services/function/useFunctionService', () => ({ useFunctionService: () => ({ generateFunction: mockGenerateFunction }), })); -jest.mock('../services/source-control/useSourceControlService', () => ({ +vi.mock('../services/source-control/useSourceControlService', () => ({ useSourceControlService: () => ({ push: mockPush, - listFunctionRepos: jest.fn(), - fetchFileContent: jest.fn(), + listFunctionRepos: vi.fn(), + fetchFileContent: vi.fn(), }), })); -jest.mock('react-router-dom-v5-compat', () => ({ +vi.mock('react-router-dom-v5-compat', () => ({ useNavigate: () => mockNavigate, })); -jest.mock('../components/UserAvatar', () => ({ +vi.mock('../components/UserAvatar', () => ({ UserAvatar: ({ enableReconnect }: { enableReconnect: boolean }) => ( {enableReconnect ? 'reconnect' : 'no-reconnect'} ), @@ -49,7 +49,7 @@ beforeEach(() => { }); afterEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); afterAll(() => { @@ -107,7 +107,7 @@ describe('FunctionCreatePage', () => { await waitFor(() => { expect(mockPush).toHaveBeenCalledWith( - { owner: 'testuser', repo: 'my-repo', branch: 'main' }, + { owner: 'testuser', name: 'my-repo', url: '', defaultBranch: 'main' }, files, 'Initialize Knative function project', ); diff --git a/src/views/FunctionCreatePage.tsx b/src/views/FunctionCreatePage.tsx index f35b75d..87d65d8 100644 --- a/src/views/FunctionCreatePage.tsx +++ b/src/views/FunctionCreatePage.tsx @@ -8,7 +8,7 @@ import { useFunctionService } from '../services/function/useFunctionService'; import { useSourceControlService } from '../services/source-control/useSourceControlService'; import { UserAvatar } from '../components/UserAvatar'; import { PAT_KEY } from '../services/types'; -import { errorMessage } from '../utils/errorMessage'; +import { errorMessage } from '../utils/utils'; export default function FunctionCreatePage() { const { t } = useTranslation('plugin__console-functions-plugin'); @@ -70,7 +70,7 @@ function useFunctionCreatePage() { }); await sourceControl.push( - { owner: data.owner, repo: data.repo, branch: data.branch }, + { owner: data.owner, name: data.repo, url: '', defaultBranch: data.branch }, files, 'Initialize Knative function project', ); diff --git a/src/views/FunctionEditPage.test.tsx b/src/views/FunctionEditPage.test.tsx new file mode 100644 index 0000000..65bd644 --- /dev/null +++ b/src/views/FunctionEditPage.test.tsx @@ -0,0 +1,199 @@ +import { act, render, screen, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { http, HttpResponse, delay } from 'msw'; +import { server } from '../../testing/msw/server'; +import { MemoryRouter, Route, Routes } from 'react-router-dom-v5-compat'; +import FunctionEditPage from './FunctionEditPage'; + +const GITHUB_API = 'https://api.github.com'; + +vi.mock('react-i18next', () => ({ + useTranslation: () => ({ t: (key: string) => key }), +})); + +let mockOnChange: ((value: string) => void) | undefined; + +vi.mock('@openshift-console/dynamic-plugin-sdk', () => ({ + DocumentTitle: ({ children }: { children: string }) => children, + ListPageHeader: ({ title }: { title: string }) => title, + CodeEditor: ({ onChange }: { onChange?: (value: string) => void }) => { + mockOnChange = onChange; + return 'CodeEditor'; + }, +})); + +function renderEditPage(name: string) { + return render( + + + } /> + + , + ); +} + +function setupSearchReposHandler() { + server.use( + http.get(`${GITHUB_API}/search/repositories`, () => + HttpResponse.json({ + total_count: 1, + items: [ + { + owner: { login: 'twoGiants' }, + name: 'my-func', + html_url: '', + default_branch: 'main', + }, + ], + }), + ), + ); +} + +function setupFetchHandlers() { + setupSearchReposHandler(); + server.use( + http.get(`${GITHUB_API}/repos/twoGiants/my-func/git/trees/main`, () => + HttpResponse.json({ + sha: 'tree-sha', + tree: [ + { path: 'func.yaml', type: 'blob', mode: '100644', sha: 'blob-1' }, + { path: 'index.js', type: 'blob', mode: '100644', sha: 'blob-2' }, + ], + }), + ), + http.get(`${GITHUB_API}/repos/twoGiants/my-func/git/blobs/blob-1`, () => + HttpResponse.json({ + content: btoa('name: my-func\nruntime: node'), + encoding: 'base64', + }), + ), + http.get(`${GITHUB_API}/repos/twoGiants/my-func/git/blobs/blob-2`, () => + HttpResponse.json({ + content: btoa('module.exports = {}'), + encoding: 'base64', + }), + ), + ); +} + +describe('FunctionEditPage', () => { + beforeAll(() => { + sessionStorage.setItem('func-console-pat', 'test-pat'); + }); + + afterAll(() => { + sessionStorage.clear(); + }); + + it('shows loading state in tree while fetching files', () => { + setupSearchReposHandler(); + server.use( + http.get(`${GITHUB_API}/repos/twoGiants/my-func/git/trees/main`, async () => { + await delay('infinite'); + return HttpResponse.json({}); + }), + ); + + renderEditPage('my-func'); + + expect(screen.getByText('Loading source...')).toBeInTheDocument(); + expect(screen.getByRole('button', { name: /Save & Deploy/ })).toBeDisabled(); + }); + + it('loads files from GitHub', async () => { + setupFetchHandlers(); + + renderEditPage('my-func'); + + await waitFor(() => { + expect(screen.getByText('func.yaml')).toBeInTheDocument(); + expect(screen.getByText('index.js')).toBeInTheDocument(); + }); + }); + + it('shows empty tree and disabled save when repo not found', async () => { + renderEditPage('nonexistent'); + + await waitFor(() => { + expect(screen.getByText('No files')).toBeInTheDocument(); + }); + expect(screen.getByRole('button', { name: /Save & Deploy/ })).toBeDisabled(); + expect(screen.getByRole('button', { name: /Back to Functions/ })).toBeInTheDocument(); + }); + + it('auto-selects handler file based on runtime from func.yaml', async () => { + setupFetchHandlers(); + + renderEditPage('my-func'); + + await waitFor(() => { + const indexItem = screen.getByText('index.js').closest('[role="treeitem"]'); + expect(indexItem).toHaveAttribute('aria-selected', 'true'); + }); + }); + + it('navigates back without modal when no changes made', async () => { + setupFetchHandlers(); + + renderEditPage('my-func'); + + await waitFor(() => { + expect(screen.getByText('func.yaml')).toBeInTheDocument(); + }); + + await userEvent.setup().click(screen.getByRole('button', { name: /Back to Functions/ })); + + expect(screen.queryByText('Unsaved changes')).not.toBeInTheDocument(); + }); + + it('shows success message after save and hides it after 2 seconds', async () => { + vi.useFakeTimers({ shouldAdvanceTime: true }); + setupFetchHandlers(); + setupPushHandlers(); + + renderEditPage('my-func'); + + await waitFor(() => { + expect(screen.getByText('func.yaml')).toBeInTheDocument(); + }); + + act(() => mockOnChange?.('edited content')); + + await userEvent.setup().click(screen.getByRole('button', { name: /Save & Deploy/ })); + + await waitFor(() => { + expect(screen.getByText('Pushed to GitHub. Deployment running...')).toBeInTheDocument(); + }); + + vi.advanceTimersByTime(2000); + + await waitFor(() => { + expect(screen.queryByText('Pushed to GitHub. Deployment running...')).not.toBeInTheDocument(); + }); + + vi.useRealTimers(); + }); +}); + +function setupPushHandlers() { + setupSearchReposHandler(); + server.use( + http.get(`${GITHUB_API}/repos/twoGiants/my-func/git/ref/:ref+`, () => + HttpResponse.json({ object: { sha: 'head-sha' } }), + ), + http.get(`${GITHUB_API}/repos/twoGiants/my-func/git/commits/head-sha`, () => + HttpResponse.json({ tree: { sha: 'parent-tree-sha' } }), + ), + http.post(`${GITHUB_API}/repos/twoGiants/my-func/git/blobs`, () => + HttpResponse.json({ sha: 'blob-sha' }), + ), + http.post(`${GITHUB_API}/repos/twoGiants/my-func/git/trees`, () => + HttpResponse.json({ sha: 'tree-sha' }), + ), + http.post(`${GITHUB_API}/repos/twoGiants/my-func/git/commits`, () => + HttpResponse.json({ sha: 'commit-sha' }), + ), + http.patch(`${GITHUB_API}/repos/twoGiants/my-func/git/refs/:ref+`, () => HttpResponse.json({})), + ); +} diff --git a/src/views/FunctionEditPage.tsx b/src/views/FunctionEditPage.tsx index 7d901e2..0da5c9e 100644 --- a/src/views/FunctionEditPage.tsx +++ b/src/views/FunctionEditPage.tsx @@ -1,20 +1,363 @@ -import { DocumentTitle, ListPageHeader } from '@openshift-console/dynamic-plugin-sdk'; -import { PageSection } from '@patternfly/react-core'; +import { CodeEditor, DocumentTitle, ListPageHeader } from '@openshift-console/dynamic-plugin-sdk'; +import { Language } from '@patternfly/react-code-editor'; +import { + Alert, + Button, + EmptyState, + EmptyStateBody, + Flex, + FlexItem, + Modal, + ModalBody, + ModalFooter, + ModalHeader, + PageSection, + Toolbar, + ToolbarContent, + ToolbarGroup, + ToolbarItem, +} from '@patternfly/react-core'; +import { ArrowLeftIcon, CodeIcon } from '@patternfly/react-icons'; +import { useEffect, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { useParams } from 'react-router-dom-v5-compat'; +import { useNavigate, useParams } from 'react-router-dom-v5-compat'; +import { FileTreeView } from '../components/FileTreeView'; import { UserAvatar } from '../components/UserAvatar'; +import { SourceControlService } from '../services/source-control/SourceControlService'; +import { useSourceControlService } from '../services/source-control/useSourceControlService'; +import { FileEntry, RepoMetadata } from '../services/types'; +import { getLanguageFromPath, handlerMap, parseNamespaceAndRuntime } from '../utils/utils'; + +// --- page component --- export default function FunctionEditPage() { const { t } = useTranslation('plugin__console-functions-plugin'); - const { name } = useParams<{ name: string }>(); + const state = useFunctionEditPage(); return ( <> {t('Edit function')} - + - {t('Coming soon.')} + + + + + + + + + + {t('Select a file from the tree view to start editing.')} + + + } + isLanguageLabelVisible + /> + + + + + ); +} + +// --- page hook --- + +interface FunctionEditPageState { + files: FileEntry[]; + selectedPath: string | null; + selectedContent: string; + selectedLanguage: Language; + dirtyPaths: Set; + hasChanges: boolean; + isLoading: boolean; + repoMetadata: RepoMetadata | undefined; + onFileSelect: (path: string) => void; + onFileChange: (content: string) => void; + saveFiles: () => Promise; +} + +function useFunctionEditPage(): FunctionEditPageState { + const sourceControl = useSourceControlService(); + const { name: repoName } = useParams<{ name: string }>(); + + const [files, setFiles] = useState([]); + const [originalFiles, setOriginalFiles] = useState([]); + const [repoMetadata, setRepoMetadata] = useState(); + const [selectedPath, setSelectedPath] = useState(''); + const [isLoading, setIsLoading] = useState(true); + + const dirtyFiles = new Set( + files + // Guard: originalFiles is empty during initial render before fetch completes. + .filter((f, i) => originalFiles[i] && f.content !== originalFiles[i].content) + .map((f) => f.path), + ); + const hasChanges = dirtyFiles.size > 0; + + const selectedFile = files.find((f) => f.path === selectedPath); + const selectedContent = selectedFile?.content ?? ''; + const selectedLanguage = getLanguageFromPath(selectedPath); + + useEffect(() => { + let ignore = false; + + async function loadFiles() { + let repo: { content: FileEntry[]; metadata: RepoMetadata }; + try { + // we ignore the error and show an empty tree if repo is not found + repo = await resolveRepoContent(repoName!, sourceControl); + } catch { + if (!ignore) setIsLoading(false); + return; + } + if (ignore) return; + + if (repo.content.length === 0) { + setIsLoading(false); + return; + } + + setFiles(repo.content); + // Shallow copy each entry so files and originalFiles hold + // different object references. When onFileChange updates a + // file's content via setFiles, the corresponding originalFiles + // entry stays unchanged, enabling dirty comparison. + setOriginalFiles(repo.content.map((f) => ({ ...f }))); + setRepoMetadata(repo.metadata); + setSelectedPath(determineHandler(repo.content)); + setIsLoading(false); + } + + loadFiles(); + return () => { + ignore = true; + }; + }, [repoName, sourceControl]); + + const onFileSelect = (path: string) => { + setSelectedPath(path); + }; + + const onFileChange = (content: string) => { + if (!selectedPath) return; + setFiles((prev) => prev.map((f) => (f.path === selectedPath ? { ...f, content } : f))); + }; + + const saveFiles = async () => { + if (!repoMetadata) return; + await sourceControl.updateRepo(repoMetadata, files, 'Update function files'); + setOriginalFiles(files.map((f) => ({ ...f }))); + }; + + return { + files, + selectedPath, + selectedContent, + selectedLanguage, + dirtyPaths: dirtyFiles, + hasChanges, + isLoading, + repoMetadata, + onFileSelect, + onFileChange, + saveFiles, + }; +} + +async function resolveRepoContent( + repoName: string, + sourceControl: SourceControlService, +): Promise<{ content: FileEntry[]; metadata: RepoMetadata }> { + const repos = await sourceControl.listFunctionRepos(); + + const repoMetadata = repos.find((r) => r.name === repoName); + if (!repoMetadata) throw new Error(`repository ${repoName} not found`); + + return { + content: await sourceControl.fetch(repoMetadata), + metadata: repoMetadata, + }; +} + +function determineHandler(loadedFiles: FileEntry[]): string { + const funcYaml = loadedFiles.find((f) => f.path === 'func.yaml'); + if (!funcYaml) return ''; + + const { runtime } = parseNamespaceAndRuntime(funcYaml.content); + + const handlerPath = handlerMap[runtime]; + if (loadedFiles.find((f) => f.path === handlerPath)) return handlerPath; + return ''; +} + +// --- toolbar component --- + +interface EditToolbarProps { + hasChanges: boolean; + onSave: () => Promise; +} + +function EditToolbar({ hasChanges, onSave }: EditToolbarProps) { + const { t } = useTranslation('plugin__console-functions-plugin'); + const { + isSaving, + errorMsg, + successMsg, + showLeaveModal, + handleSave, + handleBack, + onLeaveConfirm, + onLeaveCancel, + } = useEditToolbar(hasChanges, onSave); + + return ( + <> + + + + + + + + {errorMsg && } + {successMsg && } + + + + + + + + + + ); } + +function useEditToolbar( + hasChanges: boolean, + onSave: () => Promise, +): { + isSaving: boolean; + errorMsg: string; + successMsg: string; + showLeaveModal: boolean; + handleSave: () => Promise; + handleBack: () => void; + onLeaveConfirm: () => void; + onLeaveCancel: () => void; +} { + const navigate = useNavigate(); + const [isSaving, setIsSaving] = useState(false); + const [errorMsg, setErrorMsg] = useState(''); + const [successMsg, setSuccessMsg] = useState(''); + const [showLeaveModal, setShowLeaveModal] = useState(false); + + // Cleared on unmount to prevent state updates after navigation. + const dismissTimer = useRef>(); + + useEffect(() => { + return () => clearTimeout(dismissTimer.current); + }, []); + + const handleSave = async () => { + setIsSaving(true); + setErrorMsg(''); + setSuccessMsg(''); + try { + await onSave(); + setSuccessMsg('Pushed to GitHub. Deployment running...'); + dismissTimer.current = setTimeout(() => setSuccessMsg(''), 2000); + } catch (err) { + setErrorMsg(err instanceof Error ? err.message : String(err)); + } finally { + setIsSaving(false); + } + }; + + const handleBack = () => { + if (hasChanges) setShowLeaveModal(true); + else navigate('/faas'); + }; + + const onLeaveConfirm = () => { + setShowLeaveModal(false); + navigate('/faas'); + }; + + const onLeaveCancel = () => { + setShowLeaveModal(false); + }; + + return { + isSaving, + errorMsg, + successMsg, + showLeaveModal, + handleSave, + handleBack, + onLeaveConfirm, + onLeaveCancel, + }; +} + +// --- leave modal component --- + +function LeaveModal({ + isOpen, + onStay, + onLeave, +}: { + isOpen: boolean; + onStay: () => void; + onLeave: () => void; +}) { + const { t } = useTranslation('plugin__console-functions-plugin'); + + return ( + + + {t('You have unsaved changes. Leave anyway?')} + + + + + + ); +} diff --git a/src/views/FunctionsListPage.test.tsx b/src/views/FunctionsListPage.test.tsx index 108bd63..21024b1 100644 --- a/src/views/FunctionsListPage.test.tsx +++ b/src/views/FunctionsListPage.test.tsx @@ -3,11 +3,11 @@ import { MemoryRouter } from 'react-router-dom-v5-compat'; import FunctionsListPage from './FunctionsListPage'; import { PAT_KEY } from '../services/types'; -jest.mock('react-i18next', () => ({ +vi.mock('react-i18next', () => ({ useTranslation: () => ({ t: (key: string) => key }), })); -jest.mock('@openshift-console/dynamic-plugin-sdk', () => ({ +vi.mock('@openshift-console/dynamic-plugin-sdk', () => ({ DocumentTitle: ({ children }: { children: string }) => children, ListPageHeader: ({ title, children }: { title: string; children?: React.ReactNode }) => ( <> @@ -17,22 +17,22 @@ jest.mock('@openshift-console/dynamic-plugin-sdk', () => ({ ), })); -const mockUseSourceControl = jest.fn(); -jest.mock('../services/source-control/useSourceControlService', () => ({ +const mockUseSourceControl = vi.fn(); +vi.mock('../services/source-control/useSourceControlService', () => ({ useSourceControlService: () => mockUseSourceControl(), })); -const mockUseClusterService = jest.fn(); -jest.mock('../services/cluster/useClusterService', () => ({ +const mockUseClusterService = vi.fn(); +vi.mock('../services/cluster/useClusterService', () => ({ useClusterService: () => mockUseClusterService(), })); -jest.mock('../components/FunctionTable', () => ({ +vi.mock('../components/FunctionTable', () => ({ FunctionTable: ({ functions }: { functions: { name: string }[] }) => functions.map((f) => f.name).join(','), })); -jest.mock('../components/UserAvatar', () => ({ +vi.mock('../components/UserAvatar', () => ({ UserAvatar: ({ enableReconnect }: { enableReconnect: boolean }) => ( {enableReconnect ? 'reconnect' : 'no-reconnect'} ), @@ -48,7 +48,7 @@ describe('FunctionsListPage', () => { }); afterEach(() => { - jest.restoreAllMocks(); + vi.restoreAllMocks(); }); afterAll(() => { @@ -58,8 +58,8 @@ describe('FunctionsListPage', () => { it('renders a spinner while loading', () => { renderAuthenticated(); mockUseSourceControl.mockReturnValue({ - listFunctionRepos: jest.fn().mockResolvedValue([]), - fetchFileContent: jest.fn(), + listFunctionRepos: vi.fn().mockResolvedValue([]), + fetchFileContent: vi.fn(), }); mockUseClusterService.mockReturnValue({ deployments: [], loaded: false, error: null }); @@ -75,8 +75,8 @@ describe('FunctionsListPage', () => { it('renders the empty state when loaded with no functions', async () => { renderAuthenticated(); mockUseSourceControl.mockReturnValue({ - listFunctionRepos: jest.fn().mockResolvedValue([]), - fetchFileContent: jest.fn(), + listFunctionRepos: vi.fn().mockResolvedValue([]), + fetchFileContent: vi.fn(), }); mockUseClusterService.mockReturnValue({ deployments: [], loaded: true, error: null }); @@ -92,7 +92,7 @@ describe('FunctionsListPage', () => { it('renders table when functions are loaded', async () => { renderAuthenticated(); mockUseSourceControl.mockReturnValue({ - listFunctionRepos: jest.fn().mockResolvedValue([ + listFunctionRepos: vi.fn().mockResolvedValue([ { owner: 'twoGiants', name: 'my-func', @@ -100,9 +100,7 @@ describe('FunctionsListPage', () => { defaultBranch: 'main', }, ]), - fetchFileContent: jest - .fn() - .mockResolvedValue('name: my-func\nruntime: go\nnamespace: demo\n'), + fetchFileContent: vi.fn().mockResolvedValue('name: my-func\nruntime: go\nnamespace: demo\n'), }); mockUseClusterService.mockReturnValue({ deployments: [ @@ -134,7 +132,7 @@ describe('FunctionsListPage', () => { it('shows NotDeployed status for repos without cluster deployment', async () => { renderAuthenticated(); mockUseSourceControl.mockReturnValue({ - listFunctionRepos: jest.fn().mockResolvedValue([ + listFunctionRepos: vi.fn().mockResolvedValue([ { owner: 'twoGiants', name: 'orphan-func', @@ -142,7 +140,7 @@ describe('FunctionsListPage', () => { defaultBranch: 'main', }, ]), - fetchFileContent: jest + fetchFileContent: vi .fn() .mockResolvedValue('name: orphan-func\nruntime: node\nnamespace: demo\n'), }); @@ -160,8 +158,8 @@ describe('FunctionsListPage', () => { it('renders empty state when GitHub API fails', async () => { renderAuthenticated(); mockUseSourceControl.mockReturnValue({ - listFunctionRepos: jest.fn().mockRejectedValue(new Error('Requires authentication')), - fetchFileContent: jest.fn(), + listFunctionRepos: vi.fn().mockRejectedValue(new Error('Requires authentication')), + fetchFileContent: vi.fn(), }); mockUseClusterService.mockReturnValue({ deployments: [], loaded: true, error: null }); @@ -175,10 +173,10 @@ describe('FunctionsListPage', () => { }); it('does not call listFunctionRepos when not authenticated', async () => { - const mockListRepos = jest.fn().mockResolvedValue([]); + const mockListRepos = vi.fn().mockResolvedValue([]); mockUseSourceControl.mockReturnValue({ listFunctionRepos: mockListRepos, - fetchFileContent: jest.fn(), + fetchFileContent: vi.fn(), }); mockUseClusterService.mockReturnValue({ deployments: [], loaded: true, error: null }); @@ -196,8 +194,8 @@ describe('FunctionsListPage', () => { it('renders UserAvatar in header', () => { renderAuthenticated(); mockUseSourceControl.mockReturnValue({ - listFunctionRepos: jest.fn().mockResolvedValue([]), - fetchFileContent: jest.fn(), + listFunctionRepos: vi.fn().mockResolvedValue([]), + fetchFileContent: vi.fn(), }); mockUseClusterService.mockReturnValue({ deployments: [], loaded: true, error: null }); @@ -212,8 +210,8 @@ describe('FunctionsListPage', () => { it('empty state receives hint and isCreateDisabled when not authenticated', async () => { mockUseSourceControl.mockReturnValue({ - listFunctionRepos: jest.fn().mockResolvedValue([]), - fetchFileContent: jest.fn(), + listFunctionRepos: vi.fn().mockResolvedValue([]), + fetchFileContent: vi.fn(), }); mockUseClusterService.mockReturnValue({ deployments: [], loaded: true, error: null }); diff --git a/src/views/FunctionsListPage.tsx b/src/views/FunctionsListPage.tsx index e6e6018..f8b0c02 100644 --- a/src/views/FunctionsListPage.tsx +++ b/src/views/FunctionsListPage.tsx @@ -16,6 +16,8 @@ import { ForgeConnectionContext, } from '../context/ForgeConnectionProvider'; import { UserAvatar } from '../components/UserAvatar'; +import { RepoMetadata } from '../services/types'; +import { parseNamespaceAndRuntime } from '../utils/utils'; export default function FunctionsListPage() { return ( @@ -103,23 +105,28 @@ function useFunctionListPage(): { let ignore = false; async function loadFunctionTableItems() { - const repos = await sourceControl.listFunctionRepos(); - const items = await Promise.all( - repos.map(async (repo) => { - const funcYaml = await sourceControl.fetchFileContent(repo, 'func.yaml'); - const { namespace, runtime } = parseNamespaceAndRuntime(funcYaml, repo.name); - return newItem(repo.name, namespace, runtime); - }), - ); - if (!ignore) { - setFunctionItems(items); - setReposLoaded(true); + let repos: RepoMetadata[]; + let items: FunctionTableItem[]; + try { + repos = await sourceControl.listFunctionRepos(); + items = await Promise.all( + repos.map(async (repo) => { + const funcYaml = await sourceControl.fetchFileContent(repo, 'func.yaml'); + const { namespace, runtime } = parseNamespaceAndRuntime(funcYaml); + return newItem(repo.name, namespace, runtime); + }), + ); + } catch { + if (!ignore) setReposLoaded(true); + return; } + if (ignore) return; + + setFunctionItems(items); + setReposLoaded(true); } - loadFunctionTableItems().catch(() => { - if (!ignore) setReposLoaded(true); - }); + loadFunctionTableItems(); return () => { ignore = true; }; @@ -142,19 +149,6 @@ function useFunctionListPage(): { return { functions, loaded, onEdit, isConnectedToForge }; } -function parseNamespaceAndRuntime( - funcYaml: string, - repoName: string, -): { - namespace: string; - runtime: string; -} { - const runtimeMatch = funcYaml.match(/^runtime:\s*(.+)$/m); - const namespaceMatch = funcYaml.match(/^namespace:\s*(.+)$/m); - if (!runtimeMatch) throw new Error(`func.yaml in ${repoName} missing runtime field`); - return { namespace: namespaceMatch?.[1]?.trim() ?? '', runtime: runtimeMatch[1].trim() }; -} - function newItem(repoName: string, namespace: string, runtime: string): FunctionTableItem { return { name: repoName, diff --git a/start-console.sh b/start-console.sh index f6b49a7..1172604 100755 --- a/start-console.sh +++ b/start-console.sh @@ -59,6 +59,10 @@ fi BRIDGE_PLUGINS="${PLUGIN_NAME}=http://${PLUGIN_HOST}:9001" BRIDGE_PLUGIN_PROXY='{"services":[{"consoleAPIPath":"/api/proxy/plugin/'"${PLUGIN_NAME}"'/backend/","endpoint":"http://'"${PLUGIN_HOST}"':8080","authorize":false}]}' +# Allow browser to connect to GitHub API (CSP connect-src). +# Production uses ConsolePlugin.spec.contentSecurityPolicy instead. +BRIDGE_CONTENT_SECURITY_POLICY="connect-src=https://api.github.com" + echo "BRIDGE_PLUGINS=$BRIDGE_PLUGINS" echo "BRIDGE_PLUGIN_PROXY=$BRIDGE_PLUGIN_PROXY" diff --git a/testing/msw/handlers.ts b/testing/msw/handlers.ts new file mode 100644 index 0000000..c08266b --- /dev/null +++ b/testing/msw/handlers.ts @@ -0,0 +1,16 @@ +import { http, HttpResponse } from 'msw'; + +const GITHUB_API = 'https://api.github.com'; + +/** Default GitHub API handlers. Override per test by using server.use(). */ +export const handlers = [ + // GET /user - authenticated user + http.get(`${GITHUB_API}/user`, () => + HttpResponse.json({ login: 'twoGiants' }), + ), + + // GET /search/repositories - search for function repos + http.get(`${GITHUB_API}/search/repositories`, () => + HttpResponse.json({ total_count: 0, items: [] }), + ), +]; diff --git a/testing/msw/server.ts b/testing/msw/server.ts new file mode 100644 index 0000000..e52fee0 --- /dev/null +++ b/testing/msw/server.ts @@ -0,0 +1,4 @@ +import { setupServer } from 'msw/node'; +import { handlers } from './handlers'; + +export const server = setupServer(...handlers); diff --git a/testing/setup.ts b/testing/setup.ts new file mode 100644 index 0000000..acb4c21 --- /dev/null +++ b/testing/setup.ts @@ -0,0 +1,6 @@ +import '@testing-library/jest-dom/vitest'; +import { server } from '../testing/msw/server'; + +beforeAll(() => server.listen({ onUnhandledRequest: 'error' })); +afterEach(() => server.resetHandlers()); +afterAll(() => server.close()); diff --git a/tsconfig.json b/tsconfig.json index 1573d16..efe5d45 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,9 +8,10 @@ "jsx": "react-jsx", "allowJs": true, "strict": true, - "noUnusedLocals": true + "noUnusedLocals": true, + "types": ["vitest/globals"] }, - "include": ["src"], + "include": ["src", "testing"], "exclude": ["node_modules"], "ts-node": { "files": true, diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000..f211d59 --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + environment: 'jsdom', + globals: true, + setupFiles: ['./testing/setup.ts'], + css: false, + }, +}); diff --git a/yarn.lock b/yarn.lock index 5367c1f..5d2e818 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12,20 +12,47 @@ __metadata: languageName: node linkType: hard -"@asamuzakjp/css-color@npm:^3.2.0": - version: 3.2.0 - resolution: "@asamuzakjp/css-color@npm:3.2.0" +"@asamuzakjp/css-color@npm:^5.1.5": + version: 5.1.11 + resolution: "@asamuzakjp/css-color@npm:5.1.11" + dependencies: + "@asamuzakjp/generational-cache": "npm:^1.0.1" + "@csstools/css-calc": "npm:^3.2.0" + "@csstools/css-color-parser": "npm:^4.1.0" + "@csstools/css-parser-algorithms": "npm:^4.0.0" + "@csstools/css-tokenizer": "npm:^4.0.0" + checksum: 10c0/32720bdff8daea6a8847aba6cdfae55baa3b4a2690b51d21db7f0382bbd183f3d9f2d5126df50afd889062635684b2819e47113629ee2e80c99389e75f48d060 + languageName: node + linkType: hard + +"@asamuzakjp/dom-selector@npm:^7.0.6": + version: 7.1.1 + resolution: "@asamuzakjp/dom-selector@npm:7.1.1" dependencies: - "@csstools/css-calc": "npm:^2.1.3" - "@csstools/css-color-parser": "npm:^3.0.9" - "@csstools/css-parser-algorithms": "npm:^3.0.4" - "@csstools/css-tokenizer": "npm:^3.0.3" - lru-cache: "npm:^10.4.3" - checksum: 10c0/a4bf1c831751b1fae46b437e37e8a38c0b5bd58d23230157ae210bd1e905fe509b89b7c243e63d1522d852668a6292ed730a160e21342772b4e5b7b8ea14c092 + "@asamuzakjp/generational-cache": "npm:^1.0.1" + "@asamuzakjp/nwsapi": "npm:^2.3.9" + bidi-js: "npm:^1.0.3" + css-tree: "npm:^3.2.1" + is-potential-custom-element-name: "npm:^1.0.1" + checksum: 10c0/8cec1c618781c94de5836a215bbe5aafb4d8b835b18c51faf8547f4574afa39f92def3951e40123860062467613dd825f1e1600ff32e8045cc099a91796dcfb8 + languageName: node + linkType: hard + +"@asamuzakjp/generational-cache@npm:^1.0.1": + version: 1.0.1 + resolution: "@asamuzakjp/generational-cache@npm:1.0.1" + checksum: 10c0/1de62de43764e13fca3b9a31b7ea9b1bf0780fe053d266e40378a19ff8c66b543e011e6a0df02d410cd59bf981126706f176cdbb938985165202c4a079fe1057 + languageName: node + linkType: hard + +"@asamuzakjp/nwsapi@npm:^2.3.9": + version: 2.3.9 + resolution: "@asamuzakjp/nwsapi@npm:2.3.9" + checksum: 10c0/869b81382e775499c96c45c6dbe0d0766a6da04bcf0abb79f5333535c4e19946851acaa43398f896e2ecc5a1de9cf3db7cf8c4b1afac1ee3d15e21584546d74d languageName: node linkType: hard -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.27.1, @babel/code-frame@npm:^7.28.6, @babel/code-frame@npm:^7.29.0": +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.28.6, @babel/code-frame@npm:^7.29.0": version: 7.29.0 resolution: "@babel/code-frame@npm:7.29.0" dependencies: @@ -43,7 +70,7 @@ __metadata: languageName: node linkType: hard -"@babel/core@npm:^7.23.9, @babel/core@npm:^7.24.4, @babel/core@npm:^7.27.4, @babel/core@npm:^7.29.0": +"@babel/core@npm:^7.24.4, @babel/core@npm:^7.29.0": version: 7.29.0 resolution: "@babel/core@npm:7.29.0" dependencies: @@ -66,7 +93,7 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.27.5, @babel/generator@npm:^7.29.0": +"@babel/generator@npm:^7.29.0": version: 7.29.1 resolution: "@babel/generator@npm:7.29.1" dependencies: @@ -195,7 +222,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.27.1, @babel/helper-plugin-utils@npm:^7.28.6, @babel/helper-plugin-utils@npm:^7.8.0": +"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.27.1, @babel/helper-plugin-utils@npm:^7.28.6": version: 7.28.6 resolution: "@babel/helper-plugin-utils@npm:7.28.6" checksum: 10c0/3f5f8acc152fdbb69a84b8624145ff4f9b9f6e776cb989f9f968f8606eb7185c5c3cfcf3ba08534e37e1e0e1c118ac67080610333f56baa4f7376c99b5f1143d @@ -280,17 +307,6 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.9": - version: 7.29.2 - resolution: "@babel/parser@npm:7.29.2" - dependencies: - "@babel/types": "npm:^7.29.0" - bin: - parser: ./bin/babel-parser.js - checksum: 10c0/e5a4e69e3ac7acdde995f37cf299a68458cfe7009dff66bd0962fd04920bef287201169006af365af479c08ff216bfefbb595e331f87f6ae7283858aebbc3317 - languageName: node - linkType: hard - "@babel/parser@npm:^7.24.4, @babel/parser@npm:^7.28.6, @babel/parser@npm:^7.29.0": version: 7.29.0 resolution: "@babel/parser@npm:7.29.0" @@ -370,50 +386,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-async-generators@npm:^7.8.4": - version: 7.8.4 - resolution: "@babel/plugin-syntax-async-generators@npm:7.8.4" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.8.0" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/d13efb282838481348c71073b6be6245b35d4f2f964a8f71e4174f235009f929ef7613df25f8d2338e2d3e44bc4265a9f8638c6aaa136d7a61fe95985f9725c8 - languageName: node - linkType: hard - -"@babel/plugin-syntax-bigint@npm:^7.8.3": - version: 7.8.3 - resolution: "@babel/plugin-syntax-bigint@npm:7.8.3" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.8.0" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/686891b81af2bc74c39013655da368a480f17dd237bf9fbc32048e5865cb706d5a8f65438030da535b332b1d6b22feba336da8fa931f663b6b34e13147d12dde - languageName: node - linkType: hard - -"@babel/plugin-syntax-class-properties@npm:^7.12.13": - version: 7.12.13 - resolution: "@babel/plugin-syntax-class-properties@npm:7.12.13" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.12.13" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/95168fa186416195280b1264fb18afcdcdcea780b3515537b766cb90de6ce042d42dd6a204a39002f794ae5845b02afb0fd4861a3308a861204a55e68310a120 - languageName: node - linkType: hard - -"@babel/plugin-syntax-class-static-block@npm:^7.14.5": - version: 7.14.5 - resolution: "@babel/plugin-syntax-class-static-block@npm:7.14.5" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.14.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/4464bf9115f4a2d02ce1454411baf9cfb665af1da53709c5c56953e5e2913745b0fcce82982a00463d6facbdd93445c691024e310b91431a1e2f024b158f6371 - languageName: node - linkType: hard - "@babel/plugin-syntax-import-assertions@npm:^7.28.6": version: 7.28.6 resolution: "@babel/plugin-syntax-import-assertions@npm:7.28.6" @@ -425,7 +397,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-import-attributes@npm:^7.24.7, @babel/plugin-syntax-import-attributes@npm:^7.28.6": +"@babel/plugin-syntax-import-attributes@npm:^7.28.6": version: 7.28.6 resolution: "@babel/plugin-syntax-import-attributes@npm:7.28.6" dependencies: @@ -436,138 +408,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-import-meta@npm:^7.10.4": - version: 7.10.4 - resolution: "@babel/plugin-syntax-import-meta@npm:7.10.4" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.10.4" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/0b08b5e4c3128523d8e346f8cfc86824f0da2697b1be12d71af50a31aff7a56ceb873ed28779121051475010c28d6146a6bfea8518b150b71eeb4e46190172ee - languageName: node - linkType: hard - -"@babel/plugin-syntax-json-strings@npm:^7.8.3": - version: 7.8.3 - resolution: "@babel/plugin-syntax-json-strings@npm:7.8.3" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.8.0" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/e98f31b2ec406c57757d115aac81d0336e8434101c224edd9a5c93cefa53faf63eacc69f3138960c8b25401315af03df37f68d316c151c4b933136716ed6906e - languageName: node - linkType: hard - -"@babel/plugin-syntax-jsx@npm:^7.27.1": - version: 7.28.6 - resolution: "@babel/plugin-syntax-jsx@npm:7.28.6" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.28.6" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/b98fc3cd75e4ca3d5ca1162f610c286e14ede1486e0d297c13a5eb0ac85680ac9656d17d348bddd9160a54d797a08cea5eaac02b9330ddebb7b26732b7b99fb5 - languageName: node - linkType: hard - -"@babel/plugin-syntax-logical-assignment-operators@npm:^7.10.4": - version: 7.10.4 - resolution: "@babel/plugin-syntax-logical-assignment-operators@npm:7.10.4" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.10.4" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/2594cfbe29411ad5bc2ad4058de7b2f6a8c5b86eda525a993959438615479e59c012c14aec979e538d60a584a1a799b60d1b8942c3b18468cb9d99b8fd34cd0b - languageName: node - linkType: hard - -"@babel/plugin-syntax-nullish-coalescing-operator@npm:^7.8.3": - version: 7.8.3 - resolution: "@babel/plugin-syntax-nullish-coalescing-operator@npm:7.8.3" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.8.0" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/2024fbb1162899094cfc81152449b12bd0cc7053c6d4bda8ac2852545c87d0a851b1b72ed9560673cbf3ef6248257262c3c04aabf73117215c1b9cc7dd2542ce - languageName: node - linkType: hard - -"@babel/plugin-syntax-numeric-separator@npm:^7.10.4": - version: 7.10.4 - resolution: "@babel/plugin-syntax-numeric-separator@npm:7.10.4" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.10.4" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/c55a82b3113480942c6aa2fcbe976ff9caa74b7b1109ff4369641dfbc88d1da348aceb3c31b6ed311c84d1e7c479440b961906c735d0ab494f688bf2fd5b9bb9 - languageName: node - linkType: hard - -"@babel/plugin-syntax-object-rest-spread@npm:^7.8.3": - version: 7.8.3 - resolution: "@babel/plugin-syntax-object-rest-spread@npm:7.8.3" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.8.0" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/ee1eab52ea6437e3101a0a7018b0da698545230015fc8ab129d292980ec6dff94d265e9e90070e8ae5fed42f08f1622c14c94552c77bcac784b37f503a82ff26 - languageName: node - linkType: hard - -"@babel/plugin-syntax-optional-catch-binding@npm:^7.8.3": - version: 7.8.3 - resolution: "@babel/plugin-syntax-optional-catch-binding@npm:7.8.3" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.8.0" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/27e2493ab67a8ea6d693af1287f7e9acec206d1213ff107a928e85e173741e1d594196f99fec50e9dde404b09164f39dec5864c767212154ffe1caa6af0bc5af - languageName: node - linkType: hard - -"@babel/plugin-syntax-optional-chaining@npm:^7.8.3": - version: 7.8.3 - resolution: "@babel/plugin-syntax-optional-chaining@npm:7.8.3" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.8.0" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/46edddf2faa6ebf94147b8e8540dfc60a5ab718e2de4d01b2c0bdf250a4d642c2bd47cbcbb739febcb2bf75514dbcefad3c52208787994b8d0f8822490f55e81 - languageName: node - linkType: hard - -"@babel/plugin-syntax-private-property-in-object@npm:^7.14.5": - version: 7.14.5 - resolution: "@babel/plugin-syntax-private-property-in-object@npm:7.14.5" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.14.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/69822772561706c87f0a65bc92d0772cea74d6bc0911537904a676d5ff496a6d3ac4e05a166d8125fce4a16605bace141afc3611074e170a994e66e5397787f3 - languageName: node - linkType: hard - -"@babel/plugin-syntax-top-level-await@npm:^7.14.5": - version: 7.14.5 - resolution: "@babel/plugin-syntax-top-level-await@npm:7.14.5" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.14.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/14bf6e65d5bc1231ffa9def5f0ef30b19b51c218fcecaa78cd1bdf7939dfdf23f90336080b7f5196916368e399934ce5d581492d8292b46a2fb569d8b2da106f - languageName: node - linkType: hard - -"@babel/plugin-syntax-typescript@npm:^7.27.1": - version: 7.28.6 - resolution: "@babel/plugin-syntax-typescript@npm:7.28.6" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.28.6" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/b0c392a35624883ac480277401ac7d92d8646b66e33639f5d350de7a6723924265985ae11ab9ebd551740ded261c443eaa9a87ea19def9763ca1e0d78c97dea8 - languageName: node - linkType: hard - "@babel/plugin-syntax-unicode-sets-regex@npm:^7.18.6": version: 7.18.6 resolution: "@babel/plugin-syntax-unicode-sets-regex@npm:7.18.6" @@ -1314,7 +1154,7 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.5, @babel/types@npm:^7.28.6, @babel/types@npm:^7.29.0, @babel/types@npm:^7.4.4": +"@babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.5, @babel/types@npm:^7.28.6, @babel/types@npm:^7.29.0, @babel/types@npm:^7.4.4": version: 7.29.0 resolution: "@babel/types@npm:7.29.0" dependencies: @@ -1324,10 +1164,21 @@ __metadata: languageName: node linkType: hard -"@bcoe/v8-coverage@npm:^0.2.3": - version: 0.2.3 - resolution: "@bcoe/v8-coverage@npm:0.2.3" - checksum: 10c0/6b80ae4cb3db53f486da2dc63b6e190a74c8c3cca16bb2733f234a0b6a9382b09b146488ae08e2b22cf00f6c83e20f3e040a2f7894f05c045c946d6a090b1d52 +"@bcoe/v8-coverage@npm:^1.0.2": + version: 1.0.2 + resolution: "@bcoe/v8-coverage@npm:1.0.2" + checksum: 10c0/1eb1dc93cc17fb7abdcef21a6e7b867d6aa99a7ec88ec8207402b23d9083ab22a8011213f04b2cf26d535f1d22dc26139b7929e6c2134c254bd1e14ba5e678c3 + languageName: node + linkType: hard + +"@bramus/specificity@npm:^2.4.2": + version: 2.4.2 + resolution: "@bramus/specificity@npm:2.4.2" + dependencies: + css-tree: "npm:^3.0.0" + bin: + specificity: bin/cli.js + checksum: 10c0/c5f4e04e0bca0d2202598207a5eb0733c8109d12a68a329caa26373bec598d99db5bb785b8865fefa00fc01b08c6068138807ceb11a948fe15e904ed6cf4ba72 languageName: node linkType: hard @@ -1362,20 +1213,10 @@ __metadata: languageName: node linkType: hard -"@csstools/color-helpers@npm:^5.1.0": - version: 5.1.0 - resolution: "@csstools/color-helpers@npm:5.1.0" - checksum: 10c0/b7f99d2e455cf1c9b41a67a5327d5d02888cd5c8802a68b1887dffef537d9d4bc66b3c10c1e62b40bbed638b6c1d60b85a232f904ed7b39809c4029cb36567db - languageName: node - linkType: hard - -"@csstools/css-calc@npm:^2.1.3, @csstools/css-calc@npm:^2.1.4": - version: 2.1.4 - resolution: "@csstools/css-calc@npm:2.1.4" - peerDependencies: - "@csstools/css-parser-algorithms": ^3.0.5 - "@csstools/css-tokenizer": ^3.0.4 - checksum: 10c0/42ce5793e55ec4d772083808a11e9fb2dfe36db3ec168713069a276b4c3882205b3507c4680224c28a5d35fe0bc2d308c77f8f2c39c7c09aad8747708eb8ddd8 +"@csstools/color-helpers@npm:^6.0.2": + version: 6.0.2 + resolution: "@csstools/color-helpers@npm:6.0.2" + checksum: 10c0/4c66574563d7c960010c11e41c2673675baff07c427cca6e8dddffa5777de45770d13ff3efce1c0642798089ad55de52870d9d8141f78db3fa5bba012f2d3789 languageName: node linkType: hard @@ -1389,25 +1230,26 @@ __metadata: languageName: node linkType: hard -"@csstools/css-color-parser@npm:^3.0.9": - version: 3.1.0 - resolution: "@csstools/css-color-parser@npm:3.1.0" - dependencies: - "@csstools/color-helpers": "npm:^5.1.0" - "@csstools/css-calc": "npm:^2.1.4" +"@csstools/css-calc@npm:^3.2.0": + version: 3.2.0 + resolution: "@csstools/css-calc@npm:3.2.0" peerDependencies: - "@csstools/css-parser-algorithms": ^3.0.5 - "@csstools/css-tokenizer": ^3.0.4 - checksum: 10c0/0e0c670ad54ec8ec4d9b07568b80defd83b9482191f5e8ca84ab546b7be6db5d7cc2ba7ac9fae54488b129a4be235d6183d3aab4416fec5e89351f73af4222c5 + "@csstools/css-parser-algorithms": ^4.0.0 + "@csstools/css-tokenizer": ^4.0.0 + checksum: 10c0/a4dffeef3cb8ec9e8c1e44fa68c7634033050be52ea0b56ba6ac3815b635b587c6f3a8f8cd7b8f53881c2dd0ab9ec0af77227c532ed81b8e24a05aa997d22337 languageName: node linkType: hard -"@csstools/css-parser-algorithms@npm:^3.0.4": - version: 3.0.5 - resolution: "@csstools/css-parser-algorithms@npm:3.0.5" +"@csstools/css-color-parser@npm:^4.1.0": + version: 4.1.0 + resolution: "@csstools/css-color-parser@npm:4.1.0" + dependencies: + "@csstools/color-helpers": "npm:^6.0.2" + "@csstools/css-calc": "npm:^3.2.0" peerDependencies: - "@csstools/css-tokenizer": ^3.0.4 - checksum: 10c0/d9a1c888bd43849ae3437ca39251d5c95d2c8fd6b5ccdb7c45491dfd2c1cbdc3075645e80901d120e4d2c1993db9a5b2d83793b779dbbabcfb132adb142eb7f7 + "@csstools/css-parser-algorithms": ^4.0.0 + "@csstools/css-tokenizer": ^4.0.0 + checksum: 10c0/b5b8a697b4c1b22dd535b4d93b2ffce338d38e587ac1ab20b781c08328bfa99e5f763a99d990983560df543862fa9bd578ee966c18f9d3381c8e33c641d32a0e languageName: node linkType: hard @@ -1427,10 +1269,15 @@ __metadata: languageName: node linkType: hard -"@csstools/css-tokenizer@npm:^3.0.3": - version: 3.0.4 - resolution: "@csstools/css-tokenizer@npm:3.0.4" - checksum: 10c0/3b589f8e9942075a642213b389bab75a2d50d05d203727fcdac6827648a5572674caff07907eff3f9a2389d86a4ee47308fafe4f8588f4a77b7167c588d2559f +"@csstools/css-syntax-patches-for-csstree@npm:^1.1.1": + version: 1.1.3 + resolution: "@csstools/css-syntax-patches-for-csstree@npm:1.1.3" + peerDependencies: + css-tree: ^3.2.1 + peerDependenciesMeta: + css-tree: + optional: true + checksum: 10c0/3b8a686710a46bb460f9d560d52ce0de315828e6d452002b692013e95fbf53669d7a71e28c9b6b1333fa9f37f058fad93e5db3b8516444907713cb9aad299ce1 languageName: node linkType: hard @@ -1545,31 +1392,31 @@ __metadata: languageName: node linkType: hard -"@emnapi/core@npm:^1.4.3": - version: 1.9.1 - resolution: "@emnapi/core@npm:1.9.1" +"@emnapi/core@npm:1.10.0": + version: 1.10.0 + resolution: "@emnapi/core@npm:1.10.0" dependencies: - "@emnapi/wasi-threads": "npm:1.2.0" + "@emnapi/wasi-threads": "npm:1.2.1" tslib: "npm:^2.4.0" - checksum: 10c0/00e7a99a2bc3ad908ca8272ba861a934da87dffa8797a41316c4a3b571a1e4d2743e2fa14b1a0f131fa4a3c2018ddb601cd2a8cb7f574fa940af696df3c2fe8d + checksum: 10c0/f51d08227857b60632de7714d708124f0e100a1462dde6df8221760939aa3204a73193830371830fac0716f3ccd2129f2cac1b17cd7d7958bc4da9018a296edb languageName: node linkType: hard -"@emnapi/runtime@npm:^1.4.3": - version: 1.9.1 - resolution: "@emnapi/runtime@npm:1.9.1" +"@emnapi/runtime@npm:1.10.0": + version: 1.10.0 + resolution: "@emnapi/runtime@npm:1.10.0" dependencies: tslib: "npm:^2.4.0" - checksum: 10c0/750edca117e0363ab2de10622f8ee60e57d8690c2f29c49704813da5cd627c641798d7f3cb0d953c62fdc71688e02e333ddbf2c1204f38b47e3e40657332a6f5 + checksum: 10c0/953f14991d1aefb92ee6f8eb27dea725e484791a53a0cb5f47d9e0087b9a2c929ff2e92adf95af15d6ad456db6300c6b761ebf72b50a875b874a83520b3ba093 languageName: node linkType: hard -"@emnapi/wasi-threads@npm:1.2.0": - version: 1.2.0 - resolution: "@emnapi/wasi-threads@npm:1.2.0" +"@emnapi/wasi-threads@npm:1.2.1": + version: 1.2.1 + resolution: "@emnapi/wasi-threads@npm:1.2.1" dependencies: tslib: "npm:^2.4.0" - checksum: 10c0/1e3724b5814b06c14782fda87eee9b9aa68af01576c81ffeaefdf621ddb74386e419d5b3b1027b6a8172397729d95a92f814fc4b8d3c224376428faa07a6a01a + checksum: 10c0/32fcfa81ab396533b2ec1f4082b1ff779a05d9c836bbbd3f4398405b0e6814c0d9503b7993130e37bc6941dbc1ded49f55e9700ae9ca4e803bab2b5bc5deb331 languageName: node linkType: hard @@ -1843,6 +1690,18 @@ __metadata: languageName: node linkType: hard +"@exodus/bytes@npm:^1.11.0, @exodus/bytes@npm:^1.15.0, @exodus/bytes@npm:^1.6.0": + version: 1.15.0 + resolution: "@exodus/bytes@npm:1.15.0" + peerDependencies: + "@noble/hashes": ^1.8.0 || ^2.0.0 + peerDependenciesMeta: + "@noble/hashes": + optional: true + checksum: 10c0/b48aad9729653385d6ed055c28cfcf0b1b1481cf5d83f4375c12abd7988f1d20f69c80b5f95d4a1cc24d9abe32b9efc352a812d53884c26efea172aca8b6356d + languageName: node + linkType: hard + "@gar/promise-retry@npm:^1.0.0": version: 1.0.2 resolution: "@gar/promise-retry@npm:1.0.2" @@ -1892,6 +1751,67 @@ __metadata: languageName: node linkType: hard +"@inquirer/ansi@npm:^2.0.5": + version: 2.0.5 + resolution: "@inquirer/ansi@npm:2.0.5" + checksum: 10c0/ad61532e5bb47473e3d987c32d4015499a8ce5f4f86e46467e8e672fc52670beb303905d6b324e453935a61671f59f3b9b1b6a1edbbe1f64085e2bb87735e295 + languageName: node + linkType: hard + +"@inquirer/confirm@npm:^6.0.11": + version: 6.0.12 + resolution: "@inquirer/confirm@npm:6.0.12" + dependencies: + "@inquirer/core": "npm:^11.1.9" + "@inquirer/type": "npm:^4.0.5" + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 10c0/36e9b1ef60e08562f07bcbcd78ba0a681b2fa3e5f54fa5e12303fc5982e8ba875ed782c24161e2295028b2b404ba690e841837303d16eeeb28df7aa9eb8aa835 + languageName: node + linkType: hard + +"@inquirer/core@npm:^11.1.9": + version: 11.1.9 + resolution: "@inquirer/core@npm:11.1.9" + dependencies: + "@inquirer/ansi": "npm:^2.0.5" + "@inquirer/figures": "npm:^2.0.5" + "@inquirer/type": "npm:^4.0.5" + cli-width: "npm:^4.1.0" + fast-wrap-ansi: "npm:^0.2.0" + mute-stream: "npm:^3.0.0" + signal-exit: "npm:^4.1.0" + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 10c0/f7b162ce5f67fb75aab00a3668fdd8c8629aec790087840ea66ee8ead6009ab2066bec9cbf5bcc394ccdf130e6139051d6bace334b3a66c4f05349585213172c + languageName: node + linkType: hard + +"@inquirer/figures@npm:^2.0.5": + version: 2.0.5 + resolution: "@inquirer/figures@npm:2.0.5" + checksum: 10c0/139671b88f33f059aec85ed3fdf464999115573350c6dea61141adc1cfd43d14742b6cb68150c2ca9baf5a1bae618f990ed89b4430ae768d415bbd19944c56df + languageName: node + linkType: hard + +"@inquirer/type@npm:^4.0.5": + version: 4.0.5 + resolution: "@inquirer/type@npm:4.0.5" + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 10c0/390edb0fd1f027f9c8dc26bac28486d38bbde6c19974ef1588ea187f54a2cb58db639ebca31fa81a8fe4a4e84c2f0953ab3f5a6768ba86649368c5e806148a6f + languageName: node + linkType: hard + "@isaacs/cliui@npm:^8.0.2": version: 8.0.2 resolution: "@isaacs/cliui@npm:8.0.2" @@ -1915,372 +1835,67 @@ __metadata: languageName: node linkType: hard -"@istanbuljs/load-nyc-config@npm:^1.0.0": - version: 1.1.0 - resolution: "@istanbuljs/load-nyc-config@npm:1.1.0" +"@jridgewell/gen-mapping@npm:^0.3.12, @jridgewell/gen-mapping@npm:^0.3.5": + version: 0.3.13 + resolution: "@jridgewell/gen-mapping@npm:0.3.13" dependencies: - camelcase: "npm:^5.3.1" - find-up: "npm:^4.1.0" - get-package-type: "npm:^0.1.0" - js-yaml: "npm:^3.13.1" - resolve-from: "npm:^5.0.0" - checksum: 10c0/dd2a8b094887da5a1a2339543a4933d06db2e63cbbc2e288eb6431bd832065df0c099d091b6a67436e71b7d6bf85f01ce7c15f9253b4cbebcc3b9a496165ba42 + "@jridgewell/sourcemap-codec": "npm:^1.5.0" + "@jridgewell/trace-mapping": "npm:^0.3.24" + checksum: 10c0/9a7d65fb13bd9aec1fbab74cda08496839b7e2ceb31f5ab922b323e94d7c481ce0fc4fd7e12e2610915ed8af51178bdc61e168e92a8c8b8303b030b03489b13b languageName: node linkType: hard -"@istanbuljs/schema@npm:^0.1.2, @istanbuljs/schema@npm:^0.1.3": - version: 0.1.3 - resolution: "@istanbuljs/schema@npm:0.1.3" - checksum: 10c0/61c5286771676c9ca3eb2bd8a7310a9c063fb6e0e9712225c8471c582d157392c88f5353581c8c9adbe0dff98892317d2fdfc56c3499aa42e0194405206a963a +"@jridgewell/remapping@npm:^2.3.5": + version: 2.3.5 + resolution: "@jridgewell/remapping@npm:2.3.5" + dependencies: + "@jridgewell/gen-mapping": "npm:^0.3.5" + "@jridgewell/trace-mapping": "npm:^0.3.24" + checksum: 10c0/3de494219ffeb2c5c38711d0d7bb128097edf91893090a2dbc8ee0b55d092bb7347b1fd0f478486c5eab010e855c73927b1666f2107516d472d24a73017d1194 languageName: node linkType: hard -"@jest/console@npm:30.3.0": - version: 30.3.0 - resolution: "@jest/console@npm:30.3.0" - dependencies: - "@jest/types": "npm:30.3.0" - "@types/node": "npm:*" - chalk: "npm:^4.1.2" - jest-message-util: "npm:30.3.0" - jest-util: "npm:30.3.0" - slash: "npm:^3.0.0" - checksum: 10c0/5458f26b0591b847b719a707cbd1d6b2b99960784a1480a28d19200a807b6092f066c1bd1810df8c6adebf934a64de7b6022dc35082cd7c8f09f35940da104d9 +"@jridgewell/resolve-uri@npm:^3.0.3, @jridgewell/resolve-uri@npm:^3.1.0": + version: 3.1.2 + resolution: "@jridgewell/resolve-uri@npm:3.1.2" + checksum: 10c0/d502e6fb516b35032331406d4e962c21fe77cdf1cbdb49c6142bcbd9e30507094b18972778a6e27cbad756209cfe34b1a27729e6fa08a2eb92b33943f680cf1e languageName: node linkType: hard -"@jest/core@npm:30.3.0": - version: 30.3.0 - resolution: "@jest/core@npm:30.3.0" +"@jridgewell/source-map@npm:^0.3.3": + version: 0.3.11 + resolution: "@jridgewell/source-map@npm:0.3.11" dependencies: - "@jest/console": "npm:30.3.0" - "@jest/pattern": "npm:30.0.1" - "@jest/reporters": "npm:30.3.0" - "@jest/test-result": "npm:30.3.0" - "@jest/transform": "npm:30.3.0" - "@jest/types": "npm:30.3.0" - "@types/node": "npm:*" - ansi-escapes: "npm:^4.3.2" - chalk: "npm:^4.1.2" - ci-info: "npm:^4.2.0" - exit-x: "npm:^0.2.2" - graceful-fs: "npm:^4.2.11" - jest-changed-files: "npm:30.3.0" - jest-config: "npm:30.3.0" - jest-haste-map: "npm:30.3.0" - jest-message-util: "npm:30.3.0" - jest-regex-util: "npm:30.0.1" - jest-resolve: "npm:30.3.0" - jest-resolve-dependencies: "npm:30.3.0" - jest-runner: "npm:30.3.0" - jest-runtime: "npm:30.3.0" - jest-snapshot: "npm:30.3.0" - jest-util: "npm:30.3.0" - jest-validate: "npm:30.3.0" - jest-watcher: "npm:30.3.0" - pretty-format: "npm:30.3.0" - slash: "npm:^3.0.0" - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - checksum: 10c0/1735f2263cca10c6cae4e1dbde9c3ccb36e2cbd1cc10bac6fc45e187b06c4e33a6a029f9a6444a3cd43a2a44ffaec3b686d94f70965cebf2b885b198c8615322 + "@jridgewell/gen-mapping": "npm:^0.3.5" + "@jridgewell/trace-mapping": "npm:^0.3.25" + checksum: 10c0/50a4fdafe0b8f655cb2877e59fe81320272eaa4ccdbe6b9b87f10614b2220399ae3e05c16137a59db1f189523b42c7f88bd097ee991dbd7bc0e01113c583e844 languageName: node linkType: hard -"@jest/diff-sequences@npm:30.3.0": - version: 30.3.0 - resolution: "@jest/diff-sequences@npm:30.3.0" - checksum: 10c0/8922c16a869b839b6c05f677023b3e5a9aa1610ad78a9c5ec8bd6654e35e8136ea1c7b60ad561910e2ad964bfdb0b09b0254ff8dcfacd4562095766f60c63d76 +"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.5.0, @jridgewell/sourcemap-codec@npm:^1.5.5": + version: 1.5.5 + resolution: "@jridgewell/sourcemap-codec@npm:1.5.5" + checksum: 10c0/f9e538f302b63c0ebc06eecb1dd9918dd4289ed36147a0ddce35d6ea4d7ebbda243cda7b2213b6a5e1d8087a298d5cf630fb2bd39329cdecb82017023f6081a0 languageName: node linkType: hard -"@jest/environment-jsdom-abstract@npm:30.3.0": - version: 30.3.0 - resolution: "@jest/environment-jsdom-abstract@npm:30.3.0" +"@jridgewell/trace-mapping@npm:0.3.9": + version: 0.3.9 + resolution: "@jridgewell/trace-mapping@npm:0.3.9" dependencies: - "@jest/environment": "npm:30.3.0" - "@jest/fake-timers": "npm:30.3.0" - "@jest/types": "npm:30.3.0" - "@types/jsdom": "npm:^21.1.7" - "@types/node": "npm:*" - jest-mock: "npm:30.3.0" - jest-util: "npm:30.3.0" - peerDependencies: - canvas: ^3.0.0 - jsdom: "*" - peerDependenciesMeta: - canvas: - optional: true - checksum: 10c0/95ec44bc3cc4cf91660acd4bf7da547414a1d797a32442dd6c4f6d47c82bb4b6eb2ee6b7a5d177d0827378793433a743462d24f5e445075b69edfbc28ab5ca40 + "@jridgewell/resolve-uri": "npm:^3.0.3" + "@jridgewell/sourcemap-codec": "npm:^1.4.10" + checksum: 10c0/fa425b606d7c7ee5bfa6a31a7b050dd5814b4082f318e0e4190f991902181b4330f43f4805db1dd4f2433fd0ed9cc7a7b9c2683f1deeab1df1b0a98b1e24055b languageName: node linkType: hard -"@jest/environment@npm:30.3.0": - version: 30.3.0 - resolution: "@jest/environment@npm:30.3.0" +"@jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25, @jridgewell/trace-mapping@npm:^0.3.28, @jridgewell/trace-mapping@npm:^0.3.31": + version: 0.3.31 + resolution: "@jridgewell/trace-mapping@npm:0.3.31" dependencies: - "@jest/fake-timers": "npm:30.3.0" - "@jest/types": "npm:30.3.0" - "@types/node": "npm:*" - jest-mock: "npm:30.3.0" - checksum: 10c0/4068ccc2e4761e52909239c21e71f73b57ad087bd120b75d3232c68d911686d68fd0fb20e19725517a624b0aa9d45431b00503bd1d5ab2f4958e1a18d265d8d5 - languageName: node - linkType: hard - -"@jest/expect-utils@npm:30.3.0": - version: 30.3.0 - resolution: "@jest/expect-utils@npm:30.3.0" - dependencies: - "@jest/get-type": "npm:30.1.0" - checksum: 10c0/4bb60fb434cb8ed325735bd39171b61621e110502ecc502089805d203ecb17b9fc5a400aeffb83b41fabcc819628a9c38c955f90a716d6aaff193d10926fc854 - languageName: node - linkType: hard - -"@jest/expect@npm:30.3.0": - version: 30.3.0 - resolution: "@jest/expect@npm:30.3.0" - dependencies: - expect: "npm:30.3.0" - jest-snapshot: "npm:30.3.0" - checksum: 10c0/1e052975fdf2b977a63dc9f3db1de56be9dce8e5cd660d9c72cc25093324b990b3e93318cd0c1ff9df7cb30ec7eef71331bc7e19d39700eb3f4498e17ee4c9e0 - languageName: node - linkType: hard - -"@jest/fake-timers@npm:30.3.0": - version: 30.3.0 - resolution: "@jest/fake-timers@npm:30.3.0" - dependencies: - "@jest/types": "npm:30.3.0" - "@sinonjs/fake-timers": "npm:^15.0.0" - "@types/node": "npm:*" - jest-message-util: "npm:30.3.0" - jest-mock: "npm:30.3.0" - jest-util: "npm:30.3.0" - checksum: 10c0/114855ca14d6b34c886855445852a5b960bc3df0ef97c4b971b375747fe0206b3111ec60efc6e658565677022f0d790acd7e232e478f3390ea854d04dea0c4d8 - languageName: node - linkType: hard - -"@jest/get-type@npm:30.1.0": - version: 30.1.0 - resolution: "@jest/get-type@npm:30.1.0" - checksum: 10c0/3e65fd5015f551c51ec68fca31bbd25b466be0e8ee8075d9610fa1c686ea1e70a942a0effc7b10f4ea9a338c24337e1ad97ff69d3ebacc4681b7e3e80d1b24ac - languageName: node - linkType: hard - -"@jest/globals@npm:30.3.0": - version: 30.3.0 - resolution: "@jest/globals@npm:30.3.0" - dependencies: - "@jest/environment": "npm:30.3.0" - "@jest/expect": "npm:30.3.0" - "@jest/types": "npm:30.3.0" - jest-mock: "npm:30.3.0" - checksum: 10c0/013554dcbf75867e715801e98a5c6eefbea67cb388efd019be9e0d83979d7354874c4b33bbabc95de698215f5b891e921c26a284841504f9825fd789432b1cd0 - languageName: node - linkType: hard - -"@jest/pattern@npm:30.0.1": - version: 30.0.1 - resolution: "@jest/pattern@npm:30.0.1" - dependencies: - "@types/node": "npm:*" - jest-regex-util: "npm:30.0.1" - checksum: 10c0/32c5a7bfb6c591f004dac0ed36d645002ed168971e4c89bd915d1577031672870032594767557b855c5bc330aa1e39a2f54bf150d2ee88a7a0886e9cb65318bc - languageName: node - linkType: hard - -"@jest/reporters@npm:30.3.0": - version: 30.3.0 - resolution: "@jest/reporters@npm:30.3.0" - dependencies: - "@bcoe/v8-coverage": "npm:^0.2.3" - "@jest/console": "npm:30.3.0" - "@jest/test-result": "npm:30.3.0" - "@jest/transform": "npm:30.3.0" - "@jest/types": "npm:30.3.0" - "@jridgewell/trace-mapping": "npm:^0.3.25" - "@types/node": "npm:*" - chalk: "npm:^4.1.2" - collect-v8-coverage: "npm:^1.0.2" - exit-x: "npm:^0.2.2" - glob: "npm:^10.5.0" - graceful-fs: "npm:^4.2.11" - istanbul-lib-coverage: "npm:^3.0.0" - istanbul-lib-instrument: "npm:^6.0.0" - istanbul-lib-report: "npm:^3.0.0" - istanbul-lib-source-maps: "npm:^5.0.0" - istanbul-reports: "npm:^3.1.3" - jest-message-util: "npm:30.3.0" - jest-util: "npm:30.3.0" - jest-worker: "npm:30.3.0" - slash: "npm:^3.0.0" - string-length: "npm:^4.0.2" - v8-to-istanbul: "npm:^9.0.1" - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - checksum: 10c0/e1b6fb13df94435d4b8e6f4d4bd1c27dfc572ca7393b0a95d14c98013abe3c962aa28e2c56864f3ddd0894834d21c9a67485d11e6c31532aaaeea66ca6a2a026 - languageName: node - linkType: hard - -"@jest/schemas@npm:30.0.5": - version: 30.0.5 - resolution: "@jest/schemas@npm:30.0.5" - dependencies: - "@sinclair/typebox": "npm:^0.34.0" - checksum: 10c0/449dcd7ec5c6505e9ac3169d1143937e67044ae3e66a729ce4baf31812dfd30535f2b3b2934393c97cfdf5984ff581120e6b38f62b8560c8b5b7cc07f4175f65 - languageName: node - linkType: hard - -"@jest/snapshot-utils@npm:30.3.0": - version: 30.3.0 - resolution: "@jest/snapshot-utils@npm:30.3.0" - dependencies: - "@jest/types": "npm:30.3.0" - chalk: "npm:^4.1.2" - graceful-fs: "npm:^4.2.11" - natural-compare: "npm:^1.4.0" - checksum: 10c0/ba4fea05a418b257d128d8f9eb7672a9004952563a45ad577bed80e5b2ea2ec6e6d3a24535781cc6530d9904d8fda7b27d15952d079ccdbe88f87a5e71112df0 - languageName: node - linkType: hard - -"@jest/source-map@npm:30.0.1": - version: 30.0.1 - resolution: "@jest/source-map@npm:30.0.1" - dependencies: - "@jridgewell/trace-mapping": "npm:^0.3.25" - callsites: "npm:^3.1.0" - graceful-fs: "npm:^4.2.11" - checksum: 10c0/e7bda2786fc9f483d9dd7566c58c4bd948830997be862dfe80a3ae5550ff3f84753abb52e705d02ebe9db9f34ba7ebec4c2db11882048cdeef7a66f6332b3897 - languageName: node - linkType: hard - -"@jest/test-result@npm:30.3.0": - version: 30.3.0 - resolution: "@jest/test-result@npm:30.3.0" - dependencies: - "@jest/console": "npm:30.3.0" - "@jest/types": "npm:30.3.0" - "@types/istanbul-lib-coverage": "npm:^2.0.6" - collect-v8-coverage: "npm:^1.0.2" - checksum: 10c0/67bcd405d0a1ac85b55afabf26e0ee0f184f9cfe0e659a44e0e4a4456c1c7fed9d2288f0116b017eaddfa49ded8c44426b8694c44f9a8a2af35be9202b8a9165 - languageName: node - linkType: hard - -"@jest/test-sequencer@npm:30.3.0": - version: 30.3.0 - resolution: "@jest/test-sequencer@npm:30.3.0" - dependencies: - "@jest/test-result": "npm:30.3.0" - graceful-fs: "npm:^4.2.11" - jest-haste-map: "npm:30.3.0" - slash: "npm:^3.0.0" - checksum: 10c0/698be35e7145e79ea9d66071d4ec255f6cef4b5972b5142d299f3edbcbc0428cadf8ddecc6d21e938c98ed72b73b15a6d5f81e7b8b370aaa130d2f6b26fd017c - languageName: node - linkType: hard - -"@jest/transform@npm:30.3.0": - version: 30.3.0 - resolution: "@jest/transform@npm:30.3.0" - dependencies: - "@babel/core": "npm:^7.27.4" - "@jest/types": "npm:30.3.0" - "@jridgewell/trace-mapping": "npm:^0.3.25" - babel-plugin-istanbul: "npm:^7.0.1" - chalk: "npm:^4.1.2" - convert-source-map: "npm:^2.0.0" - fast-json-stable-stringify: "npm:^2.1.0" - graceful-fs: "npm:^4.2.11" - jest-haste-map: "npm:30.3.0" - jest-regex-util: "npm:30.0.1" - jest-util: "npm:30.3.0" - pirates: "npm:^4.0.7" - slash: "npm:^3.0.0" - write-file-atomic: "npm:^5.0.1" - checksum: 10c0/5ad0b5361910680b5160e3dc347c0beb75b4edc35a165ef4fc55837d01365179c276dd6f9cc80f7db94048c641b0c188757e1c98c6d4e9b55577956efbc00574 - languageName: node - linkType: hard - -"@jest/types@npm:30.3.0": - version: 30.3.0 - resolution: "@jest/types@npm:30.3.0" - dependencies: - "@jest/pattern": "npm:30.0.1" - "@jest/schemas": "npm:30.0.5" - "@types/istanbul-lib-coverage": "npm:^2.0.6" - "@types/istanbul-reports": "npm:^3.0.4" - "@types/node": "npm:*" - "@types/yargs": "npm:^17.0.33" - chalk: "npm:^4.1.2" - checksum: 10c0/c3e3f4de0b77a7ced345f47d3687b1094c1b6c1521529a7ca66a76f9a80194f79179a1dbc32d6761a5b67914a8f78be1e65d1408107efcb1f252c4a63b5ddd92 - languageName: node - linkType: hard - -"@jridgewell/gen-mapping@npm:^0.3.12, @jridgewell/gen-mapping@npm:^0.3.5": - version: 0.3.13 - resolution: "@jridgewell/gen-mapping@npm:0.3.13" - dependencies: - "@jridgewell/sourcemap-codec": "npm:^1.5.0" - "@jridgewell/trace-mapping": "npm:^0.3.24" - checksum: 10c0/9a7d65fb13bd9aec1fbab74cda08496839b7e2ceb31f5ab922b323e94d7c481ce0fc4fd7e12e2610915ed8af51178bdc61e168e92a8c8b8303b030b03489b13b - languageName: node - linkType: hard - -"@jridgewell/remapping@npm:^2.3.5": - version: 2.3.5 - resolution: "@jridgewell/remapping@npm:2.3.5" - dependencies: - "@jridgewell/gen-mapping": "npm:^0.3.5" - "@jridgewell/trace-mapping": "npm:^0.3.24" - checksum: 10c0/3de494219ffeb2c5c38711d0d7bb128097edf91893090a2dbc8ee0b55d092bb7347b1fd0f478486c5eab010e855c73927b1666f2107516d472d24a73017d1194 - languageName: node - linkType: hard - -"@jridgewell/resolve-uri@npm:^3.0.3, @jridgewell/resolve-uri@npm:^3.1.0": - version: 3.1.2 - resolution: "@jridgewell/resolve-uri@npm:3.1.2" - checksum: 10c0/d502e6fb516b35032331406d4e962c21fe77cdf1cbdb49c6142bcbd9e30507094b18972778a6e27cbad756209cfe34b1a27729e6fa08a2eb92b33943f680cf1e - languageName: node - linkType: hard - -"@jridgewell/source-map@npm:^0.3.3": - version: 0.3.11 - resolution: "@jridgewell/source-map@npm:0.3.11" - dependencies: - "@jridgewell/gen-mapping": "npm:^0.3.5" - "@jridgewell/trace-mapping": "npm:^0.3.25" - checksum: 10c0/50a4fdafe0b8f655cb2877e59fe81320272eaa4ccdbe6b9b87f10614b2220399ae3e05c16137a59db1f189523b42c7f88bd097ee991dbd7bc0e01113c583e844 - languageName: node - linkType: hard - -"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.5.0": - version: 1.5.5 - resolution: "@jridgewell/sourcemap-codec@npm:1.5.5" - checksum: 10c0/f9e538f302b63c0ebc06eecb1dd9918dd4289ed36147a0ddce35d6ea4d7ebbda243cda7b2213b6a5e1d8087a298d5cf630fb2bd39329cdecb82017023f6081a0 - languageName: node - linkType: hard - -"@jridgewell/trace-mapping@npm:0.3.9": - version: 0.3.9 - resolution: "@jridgewell/trace-mapping@npm:0.3.9" - dependencies: - "@jridgewell/resolve-uri": "npm:^3.0.3" - "@jridgewell/sourcemap-codec": "npm:^1.4.10" - checksum: 10c0/fa425b606d7c7ee5bfa6a31a7b050dd5814b4082f318e0e4190f991902181b4330f43f4805db1dd4f2433fd0ed9cc7a7b9c2683f1deeab1df1b0a98b1e24055b - languageName: node - linkType: hard - -"@jridgewell/trace-mapping@npm:^0.3.12, @jridgewell/trace-mapping@npm:^0.3.23, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25, @jridgewell/trace-mapping@npm:^0.3.28": - version: 0.3.31 - resolution: "@jridgewell/trace-mapping@npm:0.3.31" - dependencies: - "@jridgewell/resolve-uri": "npm:^3.1.0" - "@jridgewell/sourcemap-codec": "npm:^1.4.14" - checksum: 10c0/4b30ec8cd56c5fd9a661f088230af01e0c1a3888d11ffb6b47639700f71225be21d1f7e168048d6d4f9449207b978a235c07c8f15c07705685d16dc06280e9d9 + "@jridgewell/resolve-uri": "npm:^3.1.0" + "@jridgewell/sourcemap-codec": "npm:^1.4.14" + checksum: 10c0/4b30ec8cd56c5fd9a661f088230af01e0c1a3888d11ffb6b47639700f71225be21d1f7e168048d6d4f9449207b978a235c07c8f15c07705685d16dc06280e9d9 languageName: node linkType: hard @@ -2379,14 +1994,51 @@ __metadata: languageName: node linkType: hard -"@napi-rs/wasm-runtime@npm:^0.2.11": - version: 0.2.12 - resolution: "@napi-rs/wasm-runtime@npm:0.2.12" +"@monaco-editor/loader@npm:^1.5.0": + version: 1.7.0 + resolution: "@monaco-editor/loader@npm:1.7.0" + dependencies: + state-local: "npm:^1.0.6" + checksum: 10c0/1fd3579cb09b669493cf553dfc0723a93483140a44353ce9a739827edfa7b2c6541b254024d15c48176ece749ef666b6d16cce6cf0e4396c7fa1c5a48012d08a + languageName: node + linkType: hard + +"@monaco-editor/react@npm:^4.6.0": + version: 4.7.0 + resolution: "@monaco-editor/react@npm:4.7.0" dependencies: - "@emnapi/core": "npm:^1.4.3" - "@emnapi/runtime": "npm:^1.4.3" - "@tybys/wasm-util": "npm:^0.10.0" - checksum: 10c0/6d07922c0613aab30c6a497f4df297ca7c54e5b480e00035e0209b872d5c6aab7162fc49477267556109c2c7ed1eb9c65a174e27e9b87568106a87b0a6e3ca7d + "@monaco-editor/loader": "npm:^1.5.0" + peerDependencies: + monaco-editor: ">= 0.25.0 < 1" + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + checksum: 10c0/a4e91c6eda1a71f5fd23871bd801de435490ccbc43934d23cba65cefe2be7e9d02c9a57c4ef80fc9fe99e4d4deea51e5db19cb4e0ecf3f51818dda0eb9cdbf12 + languageName: node + linkType: hard + +"@mswjs/interceptors@npm:^0.41.3": + version: 0.41.6 + resolution: "@mswjs/interceptors@npm:0.41.6" + dependencies: + "@open-draft/deferred-promise": "npm:^2.2.0" + "@open-draft/logger": "npm:^0.3.0" + "@open-draft/until": "npm:^2.0.0" + is-node-process: "npm:^1.2.0" + outvariant: "npm:^1.4.3" + strict-event-emitter: "npm:^0.5.1" + checksum: 10c0/abedbd64c7602dd358ded2a92e0a84b0d21cc0d15cb9d6a8d73283f46938f2a5adb69d9be8124c5c5c3394cc980e758a34bd77de1aa2677b7b2b399d34c148ce + languageName: node + linkType: hard + +"@napi-rs/wasm-runtime@npm:^1.1.4": + version: 1.1.4 + resolution: "@napi-rs/wasm-runtime@npm:1.1.4" + dependencies: + "@tybys/wasm-util": "npm:^0.10.1" + peerDependencies: + "@emnapi/core": ^1.7.1 + "@emnapi/runtime": ^1.7.1 + checksum: 10c0/2e88e1955258949ccf2d18c79975821ad38071b465ef126a5e14110977b97868867b016c1ad046e963cccc42c0bd9db6c8ff5fd1ebb61b87bb3487f339041658 languageName: node linkType: hard @@ -2571,6 +2223,37 @@ __metadata: languageName: node linkType: hard +"@open-draft/deferred-promise@npm:^2.2.0": + version: 2.2.0 + resolution: "@open-draft/deferred-promise@npm:2.2.0" + checksum: 10c0/eafc1b1d0fc8edb5e1c753c5e0f3293410b40dde2f92688211a54806d4136887051f39b98c1950370be258483deac9dfd17cf8b96557553765198ef2547e4549 + languageName: node + linkType: hard + +"@open-draft/deferred-promise@npm:^3.0.0": + version: 3.0.0 + resolution: "@open-draft/deferred-promise@npm:3.0.0" + checksum: 10c0/4dd697e55495e436be9536413cc9975e792e9ca7472e81e3d3d69e9b65cb678465aac90b463ac02f2b490c0581c4e9aa8a33d2a5857decbe2c6d9ffb310f8e1f + languageName: node + linkType: hard + +"@open-draft/logger@npm:^0.3.0": + version: 0.3.0 + resolution: "@open-draft/logger@npm:0.3.0" + dependencies: + is-node-process: "npm:^1.2.0" + outvariant: "npm:^1.4.0" + checksum: 10c0/90010647b22e9693c16258f4f9adb034824d1771d3baa313057b9a37797f571181005bc50415a934eaf7c891d90ff71dcd7a9d5048b0b6bb438f31bef2c7c5c1 + languageName: node + linkType: hard + +"@open-draft/until@npm:^2.0.0": + version: 2.1.0 + resolution: "@open-draft/until@npm:2.1.0" + checksum: 10c0/61d3f99718dd86bb393fee2d7a785f961dcaf12f2055f0c693b27f4d0cd5f7a03d498a6d9289773b117590d794a43cd129366fd8e99222e4832f67b1653d54cf + languageName: node + linkType: hard + "@openshift-console/dynamic-plugin-sdk-webpack@npm:4.21-latest": version: 4.21.0 resolution: "@openshift-console/dynamic-plugin-sdk-webpack@npm:4.21.0" @@ -2640,6 +2323,30 @@ __metadata: languageName: node linkType: hard +"@oxc-project/types@npm:=0.127.0": + version: 0.127.0 + resolution: "@oxc-project/types@npm:0.127.0" + checksum: 10c0/52c0947ac64a9ca119fe971f947e784a35ecd14a072fa3f542a58a5f6c42010b53f2bf92731e39b9899b83c990a9517bbd29d1e5a5b7b489e52616685c6a9278 + languageName: node + linkType: hard + +"@patternfly/react-code-editor@npm:^6.4.3": + version: 6.4.3 + resolution: "@patternfly/react-code-editor@npm:6.4.3" + dependencies: + "@monaco-editor/react": "npm:^4.6.0" + "@patternfly/react-core": "npm:^6.4.3" + "@patternfly/react-icons": "npm:^6.4.0" + "@patternfly/react-styles": "npm:^6.4.0" + react-dropzone: "npm:14.3.5" + tslib: "npm:^2.8.1" + peerDependencies: + react: ^17 || ^18 || ^19 + react-dom: ^17 || ^18 || ^19 + checksum: 10c0/5ff88454edff81fb5c85003793e3ad883f23ba263e73faece8a663d29704b809d167369b422455e113dcdff38e836d5fa62faf182698c1b4d7c8941a9c8b4723 + languageName: node + linkType: hard + "@patternfly/react-core@npm:^6.0.0, @patternfly/react-core@npm:^6.2.2": version: 6.4.0 resolution: "@patternfly/react-core@npm:6.4.0" @@ -2657,6 +2364,23 @@ __metadata: languageName: node linkType: hard +"@patternfly/react-core@npm:^6.4.3": + version: 6.4.3 + resolution: "@patternfly/react-core@npm:6.4.3" + dependencies: + "@patternfly/react-icons": "npm:^6.4.0" + "@patternfly/react-styles": "npm:^6.4.0" + "@patternfly/react-tokens": "npm:^6.4.0" + focus-trap: "npm:7.6.4" + react-dropzone: "npm:^14.3.5" + tslib: "npm:^2.8.1" + peerDependencies: + react: ^17 || ^18 || ^19 + react-dom: ^17 || ^18 || ^19 + checksum: 10c0/c9f6b50b146a6acec22ab05c81916593a90a7d02436a89096b26e6e8880253cdcb90d2086951daac609006a80676db4dc3af7057a509084bc6cdb8d2aecd5bb6 + languageName: node + linkType: hard + "@patternfly/react-icons@npm:^6.0.0, @patternfly/react-icons@npm:^6.2.2, @patternfly/react-icons@npm:^6.4.0": version: 6.4.0 resolution: "@patternfly/react-icons@npm:6.4.0" @@ -2888,35 +2612,133 @@ __metadata: languageName: node linkType: hard -"@sinclair/typebox@npm:^0.34.0": - version: 0.34.49 - resolution: "@sinclair/typebox@npm:0.34.49" - checksum: 10c0/16b7d87f039a49b68c10bb4cdcae2ce5242b2472228851fd6483731616aba4ef977690aa517b230a8d20da8185bb416eb34e326f30568b3963c1cf26b05d1ad8 +"@rolldown/binding-android-arm64@npm:1.0.0-rc.17": + version: 1.0.0-rc.17 + resolution: "@rolldown/binding-android-arm64@npm:1.0.0-rc.17" + conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@sindresorhus/merge-streams@npm:^4.0.0": - version: 4.0.0 - resolution: "@sindresorhus/merge-streams@npm:4.0.0" - checksum: 10c0/482ee543629aa1933b332f811a1ae805a213681ecdd98c042b1c1b89387df63e7812248bb4df3910b02b3cc5589d3d73e4393f30e197c9dde18046ccd471fc6b +"@rolldown/binding-darwin-arm64@npm:1.0.0-rc.17": + version: 1.0.0-rc.17 + resolution: "@rolldown/binding-darwin-arm64@npm:1.0.0-rc.17" + conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@sinonjs/commons@npm:^3.0.1": - version: 3.0.1 - resolution: "@sinonjs/commons@npm:3.0.1" - dependencies: - type-detect: "npm:4.0.8" - checksum: 10c0/1227a7b5bd6c6f9584274db996d7f8cee2c8c350534b9d0141fc662eaf1f292ea0ae3ed19e5e5271c8fd390d27e492ca2803acd31a1978be2cdc6be0da711403 +"@rolldown/binding-darwin-x64@npm:1.0.0-rc.17": + version: 1.0.0-rc.17 + resolution: "@rolldown/binding-darwin-x64@npm:1.0.0-rc.17" + conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@sinonjs/fake-timers@npm:^15.0.0": - version: 15.1.1 - resolution: "@sinonjs/fake-timers@npm:15.1.1" +"@rolldown/binding-freebsd-x64@npm:1.0.0-rc.17": + version: 1.0.0-rc.17 + resolution: "@rolldown/binding-freebsd-x64@npm:1.0.0-rc.17" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@rolldown/binding-linux-arm-gnueabihf@npm:1.0.0-rc.17": + version: 1.0.0-rc.17 + resolution: "@rolldown/binding-linux-arm-gnueabihf@npm:1.0.0-rc.17" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@rolldown/binding-linux-arm64-gnu@npm:1.0.0-rc.17": + version: 1.0.0-rc.17 + resolution: "@rolldown/binding-linux-arm64-gnu@npm:1.0.0-rc.17" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@rolldown/binding-linux-arm64-musl@npm:1.0.0-rc.17": + version: 1.0.0-rc.17 + resolution: "@rolldown/binding-linux-arm64-musl@npm:1.0.0-rc.17" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@rolldown/binding-linux-ppc64-gnu@npm:1.0.0-rc.17": + version: 1.0.0-rc.17 + resolution: "@rolldown/binding-linux-ppc64-gnu@npm:1.0.0-rc.17" + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + +"@rolldown/binding-linux-s390x-gnu@npm:1.0.0-rc.17": + version: 1.0.0-rc.17 + resolution: "@rolldown/binding-linux-s390x-gnu@npm:1.0.0-rc.17" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@rolldown/binding-linux-x64-gnu@npm:1.0.0-rc.17": + version: 1.0.0-rc.17 + resolution: "@rolldown/binding-linux-x64-gnu@npm:1.0.0-rc.17" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@rolldown/binding-linux-x64-musl@npm:1.0.0-rc.17": + version: 1.0.0-rc.17 + resolution: "@rolldown/binding-linux-x64-musl@npm:1.0.0-rc.17" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@rolldown/binding-openharmony-arm64@npm:1.0.0-rc.17": + version: 1.0.0-rc.17 + resolution: "@rolldown/binding-openharmony-arm64@npm:1.0.0-rc.17" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + +"@rolldown/binding-wasm32-wasi@npm:1.0.0-rc.17": + version: 1.0.0-rc.17 + resolution: "@rolldown/binding-wasm32-wasi@npm:1.0.0-rc.17" dependencies: - "@sinonjs/commons": "npm:^3.0.1" - checksum: 10c0/8eaaa1c9db91256dfe31f3503cdd844ea031ffd16276b3bcd95457432d666d6d027453af5f884e010dba4ebe264b50ac0aac049e192c5f370158da9b291206b9 + "@emnapi/core": "npm:1.10.0" + "@emnapi/runtime": "npm:1.10.0" + "@napi-rs/wasm-runtime": "npm:^1.1.4" + conditions: cpu=wasm32 + languageName: node + linkType: hard + +"@rolldown/binding-win32-arm64-msvc@npm:1.0.0-rc.17": + version: 1.0.0-rc.17 + resolution: "@rolldown/binding-win32-arm64-msvc@npm:1.0.0-rc.17" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@rolldown/binding-win32-x64-msvc@npm:1.0.0-rc.17": + version: 1.0.0-rc.17 + resolution: "@rolldown/binding-win32-x64-msvc@npm:1.0.0-rc.17" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@rolldown/pluginutils@npm:1.0.0-rc.17": + version: 1.0.0-rc.17 + resolution: "@rolldown/pluginutils@npm:1.0.0-rc.17" + checksum: 10c0/5e840b20cc531910c093c1ca36e550952cf4936465a50d89f0a98fc9d0dfd7d319d06a10a5f4376209d89e9bf4d60af6cc8363ebf0dcc5e60842f7fef438b2f0 + languageName: node + linkType: hard + +"@sindresorhus/merge-streams@npm:^4.0.0": + version: 4.0.0 + resolution: "@sindresorhus/merge-streams@npm:4.0.0" + checksum: 10c0/482ee543629aa1933b332f811a1ae805a213681ecdd98c042b1c1b89387df63e7812248bb4df3910b02b3cc5589d3d73e4393f30e197c9dde18046ccd471fc6b + languageName: node + linkType: hard + +"@standard-schema/spec@npm:^1.1.0": + version: 1.1.0 + resolution: "@standard-schema/spec@npm:1.1.0" + checksum: 10c0/d90f55acde4b2deb983529c87e8025fa693de1a5e8b49ecc6eb84d1fd96328add0e03d7d551442156c7432fd78165b2c26ff561b970a9a881f046abb78d6a526 languageName: node linkType: hard @@ -3001,7 +2823,7 @@ __metadata: languageName: node linkType: hard -"@tybys/wasm-util@npm:^0.10.0": +"@tybys/wasm-util@npm:^0.10.1": version: 0.10.1 resolution: "@tybys/wasm-util@npm:0.10.1" dependencies: @@ -3017,47 +2839,6 @@ __metadata: languageName: node linkType: hard -"@types/babel__core@npm:^7.20.5": - version: 7.20.5 - resolution: "@types/babel__core@npm:7.20.5" - dependencies: - "@babel/parser": "npm:^7.20.7" - "@babel/types": "npm:^7.20.7" - "@types/babel__generator": "npm:*" - "@types/babel__template": "npm:*" - "@types/babel__traverse": "npm:*" - checksum: 10c0/bdee3bb69951e833a4b811b8ee9356b69a61ed5b7a23e1a081ec9249769117fa83aaaf023bb06562a038eb5845155ff663e2d5c75dd95c1d5ccc91db012868ff - languageName: node - linkType: hard - -"@types/babel__generator@npm:*": - version: 7.27.0 - resolution: "@types/babel__generator@npm:7.27.0" - dependencies: - "@babel/types": "npm:^7.0.0" - checksum: 10c0/9f9e959a8792df208a9d048092fda7e1858bddc95c6314857a8211a99e20e6830bdeb572e3587ae8be5429e37f2a96fcf222a9f53ad232f5537764c9e13a2bbd - languageName: node - linkType: hard - -"@types/babel__template@npm:*": - version: 7.4.4 - resolution: "@types/babel__template@npm:7.4.4" - dependencies: - "@babel/parser": "npm:^7.1.0" - "@babel/types": "npm:^7.0.0" - checksum: 10c0/cc84f6c6ab1eab1427e90dd2b76ccee65ce940b778a9a67be2c8c39e1994e6f5bbc8efa309f6cea8dc6754994524cd4d2896558df76d92e7a1f46ecffee7112b - languageName: node - linkType: hard - -"@types/babel__traverse@npm:*": - version: 7.28.0 - resolution: "@types/babel__traverse@npm:7.28.0" - dependencies: - "@babel/types": "npm:^7.28.2" - checksum: 10c0/b52d7d4e8fc6a9018fe7361c4062c1c190f5778cf2466817cb9ed19d69fbbb54f9a85ffedeb748ed8062d2cf7d4cc088ee739848f47c57740de1c48cbf0d0994 - languageName: node - linkType: hard - "@types/body-parser@npm:*": version: 1.19.2 resolution: "@types/body-parser@npm:1.19.2" @@ -3077,6 +2858,16 @@ __metadata: languageName: node linkType: hard +"@types/chai@npm:^5.2.2": + version: 5.2.3 + resolution: "@types/chai@npm:5.2.3" + dependencies: + "@types/deep-eql": "npm:*" + assertion-error: "npm:^2.0.1" + checksum: 10c0/e0ef1de3b6f8045a5e473e867c8565788c444271409d155588504840ad1a53611011f85072188c2833941189400228c1745d78323dac13fcede9c2b28bacfb2f + languageName: node + linkType: hard + "@types/connect-history-api-fallback@npm:^1.5.4": version: 1.5.4 resolution: "@types/connect-history-api-fallback@npm:1.5.4" @@ -3375,6 +3166,13 @@ __metadata: languageName: node linkType: hard +"@types/deep-eql@npm:*": + version: 4.0.2 + resolution: "@types/deep-eql@npm:4.0.2" + checksum: 10c0/bf3f811843117900d7084b9d0c852da9a044d12eb40e6de73b552598a6843c21291a8a381b0532644574beecd5e3491c5ff3a0365ab86b15d59862c025384844 + languageName: node + linkType: hard + "@types/eslint-scope@npm:^3.7.7": version: 3.7.7 resolution: "@types/eslint-scope@npm:3.7.7" @@ -3395,7 +3193,7 @@ __metadata: languageName: node linkType: hard -"@types/estree@npm:*, @types/estree@npm:^1.0.6, @types/estree@npm:^1.0.8": +"@types/estree@npm:*, @types/estree@npm:^1.0.0, @types/estree@npm:^1.0.6, @types/estree@npm:^1.0.8": version: 1.0.8 resolution: "@types/estree@npm:1.0.8" checksum: 10c0/39d34d1afaa338ab9763f37ad6066e3f349444f9052b9676a7cc0252ef9485a41c6d81c9c4e0d26e9077993354edf25efc853f3224dd4b447175ef62bdcc86a5 @@ -3467,59 +3265,6 @@ __metadata: languageName: node linkType: hard -"@types/identity-obj-proxy@npm:^3": - version: 3.0.2 - resolution: "@types/identity-obj-proxy@npm:3.0.2" - checksum: 10c0/9277c7bf75aaf3688b659ad86f33eb57bd9fab9a5ed342adfbab6b6a804b8f7ce2f0a9ce0394dc6e73b3128d61920c5d35d71b825b84bfe28a97f86f5360c7e3 - languageName: node - linkType: hard - -"@types/istanbul-lib-coverage@npm:*, @types/istanbul-lib-coverage@npm:^2.0.1, @types/istanbul-lib-coverage@npm:^2.0.6": - version: 2.0.6 - resolution: "@types/istanbul-lib-coverage@npm:2.0.6" - checksum: 10c0/3948088654f3eeb45363f1db158354fb013b362dba2a5c2c18c559484d5eb9f6fd85b23d66c0a7c2fcfab7308d0a585b14dadaca6cc8bf89ebfdc7f8f5102fb7 - languageName: node - linkType: hard - -"@types/istanbul-lib-report@npm:*": - version: 3.0.3 - resolution: "@types/istanbul-lib-report@npm:3.0.3" - dependencies: - "@types/istanbul-lib-coverage": "npm:*" - checksum: 10c0/247e477bbc1a77248f3c6de5dadaae85ff86ac2d76c5fc6ab1776f54512a745ff2a5f791d22b942e3990ddbd40f3ef5289317c4fca5741bedfaa4f01df89051c - languageName: node - linkType: hard - -"@types/istanbul-reports@npm:^3.0.4": - version: 3.0.4 - resolution: "@types/istanbul-reports@npm:3.0.4" - dependencies: - "@types/istanbul-lib-report": "npm:*" - checksum: 10c0/1647fd402aced5b6edac87274af14ebd6b3a85447ef9ad11853a70fd92a98d35f81a5d3ea9fcb5dbb5834e800c6e35b64475e33fcae6bfa9acc70d61497c54ee - languageName: node - linkType: hard - -"@types/jest@npm:^30.0.0": - version: 30.0.0 - resolution: "@types/jest@npm:30.0.0" - dependencies: - expect: "npm:^30.0.0" - pretty-format: "npm:^30.0.0" - checksum: 10c0/20c6ce574154bc16f8dd6a97afacca4b8c4921a819496a3970382031c509ebe87a1b37b152a1b8475089b82d8ca951a9e95beb4b9bf78fbf579b1536f0b65969 - languageName: node - linkType: hard - -"@types/jsdom@npm:^21.1.7": - version: 21.1.7 - resolution: "@types/jsdom@npm:21.1.7" - dependencies: - "@types/node": "npm:*" - "@types/tough-cookie": "npm:*" - parse5: "npm:^7.0.0" - checksum: 10c0/c0c0025adc2b193e85453eeeea168bb909f0ebad08d6552be7474a407e9c163db8f696dcf1e3cbe8cb9c9d970ba45f4386171794509c1a0fe5d1fed72c91679d - languageName: node - linkType: hard - "@types/json-schema@npm:*, @types/json-schema@npm:^7.0.15, @types/json-schema@npm:^7.0.9": version: 7.0.15 resolution: "@types/json-schema@npm:7.0.15" @@ -3709,6 +3454,15 @@ __metadata: languageName: node linkType: hard +"@types/set-cookie-parser@npm:^2.4.10": + version: 2.4.10 + resolution: "@types/set-cookie-parser@npm:2.4.10" + dependencies: + "@types/node": "npm:*" + checksum: 10c0/010b0c582ea70a2088618b4725808e80c30cce296c19ec58e51d94e0fd1038201b7b99238bf3ea74e1894163c8037d10a4f1729de62b2801ce240ff070f43e76 + languageName: node + linkType: hard + "@types/sinonjs__fake-timers@npm:8.1.1": version: 8.1.1 resolution: "@types/sinonjs__fake-timers@npm:8.1.1" @@ -3732,10 +3486,10 @@ __metadata: languageName: node linkType: hard -"@types/stack-utils@npm:^2.0.3": - version: 2.0.3 - resolution: "@types/stack-utils@npm:2.0.3" - checksum: 10c0/1f4658385ae936330581bcb8aa3a066df03867d90281cdf89cc356d404bd6579be0f11902304e1f775d92df22c6dd761d4451c804b0a4fba973e06211e9bd77c +"@types/statuses@npm:^2.0.6": + version: 2.0.6 + resolution: "@types/statuses@npm:2.0.6" + checksum: 10c0/dd88c220b0e2c6315686289525fd61472d2204d2e4bef4941acfb76bda01d3066f749ac74782aab5b537a45314fcd7d6261eefa40b6ec872691f5803adaa608d languageName: node linkType: hard @@ -3753,13 +3507,6 @@ __metadata: languageName: node linkType: hard -"@types/tough-cookie@npm:*": - version: 4.0.5 - resolution: "@types/tough-cookie@npm:4.0.5" - checksum: 10c0/68c6921721a3dcb40451543db2174a145ef915bc8bcbe7ad4e59194a0238e776e782b896c7a59f4b93ac6acefca9161fccb31d1ce3b3445cb6faa467297fb473 - languageName: node - linkType: hard - "@types/unist@npm:^2.0.0": version: 2.0.11 resolution: "@types/unist@npm:2.0.11" @@ -3776,22 +3523,6 @@ __metadata: languageName: node linkType: hard -"@types/yargs-parser@npm:*": - version: 21.0.3 - resolution: "@types/yargs-parser@npm:21.0.3" - checksum: 10c0/e71c3bd9d0b73ca82e10bee2064c384ab70f61034bbfb78e74f5206283fc16a6d85267b606b5c22cb2a3338373586786fed595b2009825d6a9115afba36560a0 - languageName: node - linkType: hard - -"@types/yargs@npm:^17.0.33": - version: 17.0.35 - resolution: "@types/yargs@npm:17.0.35" - dependencies: - "@types/yargs-parser": "npm:*" - checksum: 10c0/609557826a6b85e73ccf587923f6429850d6dc70e420b455bab4601b670bfadf684b09ae288bccedab042c48ba65f1666133cf375814204b544009f57d6eef63 - languageName: node - linkType: hard - "@types/yauzl@npm:^2.9.1": version: 2.10.0 resolution: "@types/yauzl@npm:2.10.0" @@ -3881,200 +3612,164 @@ __metadata: peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: ">=4.8.4 <6.0.0" - checksum: 10c0/66517aed5059ef4a29605d06a510582f934d5789ae40ad673f1f0421f8aa13ec9ba7b8caab57ae9f270afacbf13ec5359cedfe74f21ae77e9a2364929f7e7cee - languageName: node - linkType: hard - -"@typescript-eslint/types@npm:8.56.1, @typescript-eslint/types@npm:^8.56.1": - version: 8.56.1 - resolution: "@typescript-eslint/types@npm:8.56.1" - checksum: 10c0/e5a0318abddf0c4f98da3039cb10b3c0601c8601f7a9f7043630f0d622dabfe83a4cd833545ad3531fc846e46ca2874377277b392c2490dffec279d9242d827b - languageName: node - linkType: hard - -"@typescript-eslint/typescript-estree@npm:8.56.1": - version: 8.56.1 - resolution: "@typescript-eslint/typescript-estree@npm:8.56.1" - dependencies: - "@typescript-eslint/project-service": "npm:8.56.1" - "@typescript-eslint/tsconfig-utils": "npm:8.56.1" - "@typescript-eslint/types": "npm:8.56.1" - "@typescript-eslint/visitor-keys": "npm:8.56.1" - debug: "npm:^4.4.3" - minimatch: "npm:^10.2.2" - semver: "npm:^7.7.3" - tinyglobby: "npm:^0.2.15" - ts-api-utils: "npm:^2.4.0" - peerDependencies: - typescript: ">=4.8.4 <6.0.0" - checksum: 10c0/92f4421dac41be289761200dc2ed85974fa451deacb09490ae1870a25b71b97218e609a90d4addba9ded5b2abdebc265c9db7f6e9ce6d29ed20e89b8487e9618 - languageName: node - linkType: hard - -"@typescript-eslint/utils@npm:8.56.1": - version: 8.56.1 - resolution: "@typescript-eslint/utils@npm:8.56.1" - dependencies: - "@eslint-community/eslint-utils": "npm:^4.9.1" - "@typescript-eslint/scope-manager": "npm:8.56.1" - "@typescript-eslint/types": "npm:8.56.1" - "@typescript-eslint/typescript-estree": "npm:8.56.1" - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: ">=4.8.4 <6.0.0" - checksum: 10c0/d9ffd9b2944a2c425e0532f71dc61e61d0a923d1a17733cf2777c2a4ae638307d12d44f63b33b6b3dc62f02f47db93ec49344ecefe17b76ee3e4fb0833325be3 - languageName: node - linkType: hard - -"@typescript-eslint/visitor-keys@npm:8.56.1": - version: 8.56.1 - resolution: "@typescript-eslint/visitor-keys@npm:8.56.1" - dependencies: - "@typescript-eslint/types": "npm:8.56.1" - eslint-visitor-keys: "npm:^5.0.0" - checksum: 10c0/86d97905dec1af964cc177c185933d040449acf6006096497f2e0093c6a53eb92b3ac1db9eb40a5a2e8d91160f558c9734331a9280797f09f284c38978b22190 - languageName: node - linkType: hard - -"@ungap/structured-clone@npm:^1.3.0": - version: 1.3.0 - resolution: "@ungap/structured-clone@npm:1.3.0" - checksum: 10c0/0fc3097c2540ada1fc340ee56d58d96b5b536a2a0dab6e3ec17d4bfc8c4c86db345f61a375a8185f9da96f01c69678f836a2b57eeaa9e4b8eeafd26428e57b0a - languageName: node - linkType: hard - -"@unrs/resolver-binding-android-arm-eabi@npm:1.11.1": - version: 1.11.1 - resolution: "@unrs/resolver-binding-android-arm-eabi@npm:1.11.1" - conditions: os=android & cpu=arm - languageName: node - linkType: hard - -"@unrs/resolver-binding-android-arm64@npm:1.11.1": - version: 1.11.1 - resolution: "@unrs/resolver-binding-android-arm64@npm:1.11.1" - conditions: os=android & cpu=arm64 - languageName: node - linkType: hard - -"@unrs/resolver-binding-darwin-arm64@npm:1.11.1": - version: 1.11.1 - resolution: "@unrs/resolver-binding-darwin-arm64@npm:1.11.1" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"@unrs/resolver-binding-darwin-x64@npm:1.11.1": - version: 1.11.1 - resolution: "@unrs/resolver-binding-darwin-x64@npm:1.11.1" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"@unrs/resolver-binding-freebsd-x64@npm:1.11.1": - version: 1.11.1 - resolution: "@unrs/resolver-binding-freebsd-x64@npm:1.11.1" - conditions: os=freebsd & cpu=x64 - languageName: node - linkType: hard - -"@unrs/resolver-binding-linux-arm-gnueabihf@npm:1.11.1": - version: 1.11.1 - resolution: "@unrs/resolver-binding-linux-arm-gnueabihf@npm:1.11.1" - conditions: os=linux & cpu=arm - languageName: node - linkType: hard - -"@unrs/resolver-binding-linux-arm-musleabihf@npm:1.11.1": - version: 1.11.1 - resolution: "@unrs/resolver-binding-linux-arm-musleabihf@npm:1.11.1" - conditions: os=linux & cpu=arm + checksum: 10c0/66517aed5059ef4a29605d06a510582f934d5789ae40ad673f1f0421f8aa13ec9ba7b8caab57ae9f270afacbf13ec5359cedfe74f21ae77e9a2364929f7e7cee languageName: node linkType: hard -"@unrs/resolver-binding-linux-arm64-gnu@npm:1.11.1": - version: 1.11.1 - resolution: "@unrs/resolver-binding-linux-arm64-gnu@npm:1.11.1" - conditions: os=linux & cpu=arm64 & libc=glibc +"@typescript-eslint/types@npm:8.56.1, @typescript-eslint/types@npm:^8.56.1": + version: 8.56.1 + resolution: "@typescript-eslint/types@npm:8.56.1" + checksum: 10c0/e5a0318abddf0c4f98da3039cb10b3c0601c8601f7a9f7043630f0d622dabfe83a4cd833545ad3531fc846e46ca2874377277b392c2490dffec279d9242d827b languageName: node linkType: hard -"@unrs/resolver-binding-linux-arm64-musl@npm:1.11.1": - version: 1.11.1 - resolution: "@unrs/resolver-binding-linux-arm64-musl@npm:1.11.1" - conditions: os=linux & cpu=arm64 & libc=musl +"@typescript-eslint/typescript-estree@npm:8.56.1": + version: 8.56.1 + resolution: "@typescript-eslint/typescript-estree@npm:8.56.1" + dependencies: + "@typescript-eslint/project-service": "npm:8.56.1" + "@typescript-eslint/tsconfig-utils": "npm:8.56.1" + "@typescript-eslint/types": "npm:8.56.1" + "@typescript-eslint/visitor-keys": "npm:8.56.1" + debug: "npm:^4.4.3" + minimatch: "npm:^10.2.2" + semver: "npm:^7.7.3" + tinyglobby: "npm:^0.2.15" + ts-api-utils: "npm:^2.4.0" + peerDependencies: + typescript: ">=4.8.4 <6.0.0" + checksum: 10c0/92f4421dac41be289761200dc2ed85974fa451deacb09490ae1870a25b71b97218e609a90d4addba9ded5b2abdebc265c9db7f6e9ce6d29ed20e89b8487e9618 languageName: node linkType: hard -"@unrs/resolver-binding-linux-ppc64-gnu@npm:1.11.1": - version: 1.11.1 - resolution: "@unrs/resolver-binding-linux-ppc64-gnu@npm:1.11.1" - conditions: os=linux & cpu=ppc64 & libc=glibc +"@typescript-eslint/utils@npm:8.56.1": + version: 8.56.1 + resolution: "@typescript-eslint/utils@npm:8.56.1" + dependencies: + "@eslint-community/eslint-utils": "npm:^4.9.1" + "@typescript-eslint/scope-manager": "npm:8.56.1" + "@typescript-eslint/types": "npm:8.56.1" + "@typescript-eslint/typescript-estree": "npm:8.56.1" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: ">=4.8.4 <6.0.0" + checksum: 10c0/d9ffd9b2944a2c425e0532f71dc61e61d0a923d1a17733cf2777c2a4ae638307d12d44f63b33b6b3dc62f02f47db93ec49344ecefe17b76ee3e4fb0833325be3 languageName: node linkType: hard -"@unrs/resolver-binding-linux-riscv64-gnu@npm:1.11.1": - version: 1.11.1 - resolution: "@unrs/resolver-binding-linux-riscv64-gnu@npm:1.11.1" - conditions: os=linux & cpu=riscv64 & libc=glibc +"@typescript-eslint/visitor-keys@npm:8.56.1": + version: 8.56.1 + resolution: "@typescript-eslint/visitor-keys@npm:8.56.1" + dependencies: + "@typescript-eslint/types": "npm:8.56.1" + eslint-visitor-keys: "npm:^5.0.0" + checksum: 10c0/86d97905dec1af964cc177c185933d040449acf6006096497f2e0093c6a53eb92b3ac1db9eb40a5a2e8d91160f558c9734331a9280797f09f284c38978b22190 languageName: node linkType: hard -"@unrs/resolver-binding-linux-riscv64-musl@npm:1.11.1": - version: 1.11.1 - resolution: "@unrs/resolver-binding-linux-riscv64-musl@npm:1.11.1" - conditions: os=linux & cpu=riscv64 & libc=musl +"@vitest/coverage-v8@npm:^4.1.5": + version: 4.1.5 + resolution: "@vitest/coverage-v8@npm:4.1.5" + dependencies: + "@bcoe/v8-coverage": "npm:^1.0.2" + "@vitest/utils": "npm:4.1.5" + ast-v8-to-istanbul: "npm:^1.0.0" + istanbul-lib-coverage: "npm:^3.2.2" + istanbul-lib-report: "npm:^3.0.1" + istanbul-reports: "npm:^3.2.0" + magicast: "npm:^0.5.2" + obug: "npm:^2.1.1" + std-env: "npm:^4.0.0-rc.1" + tinyrainbow: "npm:^3.1.0" + peerDependencies: + "@vitest/browser": 4.1.5 + vitest: 4.1.5 + peerDependenciesMeta: + "@vitest/browser": + optional: true + checksum: 10c0/71bf669cc1714611855caef5e89b4f3e405e410bdb34e4b2f6fbc9dc5e50dd9e09e73068c1750f6bfa03f0cd9209a2b6e03665c3bdbd34e0adff1ca65c482b7b languageName: node linkType: hard -"@unrs/resolver-binding-linux-s390x-gnu@npm:1.11.1": - version: 1.11.1 - resolution: "@unrs/resolver-binding-linux-s390x-gnu@npm:1.11.1" - conditions: os=linux & cpu=s390x & libc=glibc +"@vitest/expect@npm:4.1.5": + version: 4.1.5 + resolution: "@vitest/expect@npm:4.1.5" + dependencies: + "@standard-schema/spec": "npm:^1.1.0" + "@types/chai": "npm:^5.2.2" + "@vitest/spy": "npm:4.1.5" + "@vitest/utils": "npm:4.1.5" + chai: "npm:^6.2.2" + tinyrainbow: "npm:^3.1.0" + checksum: 10c0/5184682304db471aa20024c1154210ad3d6d590afb61646201ce1a15297259f9a35f92f8fad4435bc8a82135e307ddd27c8495f72417d72d9aa139eb281d9e06 languageName: node linkType: hard -"@unrs/resolver-binding-linux-x64-gnu@npm:1.11.1": - version: 1.11.1 - resolution: "@unrs/resolver-binding-linux-x64-gnu@npm:1.11.1" - conditions: os=linux & cpu=x64 & libc=glibc +"@vitest/mocker@npm:4.1.5": + version: 4.1.5 + resolution: "@vitest/mocker@npm:4.1.5" + dependencies: + "@vitest/spy": "npm:4.1.5" + estree-walker: "npm:^3.0.3" + magic-string: "npm:^0.30.21" + peerDependencies: + msw: ^2.4.9 + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + checksum: 10c0/bcfe97700476130933c7ea33fa670c8d2768a81de5325ce407f901e55c2f66cabbb88a7b6cffb46ddf33dff7d8fc209d769fb298f568e310fbeead9b36f6fdb9 languageName: node linkType: hard -"@unrs/resolver-binding-linux-x64-musl@npm:1.11.1": - version: 1.11.1 - resolution: "@unrs/resolver-binding-linux-x64-musl@npm:1.11.1" - conditions: os=linux & cpu=x64 & libc=musl +"@vitest/pretty-format@npm:4.1.5": + version: 4.1.5 + resolution: "@vitest/pretty-format@npm:4.1.5" + dependencies: + tinyrainbow: "npm:^3.1.0" + checksum: 10c0/42b5e9b75e87c0a884d36bee364e2d07ee45e96f413377737a74993e077d90c3a12aa36743855aee5e4e28b78fae20e3e6de5eef8d5344b9aba2bc1e1d5537a1 languageName: node linkType: hard -"@unrs/resolver-binding-wasm32-wasi@npm:1.11.1": - version: 1.11.1 - resolution: "@unrs/resolver-binding-wasm32-wasi@npm:1.11.1" +"@vitest/runner@npm:4.1.5": + version: 4.1.5 + resolution: "@vitest/runner@npm:4.1.5" dependencies: - "@napi-rs/wasm-runtime": "npm:^0.2.11" - conditions: cpu=wasm32 + "@vitest/utils": "npm:4.1.5" + pathe: "npm:^2.0.3" + checksum: 10c0/6a03b313a121155f6dd9e32eeb103c0e12440f586bc4ba1f0d77444e44c6df4652a44443718552037463115635b8378e11f35902d90ce1326f77743219fca056 languageName: node linkType: hard -"@unrs/resolver-binding-win32-arm64-msvc@npm:1.11.1": - version: 1.11.1 - resolution: "@unrs/resolver-binding-win32-arm64-msvc@npm:1.11.1" - conditions: os=win32 & cpu=arm64 +"@vitest/snapshot@npm:4.1.5": + version: 4.1.5 + resolution: "@vitest/snapshot@npm:4.1.5" + dependencies: + "@vitest/pretty-format": "npm:4.1.5" + "@vitest/utils": "npm:4.1.5" + magic-string: "npm:^0.30.21" + pathe: "npm:^2.0.3" + checksum: 10c0/e11bf50d06702331290750a40eaef86078c108df3cd9a52bb1be7b84250048790163f36827525be6a383a4bb1994fc35e6d0c24239a41688b0bb68a1d15d172f languageName: node linkType: hard -"@unrs/resolver-binding-win32-ia32-msvc@npm:1.11.1": - version: 1.11.1 - resolution: "@unrs/resolver-binding-win32-ia32-msvc@npm:1.11.1" - conditions: os=win32 & cpu=ia32 +"@vitest/spy@npm:4.1.5": + version: 4.1.5 + resolution: "@vitest/spy@npm:4.1.5" + checksum: 10c0/fda6b1ee0a2fec1a152d8041aba7a79744c3876863b244d1ed406d02b36e8ccc997edb2e3963d1027d728d3dc5a33813e11bef53a0a14fc7de4de5e721d0f591 languageName: node linkType: hard -"@unrs/resolver-binding-win32-x64-msvc@npm:1.11.1": - version: 1.11.1 - resolution: "@unrs/resolver-binding-win32-x64-msvc@npm:1.11.1" - conditions: os=win32 & cpu=x64 +"@vitest/utils@npm:4.1.5": + version: 4.1.5 + resolution: "@vitest/utils@npm:4.1.5" + dependencies: + "@vitest/pretty-format": "npm:4.1.5" + convert-source-map: "npm:^2.0.0" + tinyrainbow: "npm:^3.1.0" + checksum: 10c0/72409717e68018e5fe42fa173cc4eff6def8c35bd52013f86ddb414cd28d73fcc425ac62968e01a52371b3fd5a7a775536283d2f1d64432753f628712a6a4908 languageName: node linkType: hard @@ -4418,7 +4113,7 @@ __metadata: languageName: node linkType: hard -"ansi-escapes@npm:^4.3.0, ansi-escapes@npm:^4.3.2": +"ansi-escapes@npm:^4.3.0": version: 4.3.2 resolution: "ansi-escapes@npm:4.3.2" dependencies: @@ -4489,7 +4184,7 @@ __metadata: languageName: node linkType: hard -"ansi-styles@npm:^5.0.0, ansi-styles@npm:^5.2.0": +"ansi-styles@npm:^5.0.0": version: 5.2.0 resolution: "ansi-styles@npm:5.2.0" checksum: 10c0/9c4ca80eb3c2fb7b33841c210d2f20807f40865d27008d7c3f707b7f95cab7d67462a565e2388ac3285b71cb3d9bb2173de8da37c57692a362885ec34d6e27df @@ -4733,6 +4428,24 @@ __metadata: languageName: node linkType: hard +"assertion-error@npm:^2.0.1": + version: 2.0.1 + resolution: "assertion-error@npm:2.0.1" + checksum: 10c0/bbbcb117ac6480138f8c93cf7f535614282dea9dc828f540cdece85e3c665e8f78958b96afac52f29ff883c72638e6a87d469ecc9fe5bc902df03ed24a55dba8 + languageName: node + linkType: hard + +"ast-v8-to-istanbul@npm:^1.0.0": + version: 1.0.0 + resolution: "ast-v8-to-istanbul@npm:1.0.0" + dependencies: + "@jridgewell/trace-mapping": "npm:^0.3.31" + estree-walker: "npm:^3.0.3" + js-tokens: "npm:^10.0.0" + checksum: 10c0/35e57b754ba63287358094d4f7ae8de2de27286fb4e76a1fbf28b2e67e3b670b59c3f511882473d0fd2cdbaa260062e3cd4f216b724c70032e2b09e5cebbd618 + languageName: node + linkType: hard + "astral-regex@npm:^2.0.0": version: 2.0.0 resolution: "astral-regex@npm:2.0.0" @@ -4826,23 +4539,6 @@ __metadata: languageName: node linkType: hard -"babel-jest@npm:30.3.0": - version: 30.3.0 - resolution: "babel-jest@npm:30.3.0" - dependencies: - "@jest/transform": "npm:30.3.0" - "@types/babel__core": "npm:^7.20.5" - babel-plugin-istanbul: "npm:^7.0.1" - babel-preset-jest: "npm:30.3.0" - chalk: "npm:^4.1.2" - graceful-fs: "npm:^4.2.11" - slash: "npm:^3.0.0" - peerDependencies: - "@babel/core": ^7.11.0 || ^8.0.0-0 - checksum: 10c0/5e41e124a404ddb78aa37a20336d7c883feab5ad9c4f4c72ae26db71be2fcca345874b9a7fef97d9c5f64f144a264b247ebde8acfe493578320f314ca581bac3 - languageName: node - linkType: hard - "babel-loader@npm:^10.1.0": version: 10.1.0 resolution: "babel-loader@npm:10.1.0" @@ -4861,28 +4557,6 @@ __metadata: languageName: node linkType: hard -"babel-plugin-istanbul@npm:^7.0.1": - version: 7.0.1 - resolution: "babel-plugin-istanbul@npm:7.0.1" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.0.0" - "@istanbuljs/load-nyc-config": "npm:^1.0.0" - "@istanbuljs/schema": "npm:^0.1.3" - istanbul-lib-instrument: "npm:^6.0.2" - test-exclude: "npm:^6.0.0" - checksum: 10c0/92975e3df12503b168695463b451468da0c20e117807221652eb8e33a26c160f3b9d4c5c4e65495657420e871c6a54e5e31f539e2e1da37ef2261d7ddd4b1dfd - languageName: node - linkType: hard - -"babel-plugin-jest-hoist@npm:30.3.0": - version: 30.3.0 - resolution: "babel-plugin-jest-hoist@npm:30.3.0" - dependencies: - "@types/babel__core": "npm:^7.20.5" - checksum: 10c0/5e15900a6487356131e084970f4a9ebe24b702d74930f786e897d4fab90b0987054f66661a3570ea692f429dcd158c2214c97ecf08f7356cbc60029d7b277c74 - languageName: node - linkType: hard - "babel-plugin-polyfill-corejs2@npm:^0.4.15": version: 0.4.15 resolution: "babel-plugin-polyfill-corejs2@npm:0.4.15" @@ -4919,43 +4593,6 @@ __metadata: languageName: node linkType: hard -"babel-preset-current-node-syntax@npm:^1.2.0": - version: 1.2.0 - resolution: "babel-preset-current-node-syntax@npm:1.2.0" - dependencies: - "@babel/plugin-syntax-async-generators": "npm:^7.8.4" - "@babel/plugin-syntax-bigint": "npm:^7.8.3" - "@babel/plugin-syntax-class-properties": "npm:^7.12.13" - "@babel/plugin-syntax-class-static-block": "npm:^7.14.5" - "@babel/plugin-syntax-import-attributes": "npm:^7.24.7" - "@babel/plugin-syntax-import-meta": "npm:^7.10.4" - "@babel/plugin-syntax-json-strings": "npm:^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators": "npm:^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator": "npm:^7.8.3" - "@babel/plugin-syntax-numeric-separator": "npm:^7.10.4" - "@babel/plugin-syntax-object-rest-spread": "npm:^7.8.3" - "@babel/plugin-syntax-optional-catch-binding": "npm:^7.8.3" - "@babel/plugin-syntax-optional-chaining": "npm:^7.8.3" - "@babel/plugin-syntax-private-property-in-object": "npm:^7.14.5" - "@babel/plugin-syntax-top-level-await": "npm:^7.14.5" - peerDependencies: - "@babel/core": ^7.0.0 || ^8.0.0-0 - checksum: 10c0/94a4f81cddf9b051045d08489e4fff7336292016301664c138cfa3d9ffe3fe2ba10a24ad6ae589fd95af1ac72ba0216e1653555c187e694d7b17be0c002bea10 - languageName: node - linkType: hard - -"babel-preset-jest@npm:30.3.0": - version: 30.3.0 - resolution: "babel-preset-jest@npm:30.3.0" - dependencies: - babel-plugin-jest-hoist: "npm:30.3.0" - babel-preset-current-node-syntax: "npm:^1.2.0" - peerDependencies: - "@babel/core": ^7.11.0 || ^8.0.0-beta.1 - checksum: 10c0/a6839a1527d254bf04e82c0cf61a6a2aa283123a74f0a552e6fce462cb990abebab75a13ec3e9c58b09a865d4d2dfbac710c2d3975ae3ce6f2707cb314915c66 - languageName: node - linkType: hard - "bail@npm:^1.0.0": version: 1.0.5 resolution: "bail@npm:1.0.5" @@ -5028,6 +4665,15 @@ __metadata: languageName: node linkType: hard +"bidi-js@npm:^1.0.3": + version: 1.0.3 + resolution: "bidi-js@npm:1.0.3" + dependencies: + require-from-string: "npm:^2.0.2" + checksum: 10c0/fdddea4aa4120a34285486f2267526cd9298b6e8b773ad25e765d4f104b6d7437ab4ba542e6939e3ac834a7570bcf121ee2cf6d3ae7cd7082c4b5bedc8f271e1 + languageName: node + linkType: hard + "binary-extensions@npm:^2.0.0": version: 2.2.0 resolution: "binary-extensions@npm:2.2.0" @@ -5241,24 +4887,6 @@ __metadata: languageName: node linkType: hard -"bs-logger@npm:^0.2.6": - version: 0.2.6 - resolution: "bs-logger@npm:0.2.6" - dependencies: - fast-json-stable-stringify: "npm:2.x" - checksum: 10c0/80e89aaaed4b68e3374ce936f2eb097456a0dddbf11f75238dbd53140b1e39259f0d248a5089ed456f1158984f22191c3658d54a713982f676709fbe1a6fa5a0 - languageName: node - linkType: hard - -"bser@npm:2.1.1": - version: 2.1.1 - resolution: "bser@npm:2.1.1" - dependencies: - node-int64: "npm:^0.4.0" - checksum: 10c0/24d8dfb7b6d457d73f32744e678a60cc553e4ec0e9e1a01cf614b44d85c3c87e188d3cc78ef0442ce5032ee6818de20a0162ba1074725c0d08908f62ea979227 - languageName: node - linkType: hard - "buffer-crc32@npm:~0.2.3": version: 0.2.13 resolution: "buffer-crc32@npm:0.2.13" @@ -5387,7 +5015,7 @@ __metadata: languageName: node linkType: hard -"callsites@npm:^3.0.0, callsites@npm:^3.1.0": +"callsites@npm:^3.0.0": version: 3.1.0 resolution: "callsites@npm:3.1.0" checksum: 10c0/fff92277400eb06c3079f9e74f3af120db9f8ea03bad0e84d9aede54bbe2d44a56cccb5f6cf12211f93f52306df87077ecec5b712794c5a9b5dac6d615a3f301 @@ -5429,14 +5057,7 @@ __metadata: languageName: node linkType: hard -"camelcase@npm:^5.3.1": - version: 5.3.1 - resolution: "camelcase@npm:5.3.1" - checksum: 10c0/92ff9b443bfe8abb15f2b1513ca182d16126359ad4f955ebc83dc4ddcc4ef3fdd2c078bc223f2673dc223488e75c99b16cc4d056624374b799e6a1555cf61b23 - languageName: node - linkType: hard - -"camelcase@npm:^6.0.0, camelcase@npm:^6.3.0": +"camelcase@npm:^6.0.0": version: 6.3.0 resolution: "camelcase@npm:6.3.0" checksum: 10c0/0d701658219bd3116d12da3eab31acddb3f9440790c0792e0d398f0a520a6a4058018e546862b6fba89d7ae990efaeb97da71e1913e9ebf5a8b5621a3d55c710 @@ -5471,6 +5092,13 @@ __metadata: languageName: node linkType: hard +"chai@npm:^6.2.2": + version: 6.2.2 + resolution: "chai@npm:6.2.2" + checksum: 10c0/e6c69e5f0c11dffe6ea13d0290936ebb68fcc1ad688b8e952e131df6a6d5797d5e860bc55cef1aca2e950c3e1f96daf79e9d5a70fb7dbaab4e46355e2635ed53 + languageName: node + linkType: hard + "chalk@npm:2.4.x, chalk@npm:^2.0.1, chalk@npm:^2.1.0, chalk@npm:^2.4.1": version: 2.4.2 resolution: "chalk@npm:2.4.2" @@ -5505,13 +5133,6 @@ __metadata: languageName: node linkType: hard -"char-regex@npm:^1.0.2": - version: 1.0.2 - resolution: "char-regex@npm:1.0.2" - checksum: 10c0/57a09a86371331e0be35d9083ba429e86c4f4648ecbe27455dbfb343037c16ee6fdc7f6b61f433a57cc5ded5561d71c56a150e018f40c2ffb7bc93a26dae341e - languageName: node - linkType: hard - "character-entities-html4@npm:^1.0.0": version: 1.1.4 resolution: "character-entities-html4@npm:1.1.4" @@ -5636,13 +5257,6 @@ __metadata: languageName: node linkType: hard -"ci-info@npm:^4.2.0": - version: 4.4.0 - resolution: "ci-info@npm:4.4.0" - checksum: 10c0/44156201545b8dde01aa8a09ee2fe9fc7a73b1bef9adbd4606c9f61c8caeeb73fb7a575c88b0443f7b4edb5ee45debaa59ed54ba5f99698339393ca01349eb3a - languageName: node - linkType: hard - "circular-json@npm:^0.3.1": version: 0.3.3 resolution: "circular-json@npm:0.3.3" @@ -5650,13 +5264,6 @@ __metadata: languageName: node linkType: hard -"cjs-module-lexer@npm:^2.1.0": - version: 2.2.0 - resolution: "cjs-module-lexer@npm:2.2.0" - checksum: 10c0/aec4ca58f87145fac221386790ecaae8b012f2e2359a45acb61d8c75ea4fa84f6ea869f17abc1a7e91a808eff0fed581209632f03540de16f72f0a28f5fd35ac - languageName: node - linkType: hard - "clean-stack@npm:^2.0.0": version: 2.2.0 resolution: "clean-stack@npm:2.2.0" @@ -5703,6 +5310,13 @@ __metadata: languageName: node linkType: hard +"cli-width@npm:^4.1.0": + version: 4.1.0 + resolution: "cli-width@npm:4.1.0" + checksum: 10c0/1fbd56413578f6117abcaf858903ba1f4ad78370a4032f916745fa2c7e390183a9d9029cf837df320b0fdce8137668e522f60a30a5f3d6529ff3872d265a955f + languageName: node + linkType: hard + "cliui@npm:^8.0.1": version: 8.0.1 resolution: "cliui@npm:8.0.1" @@ -5742,13 +5356,6 @@ __metadata: languageName: node linkType: hard -"co@npm:^4.6.0": - version: 4.6.0 - resolution: "co@npm:4.6.0" - checksum: 10c0/c0e85ea0ca8bf0a50cbdca82efc5af0301240ca88ebe3644a6ffb8ffe911f34d40f8fbcf8f1d52c5ddd66706abd4d3bfcd64259f1e8e2371d4f47573b0dc8c28 - languageName: node - linkType: hard - "collapse-white-space@npm:^1.0.2": version: 1.0.6 resolution: "collapse-white-space@npm:1.0.6" @@ -5756,13 +5363,6 @@ __metadata: languageName: node linkType: hard -"collect-v8-coverage@npm:^1.0.2": - version: 1.0.3 - resolution: "collect-v8-coverage@npm:1.0.3" - checksum: 10c0/bc62ba251bcce5e3354a8f88fa6442bee56e3e612fec08d4dfcf66179b41ea0bf544b0f78c4ebc0f8050871220af95bb5c5578a6aef346feea155640582f09dc - languageName: node - linkType: hard - "color-convert@npm:^1.9.0": version: 1.9.3 resolution: "color-convert@npm:1.9.3" @@ -5935,6 +5535,7 @@ __metadata: "@octokit/rest": "npm:^22.0.1" "@openshift-console/dynamic-plugin-sdk": "npm:4.21-latest" "@openshift-console/dynamic-plugin-sdk-webpack": "npm:4.21-latest" + "@patternfly/react-code-editor": "npm:^6.4.3" "@patternfly/react-core": "npm:^6.2.2" "@patternfly/react-icons": "npm:^6.2.2" "@patternfly/react-table": "npm:^6.2.2" @@ -5942,11 +5543,10 @@ __metadata: "@testing-library/jest-dom": "npm:^6.9.1" "@testing-library/react": "npm:^12.1.5" "@testing-library/user-event": "npm:^14.6.1" - "@types/identity-obj-proxy": "npm:^3" - "@types/jest": "npm:^30.0.0" "@types/node": "npm:^22.0.0" "@types/react": "npm:^17.0.37" "@types/react-router-dom": "npm:^5.3.3" + "@vitest/coverage-v8": "npm:^4.1.5" babel-loader: "npm:^10.1.0" copy-webpack-plugin: "npm:^14.0.0" css-loader: "npm:^7.1.4" @@ -5961,13 +5561,12 @@ __metadata: globals: "npm:^17.4.0" i18next: "npm:^23.11.5" i18next-parser: "npm:^9.4.0" - identity-obj-proxy: "npm:^3.0.0" - jest: "npm:^30.3.0" - jest-environment-jsdom: "npm:^30.3.0" + jsdom: "npm:^29.0.2" mocha: "npm:^11.7.5" mocha-junit-reporter: "npm:^2.2.1" mochawesome: "npm:^7.1.4" mochawesome-merge: "npm:^5.1.1" + msw: "npm:^2.13.6" pluralize: "npm:^8.0.0" prettier: "npm:^3.8.1" prettier-stylelint: "npm:^0.4.2" @@ -5980,11 +5579,11 @@ __metadata: style-loader: "npm:^4.0.0" stylelint: "npm:^17.4.0" stylelint-config-standard: "npm:^40.0.0" - ts-jest: "npm:^29.4.6" ts-loader: "npm:^9.5.4" ts-node: "npm:^10.9.2" typescript: "npm:^5.9.3" typescript-eslint: "npm:^8.56.1" + vitest: "npm:^4.1.5" webpack: "npm:^5.100.0" webpack-cli: "npm:^6.0.1" webpack-dev-server: "npm:^5.2.3" @@ -6021,6 +5620,13 @@ __metadata: languageName: node linkType: hard +"cookie@npm:^1.1.1": + version: 1.1.1 + resolution: "cookie@npm:1.1.1" + checksum: 10c0/79c4ddc0fcad9c4f045f826f42edf54bcc921a29586a4558b0898277fa89fb47be95bc384c2253f493af7b29500c830da28341274527328f18eba9f58afa112c + languageName: node + linkType: hard + "cookie@npm:~0.7.1": version: 0.7.2 resolution: "cookie@npm:0.7.2" @@ -6191,6 +5797,16 @@ __metadata: languageName: node linkType: hard +"css-tree@npm:^3.0.0, css-tree@npm:^3.2.1": + version: 3.2.1 + resolution: "css-tree@npm:3.2.1" + dependencies: + mdn-data: "npm:2.27.1" + source-map-js: "npm:^1.2.1" + checksum: 10c0/1f65e9ccaa56112a4706d6f003dd43d777f0dbcf848e66fd320f823192533581f8dd58daa906cb80622658332d50284d6be13b87a6ab4556cbbfe9ef535bbf7e + languageName: node + linkType: hard + "css-tree@npm:^3.1.0": version: 3.1.0 resolution: "css-tree@npm:3.1.0" @@ -6224,16 +5840,6 @@ __metadata: languageName: node linkType: hard -"cssstyle@npm:^4.2.1": - version: 4.6.0 - resolution: "cssstyle@npm:4.6.0" - dependencies: - "@asamuzakjp/css-color": "npm:^3.2.0" - rrweb-cssom: "npm:^0.8.0" - checksum: 10c0/71add1b0ffafa1bedbef6855db6189b9523d3320e015a0bf3fbd504760efb9a81e1f1a225228d5fa892ee58e56d06994ca372e7f4e461cda7c4c9985fe075f65 - languageName: node - linkType: hard - "csstype@npm:^3.0.2": version: 3.0.9 resolution: "csstype@npm:3.0.9" @@ -6690,13 +6296,13 @@ __metadata: languageName: node linkType: hard -"data-urls@npm:^5.0.0": - version: 5.0.0 - resolution: "data-urls@npm:5.0.0" +"data-urls@npm:^7.0.0": + version: 7.0.0 + resolution: "data-urls@npm:7.0.0" dependencies: - whatwg-mimetype: "npm:^4.0.0" - whatwg-url: "npm:^14.0.0" - checksum: 10c0/1b894d7d41c861f3a4ed2ae9b1c3f0909d4575ada02e36d3d3bc584bdd84278e20709070c79c3b3bff7ac98598cb191eb3e86a89a79ea4ee1ef360e1694f92ad + whatwg-mimetype: "npm:^5.0.0" + whatwg-url: "npm:^16.0.0" + checksum: 10c0/08d88ef50d8966a070ffdaa703e1e4b29f01bb2da364dfbc1612b1c2a4caa8045802c9532d81347b21781100132addb36a585071c8323b12cce97973961dee9f languageName: node linkType: hard @@ -6801,25 +6407,13 @@ __metadata: languageName: node linkType: hard -"decimal.js@npm:^10.5.0": +"decimal.js@npm:^10.6.0": version: 10.6.0 resolution: "decimal.js@npm:10.6.0" checksum: 10c0/07d69fbcc54167a340d2d97de95f546f9ff1f69d2b45a02fd7a5292412df3cd9eb7e23065e532a318f5474a2e1bccf8392fdf0443ef467f97f3bf8cb0477e5aa languageName: node linkType: hard -"dedent@npm:^1.6.0": - version: 1.7.2 - resolution: "dedent@npm:1.7.2" - peerDependencies: - babel-plugin-macros: ^3.1.0 - peerDependenciesMeta: - babel-plugin-macros: - optional: true - checksum: 10c0/acaff07cac355b93f17b1b17ebbb84d3cc55af6ab4b7814c3f505e061903e168bc6bf9ddce331552d64dee1525f0b4c549c9ade46aebfac6f69caaed74e90751 - languageName: node - linkType: hard - "deep-equal@npm:^2.0.5": version: 2.2.3 resolution: "deep-equal@npm:2.2.3" @@ -6860,13 +6454,6 @@ __metadata: languageName: node linkType: hard -"deepmerge@npm:^4.3.1": - version: 4.3.1 - resolution: "deepmerge@npm:4.3.1" - checksum: 10c0/e53481aaf1aa2c4082b5342be6b6d8ad9dfe387bc92ce197a66dea08bd4265904a087e75e464f14d1347cf2ac8afe1e4c16b266e0561cc5df29382d3c5f80044 - languageName: node - linkType: hard - "default-browser-id@npm:^5.0.0": version: 5.0.1 resolution: "default-browser-id@npm:5.0.1" @@ -6950,10 +6537,10 @@ __metadata: languageName: node linkType: hard -"detect-newline@npm:^3.1.0": - version: 3.1.0 - resolution: "detect-newline@npm:3.1.0" - checksum: 10c0/c38cfc8eeb9fda09febb44bcd85e467c970d4e3bf526095394e5a4f18bc26dd0cf6b22c69c1fa9969261521c593836db335c2795218f6d781a512aea2fb8209d +"detect-libc@npm:^2.0.3": + version: 2.1.2 + resolution: "detect-libc@npm:2.1.2" + checksum: 10c0/acc675c29a5649fa1fb6e255f993b8ee829e510b6b56b0910666949c80c364738833417d0edb5f90e4e46be17228b0f2b66a010513984e18b15deeeac49369c4 languageName: node linkType: hard @@ -7167,13 +6754,6 @@ __metadata: languageName: node linkType: hard -"emittery@npm:^0.13.1": - version: 0.13.1 - resolution: "emittery@npm:0.13.1" - checksum: 10c0/1573d0ae29ab34661b6c63251ff8f5facd24ccf6a823f19417ae8ba8c88ea450325788c67f16c99edec8de4b52ce93a10fe441ece389fd156e88ee7dab9bfa35 - languageName: node - linkType: hard - "emoji-regex@npm:^8.0.0": version: 8.0.0 resolution: "emoji-regex@npm:8.0.0" @@ -7268,6 +6848,13 @@ __metadata: languageName: node linkType: hard +"entities@npm:^8.0.0": + version: 8.0.0 + resolution: "entities@npm:8.0.0" + checksum: 10c0/938e631664c19451823344a351aeeafd74fae2d5fa51e4d5b6ff635afaefd4bacf0f609989888c04c42733f46ffdac15211608267ebb02488005891a4793e94d + languageName: node + linkType: hard + "env-paths@npm:^2.2.0, env-paths@npm:^2.2.1": version: 2.2.1 resolution: "env-paths@npm:2.2.1" @@ -7575,13 +7162,6 @@ __metadata: languageName: node linkType: hard -"escape-string-regexp@npm:^2.0.0": - version: 2.0.0 - resolution: "escape-string-regexp@npm:2.0.0" - checksum: 10c0/2530479fe8db57eace5e8646c9c2a9c80fa279614986d16dcc6bcaceb63ae77f05a851ba6c43756d816c61d7f4534baf56e3c705e3e0d884818a46808811c507 - languageName: node - linkType: hard - "escape-string-regexp@npm:^4.0.0": version: 4.0.0 resolution: "escape-string-regexp@npm:4.0.0" @@ -7817,6 +7397,15 @@ __metadata: languageName: node linkType: hard +"estree-walker@npm:^3.0.3": + version: 3.0.3 + resolution: "estree-walker@npm:3.0.3" + dependencies: + "@types/estree": "npm:^1.0.0" + checksum: 10c0/c12e3c2b2642d2bcae7d5aa495c60fa2f299160946535763969a1c83fc74518ffa9c2cd3a8b69ac56aea547df6a8aac25f729a342992ef0bbac5f1c73e78995d + languageName: node + linkType: hard + "esutils@npm:^2.0.2": version: 2.0.3 resolution: "esutils@npm:2.0.3" @@ -7893,23 +7482,6 @@ __metadata: languageName: node linkType: hard -"execa@npm:^5.1.1": - version: 5.1.1 - resolution: "execa@npm:5.1.1" - dependencies: - cross-spawn: "npm:^7.0.3" - get-stream: "npm:^6.0.0" - human-signals: "npm:^2.1.0" - is-stream: "npm:^2.0.0" - merge-stream: "npm:^2.0.0" - npm-run-path: "npm:^4.0.1" - onetime: "npm:^5.1.2" - signal-exit: "npm:^3.0.3" - strip-final-newline: "npm:^2.0.0" - checksum: 10c0/c8e615235e8de4c5addf2fa4c3da3e3aa59ce975a3e83533b4f6a71750fb816a2e79610dc5f1799b6e28976c9ae86747a36a606655bf8cb414a74d8d507b304f - languageName: node - linkType: hard - "execall@npm:^1.0.0": version: 1.0.0 resolution: "execall@npm:1.0.0" @@ -7928,13 +7500,6 @@ __metadata: languageName: node linkType: hard -"exit-x@npm:^0.2.2": - version: 0.2.2 - resolution: "exit-x@npm:0.2.2" - checksum: 10c0/212a7a095ca5540e9581f1ef2d1d6a40df7a6027c8cc96e78ce1d16b86d1a88326d4a0eff8dff2b5ec1e68bb0c1edd5d0dfdde87df1869bf7514d4bc6a5cbd72 - languageName: node - linkType: hard - "expand-brackets@npm:^0.1.4": version: 0.1.5 resolution: "expand-brackets@npm:0.1.5" @@ -7953,17 +7518,10 @@ __metadata: languageName: node linkType: hard -"expect@npm:30.3.0, expect@npm:^30.0.0": - version: 30.3.0 - resolution: "expect@npm:30.3.0" - dependencies: - "@jest/expect-utils": "npm:30.3.0" - "@jest/get-type": "npm:30.1.0" - jest-matcher-utils: "npm:30.3.0" - jest-message-util: "npm:30.3.0" - jest-mock: "npm:30.3.0" - jest-util: "npm:30.3.0" - checksum: 10c0/a07a157a0c8b3f1e29bfe5ccbf03a3add2c69fe60d1af8a0980053bb6403d721d5f5e4616f1ea5833b747913f8c880c79ce4d98c23a71a2f0c27cf7273892576 +"expect-type@npm:^1.3.0": + version: 1.3.0 + resolution: "expect-type@npm:1.3.0" + checksum: 10c0/8412b3fe4f392c420ab41dae220b09700e4e47c639a29ba7ba2e83cc6cffd2b4926f7ac9e47d7e277e8f4f02acda76fd6931cb81fd2b382fa9477ef9ada953fd languageName: node linkType: hard @@ -8101,7 +7659,7 @@ __metadata: languageName: node linkType: hard -"fast-json-stable-stringify@npm:2.x, fast-json-stable-stringify@npm:^2.0.0, fast-json-stable-stringify@npm:^2.1.0": +"fast-json-stable-stringify@npm:^2.0.0": version: 2.1.0 resolution: "fast-json-stable-stringify@npm:2.1.0" checksum: 10c0/7f081eb0b8a64e0057b3bb03f974b3ef00135fbf36c1c710895cd9300f13c94ba809bb3a81cf4e1b03f6e5285610a61abbd7602d0652de423144dfee5a389c9b @@ -8115,6 +7673,22 @@ __metadata: languageName: node linkType: hard +"fast-string-truncated-width@npm:^3.0.2": + version: 3.0.3 + resolution: "fast-string-truncated-width@npm:3.0.3" + checksum: 10c0/043b8663397d14a3880ce4f3407bcda60b40db9bbeafe62863a35d1f9c69ea17c8da3fcd72de235553e6c9cd053128cde9e24ca0d4a7463208f48db3cd23d981 + languageName: node + linkType: hard + +"fast-string-width@npm:^3.0.2": + version: 3.0.2 + resolution: "fast-string-width@npm:3.0.2" + dependencies: + fast-string-truncated-width: "npm:^3.0.2" + checksum: 10c0/c8822d175315bb353ebe782b65214ac53b13e3bf704e03b132ea7bdfa8de6a636375b3ab7a4097545393d109381c37c4f387c72a462c90b61412dbc4632f39a7 + languageName: node + linkType: hard + "fast-uri@npm:^3.0.1": version: 3.1.0 resolution: "fast-uri@npm:3.1.0" @@ -8122,6 +7696,15 @@ __metadata: languageName: node linkType: hard +"fast-wrap-ansi@npm:^0.2.0": + version: 0.2.0 + resolution: "fast-wrap-ansi@npm:0.2.0" + dependencies: + fast-string-width: "npm:^3.0.2" + checksum: 10c0/c0eb6debee565c5dbb9132dddff5c4d4aba5eb02185ae4dab285acd6186018cffca04264e92f373cbf592a9bcd1c33d65dba036030a8f3baeff1169969a1b59b + languageName: node + linkType: hard + "fastest-levenshtein@npm:^1.0.12, fastest-levenshtein@npm:^1.0.16": version: 1.0.16 resolution: "fastest-levenshtein@npm:1.0.16" @@ -8147,15 +7730,6 @@ __metadata: languageName: node linkType: hard -"fb-watchman@npm:^2.0.2": - version: 2.0.2 - resolution: "fb-watchman@npm:2.0.2" - dependencies: - bser: "npm:2.1.1" - checksum: 10c0/feae89ac148adb8f6ae8ccd87632e62b13563e6fb114cacb5265c51f585b17e2e268084519fb2edd133872f1d47a18e6bfd7e5e08625c0d41b93149694187581 - languageName: node - linkType: hard - "fd-slicer@npm:~1.1.0": version: 1.1.0 resolution: "fd-slicer@npm:1.1.0" @@ -8267,7 +7841,7 @@ __metadata: languageName: node linkType: hard -"find-up@npm:4.x, find-up@npm:^4.0.0, find-up@npm:^4.1.0": +"find-up@npm:4.x, find-up@npm:^4.0.0": version: 4.1.0 resolution: "find-up@npm:4.1.0" dependencies: @@ -8540,16 +8114,6 @@ __metadata: languageName: node linkType: hard -"fsevents@npm:^2.3.3": - version: 2.3.3 - resolution: "fsevents@npm:2.3.3" - dependencies: - node-gyp: "npm:latest" - checksum: 10c0/a1f0c44595123ed717febbc478aa952e47adfc28e2092be66b8ab1635147254ca6cfe1df792a8997f22716d4cbafc73309899ff7bfac2ac3ad8cf2e4ecc3ec60 - conditions: os=darwin - languageName: node - linkType: hard - "fsevents@npm:~2.3.2": version: 2.3.2 resolution: "fsevents@npm:2.3.2" @@ -8560,11 +8124,12 @@ __metadata: languageName: node linkType: hard -"fsevents@patch:fsevents@npm%3A^2.3.3#optional!builtin": +"fsevents@npm:~2.3.3": version: 2.3.3 - resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1" + resolution: "fsevents@npm:2.3.3" dependencies: node-gyp: "npm:latest" + checksum: 10c0/a1f0c44595123ed717febbc478aa952e47adfc28e2092be66b8ab1635147254ca6cfe1df792a8997f22716d4cbafc73309899ff7bfac2ac3ad8cf2e4ecc3ec60 conditions: os=darwin languageName: node linkType: hard @@ -8578,6 +8143,15 @@ __metadata: languageName: node linkType: hard +"fsevents@patch:fsevents@npm%3A~2.3.3#optional!builtin": + version: 2.3.3 + resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1" + dependencies: + node-gyp: "npm:latest" + conditions: os=darwin + languageName: node + linkType: hard + "fsu@npm:^1.1.1": version: 1.1.1 resolution: "fsu@npm:1.1.1" @@ -8662,13 +8236,6 @@ __metadata: languageName: node linkType: hard -"get-package-type@npm:^0.1.0": - version: 0.1.0 - resolution: "get-package-type@npm:0.1.0" - checksum: 10c0/e34cdf447fdf1902a1f6d5af737eaadf606d2ee3518287abde8910e04159368c268568174b2e71102b87b26c2020486f126bfca9c4fb1ceb986ff99b52ecd1be - languageName: node - linkType: hard - "get-proto@npm:^1.0.0, get-proto@npm:^1.0.1": version: 1.0.1 resolution: "get-proto@npm:1.0.1" @@ -8709,13 +8276,6 @@ __metadata: languageName: node linkType: hard -"get-stream@npm:^6.0.0": - version: 6.0.1 - resolution: "get-stream@npm:6.0.1" - checksum: 10c0/49825d57d3fd6964228e6200a58169464b8e8970489b3acdc24906c782fb7f01f9f56f8e6653c4a50713771d6658f7cfe051e5eb8c12e334138c9c918b296341 - languageName: node - linkType: hard - "get-symbol-description@npm:^1.1.0": version: 1.1.0 resolution: "get-symbol-description@npm:1.1.0" @@ -8805,7 +8365,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:7.x, glob@npm:^7.0.3, glob@npm:^7.1.2, glob@npm:^7.1.3, glob@npm:^7.1.4": +"glob@npm:7.x, glob@npm:^7.0.3, glob@npm:^7.1.2, glob@npm:^7.1.3": version: 7.2.3 resolution: "glob@npm:7.2.3" dependencies: @@ -8819,7 +8379,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:^10.4.5, glob@npm:^10.5.0": +"glob@npm:^10.4.5": version: 10.5.0 resolution: "glob@npm:10.5.0" dependencies: @@ -9000,6 +8560,13 @@ __metadata: languageName: node linkType: hard +"graphql@npm:^16.13.2": + version: 16.13.2 + resolution: "graphql@npm:16.13.2" + checksum: 10c0/64e822a0a0e4398781e4bc9765b88d370c08261498b517add4b878038ef7be2005b6b394a79a5102b9379d57052f60bc7f23fec8f39808d101984a74772ebd9d + languageName: node + linkType: hard + "gulp-sort@npm:^2.0.0": version: 2.0.0 resolution: "gulp-sort@npm:2.0.0" @@ -9016,31 +8583,6 @@ __metadata: languageName: node linkType: hard -"handlebars@npm:^4.7.8": - version: 4.7.9 - resolution: "handlebars@npm:4.7.9" - dependencies: - minimist: "npm:^1.2.5" - neo-async: "npm:^2.6.2" - source-map: "npm:^0.6.1" - uglify-js: "npm:^3.1.4" - wordwrap: "npm:^1.0.0" - dependenciesMeta: - uglify-js: - optional: true - bin: - handlebars: bin/handlebars - checksum: 10c0/22f8105a7e68e81aff2662bb434edf05f757d21d850731d71cec886d69c10cd33d3c43e34b2892968ec62de8241611851d3d0674c8ef324ea3e01dc66262faa9 - languageName: node - linkType: hard - -"harmony-reflect@npm:^1.4.6": - version: 1.6.2 - resolution: "harmony-reflect@npm:1.6.2" - checksum: 10c0/fa5b251fbeff0e2d925f0bfb5ffe39e0627639e998c453562d6a39e41789c15499649dc022178c807cf99bfb97e7b974bbbc031ba82078a26be7b098b9bc2b1a - languageName: node - linkType: hard - "has-ansi@npm:^2.0.0": version: 2.0.0 resolution: "has-ansi@npm:2.0.0" @@ -9163,6 +8705,16 @@ __metadata: languageName: node linkType: hard +"headers-polyfill@npm:^5.0.1": + version: 5.0.1 + resolution: "headers-polyfill@npm:5.0.1" + dependencies: + "@types/set-cookie-parser": "npm:^2.4.10" + set-cookie-parser: "npm:^3.0.1" + checksum: 10c0/c269730a88a12c88718037aa71f178601f2b193ba8a37e276b6ced6b8f7e06fc1ac051f2a7acb0a8b4cc878407066555fdcdbb270e90374baaa472cb26af0c30 + languageName: node + linkType: hard + "heimdalljs-logger@npm:^0.1.10, heimdalljs-logger@npm:^0.1.7": version: 0.1.10 resolution: "heimdalljs-logger@npm:0.1.10" @@ -9256,12 +8808,12 @@ __metadata: languageName: node linkType: hard -"html-encoding-sniffer@npm:^4.0.0": - version: 4.0.0 - resolution: "html-encoding-sniffer@npm:4.0.0" +"html-encoding-sniffer@npm:^6.0.0": + version: 6.0.0 + resolution: "html-encoding-sniffer@npm:6.0.0" dependencies: - whatwg-encoding: "npm:^3.1.1" - checksum: 10c0/523398055dc61ac9b34718a719cb4aa691e4166f29187e211e1607de63dc25ac7af52ca7c9aead0c4b3c0415ffecb17326396e1202e2e86ff4bca4c0ee4c6140 + "@exodus/bytes": "npm:^1.6.0" + checksum: 10c0/66dc3f6f5539cc3beb814fcbfae7eacf4ec38cf824d6e1425b72039b51a40f4456bd8541ba66f4f4fe09cdf885ab5cd5bae6ec6339d6895a930b2fdb83c53025 languageName: node linkType: hard @@ -9367,7 +8919,7 @@ __metadata: languageName: node linkType: hard -"http-proxy-agent@npm:^7.0.0, http-proxy-agent@npm:^7.0.2": +"http-proxy-agent@npm:^7.0.0": version: 7.0.2 resolution: "http-proxy-agent@npm:7.0.2" dependencies: @@ -9417,7 +8969,7 @@ __metadata: languageName: node linkType: hard -"https-proxy-agent@npm:^7.0.1, https-proxy-agent@npm:^7.0.6": +"https-proxy-agent@npm:^7.0.1": version: 7.0.6 resolution: "https-proxy-agent@npm:7.0.6" dependencies: @@ -9434,13 +8986,6 @@ __metadata: languageName: node linkType: hard -"human-signals@npm:^2.1.0": - version: 2.1.0 - resolution: "human-signals@npm:2.1.0" - checksum: 10c0/695edb3edfcfe9c8b52a76926cd31b36978782062c0ed9b1192b36bebc75c4c87c82e178dfcb0ed0fc27ca59d434198aac0bd0be18f5781ded775604db22304a - languageName: node - linkType: hard - "hyperdyperid@npm:^1.2.0": version: 1.2.0 resolution: "hyperdyperid@npm:1.2.0" @@ -9534,15 +9079,6 @@ __metadata: languageName: node linkType: hard -"identity-obj-proxy@npm:^3.0.0": - version: 3.0.0 - resolution: "identity-obj-proxy@npm:3.0.0" - dependencies: - harmony-reflect: "npm:^1.4.6" - checksum: 10c0/a3fc4de0042d7b45bf8652d5596c80b42139d8625c9cd6a8834e29e1b6dce8fccabd1228e08744b78677a19ceed7201a32fed8ca3dc3e4852e8fee24360a6cfc - languageName: node - linkType: hard - "ieee754@npm:^1.1.13, ieee754@npm:^1.2.1": version: 1.2.1 resolution: "ieee754@npm:1.2.1" @@ -9619,18 +9155,6 @@ __metadata: languageName: node linkType: hard -"import-local@npm:^3.2.0": - version: 3.2.0 - resolution: "import-local@npm:3.2.0" - dependencies: - pkg-dir: "npm:^4.2.0" - resolve-cwd: "npm:^3.0.0" - bin: - import-local-fixture: fixtures/cli.js - checksum: 10c0/94cd6367a672b7e0cb026970c85b76902d2710a64896fa6de93bd5c571dd03b228c5759308959de205083e3b1c61e799f019c9e36ee8e9c523b993e1057f0433 - languageName: node - linkType: hard - "import-meta-resolve@npm:^4.2.0": version: 4.2.0 resolution: "import-meta-resolve@npm:4.2.0" @@ -9997,13 +9521,6 @@ __metadata: languageName: node linkType: hard -"is-generator-fn@npm:^2.1.0": - version: 2.1.0 - resolution: "is-generator-fn@npm:2.1.0" - checksum: 10c0/2957cab387997a466cd0bf5c1b6047bd21ecb32bdcfd8996b15747aa01002c1c88731802f1b3d34ac99f4f6874b626418bd118658cf39380fe5fff32a3af9c4d - languageName: node - linkType: hard - "is-generator-function@npm:^1.0.10": version: 1.1.2 resolution: "is-generator-function@npm:1.1.2" @@ -10101,6 +9618,13 @@ __metadata: languageName: node linkType: hard +"is-node-process@npm:^1.2.0": + version: 1.2.0 + resolution: "is-node-process@npm:1.2.0" + checksum: 10c0/5b24fda6776d00e42431d7bcd86bce81cb0b6cabeb944142fe7b077a54ada2e155066ad06dbe790abdb397884bdc3151e04a9707b8cd185099efbc79780573ed + languageName: node + linkType: hard + "is-npm@npm:^1.0.0": version: 1.0.0 resolution: "is-npm@npm:1.0.0" @@ -10436,558 +9960,100 @@ __metadata: "isarray@npm:^2.0.5": version: 2.0.5 - resolution: "isarray@npm:2.0.5" - checksum: 10c0/4199f14a7a13da2177c66c31080008b7124331956f47bca57dd0b6ea9f11687aa25e565a2c7a2b519bc86988d10398e3049a1f5df13c9f6b7664154690ae79fd - languageName: node - linkType: hard - -"isexe@npm:^2.0.0": - version: 2.0.0 - resolution: "isexe@npm:2.0.0" - checksum: 10c0/228cfa503fadc2c31596ab06ed6aa82c9976eec2bfd83397e7eaf06d0ccf42cd1dfd6743bf9aeb01aebd4156d009994c5f76ea898d2832c1fe342da923ca457d - languageName: node - linkType: hard - -"isexe@npm:^4.0.0": - version: 4.0.0 - resolution: "isexe@npm:4.0.0" - checksum: 10c0/5884815115bceac452877659a9c7726382531592f43dc29e5d48b7c4100661aed54018cb90bd36cb2eaeba521092570769167acbb95c18d39afdccbcca06c5ce - languageName: node - linkType: hard - -"isobject@npm:^2.0.0": - version: 2.1.0 - resolution: "isobject@npm:2.1.0" - dependencies: - isarray: "npm:1.0.0" - checksum: 10c0/c4cafec73b3b2ee11be75dff8dafd283b5728235ac099b07d7873d5182553a707768e208327bbc12931b9422d8822280bf88d894a0024ff5857b3efefb480e7b - languageName: node - linkType: hard - -"isobject@npm:^3.0.1": - version: 3.0.1 - resolution: "isobject@npm:3.0.1" - checksum: 10c0/03344f5064a82f099a0cd1a8a407f4c0d20b7b8485e8e816c39f249e9416b06c322e8dec5b842b6bb8a06de0af9cb48e7bc1b5352f0fadc2f0abac033db3d4db - languageName: node - linkType: hard - -"isstream@npm:~0.1.2": - version: 0.1.2 - resolution: "isstream@npm:0.1.2" - checksum: 10c0/a6686a878735ca0a48e0d674dd6d8ad31aedfaf70f07920da16ceadc7577b46d67179a60b313f2e6860cb097a2c2eb3cbd0b89e921ae89199a59a17c3273d66f - languageName: node - linkType: hard - -"istanbul-lib-coverage@npm:^3.0.0, istanbul-lib-coverage@npm:^3.2.0": - version: 3.2.2 - resolution: "istanbul-lib-coverage@npm:3.2.2" - checksum: 10c0/6c7ff2106769e5f592ded1fb418f9f73b4411fd5a084387a5410538332b6567cd1763ff6b6cadca9b9eb2c443cce2f7ea7d7f1b8d315f9ce58539793b1e0922b - languageName: node - linkType: hard - -"istanbul-lib-instrument@npm:^6.0.0, istanbul-lib-instrument@npm:^6.0.2": - version: 6.0.3 - resolution: "istanbul-lib-instrument@npm:6.0.3" - dependencies: - "@babel/core": "npm:^7.23.9" - "@babel/parser": "npm:^7.23.9" - "@istanbuljs/schema": "npm:^0.1.3" - istanbul-lib-coverage: "npm:^3.2.0" - semver: "npm:^7.5.4" - checksum: 10c0/a1894e060dd2a3b9f046ffdc87b44c00a35516f5e6b7baf4910369acca79e506fc5323a816f811ae23d82334b38e3ddeb8b3b331bd2c860540793b59a8689128 - languageName: node - linkType: hard - -"istanbul-lib-report@npm:^3.0.0": - version: 3.0.1 - resolution: "istanbul-lib-report@npm:3.0.1" - dependencies: - istanbul-lib-coverage: "npm:^3.0.0" - make-dir: "npm:^4.0.0" - supports-color: "npm:^7.1.0" - checksum: 10c0/84323afb14392de8b6a5714bd7e9af845cfbd56cfe71ed276cda2f5f1201aea673c7111901227ee33e68e4364e288d73861eb2ed48f6679d1e69a43b6d9b3ba7 - languageName: node - linkType: hard - -"istanbul-lib-source-maps@npm:^5.0.0": - version: 5.0.6 - resolution: "istanbul-lib-source-maps@npm:5.0.6" - dependencies: - "@jridgewell/trace-mapping": "npm:^0.3.23" - debug: "npm:^4.1.1" - istanbul-lib-coverage: "npm:^3.0.0" - checksum: 10c0/ffe75d70b303a3621ee4671554f306e0831b16f39ab7f4ab52e54d356a5d33e534d97563e318f1333a6aae1d42f91ec49c76b6cd3f3fb378addcb5c81da0255f - languageName: node - linkType: hard - -"istanbul-reports@npm:^3.1.3": - version: 3.2.0 - resolution: "istanbul-reports@npm:3.2.0" - dependencies: - html-escaper: "npm:^2.0.0" - istanbul-lib-report: "npm:^3.0.0" - checksum: 10c0/d596317cfd9c22e1394f22a8d8ba0303d2074fe2e971887b32d870e4b33f8464b10f8ccbe6847808f7db485f084eba09e6c2ed706b3a978e4b52f07085b8f9bc - languageName: node - linkType: hard - -"iterator.prototype@npm:^1.1.5": - version: 1.1.5 - resolution: "iterator.prototype@npm:1.1.5" - dependencies: - define-data-property: "npm:^1.1.4" - es-object-atoms: "npm:^1.0.0" - get-intrinsic: "npm:^1.2.6" - get-proto: "npm:^1.0.0" - has-symbols: "npm:^1.1.0" - set-function-name: "npm:^2.0.2" - checksum: 10c0/f7a262808e1b41049ab55f1e9c29af7ec1025a000d243b83edf34ce2416eedd56079b117fa59376bb4a724110690f13aa8427f2ee29a09eec63a7e72367626d0 - languageName: node - linkType: hard - -"jackspeak@npm:^3.1.2": - version: 3.4.3 - resolution: "jackspeak@npm:3.4.3" - dependencies: - "@isaacs/cliui": "npm:^8.0.2" - "@pkgjs/parseargs": "npm:^0.11.0" - dependenciesMeta: - "@pkgjs/parseargs": - optional: true - checksum: 10c0/6acc10d139eaefdbe04d2f679e6191b3abf073f111edf10b1de5302c97ec93fffeb2fdd8681ed17f16268aa9dd4f8c588ed9d1d3bffbbfa6e8bf897cbb3149b9 - languageName: node - linkType: hard - -"jest-changed-files@npm:30.3.0": - version: 30.3.0 - resolution: "jest-changed-files@npm:30.3.0" - dependencies: - execa: "npm:^5.1.1" - jest-util: "npm:30.3.0" - p-limit: "npm:^3.1.0" - checksum: 10c0/5a2f9790f8ab7f5804ebbf0fcdd908c40286d602d76abbecc6bea72e7f3c60b77dc8a3d3f5acdddd11653b2574f471a5c126ceda0734bc6a7d607cf145843525 - languageName: node - linkType: hard - -"jest-circus@npm:30.3.0": - version: 30.3.0 - resolution: "jest-circus@npm:30.3.0" - dependencies: - "@jest/environment": "npm:30.3.0" - "@jest/expect": "npm:30.3.0" - "@jest/test-result": "npm:30.3.0" - "@jest/types": "npm:30.3.0" - "@types/node": "npm:*" - chalk: "npm:^4.1.2" - co: "npm:^4.6.0" - dedent: "npm:^1.6.0" - is-generator-fn: "npm:^2.1.0" - jest-each: "npm:30.3.0" - jest-matcher-utils: "npm:30.3.0" - jest-message-util: "npm:30.3.0" - jest-runtime: "npm:30.3.0" - jest-snapshot: "npm:30.3.0" - jest-util: "npm:30.3.0" - p-limit: "npm:^3.1.0" - pretty-format: "npm:30.3.0" - pure-rand: "npm:^7.0.0" - slash: "npm:^3.0.0" - stack-utils: "npm:^2.0.6" - checksum: 10c0/a3a0eb973699b400fb6de4207a7fbc5b33f51523e5e94f954d0e6e60418ea95099883614495fce54d805a321cb65e883592048b73203a59b8f4e53d1bb975a07 - languageName: node - linkType: hard - -"jest-cli@npm:30.3.0": - version: 30.3.0 - resolution: "jest-cli@npm:30.3.0" - dependencies: - "@jest/core": "npm:30.3.0" - "@jest/test-result": "npm:30.3.0" - "@jest/types": "npm:30.3.0" - chalk: "npm:^4.1.2" - exit-x: "npm:^0.2.2" - import-local: "npm:^3.2.0" - jest-config: "npm:30.3.0" - jest-util: "npm:30.3.0" - jest-validate: "npm:30.3.0" - yargs: "npm:^17.7.2" - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - bin: - jest: ./bin/jest.js - checksum: 10c0/764d77551e0fb6d666212e89d01be6f7bb1a2b3adb918bba7c5c37593a11b01cf2af645506c2b6438335cfc79bfcf41bfd4680958d8ca751851752a7c66269d3 - languageName: node - linkType: hard - -"jest-config@npm:30.3.0": - version: 30.3.0 - resolution: "jest-config@npm:30.3.0" - dependencies: - "@babel/core": "npm:^7.27.4" - "@jest/get-type": "npm:30.1.0" - "@jest/pattern": "npm:30.0.1" - "@jest/test-sequencer": "npm:30.3.0" - "@jest/types": "npm:30.3.0" - babel-jest: "npm:30.3.0" - chalk: "npm:^4.1.2" - ci-info: "npm:^4.2.0" - deepmerge: "npm:^4.3.1" - glob: "npm:^10.5.0" - graceful-fs: "npm:^4.2.11" - jest-circus: "npm:30.3.0" - jest-docblock: "npm:30.2.0" - jest-environment-node: "npm:30.3.0" - jest-regex-util: "npm:30.0.1" - jest-resolve: "npm:30.3.0" - jest-runner: "npm:30.3.0" - jest-util: "npm:30.3.0" - jest-validate: "npm:30.3.0" - parse-json: "npm:^5.2.0" - pretty-format: "npm:30.3.0" - slash: "npm:^3.0.0" - strip-json-comments: "npm:^3.1.1" - peerDependencies: - "@types/node": "*" - esbuild-register: ">=3.4.0" - ts-node: ">=9.0.0" - peerDependenciesMeta: - "@types/node": - optional: true - esbuild-register: - optional: true - ts-node: - optional: true - checksum: 10c0/157607e5ac5e83924df97d992fbd40a1540af07c5a7be296fae49455b3729687847304f3b4a9112e7da17593b76cec3453cd55c1ecd4334f7318f2489d7d10a1 - languageName: node - linkType: hard - -"jest-diff@npm:30.3.0": - version: 30.3.0 - resolution: "jest-diff@npm:30.3.0" - dependencies: - "@jest/diff-sequences": "npm:30.3.0" - "@jest/get-type": "npm:30.1.0" - chalk: "npm:^4.1.2" - pretty-format: "npm:30.3.0" - checksum: 10c0/573a2a1a155b95fbde547d8ee33a5375179a8d03d4586025478dac16d695e4614aef075c3afa57e0f3a96cea8f638fa68a55c1e625f6e86b4f5b9e5850311ffb - languageName: node - linkType: hard - -"jest-docblock@npm:30.2.0": - version: 30.2.0 - resolution: "jest-docblock@npm:30.2.0" - dependencies: - detect-newline: "npm:^3.1.0" - checksum: 10c0/2578366604eef1b36d59ffe1fc52a710995571535d437f83d94ff94756a83f78e699c1ba004c38a34c01859d669fd6c64e865c23c5a7d5bf4837cfca4bef3dda - languageName: node - linkType: hard - -"jest-each@npm:30.3.0": - version: 30.3.0 - resolution: "jest-each@npm:30.3.0" - dependencies: - "@jest/get-type": "npm:30.1.0" - "@jest/types": "npm:30.3.0" - chalk: "npm:^4.1.2" - jest-util: "npm:30.3.0" - pretty-format: "npm:30.3.0" - checksum: 10c0/d23d2b43b3ea42beaf99648e2cf1c74b8a13c3e45c7c882979171471c225f7d666cb4a0d5f1ff9031b4504866fa3badc7266ffd885d3d8035420c559a31501e1 - languageName: node - linkType: hard - -"jest-environment-jsdom@npm:^30.3.0": - version: 30.3.0 - resolution: "jest-environment-jsdom@npm:30.3.0" - dependencies: - "@jest/environment": "npm:30.3.0" - "@jest/environment-jsdom-abstract": "npm:30.3.0" - jsdom: "npm:^26.1.0" - peerDependencies: - canvas: ^3.0.0 - peerDependenciesMeta: - canvas: - optional: true - checksum: 10c0/1d9a288c847dc7d3fe0ac4bd494fa5f78581d5f7f1f28fd1f58073634f139b6e4d13d1ea1bbed8e68693f45b74279fb7ea002dd453faa98ab6ab657c443cc0ce - languageName: node - linkType: hard - -"jest-environment-node@npm:30.3.0": - version: 30.3.0 - resolution: "jest-environment-node@npm:30.3.0" - dependencies: - "@jest/environment": "npm:30.3.0" - "@jest/fake-timers": "npm:30.3.0" - "@jest/types": "npm:30.3.0" - "@types/node": "npm:*" - jest-mock: "npm:30.3.0" - jest-util: "npm:30.3.0" - jest-validate: "npm:30.3.0" - checksum: 10c0/2a4be80861e569fa11456d89ff2aaedd71726ae02ade8f2cc6fbc86ba8749e24c37864676c4718fc08a40f6e6d2b2b51bc48d715b09b1e93e15e42e4a10f7b5b - languageName: node - linkType: hard - -"jest-haste-map@npm:30.3.0": - version: 30.3.0 - resolution: "jest-haste-map@npm:30.3.0" - dependencies: - "@jest/types": "npm:30.3.0" - "@types/node": "npm:*" - anymatch: "npm:^3.1.3" - fb-watchman: "npm:^2.0.2" - fsevents: "npm:^2.3.3" - graceful-fs: "npm:^4.2.11" - jest-regex-util: "npm:30.0.1" - jest-util: "npm:30.3.0" - jest-worker: "npm:30.3.0" - picomatch: "npm:^4.0.3" - walker: "npm:^1.0.8" - dependenciesMeta: - fsevents: - optional: true - checksum: 10c0/b9ef350082b15d4c119d6188f781024d859d6cfb17ae25d15c90c3a373234e16109afbeffdcf1af4baf6a85eb0cbbab00439c981ad43037c0f05d89ff98bd1af - languageName: node - linkType: hard - -"jest-leak-detector@npm:30.3.0": - version: 30.3.0 - resolution: "jest-leak-detector@npm:30.3.0" - dependencies: - "@jest/get-type": "npm:30.1.0" - pretty-format: "npm:30.3.0" - checksum: 10c0/a648c082b74e6c7d0c2e890002094ba97b108398fa3d0316958fc74321aa7b0824507a685d261a463856f219a724b86a6073bac86d351cf0675ecf962c1ee0ca - languageName: node - linkType: hard - -"jest-matcher-utils@npm:30.3.0": - version: 30.3.0 - resolution: "jest-matcher-utils@npm:30.3.0" - dependencies: - "@jest/get-type": "npm:30.1.0" - chalk: "npm:^4.1.2" - jest-diff: "npm:30.3.0" - pretty-format: "npm:30.3.0" - checksum: 10c0/4c5f4b6435964110e64c4b5b42e3553fffe303ecdd68021147a7bcc72914aec3a899867c50db22b250c72aded53e3f7a9f64d83c9dca2e65ce27f36d23c6ca78 - languageName: node - linkType: hard - -"jest-message-util@npm:30.3.0": - version: 30.3.0 - resolution: "jest-message-util@npm:30.3.0" - dependencies: - "@babel/code-frame": "npm:^7.27.1" - "@jest/types": "npm:30.3.0" - "@types/stack-utils": "npm:^2.0.3" - chalk: "npm:^4.1.2" - graceful-fs: "npm:^4.2.11" - picomatch: "npm:^4.0.3" - pretty-format: "npm:30.3.0" - slash: "npm:^3.0.0" - stack-utils: "npm:^2.0.6" - checksum: 10c0/6ce611caef76394872b23a111286b48e56f42655d14a5fbd0629d9b7437ed892e85ad96b15864bc22185c24ef670afb6665c57b9729458a36d50ffe8310f0926 + resolution: "isarray@npm:2.0.5" + checksum: 10c0/4199f14a7a13da2177c66c31080008b7124331956f47bca57dd0b6ea9f11687aa25e565a2c7a2b519bc86988d10398e3049a1f5df13c9f6b7664154690ae79fd languageName: node linkType: hard -"jest-mock@npm:30.3.0": - version: 30.3.0 - resolution: "jest-mock@npm:30.3.0" - dependencies: - "@jest/types": "npm:30.3.0" - "@types/node": "npm:*" - jest-util: "npm:30.3.0" - checksum: 10c0/9d95d550c6c998a85887c48ff5ee26de4bca18be91462ea8a8135d6023d591132465756f74981ca39b60f8708dfe38213a55bd4b619798a7b9438ca10d718099 +"isexe@npm:^2.0.0": + version: 2.0.0 + resolution: "isexe@npm:2.0.0" + checksum: 10c0/228cfa503fadc2c31596ab06ed6aa82c9976eec2bfd83397e7eaf06d0ccf42cd1dfd6743bf9aeb01aebd4156d009994c5f76ea898d2832c1fe342da923ca457d languageName: node linkType: hard -"jest-pnp-resolver@npm:^1.2.3": - version: 1.2.3 - resolution: "jest-pnp-resolver@npm:1.2.3" - peerDependencies: - jest-resolve: "*" - peerDependenciesMeta: - jest-resolve: - optional: true - checksum: 10c0/86eec0c78449a2de733a6d3e316d49461af6a858070e113c97f75fb742a48c2396ea94150cbca44159ffd4a959f743a47a8b37a792ef6fdad2cf0a5cba973fac +"isexe@npm:^4.0.0": + version: 4.0.0 + resolution: "isexe@npm:4.0.0" + checksum: 10c0/5884815115bceac452877659a9c7726382531592f43dc29e5d48b7c4100661aed54018cb90bd36cb2eaeba521092570769167acbb95c18d39afdccbcca06c5ce languageName: node linkType: hard -"jest-regex-util@npm:30.0.1": - version: 30.0.1 - resolution: "jest-regex-util@npm:30.0.1" - checksum: 10c0/f30c70524ebde2d1012afe5ffa5691d5d00f7d5ba9e43d588f6460ac6fe96f9e620f2f9b36a02d0d3e7e77bc8efb8b3450ae3b80ac53c8be5099e01bf54f6728 +"isobject@npm:^2.0.0": + version: 2.1.0 + resolution: "isobject@npm:2.1.0" + dependencies: + isarray: "npm:1.0.0" + checksum: 10c0/c4cafec73b3b2ee11be75dff8dafd283b5728235ac099b07d7873d5182553a707768e208327bbc12931b9422d8822280bf88d894a0024ff5857b3efefb480e7b languageName: node linkType: hard -"jest-resolve-dependencies@npm:30.3.0": - version: 30.3.0 - resolution: "jest-resolve-dependencies@npm:30.3.0" - dependencies: - jest-regex-util: "npm:30.0.1" - jest-snapshot: "npm:30.3.0" - checksum: 10c0/25dde0c8c050bc3437332f37ab87484f597596b80ece77a93e4da2b466b42e45cc5ad748270c1477587536de15eea1ffe83a32638e824b120830c3a87c9a5b71 +"isobject@npm:^3.0.1": + version: 3.0.1 + resolution: "isobject@npm:3.0.1" + checksum: 10c0/03344f5064a82f099a0cd1a8a407f4c0d20b7b8485e8e816c39f249e9416b06c322e8dec5b842b6bb8a06de0af9cb48e7bc1b5352f0fadc2f0abac033db3d4db languageName: node linkType: hard -"jest-resolve@npm:30.3.0": - version: 30.3.0 - resolution: "jest-resolve@npm:30.3.0" - dependencies: - chalk: "npm:^4.1.2" - graceful-fs: "npm:^4.2.11" - jest-haste-map: "npm:30.3.0" - jest-pnp-resolver: "npm:^1.2.3" - jest-util: "npm:30.3.0" - jest-validate: "npm:30.3.0" - slash: "npm:^3.0.0" - unrs-resolver: "npm:^1.7.11" - checksum: 10c0/540f59f160c232c1b922b111a93f24ef5202d75e00f2e994de976badf6e88879893b474320ff363a6b97259a7a208b6a4f5eeabede787eea9b7912a12ac64b1b +"isstream@npm:~0.1.2": + version: 0.1.2 + resolution: "isstream@npm:0.1.2" + checksum: 10c0/a6686a878735ca0a48e0d674dd6d8ad31aedfaf70f07920da16ceadc7577b46d67179a60b313f2e6860cb097a2c2eb3cbd0b89e921ae89199a59a17c3273d66f languageName: node linkType: hard -"jest-runner@npm:30.3.0": - version: 30.3.0 - resolution: "jest-runner@npm:30.3.0" - dependencies: - "@jest/console": "npm:30.3.0" - "@jest/environment": "npm:30.3.0" - "@jest/test-result": "npm:30.3.0" - "@jest/transform": "npm:30.3.0" - "@jest/types": "npm:30.3.0" - "@types/node": "npm:*" - chalk: "npm:^4.1.2" - emittery: "npm:^0.13.1" - exit-x: "npm:^0.2.2" - graceful-fs: "npm:^4.2.11" - jest-docblock: "npm:30.2.0" - jest-environment-node: "npm:30.3.0" - jest-haste-map: "npm:30.3.0" - jest-leak-detector: "npm:30.3.0" - jest-message-util: "npm:30.3.0" - jest-resolve: "npm:30.3.0" - jest-runtime: "npm:30.3.0" - jest-util: "npm:30.3.0" - jest-watcher: "npm:30.3.0" - jest-worker: "npm:30.3.0" - p-limit: "npm:^3.1.0" - source-map-support: "npm:0.5.13" - checksum: 10c0/6fb205f48541658f0b23b6c9a6730f0133f07c994a22ef506ebfcded5bbb444b655ac828074157e6579e664609a46f6a5bf3d366b694c6c8b523b5207a70499c - languageName: node - linkType: hard - -"jest-runtime@npm:30.3.0": - version: 30.3.0 - resolution: "jest-runtime@npm:30.3.0" - dependencies: - "@jest/environment": "npm:30.3.0" - "@jest/fake-timers": "npm:30.3.0" - "@jest/globals": "npm:30.3.0" - "@jest/source-map": "npm:30.0.1" - "@jest/test-result": "npm:30.3.0" - "@jest/transform": "npm:30.3.0" - "@jest/types": "npm:30.3.0" - "@types/node": "npm:*" - chalk: "npm:^4.1.2" - cjs-module-lexer: "npm:^2.1.0" - collect-v8-coverage: "npm:^1.0.2" - glob: "npm:^10.5.0" - graceful-fs: "npm:^4.2.11" - jest-haste-map: "npm:30.3.0" - jest-message-util: "npm:30.3.0" - jest-mock: "npm:30.3.0" - jest-regex-util: "npm:30.0.1" - jest-resolve: "npm:30.3.0" - jest-snapshot: "npm:30.3.0" - jest-util: "npm:30.3.0" - slash: "npm:^3.0.0" - strip-bom: "npm:^4.0.0" - checksum: 10c0/79c486157a926d5be5c66356ad26cc3792cca1afb1490e255a550f52784b6c92eea42f1cb3b2c7565650ea777cf17ffc3f8e305d6b97888e7d273f6d7f282686 - languageName: node - linkType: hard - -"jest-snapshot@npm:30.3.0": - version: 30.3.0 - resolution: "jest-snapshot@npm:30.3.0" - dependencies: - "@babel/core": "npm:^7.27.4" - "@babel/generator": "npm:^7.27.5" - "@babel/plugin-syntax-jsx": "npm:^7.27.1" - "@babel/plugin-syntax-typescript": "npm:^7.27.1" - "@babel/types": "npm:^7.27.3" - "@jest/expect-utils": "npm:30.3.0" - "@jest/get-type": "npm:30.1.0" - "@jest/snapshot-utils": "npm:30.3.0" - "@jest/transform": "npm:30.3.0" - "@jest/types": "npm:30.3.0" - babel-preset-current-node-syntax: "npm:^1.2.0" - chalk: "npm:^4.1.2" - expect: "npm:30.3.0" - graceful-fs: "npm:^4.2.11" - jest-diff: "npm:30.3.0" - jest-matcher-utils: "npm:30.3.0" - jest-message-util: "npm:30.3.0" - jest-util: "npm:30.3.0" - pretty-format: "npm:30.3.0" - semver: "npm:^7.7.2" - synckit: "npm:^0.11.8" - checksum: 10c0/c1dd295d9d4962f2504c965575212fc62a358a849c66ab96b2f6e608ebdf6a6029ca505bb0693664a54a534e581883665d404a59976a5b46b1a1f88b537e96c5 +"istanbul-lib-coverage@npm:^3.0.0, istanbul-lib-coverage@npm:^3.2.2": + version: 3.2.2 + resolution: "istanbul-lib-coverage@npm:3.2.2" + checksum: 10c0/6c7ff2106769e5f592ded1fb418f9f73b4411fd5a084387a5410538332b6567cd1763ff6b6cadca9b9eb2c443cce2f7ea7d7f1b8d315f9ce58539793b1e0922b languageName: node linkType: hard -"jest-util@npm:30.3.0": - version: 30.3.0 - resolution: "jest-util@npm:30.3.0" +"istanbul-lib-report@npm:^3.0.0, istanbul-lib-report@npm:^3.0.1": + version: 3.0.1 + resolution: "istanbul-lib-report@npm:3.0.1" dependencies: - "@jest/types": "npm:30.3.0" - "@types/node": "npm:*" - chalk: "npm:^4.1.2" - ci-info: "npm:^4.2.0" - graceful-fs: "npm:^4.2.11" - picomatch: "npm:^4.0.3" - checksum: 10c0/eea6f39e52a8cb2b1a28bb315a90dc6a8e450fffed73bb5ef4489d02d86f7d91be600d83f1dcba22956b8ac5fefa8f1b250e636c8402d3e8b50a5eec8b5963b2 + istanbul-lib-coverage: "npm:^3.0.0" + make-dir: "npm:^4.0.0" + supports-color: "npm:^7.1.0" + checksum: 10c0/84323afb14392de8b6a5714bd7e9af845cfbd56cfe71ed276cda2f5f1201aea673c7111901227ee33e68e4364e288d73861eb2ed48f6679d1e69a43b6d9b3ba7 languageName: node linkType: hard -"jest-validate@npm:30.3.0": - version: 30.3.0 - resolution: "jest-validate@npm:30.3.0" +"istanbul-reports@npm:^3.2.0": + version: 3.2.0 + resolution: "istanbul-reports@npm:3.2.0" dependencies: - "@jest/get-type": "npm:30.1.0" - "@jest/types": "npm:30.3.0" - camelcase: "npm:^6.3.0" - chalk: "npm:^4.1.2" - leven: "npm:^3.1.0" - pretty-format: "npm:30.3.0" - checksum: 10c0/645629e9ae0926252dee26b0ad71b9f0392daa896328393479c63b1b13d2a70df4dac8b5053227c64e0120e930db1242897898c40706f135f20f73ef77fcf4f5 + html-escaper: "npm:^2.0.0" + istanbul-lib-report: "npm:^3.0.0" + checksum: 10c0/d596317cfd9c22e1394f22a8d8ba0303d2074fe2e971887b32d870e4b33f8464b10f8ccbe6847808f7db485f084eba09e6c2ed706b3a978e4b52f07085b8f9bc languageName: node linkType: hard -"jest-watcher@npm:30.3.0": - version: 30.3.0 - resolution: "jest-watcher@npm:30.3.0" +"iterator.prototype@npm:^1.1.5": + version: 1.1.5 + resolution: "iterator.prototype@npm:1.1.5" dependencies: - "@jest/test-result": "npm:30.3.0" - "@jest/types": "npm:30.3.0" - "@types/node": "npm:*" - ansi-escapes: "npm:^4.3.2" - chalk: "npm:^4.1.2" - emittery: "npm:^0.13.1" - jest-util: "npm:30.3.0" - string-length: "npm:^4.0.2" - checksum: 10c0/2631be5cc122fbf14cb0bb7566cdea6d6c432b984d8ef3c6385254bb6c378342e0754cbd2dfe094d80762d44bd1c7015de2ec2100eb6f192906619d8b229e1a5 + define-data-property: "npm:^1.1.4" + es-object-atoms: "npm:^1.0.0" + get-intrinsic: "npm:^1.2.6" + get-proto: "npm:^1.0.0" + has-symbols: "npm:^1.1.0" + set-function-name: "npm:^2.0.2" + checksum: 10c0/f7a262808e1b41049ab55f1e9c29af7ec1025a000d243b83edf34ce2416eedd56079b117fa59376bb4a724110690f13aa8427f2ee29a09eec63a7e72367626d0 languageName: node linkType: hard -"jest-worker@npm:30.3.0": - version: 30.3.0 - resolution: "jest-worker@npm:30.3.0" +"jackspeak@npm:^3.1.2": + version: 3.4.3 + resolution: "jackspeak@npm:3.4.3" dependencies: - "@types/node": "npm:*" - "@ungap/structured-clone": "npm:^1.3.0" - jest-util: "npm:30.3.0" - merge-stream: "npm:^2.0.0" - supports-color: "npm:^8.1.1" - checksum: 10c0/25dfb1bc43d389e1daf8baad0ef7964249f001a7da7d92c61e398840424ca13fb1fb6242f6e021f0cbb37952f90371fb8be1ef0183b5d04ef161fdb8f09ee78e + "@isaacs/cliui": "npm:^8.0.2" + "@pkgjs/parseargs": "npm:^0.11.0" + dependenciesMeta: + "@pkgjs/parseargs": + optional: true + checksum: 10c0/6acc10d139eaefdbe04d2f679e6191b3abf073f111edf10b1de5302c97ec93fffeb2fdd8681ed17f16268aa9dd4f8c588ed9d1d3bffbbfa6e8bf897cbb3149b9 languageName: node linkType: hard @@ -11002,25 +10068,6 @@ __metadata: languageName: node linkType: hard -"jest@npm:^30.3.0": - version: 30.3.0 - resolution: "jest@npm:30.3.0" - dependencies: - "@jest/core": "npm:30.3.0" - "@jest/types": "npm:30.3.0" - import-local: "npm:^3.2.0" - jest-cli: "npm:30.3.0" - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - bin: - jest: ./bin/jest.js - checksum: 10c0/1f940424b741d1541c3d71e311f77c3cfaf31cff9ab2d53180333f00a31f157790a8d3d413b72b8dd2bb191aa75769fa741d9bc9085df779cd59689559a65815 - languageName: node - linkType: hard - "js-base64@npm:^2.1.9": version: 2.6.4 resolution: "js-base64@npm:2.6.4" @@ -11028,6 +10075,13 @@ __metadata: languageName: node linkType: hard +"js-tokens@npm:^10.0.0": + version: 10.0.0 + resolution: "js-tokens@npm:10.0.0" + checksum: 10c0/a93498747812ba3e0c8626f95f75ab29319f2a13613a0de9e610700405760931624433a0de59eb7c27ff8836e526768fb20783861b86ef89be96676f2c996b64 + languageName: node + linkType: hard + "js-tokens@npm:^3.0.0 || ^4.0.0, js-tokens@npm:^4.0.0": version: 4.0.0 resolution: "js-tokens@npm:4.0.0" @@ -11035,18 +10089,6 @@ __metadata: languageName: node linkType: hard -"js-yaml@npm:^3.13.1": - version: 3.14.2 - resolution: "js-yaml@npm:3.14.2" - dependencies: - argparse: "npm:^1.0.7" - esprima: "npm:^4.0.0" - bin: - js-yaml: bin/js-yaml.js - checksum: 10c0/3261f25912f5dd76605e5993d0a126c2b6c346311885d3c483706cd722efe34f697ea0331f654ce27c00a42b426e524518ec89d65ed02ea47df8ad26dcc8ce69 - languageName: node - linkType: hard - "js-yaml@npm:^3.9.0": version: 3.14.1 resolution: "js-yaml@npm:3.14.1" @@ -11077,36 +10119,37 @@ __metadata: languageName: node linkType: hard -"jsdom@npm:^26.1.0": - version: 26.1.0 - resolution: "jsdom@npm:26.1.0" +"jsdom@npm:^29.0.2": + version: 29.0.2 + resolution: "jsdom@npm:29.0.2" dependencies: - cssstyle: "npm:^4.2.1" - data-urls: "npm:^5.0.0" - decimal.js: "npm:^10.5.0" - html-encoding-sniffer: "npm:^4.0.0" - http-proxy-agent: "npm:^7.0.2" - https-proxy-agent: "npm:^7.0.6" + "@asamuzakjp/css-color": "npm:^5.1.5" + "@asamuzakjp/dom-selector": "npm:^7.0.6" + "@bramus/specificity": "npm:^2.4.2" + "@csstools/css-syntax-patches-for-csstree": "npm:^1.1.1" + "@exodus/bytes": "npm:^1.15.0" + css-tree: "npm:^3.2.1" + data-urls: "npm:^7.0.0" + decimal.js: "npm:^10.6.0" + html-encoding-sniffer: "npm:^6.0.0" is-potential-custom-element-name: "npm:^1.0.1" - nwsapi: "npm:^2.2.16" - parse5: "npm:^7.2.1" - rrweb-cssom: "npm:^0.8.0" + lru-cache: "npm:^11.2.7" + parse5: "npm:^8.0.0" saxes: "npm:^6.0.0" symbol-tree: "npm:^3.2.4" - tough-cookie: "npm:^5.1.1" + tough-cookie: "npm:^6.0.1" + undici: "npm:^7.24.5" w3c-xmlserializer: "npm:^5.0.0" - webidl-conversions: "npm:^7.0.0" - whatwg-encoding: "npm:^3.1.1" - whatwg-mimetype: "npm:^4.0.0" - whatwg-url: "npm:^14.1.1" - ws: "npm:^8.18.0" + webidl-conversions: "npm:^8.0.1" + whatwg-mimetype: "npm:^5.0.0" + whatwg-url: "npm:^16.0.1" xml-name-validator: "npm:^5.0.0" peerDependencies: canvas: ^3.0.0 peerDependenciesMeta: canvas: optional: true - checksum: 10c0/5b14a5bc32ce077a06fb42d1ab95b1191afa5cbbce8859e3b96831c5143becbbcbf0511d4d4934e922d2901443ced2cdc3b734c1cf30b5f73b3e067ce457d0f4 + checksum: 10c0/a325324117932de83d13f00c74ff91a5f6b4bbbf11f45e7e31189fea06d007f764aac286dad80f643430c81b618b9fb20eac1ef03f120cec4c68df271e7547e2 languageName: node linkType: hard @@ -11305,13 +10348,6 @@ __metadata: languageName: node linkType: hard -"leven@npm:^3.1.0": - version: 3.1.0 - resolution: "leven@npm:3.1.0" - checksum: 10c0/cd778ba3fbab0f4d0500b7e87d1f6e1f041507c56fdcd47e8256a3012c98aaee371d4c15e0a76e0386107af2d42e2b7466160a2d80688aaa03e66e49949f42df - languageName: node - linkType: hard - "levn@npm:^0.4.1": version: 0.4.1 resolution: "levn@npm:0.4.1" @@ -11322,6 +10358,126 @@ __metadata: languageName: node linkType: hard +"lightningcss-android-arm64@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss-android-arm64@npm:1.32.0" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"lightningcss-darwin-arm64@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss-darwin-arm64@npm:1.32.0" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"lightningcss-darwin-x64@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss-darwin-x64@npm:1.32.0" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"lightningcss-freebsd-x64@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss-freebsd-x64@npm:1.32.0" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"lightningcss-linux-arm-gnueabihf@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss-linux-arm-gnueabihf@npm:1.32.0" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"lightningcss-linux-arm64-gnu@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss-linux-arm64-gnu@npm:1.32.0" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"lightningcss-linux-arm64-musl@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss-linux-arm64-musl@npm:1.32.0" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"lightningcss-linux-x64-gnu@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss-linux-x64-gnu@npm:1.32.0" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"lightningcss-linux-x64-musl@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss-linux-x64-musl@npm:1.32.0" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"lightningcss-win32-arm64-msvc@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss-win32-arm64-msvc@npm:1.32.0" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"lightningcss-win32-x64-msvc@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss-win32-x64-msvc@npm:1.32.0" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"lightningcss@npm:^1.32.0": + version: 1.32.0 + resolution: "lightningcss@npm:1.32.0" + dependencies: + detect-libc: "npm:^2.0.3" + lightningcss-android-arm64: "npm:1.32.0" + lightningcss-darwin-arm64: "npm:1.32.0" + lightningcss-darwin-x64: "npm:1.32.0" + lightningcss-freebsd-x64: "npm:1.32.0" + lightningcss-linux-arm-gnueabihf: "npm:1.32.0" + lightningcss-linux-arm64-gnu: "npm:1.32.0" + lightningcss-linux-arm64-musl: "npm:1.32.0" + lightningcss-linux-x64-gnu: "npm:1.32.0" + lightningcss-linux-x64-musl: "npm:1.32.0" + lightningcss-win32-arm64-msvc: "npm:1.32.0" + lightningcss-win32-x64-msvc: "npm:1.32.0" + dependenciesMeta: + lightningcss-android-arm64: + optional: true + lightningcss-darwin-arm64: + optional: true + lightningcss-darwin-x64: + optional: true + lightningcss-freebsd-x64: + optional: true + lightningcss-linux-arm-gnueabihf: + optional: true + lightningcss-linux-arm64-gnu: + optional: true + lightningcss-linux-arm64-musl: + optional: true + lightningcss-linux-x64-gnu: + optional: true + lightningcss-linux-x64-musl: + optional: true + lightningcss-win32-arm64-msvc: + optional: true + lightningcss-win32-x64-msvc: + optional: true + checksum: 10c0/70945bd55097af46fc9fab7f5ed09cd5869d85940a2acab7ee06d0117004a1d68155708a2d462531cea2fc3c67aefc9333a7068c80b0b78dd404c16838809e03 + languageName: node + linkType: hard + "lilconfig@npm:^3.1.3": version: 3.1.3 resolution: "lilconfig@npm:3.1.3" @@ -11459,13 +10615,6 @@ __metadata: languageName: node linkType: hard -"lodash.memoize@npm:^4.1.2": - version: 4.1.2 - resolution: "lodash.memoize@npm:4.1.2" - checksum: 10c0/c8713e51eccc650422716a14cece1809cfe34bc5ab5e242b7f8b4e2241c2483697b971a604252807689b9dd69bfe3a98852e19a5b89d506b000b4187a1285df8 - languageName: node - linkType: hard - "lodash.merge@npm:^4.6.2": version: 4.6.2 resolution: "lodash.merge@npm:4.6.2" @@ -11560,7 +10709,7 @@ __metadata: languageName: node linkType: hard -"lru-cache@npm:^10.2.0, lru-cache@npm:^10.4.3": +"lru-cache@npm:^10.2.0": version: 10.4.3 resolution: "lru-cache@npm:10.4.3" checksum: 10c0/ebd04fbca961e6c1d6c0af3799adcc966a1babe798f685bb84e6599266599cd95d94630b10262f5424539bc4640107e8a33aa28585374abf561d30d16f4b39fb @@ -11574,6 +10723,13 @@ __metadata: languageName: node linkType: hard +"lru-cache@npm:^11.2.7": + version: 11.3.5 + resolution: "lru-cache@npm:11.3.5" + checksum: 10c0/5b54ef7b88afb4bd25b7a778f1b2b1cde32d9770913e530da34ab203cf0442413bcaa6e372800cbab9562557a4480e4d8bf32e3a368bb5a91b12218eca085c66 + languageName: node + linkType: hard + "lru-cache@npm:^4.0.1": version: 4.1.5 resolution: "lru-cache@npm:4.1.5" @@ -11602,6 +10758,26 @@ __metadata: languageName: node linkType: hard +"magic-string@npm:^0.30.21": + version: 0.30.21 + resolution: "magic-string@npm:0.30.21" + dependencies: + "@jridgewell/sourcemap-codec": "npm:^1.5.5" + checksum: 10c0/299378e38f9a270069fc62358522ddfb44e94244baa0d6a8980ab2a9b2490a1d03b236b447eee309e17eb3bddfa482c61259d47960eb018a904f0ded52780c4a + languageName: node + linkType: hard + +"magicast@npm:^0.5.2": + version: 0.5.2 + resolution: "magicast@npm:0.5.2" + dependencies: + "@babel/parser": "npm:^7.29.0" + "@babel/types": "npm:^7.29.0" + source-map-js: "npm:^1.2.1" + checksum: 10c0/924af677643c5a0a7d6cdb3247c0eb96fa7611b2ba6a5e720d35d81c503d3d9f5948eb5227f80f90f82ea3e7d38cffd10bb988f3fc09020db428e14f26e960d7 + languageName: node + linkType: hard + "make-dir@npm:^1.0.0": version: 1.3.0 resolution: "make-dir@npm:1.3.0" @@ -11620,7 +10796,7 @@ __metadata: languageName: node linkType: hard -"make-error@npm:^1.1.1, make-error@npm:^1.3.6": +"make-error@npm:^1.1.1": version: 1.3.6 resolution: "make-error@npm:1.3.6" checksum: 10c0/171e458d86854c6b3fc46610cfacf0b45149ba043782558c6875d9f42f222124384ad0b468c92e996d815a8a2003817a710c0a160e49c1c394626f76fa45396f @@ -11646,15 +10822,6 @@ __metadata: languageName: node linkType: hard -"makeerror@npm:1.0.12": - version: 1.0.12 - resolution: "makeerror@npm:1.0.12" - dependencies: - tmpl: "npm:1.0.5" - checksum: 10c0/b0e6e599780ce6bab49cc413eba822f7d1f0dfebd1c103eaa3785c59e43e22c59018323cf9e1708f0ef5329e94a745d163fcbb6bff8e4c6742f9be9e86f3500c - languageName: node - linkType: hard - "map-obj@npm:^1.0.0, map-obj@npm:^1.0.1": version: 1.0.1 resolution: "map-obj@npm:1.0.1" @@ -11748,6 +10915,13 @@ __metadata: languageName: node linkType: hard +"mdn-data@npm:2.27.1": + version: 2.27.1 + resolution: "mdn-data@npm:2.27.1" + checksum: 10c0/eb8abf5d22e4d1e090346f5e81b67d23cef14c83940e445da5c44541ad874dc8fb9f6ca236e8258c3a489d9fb5884188a4d7d58773adb9089ac2c0b966796393 + languageName: node + linkType: hard + "media-typer@npm:0.3.0": version: 0.3.0 resolution: "media-typer@npm:0.3.0" @@ -12233,6 +11407,39 @@ __metadata: languageName: node linkType: hard +"msw@npm:^2.13.6": + version: 2.13.6 + resolution: "msw@npm:2.13.6" + dependencies: + "@inquirer/confirm": "npm:^6.0.11" + "@mswjs/interceptors": "npm:^0.41.3" + "@open-draft/deferred-promise": "npm:^3.0.0" + "@types/statuses": "npm:^2.0.6" + cookie: "npm:^1.1.1" + graphql: "npm:^16.13.2" + headers-polyfill: "npm:^5.0.1" + is-node-process: "npm:^1.2.0" + outvariant: "npm:^1.4.3" + path-to-regexp: "npm:^6.3.0" + picocolors: "npm:^1.1.1" + rettime: "npm:^0.11.7" + statuses: "npm:^2.0.2" + strict-event-emitter: "npm:^0.5.1" + tough-cookie: "npm:^6.0.1" + type-fest: "npm:^5.5.0" + until-async: "npm:^3.0.2" + yargs: "npm:^17.7.2" + peerDependencies: + typescript: ">= 4.8.x" + peerDependenciesMeta: + typescript: + optional: true + bin: + msw: cli/index.js + checksum: 10c0/33f4c3b16aa290d2820cb2f0b33e05d414516b6a6e2cc15f7a8068e3b61247992985371719a9fb75a433c2b6455cb2d0a1d93446b8610a17601ab28cd3a8a9a2 + languageName: node + linkType: hard + "multicast-dns@npm:^7.2.5": version: 7.2.5 resolution: "multicast-dns@npm:7.2.5" @@ -12245,6 +11452,13 @@ __metadata: languageName: node linkType: hard +"mute-stream@npm:^3.0.0": + version: 3.0.0 + resolution: "mute-stream@npm:3.0.0" + checksum: 10c0/12cdb36a101694c7a6b296632e6d93a30b74401873cf7507c88861441a090c71c77a58f213acadad03bc0c8fa186639dec99d68a14497773a8744320c136e701 + languageName: node + linkType: hard + "nanoclone@npm:^0.2.1": version: 0.2.1 resolution: "nanoclone@npm:0.2.1" @@ -12261,15 +11475,6 @@ __metadata: languageName: node linkType: hard -"napi-postinstall@npm:^0.3.0": - version: 0.3.4 - resolution: "napi-postinstall@npm:0.3.4" - bin: - napi-postinstall: lib/cli.js - checksum: 10c0/b33d64150828bdade3a5d07368a8b30da22ee393f8dd8432f1b9e5486867be21c84ec443dd875dd3ef3c7401a079a7ab7e2aa9d3538a889abbcd96495d5104fe - languageName: node - linkType: hard - "natural-compare@npm:^1.4.0": version: 1.4.0 resolution: "natural-compare@npm:1.4.0" @@ -12337,13 +11542,6 @@ __metadata: languageName: node linkType: hard -"node-int64@npm:^0.4.0": - version: 0.4.0 - resolution: "node-int64@npm:0.4.0" - checksum: 10c0/a6a4d8369e2f2720e9c645255ffde909c0fbd41c92ea92a5607fc17055955daac99c1ff589d421eee12a0d24e99f7bfc2aabfeb1a4c14742f6c099a51863f31a - languageName: node - linkType: hard - "node-releases@npm:^2.0.27": version: 2.0.27 resolution: "node-releases@npm:2.0.27" @@ -12422,7 +11620,7 @@ __metadata: languageName: node linkType: hard -"npm-run-path@npm:^4.0.0, npm-run-path@npm:^4.0.1": +"npm-run-path@npm:^4.0.0": version: 4.0.1 resolution: "npm-run-path@npm:4.0.1" dependencies: @@ -12447,13 +11645,6 @@ __metadata: languageName: node linkType: hard -"nwsapi@npm:^2.2.16": - version: 2.2.23 - resolution: "nwsapi@npm:2.2.23" - checksum: 10c0/e44bfc9246baf659581206ed716d291a1905185247795fb8a302cb09315c943a31023b4ac4d026a5eaf32b2def51d77b3d0f9ebf4f3d35f70e105fcb6447c76e - languageName: node - linkType: hard - "object-assign@npm:^4.0.1, object-assign@npm:^4.1.0, object-assign@npm:^4.1.1": version: 4.1.1 resolution: "object-assign@npm:4.1.1" @@ -12552,6 +11743,13 @@ __metadata: languageName: node linkType: hard +"obug@npm:^2.1.1": + version: 2.1.1 + resolution: "obug@npm:2.1.1" + checksum: 10c0/59dccd7de72a047e08f8649e94c1015ec72f94eefb6ddb57fb4812c4b425a813bc7e7cd30c9aca20db3c59abc3c85cc7a62bb656a968741d770f4e8e02bc2e78 + languageName: node + linkType: hard + "on-finished@npm:^2.4.1, on-finished@npm:~2.4.1": version: 2.4.1 resolution: "on-finished@npm:2.4.1" @@ -12577,7 +11775,7 @@ __metadata: languageName: node linkType: hard -"onetime@npm:^5.1.0, onetime@npm:^5.1.2": +"onetime@npm:^5.1.0": version: 5.1.2 resolution: "onetime@npm:5.1.2" dependencies: @@ -12628,6 +11826,13 @@ __metadata: languageName: node linkType: hard +"outvariant@npm:^1.4.0, outvariant@npm:^1.4.3": + version: 1.4.3 + resolution: "outvariant@npm:1.4.3" + checksum: 10c0/5976ca7740349cb8c71bd3382e2a762b1aeca6f33dc984d9d896acdf3c61f78c3afcf1bfe9cc633a7b3c4b295ec94d292048f83ea2b2594fae4496656eba992c + languageName: node + linkType: hard + "own-keys@npm:^1.0.1": version: 1.0.1 resolution: "own-keys@npm:1.0.1" @@ -12664,7 +11869,7 @@ __metadata: languageName: node linkType: hard -"p-limit@npm:^3.0.2, p-limit@npm:^3.1.0": +"p-limit@npm:^3.0.2": version: 3.1.0 resolution: "p-limit@npm:3.1.0" dependencies: @@ -12854,7 +12059,7 @@ __metadata: languageName: node linkType: hard -"parse5@npm:^7.0.0, parse5@npm:^7.2.1, parse5@npm:^7.3.0": +"parse5@npm:^7.0.0, parse5@npm:^7.3.0": version: 7.3.0 resolution: "parse5@npm:7.3.0" dependencies: @@ -12863,6 +12068,15 @@ __metadata: languageName: node linkType: hard +"parse5@npm:^8.0.0": + version: 8.0.1 + resolution: "parse5@npm:8.0.1" + dependencies: + entities: "npm:^8.0.0" + checksum: 10c0/c3c1c5aab55f6e4be5245599790e56e64be7764a4a0edd7f98db4fe3bb380f63add752fa047dff0496446c25f4104f0c7c1967723de640bde92306a7bb67ed2f + languageName: node + linkType: hard + "parseurl@npm:~1.3.2, parseurl@npm:~1.3.3": version: 1.3.3 resolution: "parseurl@npm:1.3.3" @@ -12964,6 +12178,13 @@ __metadata: languageName: node linkType: hard +"path-to-regexp@npm:^6.3.0": + version: 6.3.0 + resolution: "path-to-regexp@npm:6.3.0" + checksum: 10c0/73b67f4638b41cde56254e6354e46ae3a2ebc08279583f6af3d96fe4664fc75788f74ed0d18ca44fa4a98491b69434f9eee73b97bb5314bd1b5adb700f5c18d6 + languageName: node + linkType: hard + "path-to-regexp@npm:~0.1.12": version: 0.1.12 resolution: "path-to-regexp@npm:0.1.12" @@ -12991,6 +12212,13 @@ __metadata: languageName: node linkType: hard +"pathe@npm:^2.0.3": + version: 2.0.3 + resolution: "pathe@npm:2.0.3" + checksum: 10c0/c118dc5a8b5c4166011b2b70608762e260085180bb9e33e80a50dcdb1e78c010b1624f4280c492c92b05fc276715a4c357d1f9edc570f8f1b3d90b6839ebaca1 + languageName: node + linkType: hard + "pend@npm:~1.2.0": version: 1.2.0 resolution: "pend@npm:1.2.0" @@ -13026,6 +12254,13 @@ __metadata: languageName: node linkType: hard +"picomatch@npm:^4.0.4": + version: 4.0.4 + resolution: "picomatch@npm:4.0.4" + checksum: 10c0/e2c6023372cc7b5764719a5ffb9da0f8e781212fa7ca4bd0562db929df8e117460f00dff3cb7509dacfc06b86de924b247f504d0ce1806a37fac4633081466b0 + languageName: node + linkType: hard + "pify@npm:^2.0.0, pify@npm:^2.2.0": version: 2.3.0 resolution: "pify@npm:2.3.0" @@ -13051,15 +12286,8 @@ __metadata: "pinkie@npm:^2.0.0": version: 2.0.4 - resolution: "pinkie@npm:2.0.4" - checksum: 10c0/25228b08b5597da42dc384221aa0ce56ee0fbf32965db12ba838e2a9ca0193c2f0609c45551ee077ccd2060bf109137fdb185b00c6d7e0ed7e35006d20fdcbc6 - languageName: node - linkType: hard - -"pirates@npm:^4.0.7": - version: 4.0.7 - resolution: "pirates@npm:4.0.7" - checksum: 10c0/a51f108dd811beb779d58a76864bbd49e239fa40c7984cd11596c75a121a8cc789f1c8971d8bb15f0dbf9d48b76c05bb62fcbce840f89b688c0fa64b37e8478a + resolution: "pinkie@npm:2.0.4" + checksum: 10c0/25228b08b5597da42dc384221aa0ce56ee0fbf32965db12ba838e2a9ca0193c2f0609c45551ee077ccd2060bf109137fdb185b00c6d7e0ed7e35006d20fdcbc6 languageName: node linkType: hard @@ -13326,6 +12554,17 @@ __metadata: languageName: node linkType: hard +"postcss@npm:^8.5.10": + version: 8.5.10 + resolution: "postcss@npm:8.5.10" + dependencies: + nanoid: "npm:^3.3.11" + picocolors: "npm:^1.1.1" + source-map-js: "npm:^1.2.1" + checksum: 10c0/c592dffa0c4873b401f01955b265538d9942f425040df5e2b8f0ad34c83773a792ea0fa5859ccc99cfb5b955b4ebff118ab7056315388dc83b107b0fa8313576 + languageName: node + linkType: hard + "prelude-ls@npm:^1.2.1": version: 1.2.1 resolution: "prelude-ls@npm:1.2.1" @@ -13405,17 +12644,6 @@ __metadata: languageName: node linkType: hard -"pretty-format@npm:30.3.0, pretty-format@npm:^30.0.0": - version: 30.3.0 - resolution: "pretty-format@npm:30.3.0" - dependencies: - "@jest/schemas": "npm:30.0.5" - ansi-styles: "npm:^5.2.0" - react-is: "npm:^18.3.1" - checksum: 10c0/719b27d70cd8b01013485054c5d094e1fe85e093b09ee73553e3b19302da3cf54fbd6a7ea9577d6471aeff8d372200e56979ffc4c831e2133520bd18060895fb - languageName: node - linkType: hard - "pretty-format@npm:^27.0.2": version: 27.5.1 resolution: "pretty-format@npm:27.5.1" @@ -13521,13 +12749,6 @@ __metadata: languageName: node linkType: hard -"pure-rand@npm:^7.0.0": - version: 7.0.1 - resolution: "pure-rand@npm:7.0.1" - checksum: 10c0/9cade41030f5ec95f5d55a11a71404cd6f46b69becaad892097cd7f58e2c6248cd0a933349ca7d21336ab629f1da42ffe899699b671bc4651600eaf6e57f837e - languageName: node - linkType: hard - "pvtsutils@npm:^1.3.6": version: 1.3.6 resolution: "pvtsutils@npm:1.3.6" @@ -13653,7 +12874,7 @@ __metadata: languageName: node linkType: hard -"react-dropzone@npm:^14.3.5": +"react-dropzone@npm:14.3.5, react-dropzone@npm:^14.3.5": version: 14.3.5 resolution: "react-dropzone@npm:14.3.5" dependencies: @@ -13698,13 +12919,6 @@ __metadata: languageName: node linkType: hard -"react-is@npm:^18.3.1": - version: 18.3.1 - resolution: "react-is@npm:18.3.1" - checksum: 10c0/f2f1e60010c683479e74c63f96b09fb41603527cd131a9959e2aee1e5a8b0caf270b365e5ca77d4a6b18aae659b60a86150bb3979073528877029b35aecd2072 - languageName: node - linkType: hard - "react-redux@npm:7.2.9": version: 7.2.9 resolution: "react-redux@npm:7.2.9" @@ -14330,6 +13544,13 @@ __metadata: languageName: node linkType: hard +"rettime@npm:^0.11.7": + version: 0.11.8 + resolution: "rettime@npm:0.11.8" + checksum: 10c0/a0e53133e5d3345a60ca4a86f29e5b67715ce6de61427eb5bdd223c41e80789f62a926f9efd9524dee38d3ab968444096564e29263a9abd61f1695fdd1114867 + languageName: node + linkType: hard + "reusify@npm:^1.0.4": version: 1.0.4 resolution: "reusify@npm:1.0.4" @@ -14384,10 +13605,61 @@ __metadata: languageName: node linkType: hard -"rrweb-cssom@npm:^0.8.0": - version: 0.8.0 - resolution: "rrweb-cssom@npm:0.8.0" - checksum: 10c0/56f2bfd56733adb92c0b56e274c43f864b8dd48784d6fe946ef5ff8d438234015e59ad837fc2ad54714b6421384141c1add4eb569e72054e350d1f8a50b8ac7b +"rolldown@npm:1.0.0-rc.17": + version: 1.0.0-rc.17 + resolution: "rolldown@npm:1.0.0-rc.17" + dependencies: + "@oxc-project/types": "npm:=0.127.0" + "@rolldown/binding-android-arm64": "npm:1.0.0-rc.17" + "@rolldown/binding-darwin-arm64": "npm:1.0.0-rc.17" + "@rolldown/binding-darwin-x64": "npm:1.0.0-rc.17" + "@rolldown/binding-freebsd-x64": "npm:1.0.0-rc.17" + "@rolldown/binding-linux-arm-gnueabihf": "npm:1.0.0-rc.17" + "@rolldown/binding-linux-arm64-gnu": "npm:1.0.0-rc.17" + "@rolldown/binding-linux-arm64-musl": "npm:1.0.0-rc.17" + "@rolldown/binding-linux-ppc64-gnu": "npm:1.0.0-rc.17" + "@rolldown/binding-linux-s390x-gnu": "npm:1.0.0-rc.17" + "@rolldown/binding-linux-x64-gnu": "npm:1.0.0-rc.17" + "@rolldown/binding-linux-x64-musl": "npm:1.0.0-rc.17" + "@rolldown/binding-openharmony-arm64": "npm:1.0.0-rc.17" + "@rolldown/binding-wasm32-wasi": "npm:1.0.0-rc.17" + "@rolldown/binding-win32-arm64-msvc": "npm:1.0.0-rc.17" + "@rolldown/binding-win32-x64-msvc": "npm:1.0.0-rc.17" + "@rolldown/pluginutils": "npm:1.0.0-rc.17" + dependenciesMeta: + "@rolldown/binding-android-arm64": + optional: true + "@rolldown/binding-darwin-arm64": + optional: true + "@rolldown/binding-darwin-x64": + optional: true + "@rolldown/binding-freebsd-x64": + optional: true + "@rolldown/binding-linux-arm-gnueabihf": + optional: true + "@rolldown/binding-linux-arm64-gnu": + optional: true + "@rolldown/binding-linux-arm64-musl": + optional: true + "@rolldown/binding-linux-ppc64-gnu": + optional: true + "@rolldown/binding-linux-s390x-gnu": + optional: true + "@rolldown/binding-linux-x64-gnu": + optional: true + "@rolldown/binding-linux-x64-musl": + optional: true + "@rolldown/binding-openharmony-arm64": + optional: true + "@rolldown/binding-wasm32-wasi": + optional: true + "@rolldown/binding-win32-arm64-msvc": + optional: true + "@rolldown/binding-win32-x64-msvc": + optional: true + bin: + rolldown: bin/cli.mjs + checksum: 10c0/bb99abc62ece4e34edd06d2b8eb9ffb7194dc2f0465a4329bb106cbde3006a10f1575e3580b198b793341109a2109581aed623c537c12b0c3a4ba0d72169b2fb languageName: node linkType: hard @@ -14567,7 +13839,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.3, semver@npm:^7.7.2, semver@npm:^7.7.3": +"semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.5.3, semver@npm:^7.6.3, semver@npm:^7.7.3": version: 7.7.4 resolution: "semver@npm:7.7.4" bin: @@ -14640,6 +13912,13 @@ __metadata: languageName: node linkType: hard +"set-cookie-parser@npm:^3.0.1": + version: 3.1.0 + resolution: "set-cookie-parser@npm:3.1.0" + checksum: 10c0/7465e389ff9fb7ff243fd55f0f48b5648d53a560903db170a7f766c2b82f22f4242c4d366fcdf12afdd376496f84058025d889e718459256ecbfc9a5fe7755f5 + languageName: node + linkType: hard + "set-function-length@npm:^1.2.2": version: 1.2.2 resolution: "set-function-length@npm:1.2.2" @@ -14787,14 +14066,21 @@ __metadata: languageName: node linkType: hard -"signal-exit@npm:^3.0.0, signal-exit@npm:^3.0.2, signal-exit@npm:^3.0.3": +"siginfo@npm:^2.0.0": + version: 2.0.0 + resolution: "siginfo@npm:2.0.0" + checksum: 10c0/3def8f8e516fbb34cb6ae415b07ccc5d9c018d85b4b8611e3dc6f8be6d1899f693a4382913c9ed51a06babb5201639d76453ab297d1c54a456544acf5c892e34 + languageName: node + linkType: hard + +"signal-exit@npm:^3.0.0, signal-exit@npm:^3.0.2": version: 3.0.7 resolution: "signal-exit@npm:3.0.7" checksum: 10c0/25d272fa73e146048565e08f3309d5b942c1979a6f4a58a8c59d5fa299728e9c2fcd1a759ec870863b1fd38653670240cd420dad2ad9330c71f36608a6a1c912 languageName: node linkType: hard -"signal-exit@npm:^4.0.1": +"signal-exit@npm:^4.0.1, signal-exit@npm:^4.1.0": version: 4.1.0 resolution: "signal-exit@npm:4.1.0" checksum: 10c0/41602dce540e46d599edba9d9860193398d135f7ff72cab629db5171516cfae628d21e7bfccde1bbfdf11c48726bc2a6d1a8fb8701125852fbfda7cf19c6aa83 @@ -14808,13 +14094,6 @@ __metadata: languageName: node linkType: hard -"slash@npm:^3.0.0": - version: 3.0.0 - resolution: "slash@npm:3.0.0" - checksum: 10c0/e18488c6a42bdfd4ac5be85b2ced3ccd0224773baae6ad42cfbb9ec74fc07f9fa8396bd35ee638084ead7a2a0818eb5e7151111544d4731ce843019dab4be47b - languageName: node - linkType: hard - "slash@npm:^5.1.0": version: 5.1.0 resolution: "slash@npm:5.1.0" @@ -14908,16 +14187,6 @@ __metadata: languageName: node linkType: hard -"source-map-support@npm:0.5.13": - version: 0.5.13 - resolution: "source-map-support@npm:0.5.13" - dependencies: - buffer-from: "npm:^1.0.0" - source-map: "npm:^0.6.0" - checksum: 10c0/137539f8c453fa0f496ea42049ab5da4569f96781f6ac8e5bfda26937be9494f4e8891f523c5f98f0e85f71b35d74127a00c46f83f6a4f54672b58d53202565e - languageName: node - linkType: hard - "source-map-support@npm:~0.5.20": version: 0.5.20 resolution: "source-map-support@npm:0.5.20" @@ -15063,12 +14332,17 @@ __metadata: languageName: node linkType: hard -"stack-utils@npm:^2.0.6": - version: 2.0.6 - resolution: "stack-utils@npm:2.0.6" - dependencies: - escape-string-regexp: "npm:^2.0.0" - checksum: 10c0/651c9f87667e077584bbe848acaecc6049bc71979f1e9a46c7b920cad4431c388df0f51b8ad7cfd6eed3db97a2878d0fc8b3122979439ea8bac29c61c95eec8a +"stackback@npm:0.0.2": + version: 0.0.2 + resolution: "stackback@npm:0.0.2" + checksum: 10c0/89a1416668f950236dd5ac9f9a6b2588e1b9b62b1b6ad8dff1bfc5d1a15dbf0aafc9b52d2226d00c28dffff212da464eaeebfc6b7578b9d180cef3e3782c5983 + languageName: node + linkType: hard + +"state-local@npm:^1.0.6": + version: 1.0.7 + resolution: "state-local@npm:1.0.7" + checksum: 10c0/8dc7daeac71844452fafb514a6d6b6f40d7e2b33df398309ea1c7b3948d6110c57f112b7196500a10c54fdde40291488c52c875575670fb5c819602deca48bd9 languageName: node linkType: hard @@ -15086,13 +14360,20 @@ __metadata: languageName: node linkType: hard -"statuses@npm:~2.0.1, statuses@npm:~2.0.2": +"statuses@npm:^2.0.2, statuses@npm:~2.0.1, statuses@npm:~2.0.2": version: 2.0.2 resolution: "statuses@npm:2.0.2" checksum: 10c0/a9947d98ad60d01f6b26727570f3bcceb6c8fa789da64fe6889908fe2e294d57503b14bf2b5af7605c2d36647259e856635cd4c49eab41667658ec9d0080ec3f languageName: node linkType: hard +"std-env@npm:^4.0.0-rc.1": + version: 4.1.0 + resolution: "std-env@npm:4.1.0" + checksum: 10c0/2e14b6b490db34cb969a48d9cf7c35bca4a47653914aac2814221baae7b867a5b15940d133625c391621971f98cd2266a5dc7036669960e883f1081db2a56558 + languageName: node + linkType: hard + "stop-iteration-iterator@npm:^1.0.0, stop-iteration-iterator@npm:^1.1.0": version: 1.1.0 resolution: "stop-iteration-iterator@npm:1.1.0" @@ -15123,13 +14404,10 @@ __metadata: languageName: node linkType: hard -"string-length@npm:^4.0.2": - version: 4.0.2 - resolution: "string-length@npm:4.0.2" - dependencies: - char-regex: "npm:^1.0.2" - strip-ansi: "npm:^6.0.0" - checksum: 10c0/1cd77409c3d7db7bc59406f6bcc9ef0783671dcbabb23597a1177c166906ef2ee7c8290f78cae73a8aec858768f189d2cb417797df5e15ec4eb5e16b3346340c +"strict-event-emitter@npm:^0.5.1": + version: 0.5.1 + resolution: "strict-event-emitter@npm:0.5.1" + checksum: 10c0/f5228a6e6b6393c57f52f62e673cfe3be3294b35d6f7842fc24b172ae0a6e6c209fa83241d0e433fc267c503bc2f4ffdbe41a9990ff8ffd5ac425ec0489417f7 languageName: node linkType: hard @@ -15317,13 +14595,6 @@ __metadata: languageName: node linkType: hard -"strip-bom@npm:^4.0.0": - version: 4.0.0 - resolution: "strip-bom@npm:4.0.0" - checksum: 10c0/26abad1172d6bc48985ab9a5f96c21e440f6e7e476686de49be813b5a59b3566dccb5c525b831ec54fe348283b47f3ffb8e080bc3f965fde12e84df23f6bb7ef - languageName: node - linkType: hard - "strip-eof@npm:^1.0.0": version: 1.0.0 resolution: "strip-eof@npm:1.0.0" @@ -15608,7 +14879,7 @@ __metadata: languageName: node linkType: hard -"synckit@npm:^0.11.12, synckit@npm:^0.11.8": +"synckit@npm:^0.11.12": version: 0.11.12 resolution: "synckit@npm:0.11.12" dependencies: @@ -15661,6 +14932,13 @@ __metadata: languageName: node linkType: hard +"tagged-tag@npm:^1.0.0": + version: 1.0.0 + resolution: "tagged-tag@npm:1.0.0" + checksum: 10c0/91d25c9ffb86a91f20522cefb2cbec9b64caa1febe27ad0df52f08993ff60888022d771e868e6416cf2e72dab68449d2139e8709ba009b74c6c7ecd4000048d1 + languageName: node + linkType: hard + "tapable@npm:^2.3.0": version: 2.3.0 resolution: "tapable@npm:2.3.0" @@ -15781,17 +15059,6 @@ __metadata: languageName: node linkType: hard -"test-exclude@npm:^6.0.0": - version: 6.0.0 - resolution: "test-exclude@npm:6.0.0" - dependencies: - "@istanbuljs/schema": "npm:^0.1.2" - glob: "npm:^7.1.4" - minimatch: "npm:^3.0.4" - checksum: 10c0/019d33d81adff3f9f1bfcff18125fb2d3c65564f437d9be539270ee74b994986abb8260c7c2ce90e8f30162178b09dbbce33c6389273afac4f36069c48521f57 - languageName: node - linkType: hard - "text-decoder@npm:^1.1.0": version: 1.2.3 resolution: "text-decoder@npm:1.2.3" @@ -15862,6 +15129,20 @@ __metadata: languageName: node linkType: hard +"tinybench@npm:^2.9.0": + version: 2.9.0 + resolution: "tinybench@npm:2.9.0" + checksum: 10c0/c3500b0f60d2eb8db65250afe750b66d51623057ee88720b7f064894a6cb7eb93360ca824a60a31ab16dab30c7b1f06efe0795b352e37914a9d4bad86386a20c + languageName: node + linkType: hard + +"tinyexec@npm:^1.0.2": + version: 1.1.1 + resolution: "tinyexec@npm:1.1.1" + checksum: 10c0/48433cb32573a767e2b63bb92343cbbae4240d05a19a63f7869f9447491305e7bd82d11daccb79b2628b596ad703a25798226c50bfd1d8e63477fb42af6a5b35 + languageName: node + linkType: hard + "tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.15": version: 0.2.15 resolution: "tinyglobby@npm:0.2.15" @@ -15872,6 +15153,23 @@ __metadata: languageName: node linkType: hard +"tinyglobby@npm:^0.2.16": + version: 0.2.16 + resolution: "tinyglobby@npm:0.2.16" + dependencies: + fdir: "npm:^6.5.0" + picomatch: "npm:^4.0.4" + checksum: 10c0/f2e09fd93dd95c41e522113b686ff6f7c13020962f8698a864a257f3d7737599afc47722b7ab726e12f8a813f779906187911ff8ee6701ede65072671a7e934b + languageName: node + linkType: hard + +"tinyrainbow@npm:^3.1.0": + version: 3.1.0 + resolution: "tinyrainbow@npm:3.1.0" + checksum: 10c0/f11cf387a26c5c9255bec141a90ac511b26172981b10c3e50053bc6700ea7d2336edcc4a3a21dbb8412fe7c013477d2ba4d7e4877800f3f8107be5105aad6511 + languageName: node + linkType: hard + "tldts-core@npm:^6.1.86": version: 6.1.86 resolution: "tldts-core@npm:6.1.86" @@ -15879,6 +15177,13 @@ __metadata: languageName: node linkType: hard +"tldts-core@npm:^7.0.28": + version: 7.0.28 + resolution: "tldts-core@npm:7.0.28" + checksum: 10c0/1fde2a2806c758d13c7eb2bd285a9482bf905829b38c060d66127e9e0682a103c42e181509f0d3c6da046e9aa2f71fe9d61afadb1b85a6b6c557cb98d6b7dede + languageName: node + linkType: hard + "tldts@npm:^6.1.32": version: 6.1.86 resolution: "tldts@npm:6.1.86" @@ -15890,6 +15195,17 @@ __metadata: languageName: node linkType: hard +"tldts@npm:^7.0.5": + version: 7.0.28 + resolution: "tldts@npm:7.0.28" + dependencies: + tldts-core: "npm:^7.0.28" + bin: + tldts: bin/cli.js + checksum: 10c0/37f92481bc7276f60f06d93d2671a67fd94dc8e245c232a50c69b8704d34c908658968f7298810e1b4df68a84be9ff6248867981d1cc7ddb08755565edd3f496 + languageName: node + linkType: hard + "tmp@npm:~0.2.4": version: 0.2.5 resolution: "tmp@npm:0.2.5" @@ -15897,13 +15213,6 @@ __metadata: languageName: node linkType: hard -"tmpl@npm:1.0.5": - version: 1.0.5 - resolution: "tmpl@npm:1.0.5" - checksum: 10c0/f935537799c2d1922cb5d6d3805f594388f75338fe7a4a9dac41504dd539704ca4db45b883b52e7b0aa5b2fd5ddadb1452bf95cd23a69da2f793a843f9451cc9 - languageName: node - linkType: hard - "to-regex-range@npm:^5.0.1": version: 5.0.1 resolution: "to-regex-range@npm:5.0.1" @@ -15936,7 +15245,7 @@ __metadata: languageName: node linkType: hard -"tough-cookie@npm:^5.0.0, tough-cookie@npm:^5.1.1": +"tough-cookie@npm:^5.0.0": version: 5.1.2 resolution: "tough-cookie@npm:5.1.2" dependencies: @@ -15945,12 +15254,21 @@ __metadata: languageName: node linkType: hard -"tr46@npm:^5.1.0": - version: 5.1.1 - resolution: "tr46@npm:5.1.1" +"tough-cookie@npm:^6.0.1": + version: 6.0.1 + resolution: "tough-cookie@npm:6.0.1" + dependencies: + tldts: "npm:^7.0.5" + checksum: 10c0/ec70bd6b1215efe4ed31a158f0be3e4c9088fcbd8620edc23a5860d4f3d85c757b77e274baaa700f7b25e409f4181552ed189603c2b2e1a9f88104da3a61a37d + languageName: node + linkType: hard + +"tr46@npm:^6.0.0": + version: 6.0.0 + resolution: "tr46@npm:6.0.0" dependencies: punycode: "npm:^2.3.1" - checksum: 10c0/ae270e194d52ec67ebd695c1a42876e0f19b96e4aca2ab464ab1d9d17dc3acd3e18764f5034c93897db73421563be27c70c98359c4501136a497e46deda5d5ec + checksum: 10c0/83130df2f649228aa91c17754b66248030a3af34911d713b5ea417066fa338aa4bc8668d06bd98aa21a2210f43fc0a3db8b9099e7747fb5830e40e39a6a1058e languageName: node linkType: hard @@ -16016,46 +15334,6 @@ __metadata: languageName: node linkType: hard -"ts-jest@npm:^29.4.6": - version: 29.4.6 - resolution: "ts-jest@npm:29.4.6" - dependencies: - bs-logger: "npm:^0.2.6" - fast-json-stable-stringify: "npm:^2.1.0" - handlebars: "npm:^4.7.8" - json5: "npm:^2.2.3" - lodash.memoize: "npm:^4.1.2" - make-error: "npm:^1.3.6" - semver: "npm:^7.7.3" - type-fest: "npm:^4.41.0" - yargs-parser: "npm:^21.1.1" - 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 - 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 - bin: - ts-jest: cli.js - checksum: 10c0/013dda99ac938cd4b94bae9323ed1b633cd295976c256d596d01776866188078fe7b82b8b3ebd05deb401b27b5618d9d76208eded2568661240ecf9694a5c933 - languageName: node - linkType: hard - "ts-loader@npm:^9.5.4": version: 9.5.4 resolution: "ts-loader@npm:9.5.4" @@ -16158,13 +15436,6 @@ __metadata: languageName: node linkType: hard -"type-detect@npm:4.0.8": - version: 4.0.8 - resolution: "type-detect@npm:4.0.8" - checksum: 10c0/8fb9a51d3f365a7de84ab7f73b653534b61b622aa6800aecdb0f1095a4a646d3f5eb295322127b6573db7982afcd40ab492d038cf825a42093a58b1e1353e0bd - languageName: node - linkType: hard - "type-fest@npm:^0.21.3": version: 0.21.3 resolution: "type-fest@npm:0.21.3" @@ -16186,10 +15457,12 @@ __metadata: languageName: node linkType: hard -"type-fest@npm:^4.41.0": - version: 4.41.0 - resolution: "type-fest@npm:4.41.0" - checksum: 10c0/f5ca697797ed5e88d33ac8f1fec21921839871f808dc59345c9cf67345bfb958ce41bd821165dbf3ae591cedec2bf6fe8882098dfdd8dc54320b859711a2c1e4 +"type-fest@npm:^5.5.0": + version: 5.6.0 + resolution: "type-fest@npm:5.6.0" + dependencies: + tagged-tag: "npm:^1.0.0" + checksum: 10c0/5468a8ffda7f3904e6f7bbd8069eb8b6dd4bd9156e206df7a01d09a73e28cd1afedf74ead9d0fc12841c8c90074194859feca240511c50800962fde1bd9ddcbc languageName: node linkType: hard @@ -16298,15 +15571,6 @@ __metadata: languageName: node linkType: hard -"uglify-js@npm:^3.1.4": - version: 3.19.3 - resolution: "uglify-js@npm:3.19.3" - bin: - uglifyjs: bin/uglifyjs - checksum: 10c0/83b0a90eca35f778e07cad9622b80c448b6aad457c9ff8e568afed978212b42930a95f9e1be943a1ffa4258a3340fbb899f41461131c05bb1d0a9c303aed8479 - languageName: node - linkType: hard - "unbox-primitive@npm:^1.1.0": version: 1.1.0 resolution: "unbox-primitive@npm:1.1.0" @@ -16343,6 +15607,13 @@ __metadata: languageName: node linkType: hard +"undici@npm:^7.24.5": + version: 7.25.0 + resolution: "undici@npm:7.25.0" + checksum: 10c0/02a0b45dc14eb91bc488948750232450fe52f27a6b08086d6ac6736bb47908d600fe3a96d346f12eab24729c782e5c2f693bc8e8eca6696d4e4c09b1ed4cb4ec + languageName: node + linkType: hard + "unherit@npm:^1.0.4": version: 1.1.3 resolution: "unherit@npm:1.1.3" @@ -16517,70 +15788,10 @@ __metadata: languageName: node linkType: hard -"unrs-resolver@npm:^1.7.11": - version: 1.11.1 - resolution: "unrs-resolver@npm:1.11.1" - dependencies: - "@unrs/resolver-binding-android-arm-eabi": "npm:1.11.1" - "@unrs/resolver-binding-android-arm64": "npm:1.11.1" - "@unrs/resolver-binding-darwin-arm64": "npm:1.11.1" - "@unrs/resolver-binding-darwin-x64": "npm:1.11.1" - "@unrs/resolver-binding-freebsd-x64": "npm:1.11.1" - "@unrs/resolver-binding-linux-arm-gnueabihf": "npm:1.11.1" - "@unrs/resolver-binding-linux-arm-musleabihf": "npm:1.11.1" - "@unrs/resolver-binding-linux-arm64-gnu": "npm:1.11.1" - "@unrs/resolver-binding-linux-arm64-musl": "npm:1.11.1" - "@unrs/resolver-binding-linux-ppc64-gnu": "npm:1.11.1" - "@unrs/resolver-binding-linux-riscv64-gnu": "npm:1.11.1" - "@unrs/resolver-binding-linux-riscv64-musl": "npm:1.11.1" - "@unrs/resolver-binding-linux-s390x-gnu": "npm:1.11.1" - "@unrs/resolver-binding-linux-x64-gnu": "npm:1.11.1" - "@unrs/resolver-binding-linux-x64-musl": "npm:1.11.1" - "@unrs/resolver-binding-wasm32-wasi": "npm:1.11.1" - "@unrs/resolver-binding-win32-arm64-msvc": "npm:1.11.1" - "@unrs/resolver-binding-win32-ia32-msvc": "npm:1.11.1" - "@unrs/resolver-binding-win32-x64-msvc": "npm:1.11.1" - napi-postinstall: "npm:^0.3.0" - dependenciesMeta: - "@unrs/resolver-binding-android-arm-eabi": - optional: true - "@unrs/resolver-binding-android-arm64": - optional: true - "@unrs/resolver-binding-darwin-arm64": - optional: true - "@unrs/resolver-binding-darwin-x64": - optional: true - "@unrs/resolver-binding-freebsd-x64": - optional: true - "@unrs/resolver-binding-linux-arm-gnueabihf": - optional: true - "@unrs/resolver-binding-linux-arm-musleabihf": - optional: true - "@unrs/resolver-binding-linux-arm64-gnu": - optional: true - "@unrs/resolver-binding-linux-arm64-musl": - optional: true - "@unrs/resolver-binding-linux-ppc64-gnu": - optional: true - "@unrs/resolver-binding-linux-riscv64-gnu": - optional: true - "@unrs/resolver-binding-linux-riscv64-musl": - optional: true - "@unrs/resolver-binding-linux-s390x-gnu": - optional: true - "@unrs/resolver-binding-linux-x64-gnu": - optional: true - "@unrs/resolver-binding-linux-x64-musl": - optional: true - "@unrs/resolver-binding-wasm32-wasi": - optional: true - "@unrs/resolver-binding-win32-arm64-msvc": - optional: true - "@unrs/resolver-binding-win32-ia32-msvc": - optional: true - "@unrs/resolver-binding-win32-x64-msvc": - optional: true - checksum: 10c0/c91b112c71a33d6b24e5c708dab43ab80911f2df8ee65b87cd7a18fb5af446708e98c4b415ca262026ad8df326debcc7ca6a801b2935504d87fd6f0b9d70dce1 +"until-async@npm:^3.0.2": + version: 3.0.2 + resolution: "until-async@npm:3.0.2" + checksum: 10c0/61c8b03895dbe18fe3d90316d0a1894e0c131ea4b1673f6ce78eed993d0bb81bbf4b7adf8477e9ff7725782a76767eed9d077561cfc9f89b4a1ebe61f7c9828e languageName: node linkType: hard @@ -16687,17 +15898,6 @@ __metadata: languageName: node linkType: hard -"v8-to-istanbul@npm:^9.0.1": - version: 9.3.0 - resolution: "v8-to-istanbul@npm:9.3.0" - dependencies: - "@jridgewell/trace-mapping": "npm:^0.3.12" - "@types/istanbul-lib-coverage": "npm:^2.0.1" - convert-source-map: "npm:^2.0.0" - checksum: 10c0/968bcf1c7c88c04df1ffb463c179558a2ec17aa49e49376120504958239d9e9dad5281aa05f2a78542b8557f2be0b0b4c325710262f3b838b40d703d5ed30c23 - languageName: node - linkType: hard - "validate-npm-package-license@npm:^3.0.1": version: 3.0.4 resolution: "validate-npm-package-license@npm:3.0.4" @@ -16826,6 +16026,131 @@ __metadata: languageName: node linkType: hard +"vite@npm:^6.0.0 || ^7.0.0 || ^8.0.0": + version: 8.0.10 + resolution: "vite@npm:8.0.10" + dependencies: + fsevents: "npm:~2.3.3" + lightningcss: "npm:^1.32.0" + picomatch: "npm:^4.0.4" + postcss: "npm:^8.5.10" + rolldown: "npm:1.0.0-rc.17" + tinyglobby: "npm:^0.2.16" + peerDependencies: + "@types/node": ^20.19.0 || >=22.12.0 + "@vitejs/devtools": ^0.1.0 + esbuild: ^0.27.0 || ^0.28.0 + jiti: ">=1.21.0" + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: ">=0.54.8" + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + dependenciesMeta: + fsevents: + optional: true + peerDependenciesMeta: + "@types/node": + optional: true + "@vitejs/devtools": + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + bin: + vite: bin/vite.js + checksum: 10c0/92188b82654f856dbe562a1b679de695bb6ca18c0f43c4c276f84a869fb78e22dedb7c2df83b5617d6afdca979c059d654b5f61a0936a45f49917f352b9325ca + languageName: node + linkType: hard + +"vitest@npm:^4.1.5": + version: 4.1.5 + resolution: "vitest@npm:4.1.5" + dependencies: + "@vitest/expect": "npm:4.1.5" + "@vitest/mocker": "npm:4.1.5" + "@vitest/pretty-format": "npm:4.1.5" + "@vitest/runner": "npm:4.1.5" + "@vitest/snapshot": "npm:4.1.5" + "@vitest/spy": "npm:4.1.5" + "@vitest/utils": "npm:4.1.5" + es-module-lexer: "npm:^2.0.0" + expect-type: "npm:^1.3.0" + magic-string: "npm:^0.30.21" + obug: "npm:^2.1.1" + pathe: "npm:^2.0.3" + picomatch: "npm:^4.0.3" + std-env: "npm:^4.0.0-rc.1" + tinybench: "npm:^2.9.0" + tinyexec: "npm:^1.0.2" + tinyglobby: "npm:^0.2.15" + tinyrainbow: "npm:^3.1.0" + vite: "npm:^6.0.0 || ^7.0.0 || ^8.0.0" + why-is-node-running: "npm:^2.3.0" + peerDependencies: + "@edge-runtime/vm": "*" + "@opentelemetry/api": ^1.9.0 + "@types/node": ^20.0.0 || ^22.0.0 || >=24.0.0 + "@vitest/browser-playwright": 4.1.5 + "@vitest/browser-preview": 4.1.5 + "@vitest/browser-webdriverio": 4.1.5 + "@vitest/coverage-istanbul": 4.1.5 + "@vitest/coverage-v8": 4.1.5 + "@vitest/ui": 4.1.5 + happy-dom: "*" + jsdom: "*" + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + "@edge-runtime/vm": + optional: true + "@opentelemetry/api": + optional: true + "@types/node": + optional: true + "@vitest/browser-playwright": + optional: true + "@vitest/browser-preview": + optional: true + "@vitest/browser-webdriverio": + optional: true + "@vitest/coverage-istanbul": + optional: true + "@vitest/coverage-v8": + optional: true + "@vitest/ui": + optional: true + happy-dom: + optional: true + jsdom: + optional: true + vite: + optional: false + bin: + vitest: vitest.mjs + checksum: 10c0/196eaf5e95b45a3f6d3001a2408d7dc6f146c29c873ed4e42e1ad4c9327122934fb3793a12b6ce3b7c25d355e738b20123acc0894ce30358c3370b15f4bd0865 + languageName: node + linkType: hard + "void-elements@npm:3.1.0": version: 3.1.0 resolution: "void-elements@npm:3.1.0" @@ -16854,15 +16179,6 @@ __metadata: languageName: node linkType: hard -"walker@npm:^1.0.8": - version: 1.0.8 - resolution: "walker@npm:1.0.8" - dependencies: - makeerror: "npm:1.0.12" - checksum: 10c0/a17e037bccd3ca8a25a80cb850903facdfed0de4864bd8728f1782370715d679fa72e0a0f5da7c1c1379365159901e5935f35be531229da53bbfc0efdabdb48e - languageName: node - linkType: hard - "watchpack@npm:^2.5.1": version: 2.5.1 resolution: "watchpack@npm:2.5.1" @@ -16894,10 +16210,10 @@ __metadata: languageName: node linkType: hard -"webidl-conversions@npm:^7.0.0": - version: 7.0.0 - resolution: "webidl-conversions@npm:7.0.0" - checksum: 10c0/228d8cb6d270c23b0720cb2d95c579202db3aaf8f633b4e9dd94ec2000a04e7e6e43b76a94509cdb30479bd00ae253ab2371a2da9f81446cc313f89a4213a2c4 +"webidl-conversions@npm:^8.0.1": + version: 8.0.1 + resolution: "webidl-conversions@npm:8.0.1" + checksum: 10c0/3f6f327ca5fa0c065ed8ed0ef3b72f33623376e68f958e9b7bd0df49fdb0b908139ac2338d19fb45bd0e05595bda96cb6d1622222a8b413daa38a17aacc4dd46 languageName: node linkType: hard @@ -17085,13 +16401,21 @@ __metadata: languageName: node linkType: hard -"whatwg-url@npm:^14.0.0, whatwg-url@npm:^14.1.1": - version: 14.2.0 - resolution: "whatwg-url@npm:14.2.0" +"whatwg-mimetype@npm:^5.0.0": + version: 5.0.0 + resolution: "whatwg-mimetype@npm:5.0.0" + checksum: 10c0/eead164fe73a00dd82f817af6fc0bd22e9c273e1d55bf4bc6bdf2da7ad8127fca82ef00ea6a37892f5f5641f8e34128e09508f92126086baba126b9e0d57feb4 + languageName: node + linkType: hard + +"whatwg-url@npm:^16.0.0, whatwg-url@npm:^16.0.1": + version: 16.0.1 + resolution: "whatwg-url@npm:16.0.1" dependencies: - tr46: "npm:^5.1.0" - webidl-conversions: "npm:^7.0.0" - checksum: 10c0/f746fc2f4c906607d09537de1227b13f9494c171141e5427ed7d2c0dd0b6a48b43d8e71abaae57d368d0c06b673fd8ec63550b32ad5ed64990c7b0266c2b4272 + "@exodus/bytes": "npm:^1.11.0" + tr46: "npm:^6.0.0" + webidl-conversions: "npm:^8.0.1" + checksum: 10c0/e75565566abf3a2cdbd9f06c965dbcccee6ec4e9f0d3728ad5e08ceb9944279848bcaa211d35a29cb6d2df1e467dd05cfb59fbddf8a0adcd7d0bce9ffb703fd2 languageName: node linkType: hard @@ -17189,6 +16513,18 @@ __metadata: languageName: node linkType: hard +"why-is-node-running@npm:^2.3.0": + version: 2.3.0 + resolution: "why-is-node-running@npm:2.3.0" + dependencies: + siginfo: "npm:^2.0.0" + stackback: "npm:0.0.2" + bin: + why-is-node-running: cli.js + checksum: 10c0/1cde0b01b827d2cf4cb11db962f3958b9175d5d9e7ac7361d1a7b0e2dc6069a263e69118bd974c4f6d0a890ef4eedfe34cf3d5167ec14203dbc9a18620537054 + languageName: node + linkType: hard + "widest-line@npm:^2.0.0": version: 2.0.1 resolution: "widest-line@npm:2.0.1" @@ -17212,13 +16548,6 @@ __metadata: languageName: node linkType: hard -"wordwrap@npm:^1.0.0": - version: 1.0.0 - resolution: "wordwrap@npm:1.0.0" - checksum: 10c0/7ed2e44f3c33c5c3e3771134d2b0aee4314c9e49c749e37f464bf69f2bcdf0cbf9419ca638098e2717cff4875c47f56a007532f6111c3319f557a2ca91278e92 - languageName: node - linkType: hard - "workerpool@npm:^9.2.0": version: 9.3.4 resolution: "workerpool@npm:9.3.4" @@ -17277,16 +16606,6 @@ __metadata: languageName: node linkType: hard -"write-file-atomic@npm:^5.0.1": - version: 5.0.1 - resolution: "write-file-atomic@npm:5.0.1" - dependencies: - imurmurhash: "npm:^0.1.4" - signal-exit: "npm:^4.0.1" - checksum: 10c0/e8c850a8e3e74eeadadb8ad23c9d9d63e4e792bd10f4836ed74189ef6e996763959f1249c5650e232f3c77c11169d239cbfc8342fc70f3fe401407d23810505d - languageName: node - linkType: hard - "write-file-atomic@npm:^7.0.0": version: 7.0.1 resolution: "write-file-atomic@npm:7.0.1"