From c930453afb01df1f8914464c1b503b2bd4030078 Mon Sep 17 00:00:00 2001 From: Graham Wheeler <> Date: Fri, 6 Feb 2026 10:58:06 -0800 Subject: [PATCH 1/4] Add test coverage plan and epics for Rust port preparation - Created 11 epics tracking test coverage needs - Added ~50 tasks covering all major pyright components - Created comprehensive documentation in docs/rust-port-test-coverage-plan.md - Identified components needing refactoring for testability Components covered: - Parser (tokenizer, parser, parse nodes) - Binder (scopes, symbols, declarations) - Type Evaluator (types, type utils, type printer) - Code Flow Engine (narrowing, reachability) - Checker (diagnostics, protocol checks) - Constraint Solver (TypeVar, ParamSpec, TypeVarTuple) - Import Resolver (module, package, stub resolution) - Program/Service (file management, incremental analysis) - Language Service (completions, hover, definitions) - Common Utilities (URI, path, text range) - Special Type Handlers (dataclass, namedtuple, typeddict) --- .beads/.gitignore | 44 +++ .beads/README.md | 81 ++++++ .beads/config.yaml | 62 +++++ .beads/interactions.jsonl | 0 .beads/issues.jsonl | 0 .beads/metadata.json | 4 + .gitattributes | 3 + docs/rust-port-test-coverage-plan.md | 400 +++++++++++++++++++++++++++ 8 files changed, 594 insertions(+) create mode 100644 .beads/.gitignore create mode 100644 .beads/README.md create mode 100644 .beads/config.yaml create mode 100644 .beads/interactions.jsonl create mode 100644 .beads/issues.jsonl create mode 100644 .beads/metadata.json create mode 100644 docs/rust-port-test-coverage-plan.md diff --git a/.beads/.gitignore b/.beads/.gitignore new file mode 100644 index 000000000000..d27a1db571d8 --- /dev/null +++ b/.beads/.gitignore @@ -0,0 +1,44 @@ +# SQLite databases +*.db +*.db?* +*.db-journal +*.db-wal +*.db-shm + +# Daemon runtime files +daemon.lock +daemon.log +daemon.pid +bd.sock +sync-state.json +last-touched + +# Local version tracking (prevents upgrade notification spam after git ops) +.local_version + +# Legacy database files +db.sqlite +bd.db + +# Worktree redirect file (contains relative path to main repo's .beads/) +# Must not be committed as paths would be wrong in other clones +redirect + +# Merge artifacts (temporary files from 3-way merge) +beads.base.jsonl +beads.base.meta.json +beads.left.jsonl +beads.left.meta.json +beads.right.jsonl +beads.right.meta.json + +# Sync state (local-only, per-machine) +# These files are machine-specific and should not be shared across clones +.sync.lock +sync_base.jsonl + +# NOTE: Do NOT add negation patterns (e.g., !issues.jsonl) here. +# They would override fork protection in .git/info/exclude, allowing +# contributors to accidentally commit upstream issue databases. +# The JSONL files (issues.jsonl, interactions.jsonl) and config files +# are tracked by git by default since no pattern above ignores them. diff --git a/.beads/README.md b/.beads/README.md new file mode 100644 index 000000000000..50f281f032bb --- /dev/null +++ b/.beads/README.md @@ -0,0 +1,81 @@ +# Beads - AI-Native Issue Tracking + +Welcome to Beads! This repository uses **Beads** for issue tracking - a modern, AI-native tool designed to live directly in your codebase alongside your code. + +## What is Beads? + +Beads is issue tracking that lives in your repo, making it perfect for AI coding agents and developers who want their issues close to their code. No web UI required - everything works through the CLI and integrates seamlessly with git. + +**Learn more:** [github.com/steveyegge/beads](https://github.com/steveyegge/beads) + +## Quick Start + +### Essential Commands + +```bash +# Create new issues +bd create "Add user authentication" + +# View all issues +bd list + +# View issue details +bd show + +# Update issue status +bd update --status in_progress +bd update --status done + +# Sync with git remote +bd sync +``` + +### Working with Issues + +Issues in Beads are: +- **Git-native**: Stored in `.beads/issues.jsonl` and synced like code +- **AI-friendly**: CLI-first design works perfectly with AI coding agents +- **Branch-aware**: Issues can follow your branch workflow +- **Always in sync**: Auto-syncs with your commits + +## Why Beads? + +โœจ **AI-Native Design** +- Built specifically for AI-assisted development workflows +- CLI-first interface works seamlessly with AI coding agents +- No context switching to web UIs + +๐Ÿš€ **Developer Focused** +- Issues live in your repo, right next to your code +- Works offline, syncs when you push +- Fast, lightweight, and stays out of your way + +๐Ÿ”ง **Git Integration** +- Automatic sync with git commits +- Branch-aware issue tracking +- Intelligent JSONL merge resolution + +## Get Started with Beads + +Try Beads in your own projects: + +```bash +# Install Beads +curl -sSL https://raw.githubusercontent.com/steveyegge/beads/main/scripts/install.sh | bash + +# Initialize in your repo +bd init + +# Create your first issue +bd create "Try out Beads" +``` + +## Learn More + +- **Documentation**: [github.com/steveyegge/beads/docs](https://github.com/steveyegge/beads/tree/main/docs) +- **Quick Start Guide**: Run `bd quickstart` +- **Examples**: [github.com/steveyegge/beads/examples](https://github.com/steveyegge/beads/tree/main/examples) + +--- + +*Beads: Issue tracking that moves at the speed of thought* โšก diff --git a/.beads/config.yaml b/.beads/config.yaml new file mode 100644 index 000000000000..1de3590ea1af --- /dev/null +++ b/.beads/config.yaml @@ -0,0 +1,62 @@ +# Beads Configuration File +# This file configures default behavior for all bd commands in this repository +# All settings can also be set via environment variables (BD_* prefix) +# or overridden with command-line flags + +# Issue prefix for this repository (used by bd init) +# If not set, bd init will auto-detect from directory name +# Example: issue-prefix: "myproject" creates issues like "myproject-1", "myproject-2", etc. +# issue-prefix: "" + +# Use no-db mode: load from JSONL, no SQLite, write back after each command +# When true, bd will use .beads/issues.jsonl as the source of truth +# instead of SQLite database +# no-db: false + +# Disable daemon for RPC communication (forces direct database access) +# no-daemon: false + +# Disable auto-flush of database to JSONL after mutations +# no-auto-flush: false + +# Disable auto-import from JSONL when it's newer than database +# no-auto-import: false + +# Enable JSON output by default +# json: false + +# Default actor for audit trails (overridden by BD_ACTOR or --actor) +# actor: "" + +# Path to database (overridden by BEADS_DB or --db) +# db: "" + +# Auto-start daemon if not running (can also use BEADS_AUTO_START_DAEMON) +# auto-start-daemon: true + +# Debounce interval for auto-flush (can also use BEADS_FLUSH_DEBOUNCE) +# flush-debounce: "5s" + +# Git branch for beads commits (bd sync will commit to this branch) +# IMPORTANT: Set this for team projects so all clones use the same sync branch. +# This setting persists across clones (unlike database config which is gitignored). +# Can also use BEADS_SYNC_BRANCH env var for local override. +# If not set, bd sync will require you to run 'bd config set sync.branch '. +sync-branch: "beads-sync" + +# Multi-repo configuration (experimental - bd-307) +# Allows hydrating from multiple repositories and routing writes to the correct JSONL +# repos: +# primary: "." # Primary repo (where this database lives) +# additional: # Additional repos to hydrate from (read-only) +# - ~/beads-planning # Personal planning repo +# - ~/work-planning # Work planning repo + +# Integration settings (access with 'bd config get/set') +# These are stored in the database, not in this file: +# - jira.url +# - jira.project +# - linear.url +# - linear.api-key +# - github.org +# - github.repo \ No newline at end of file diff --git a/.beads/interactions.jsonl b/.beads/interactions.jsonl new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/.beads/metadata.json b/.beads/metadata.json new file mode 100644 index 000000000000..c787975e1ff5 --- /dev/null +++ b/.beads/metadata.json @@ -0,0 +1,4 @@ +{ + "database": "beads.db", + "jsonl_export": "issues.jsonl" +} \ No newline at end of file diff --git a/.gitattributes b/.gitattributes index dbd06508a86a..b0eecb85e295 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,4 @@ *.json linguist-language=JSON-with-Comments + +# Use bd merge for beads JSONL files +.beads/issues.jsonl merge=beads diff --git a/docs/rust-port-test-coverage-plan.md b/docs/rust-port-test-coverage-plan.md new file mode 100644 index 000000000000..40d945a7caba --- /dev/null +++ b/docs/rust-port-test-coverage-plan.md @@ -0,0 +1,400 @@ +# Pyright Test Coverage Plan for Rust Port + +This document outlines the comprehensive test coverage plan required before porting pyright to Rust. + +## Executive Summary + +| Component | Source Files | LOC (approx) | Current Tests | Coverage Status | +|-----------|-------------|--------------|---------------|-----------------| +| Parser | 9 | 8,500 | Basic | Needs expansion | +| Binder | 7+ | 6,000 | Indirect only | Needs refactoring + tests | +| Type Evaluator | 10+ | 35,000 | Good integration | Needs unit tests | +| Code Flow Engine | 3 | 3,000 | None direct | Needs tests | +| Checker | 1 | 7,600 | Good integration | Needs unit tests | +| Constraint Solver | 3 | 2,500 | None direct | Needs tests | +| Import Resolver | 4 | 3,000 | Basic | Needs expansion | +| Language Service | 23 | 8,000 | Fourslash tests | Adequate | +| Common Utilities | 51 | 6,000 | Partial | Needs expansion | + +## Epic Breakdown + +### 1. Parser Component Test Coverage (pyright-rzw) - P1 + +**Current State:** +- `tokenizer.test.ts` - Basic tokenizer tests exist +- `parser.test.ts` - Very basic parser tests (170 lines) +- Most parser testing is indirect through type evaluator tests + +**Components:** +| File | Lines | Testability | Action Required | +|------|-------|-------------|-----------------| +| parser.ts | 5,415 | Moderate | Extract parsing functions for unit testing | +| tokenizer.ts | 1,800 | Good | Expand token type coverage | +| characterStream.ts | ~200 | Good | Add stream manipulation tests | +| stringTokenUtils.ts | ~400 | Good | Add string parsing tests | +| parseNodes.ts | ~1,500 | N/A (types) | No tests needed | +| parseNodeUtils.ts | ~300 | Good | Add utility function tests | + +**Tasks:** +1. Tokenizer unit tests for all token types (pyright-rzw.1) +2. Parser unit tests for statement types (pyright-rzw.2) +3. Parser unit tests for expression types (pyright-rzw.3) +4. Parser error recovery tests (pyright-rzw.4) +5. String token utilities tests (pyright-rzw.5) + +--- + +### 2. Binder Component Test Coverage (pyright-9vm) - P1 + +**Current State:** +- No direct `binder.test.ts` exists +- Binder is tested only indirectly through checker tests +- Tightly coupled to parse tree walker pattern + +**Components:** +| File | Lines | Testability | Action Required | +|------|-------|-------------|-----------------| +| binder.ts | 4,437 | Poor | Extract pure functions, add dependency injection | +| scope.ts | ~400 | Moderate | Add scope creation tests | +| scopeUtils.ts | ~200 | Good | Add utility tests | +| symbol.ts | ~500 | Good | Add symbol tests | +| symbolUtils.ts | ~300 | Good | Add utility tests | +| declaration.ts | ~200 | N/A (types) | No tests needed | +| declarationUtils.ts | ~400 | Good | Add utility tests | + +**Refactoring Required:** +- Extract scope creation logic into testable functions +- Extract symbol binding logic from walker methods +- Create mock parse tree builders for testing + +**Tasks:** +1. Refactor binder for testability (pyright-9vm.1) +2. Scope creation and nesting tests (pyright-9vm.2) +3. Symbol binding and resolution tests (pyright-9vm.3) +4. Declaration binding tests (pyright-9vm.4) +5. Control flow node creation tests (pyright-9vm.5) + +--- + +### 3. Type Evaluator Test Coverage (pyright-5mj) - P1 + +**Current State:** +- `typeEvaluator1-8.test.ts` - 8 test files with good coverage via sample files +- `typePrinter.test.ts` - Type printing tests exist +- Tests are integration-style, not unit tests + +**Components:** +| File | Lines | Testability | Action Required | +|------|-------|-------------|-----------------| +| typeEvaluator.ts | 28,881 | Very Poor | Major refactoring needed | +| types.ts | ~2,000 | Good | Add type creation tests | +| typeUtils.ts | ~3,000 | Good | Add utility tests | +| typePrinter.ts | ~800 | Good | Expand tests | +| typeGuards.ts | ~2,000 | Moderate | Add narrowing tests | +| typeWalker.ts | ~300 | Good | Add walker tests | + +**Refactoring Required:** +- The 29K line `typeEvaluator.ts` is a closure-based module for performance +- Cannot easily unit test internal functions +- Need to identify and extract pure functions where possible +- Consider creating a test harness that exposes internal functions + +**Tasks:** +1. Refactor typeEvaluator for testability (pyright-5mj.1) +2. Type creation and manipulation unit tests (pyright-5mj.2) +3. Type compatibility and assignability tests (pyright-5mj.3) +4. Generic type instantiation tests (pyright-5mj.4) +5. TypeVar constraint solving tests (pyright-5mj.5) +6. Type printer comprehensive tests (pyright-5mj.6) + +--- + +### 4. Code Flow Engine Test Coverage (pyright-6kc) - P1 + +**Current State:** +- No direct tests for code flow engine +- Tested indirectly through type narrowing samples + +**Components:** +| File | Lines | Testability | Action Required | +|------|-------|-------------|-----------------| +| codeFlowEngine.ts | 2,040 | Moderate | Add graph traversal tests | +| codeFlowTypes.ts | ~300 | N/A (types) | No tests needed | +| codeFlowUtils.ts | ~200 | Good | Add utility tests | + +**Tasks:** +1. Code flow graph traversal tests (pyright-6kc.1) +2. Type narrowing via code flow tests (pyright-6kc.2) +3. Reachability analysis tests (pyright-6kc.3) +4. Loop type widening tests (pyright-6kc.4) + +--- + +### 5. Checker Component Test Coverage (pyright-d1f) - P1 + +**Current State:** +- `checker.test.ts` - 704 lines, good integration tests via samples +- Tests all major checking scenarios +- Missing unit tests for individual check functions + +**Components:** +| File | Lines | Testability | Action Required | +|------|-------|-------------|-----------------| +| checker.ts | 7,634 | Moderate | Add unit tests for check functions | + +**Tasks:** +1. Checker diagnostic rule tests (pyright-d1f.1) +2. Type annotation check tests (pyright-d1f.2) +3. Function/method override check tests (pyright-d1f.3) +4. Protocol conformance check tests (pyright-d1f.4) + +--- + +### 6. Constraint Solver Test Coverage (pyright-vsr) - P1 + +**Current State:** +- No direct tests +- Tested indirectly through type evaluator tests + +**Components:** +| File | Lines | Testability | Action Required | +|------|-------|-------------|-----------------| +| constraintSolver.ts | 1,398 | Good | Add solving algorithm tests | +| constraintTracker.ts | ~500 | Good | Add tracking tests | +| constraintSolution.ts | ~300 | Good | Add solution tests | + +**Tasks:** +1. Basic TypeVar constraint solving tests (pyright-vsr.1) +2. ParamSpec constraint solving tests (pyright-vsr.2) +3. TypeVarTuple constraint solving tests (pyright-vsr.3) +4. Constraint widening and narrowing tests (pyright-vsr.4) +5. Multiple constraint unification tests (pyright-vsr.5) + +--- + +### 7. Import Resolver Test Coverage (pyright-5j8) - P1 + +**Current State:** +- `importResolver.test.ts` exists with some tests +- Missing comprehensive module resolution tests + +**Components:** +| File | Lines | Testability | Action Required | +|------|-------|-------------|-----------------| +| importResolver.ts | ~2,000 | Good | Expand test coverage | +| importResult.ts | ~100 | N/A (types) | No tests needed | +| importStatementUtils.ts | ~300 | Good | Add utility tests | +| importLogger.ts | ~100 | Good | Add logging tests | + +**Tasks:** +1. Module resolution algorithm tests (pyright-5j8.1) +2. Package resolution tests (pyright-5j8.2) +3. Stub file resolution tests (pyright-5j8.3) +4. Relative import resolution tests (pyright-5j8.4) +5. sys.path manipulation tests (pyright-5j8.5) + +--- + +### 8. Program and Service Test Coverage (pyright-cnp) - P1 + +**Current State:** +- `service.test.ts` exists with basic tests +- `sourceFile.test.ts` exists with some tests +- Missing incremental analysis tests + +**Components:** +| File | Lines | Testability | Action Required | +|------|-------|-------------|-----------------| +| program.ts | ~1,500 | Moderate | Add program management tests | +| service.ts | ~1,000 | Good | Expand service tests | +| sourceFile.ts | ~1,200 | Moderate | Add caching tests | +| backgroundAnalysisProgram.ts | ~500 | Moderate | Add background tests | + +**Tasks:** +1. Program file management tests (pyright-cnp.1) +2. Incremental analysis tests (pyright-cnp.2) +3. SourceFile parsing and caching tests (pyright-cnp.3) +4. Service configuration handling tests (pyright-cnp.4) + +--- + +### 9. Language Service Test Coverage (pyright-3wx) - P2 + +**Current State:** +- Good coverage via fourslash tests (200+ tests) +- `completions.test.ts`, `hoverProvider.test.ts`, `signatureHelp.test.ts` exist +- Missing unit-level tests for provider internals + +**Components:** +| File | Lines | Testability | Action Required | +|------|-------|-------------|-----------------| +| completionProvider.ts | ~2,000 | Good | Add provider unit tests | +| hoverProvider.ts | ~500 | Good | Add provider unit tests | +| definitionProvider.ts | ~400 | Good | Add provider unit tests | +| referencesProvider.ts | ~400 | Good | Add provider unit tests | +| renameProvider.ts | ~600 | Good | Add provider unit tests | +| signatureHelpProvider.ts | ~500 | Good | Add provider unit tests | +| codeActionProvider.ts | ~800 | Good | Add provider unit tests | + +**Tasks:** +1. Completion provider unit tests (pyright-3wx.1) +2. Hover provider unit tests (pyright-3wx.2) +3. Definition provider unit tests (pyright-3wx.3) +4. References provider unit tests (pyright-3wx.4) +5. Rename provider unit tests (pyright-3wx.5) +6. Code action provider unit tests (pyright-3wx.6) +7. Signature help provider unit tests (pyright-3wx.7) + +--- + +### 10. Common Utilities Test Coverage (pyright-7ea) - P2 + +**Current State:** +- Several utility test files exist +- `uri.test.ts`, `pathUtils.test.ts`, `collectionUtils.test.ts`, etc. +- Some gaps in coverage + +**Components to Test:** +- URI handling (uri/, 9 files) +- Path utilities +- Text range utilities +- Collection utilities +- Configuration options +- Diagnostic utilities + +**Tasks:** +1. URI handling tests (pyright-7ea.1) +2. Path utilities tests (pyright-7ea.2) +3. Text range and position utilities tests (pyright-7ea.3) +4. Collection utilities tests (pyright-7ea.4) +5. Configuration options tests (pyright-7ea.5) +6. Diagnostic utilities tests (pyright-7ea.6) + +--- + +### 11. Special Type Handlers Test Coverage (pyright-asn) - P2 + +**Current State:** +- Tested indirectly through type evaluator sample tests +- Missing dedicated unit tests for special type handlers + +**Components:** +| File | Lines | Testability | Action Required | +|------|-------|-------------|-----------------| +| dataClasses.ts | ~1,000 | Good | Add dataclass tests | +| namedTuples.ts | ~500 | Good | Add named tuple tests | +| typedDicts.ts | ~800 | Good | Add typed dict tests | +| enums.ts | ~600 | Good | Add enum tests | +| protocols.ts | ~800 | Good | Add protocol tests | +| patternMatching.ts | ~1,200 | Moderate | Add pattern tests | + +**Tasks:** +1. DataClass handler tests (pyright-asn.1) +2. NamedTuple handler tests (pyright-asn.2) +3. TypedDict handler tests (pyright-asn.3) +4. Enum handler tests (pyright-asn.4) +5. Protocol handler tests (pyright-asn.5) +6. Pattern matching type narrowing tests (pyright-asn.6) + +--- + +## Testability Assessment Summary + +### Files Requiring Refactoring Before Testing + +| File | Issue | Suggested Refactoring | +|------|-------|----------------------| +| typeEvaluator.ts | 29K line closure | Extract pure functions, create test harness | +| binder.ts | Tightly coupled walker | Extract binding logic, add DI | +| codeFlowEngine.ts | Coupled to type evaluator | Create mock type evaluator interface | +| checker.ts | Large file | Extract check functions into testable units | + +### Files Ready for Testing (No Refactoring) + +- All parser/*.ts files +- All common/*.ts utility files +- constraintSolver.ts, constraintTracker.ts +- importResolver.ts +- All languageService/*.ts provider files +- types.ts, typeUtils.ts +- Special type handlers (dataClasses.ts, etc.) + +--- + +## Recommended Priority Order + +1. **Parser** (pyright-rzw) - Foundation for everything else +2. **Common Utilities** (pyright-7ea) - Used by all components +3. **Import Resolver** (pyright-5j8) - Critical for module loading +4. **Binder** (pyright-9vm) - Depends on parser +5. **Constraint Solver** (pyright-vsr) - Relatively isolated +6. **Type Evaluator** (pyright-5mj) - Core, needs most work +7. **Code Flow Engine** (pyright-6kc) - Depends on type evaluator +8. **Checker** (pyright-d1f) - Integration point +9. **Program/Service** (pyright-cnp) - Top-level orchestration +10. **Language Service** (pyright-3wx) - Already well-tested +11. **Special Type Handlers** (pyright-asn) - Can be done in parallel + +--- + +## Test Infrastructure Needed + +### New Test Utilities Required + +1. **Parse Tree Builders** - Create parse trees programmatically for testing +2. **Type Builders** - Create Type objects for testing type operations +3. **Mock File System** - Already exists, needs enhancement +4. **Mock Type Evaluator** - For testing code flow engine +5. **Scope/Symbol Builders** - For binder unit tests + +### Test Patterns to Adopt + +1. **Property-based testing** - For parser and type operations +2. **Snapshot testing** - For type printer output +3. **Parameterized tests** - For systematic coverage +4. **Fuzz testing** - For parser robustness + +--- + +## Metrics to Track + +- Lines of code covered by unit tests +- Number of public functions with direct tests +- Mutation testing score +- Test execution time (for CI) + +--- + +## Timeline Estimate + +| Phase | Epics | Est. Effort | Prerequisites | +|-------|-------|-------------|---------------| +| Phase 1 | Parser, Common Utils | 2 weeks | None | +| Phase 2 | Import Resolver, Binder refactoring | 2 weeks | Phase 1 | +| Phase 3 | Constraint Solver, Type Evaluator refactoring | 3 weeks | Phase 2 | +| Phase 4 | Code Flow, Checker | 2 weeks | Phase 3 | +| Phase 5 | Program/Service, Language Service | 1 week | Phase 4 | +| Phase 6 | Special Type Handlers | 1 week | Phase 3 | + +**Total: ~11 weeks** + +--- + +## Issue Tracking + +All epics and tasks have been created in the bd issue tracker: + +### Epics (11 total) +- pyright-rzw: Parser Component Test Coverage (P1) +- pyright-9vm: Binder Component Test Coverage (P1) +- pyright-5mj: Type Evaluator Test Coverage (P1) +- pyright-6kc: Code Flow Engine Test Coverage (P1) +- pyright-d1f: Checker Component Test Coverage (P1) +- pyright-vsr: Constraint Solver Test Coverage (P1) +- pyright-5j8: Import Resolver Test Coverage (P1) +- pyright-cnp: Program and Service Test Coverage (P1) +- pyright-3wx: Language Service Test Coverage (P2) +- pyright-7ea: Common Utilities Test Coverage (P2) +- pyright-asn: Special Type Handlers Test Coverage (P2) + +Run `bd list --tree` to see full task hierarchy. From 1f2c4d92cb2128d93dec9c56ff4a6b5e51bda7dc Mon Sep 17 00:00:00 2001 From: Graham Wheeler <> Date: Fri, 6 Feb 2026 11:20:05 -0800 Subject: [PATCH 2/4] Add comprehensive tokenizer unit tests Added 27 new tests (86 -> 113 total) covering: - Template strings (t-strings) for Python 3.14+ - Raw template strings (rt/tr prefixes) - Multiline template strings - Matrix multiply operator (@) - Matrix multiply assignment operator (@=) - All 39 Python keywords - Soft keywords as identifiers - Unicode identifiers (Greek, Japanese, Chinese) - Complex number literals - Numbers with leading zeros - All escape sequences in strings - Line continuation in expressions - Mixed tabs/spaces indentation - Empty f-strings and template strings - Deeply nested f-strings - F-strings with colons in expressions - Very long identifiers, strings, and numbers - Named Unicode escapes - Multiple operators without spaces - Chained comparison operators - All bitwise operators - All assignment operators Part of: pyright-rzw (Parser Component Test Coverage) --- .beads/issues.jsonl | 68 + AGENTS.md | 40 + package-lock.json | 25 + packages/pyright-internal/package-lock.json | 2384 +---------------- packages/pyright-internal/package.json | 1 + .../src/tests/tokenizer.test.ts | 436 +++ 6 files changed, 716 insertions(+), 2238 deletions(-) create mode 100644 AGENTS.md diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index e69de29bb2d1..9e1b3022bdfd 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -0,0 +1,68 @@ +{"id":"pyright-3wx","title":"Epic: Language Service Test Coverage","status":"open","priority":2,"issue_type":"epic","created_at":"2026-02-06T10:55:01.590617-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:01.590617-08:00"} +{"id":"pyright-3wx.1","title":"Completion provider unit tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:55:58.409216-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:58.409216-08:00","dependencies":[{"issue_id":"pyright-3wx.1","depends_on_id":"pyright-3wx","type":"parent-child","created_at":"2026-02-06T10:55:58.409849-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-3wx.2","title":"Hover provider unit tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:55:58.496883-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:58.496883-08:00","dependencies":[{"issue_id":"pyright-3wx.2","depends_on_id":"pyright-3wx","type":"parent-child","created_at":"2026-02-06T10:55:58.49748-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-3wx.3","title":"Definition provider unit tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:55:58.583444-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:58.583444-08:00","dependencies":[{"issue_id":"pyright-3wx.3","depends_on_id":"pyright-3wx","type":"parent-child","created_at":"2026-02-06T10:55:58.584006-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-3wx.4","title":"References provider unit tests","status":"open","priority":2,"issue_type":"task","created_at":"2026-02-06T10:55:58.666824-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:58.666824-08:00","dependencies":[{"issue_id":"pyright-3wx.4","depends_on_id":"pyright-3wx","type":"parent-child","created_at":"2026-02-06T10:55:58.667357-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-3wx.5","title":"Rename provider unit tests","status":"open","priority":2,"issue_type":"task","created_at":"2026-02-06T10:55:58.747657-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:58.747657-08:00","dependencies":[{"issue_id":"pyright-3wx.5","depends_on_id":"pyright-3wx","type":"parent-child","created_at":"2026-02-06T10:55:58.748205-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-3wx.6","title":"Code action provider unit tests","status":"open","priority":2,"issue_type":"task","created_at":"2026-02-06T10:55:58.833091-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:58.833091-08:00","dependencies":[{"issue_id":"pyright-3wx.6","depends_on_id":"pyright-3wx","type":"parent-child","created_at":"2026-02-06T10:55:58.833633-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-3wx.7","title":"Signature help provider unit tests","status":"open","priority":2,"issue_type":"task","created_at":"2026-02-06T10:55:58.925213-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:58.925213-08:00","dependencies":[{"issue_id":"pyright-3wx.7","depends_on_id":"pyright-3wx","type":"parent-child","created_at":"2026-02-06T10:55:58.925849-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-5j8","title":"Epic: Import Resolver Test Coverage","status":"open","priority":1,"issue_type":"epic","created_at":"2026-02-06T10:55:01.689164-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:01.689164-08:00"} +{"id":"pyright-5j8.1","title":"Module resolution algorithm tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:55:47.669375-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:47.669375-08:00","dependencies":[{"issue_id":"pyright-5j8.1","depends_on_id":"pyright-5j8","type":"parent-child","created_at":"2026-02-06T10:55:47.670006-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-5j8.2","title":"Package resolution tests including namespace packages","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:55:47.74412-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:47.74412-08:00","dependencies":[{"issue_id":"pyright-5j8.2","depends_on_id":"pyright-5j8","type":"parent-child","created_at":"2026-02-06T10:55:47.744665-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-5j8.3","title":"Stub file resolution tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:55:47.819676-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:47.819676-08:00","dependencies":[{"issue_id":"pyright-5j8.3","depends_on_id":"pyright-5j8","type":"parent-child","created_at":"2026-02-06T10:55:47.820227-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-5j8.4","title":"Relative import resolution tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:55:47.897502-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:47.897502-08:00","dependencies":[{"issue_id":"pyright-5j8.4","depends_on_id":"pyright-5j8","type":"parent-child","created_at":"2026-02-06T10:55:47.898016-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-5j8.5","title":"sys.path manipulation tests","status":"open","priority":2,"issue_type":"task","created_at":"2026-02-06T10:55:47.986399-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:47.986399-08:00","dependencies":[{"issue_id":"pyright-5j8.5","depends_on_id":"pyright-5j8","type":"parent-child","created_at":"2026-02-06T10:55:47.98696-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-5mj","title":"Epic: Type Evaluator Test Coverage","status":"open","priority":1,"issue_type":"epic","created_at":"2026-02-06T10:54:50.081585-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:54:50.081585-08:00"} +{"id":"pyright-5mj.1","title":"Refactor typeEvaluator for testability - identify extractable functions","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:55:27.566628-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:27.566628-08:00","dependencies":[{"issue_id":"pyright-5mj.1","depends_on_id":"pyright-5mj","type":"parent-child","created_at":"2026-02-06T10:55:27.567261-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-5mj.2","title":"Type creation and manipulation unit tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:55:27.642079-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:27.642079-08:00","dependencies":[{"issue_id":"pyright-5mj.2","depends_on_id":"pyright-5mj","type":"parent-child","created_at":"2026-02-06T10:55:27.642634-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-5mj.3","title":"Type compatibility and assignability tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:55:27.716506-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:27.716506-08:00","dependencies":[{"issue_id":"pyright-5mj.3","depends_on_id":"pyright-5mj","type":"parent-child","created_at":"2026-02-06T10:55:27.71705-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-5mj.4","title":"Generic type instantiation tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:55:27.788919-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:27.788919-08:00","dependencies":[{"issue_id":"pyright-5mj.4","depends_on_id":"pyright-5mj","type":"parent-child","created_at":"2026-02-06T10:55:27.789482-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-5mj.5","title":"TypeVar constraint solving tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:55:27.860254-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:27.860254-08:00","dependencies":[{"issue_id":"pyright-5mj.5","depends_on_id":"pyright-5mj","type":"parent-child","created_at":"2026-02-06T10:55:27.860779-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-5mj.6","title":"Type printer comprehensive tests","status":"open","priority":2,"issue_type":"task","created_at":"2026-02-06T10:55:27.933388-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:27.933388-08:00","dependencies":[{"issue_id":"pyright-5mj.6","depends_on_id":"pyright-5mj","type":"parent-child","created_at":"2026-02-06T10:55:27.933953-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-6kc","title":"Epic: Code Flow Engine Test Coverage","status":"open","priority":1,"issue_type":"epic","created_at":"2026-02-06T10:54:53.543605-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:54:53.543605-08:00"} +{"id":"pyright-6kc.1","title":"Code flow graph traversal tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:55:32.732485-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:32.732485-08:00","dependencies":[{"issue_id":"pyright-6kc.1","depends_on_id":"pyright-6kc","type":"parent-child","created_at":"2026-02-06T10:55:32.733055-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-6kc.2","title":"Type narrowing via code flow tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:55:32.804467-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:32.804467-08:00","dependencies":[{"issue_id":"pyright-6kc.2","depends_on_id":"pyright-6kc","type":"parent-child","created_at":"2026-02-06T10:55:32.805028-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-6kc.3","title":"Reachability analysis tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:55:32.87571-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:32.87571-08:00","dependencies":[{"issue_id":"pyright-6kc.3","depends_on_id":"pyright-6kc","type":"parent-child","created_at":"2026-02-06T10:55:32.876244-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-6kc.4","title":"Loop type widening tests","status":"open","priority":2,"issue_type":"task","created_at":"2026-02-06T10:55:32.949715-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:32.949715-08:00","dependencies":[{"issue_id":"pyright-6kc.4","depends_on_id":"pyright-6kc","type":"parent-child","created_at":"2026-02-06T10:55:32.950298-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-7ea","title":"Epic: Common Utilities Test Coverage","status":"open","priority":2,"issue_type":"epic","created_at":"2026-02-06T10:55:01.778088-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:01.778088-08:00"} +{"id":"pyright-7ea.1","title":"URI handling tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:56:04.071105-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:56:04.071105-08:00","dependencies":[{"issue_id":"pyright-7ea.1","depends_on_id":"pyright-7ea","type":"parent-child","created_at":"2026-02-06T10:56:04.071691-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-7ea.2","title":"Path utilities tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:56:04.164622-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:56:04.164622-08:00","dependencies":[{"issue_id":"pyright-7ea.2","depends_on_id":"pyright-7ea","type":"parent-child","created_at":"2026-02-06T10:56:04.165223-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-7ea.3","title":"Text range and position utilities tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:56:04.255559-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:56:04.255559-08:00","dependencies":[{"issue_id":"pyright-7ea.3","depends_on_id":"pyright-7ea","type":"parent-child","created_at":"2026-02-06T10:56:04.256149-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-7ea.4","title":"Collection utilities tests","status":"open","priority":2,"issue_type":"task","created_at":"2026-02-06T10:56:04.347283-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:56:04.347283-08:00","dependencies":[{"issue_id":"pyright-7ea.4","depends_on_id":"pyright-7ea","type":"parent-child","created_at":"2026-02-06T10:56:04.347858-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-7ea.5","title":"Configuration options tests","status":"open","priority":2,"issue_type":"task","created_at":"2026-02-06T10:56:04.42834-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:56:04.42834-08:00","dependencies":[{"issue_id":"pyright-7ea.5","depends_on_id":"pyright-7ea","type":"parent-child","created_at":"2026-02-06T10:56:04.428923-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-7ea.6","title":"Diagnostic utilities tests","status":"open","priority":2,"issue_type":"task","created_at":"2026-02-06T10:56:04.515675-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:56:04.515675-08:00","dependencies":[{"issue_id":"pyright-7ea.6","depends_on_id":"pyright-7ea","type":"parent-child","created_at":"2026-02-06T10:56:04.516269-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-9vm","title":"Epic: Binder Component Test Coverage","description":"Add comprehensive unit tests for the binder component.\n\n## Components to Test\n- binder.ts (4437 lines) - Main name binding logic\n- scope.ts - Scope management\n- scopeUtils.ts - Scope utilities\n- symbol.ts - Symbol definitions\n- symbolUtils.ts - Symbol utilities\n- declaration.ts - Declaration types\n- declarationUtils.ts - Declaration utilities\n\n## Current Status\n- No direct binder.test.ts exists\n- Binder is tested indirectly through checker.test.ts\n\n## Issues for Testability \n- Binder is tightly coupled to the parse tree walker\n- May need extraction of pure functions for unit testing\n- Scope creation logic needs isolation\n\n## Goals\n- Unit tests for scope creation\n- Symbol resolution tests\n- Declaration binding tests\n- Control flow node creation tests","status":"open","priority":1,"issue_type":"epic","created_at":"2026-02-06T10:54:19.73064-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:54:19.73064-08:00"} +{"id":"pyright-9vm.1","title":"Refactor binder for testability - extract pure functions","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:55:21.739623-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:21.739623-08:00","dependencies":[{"issue_id":"pyright-9vm.1","depends_on_id":"pyright-9vm","type":"parent-child","created_at":"2026-02-06T10:55:21.7403-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-9vm.2","title":"Scope creation and nesting tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:55:21.812821-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:21.812821-08:00","dependencies":[{"issue_id":"pyright-9vm.2","depends_on_id":"pyright-9vm","type":"parent-child","created_at":"2026-02-06T10:55:21.813378-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-9vm.3","title":"Symbol binding and resolution tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:55:21.899107-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:21.899107-08:00","dependencies":[{"issue_id":"pyright-9vm.3","depends_on_id":"pyright-9vm","type":"parent-child","created_at":"2026-02-06T10:55:21.89965-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-9vm.4","title":"Declaration binding tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:55:21.979876-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:21.979876-08:00","dependencies":[{"issue_id":"pyright-9vm.4","depends_on_id":"pyright-9vm","type":"parent-child","created_at":"2026-02-06T10:55:21.980423-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-9vm.5","title":"Control flow node creation tests","status":"open","priority":2,"issue_type":"task","created_at":"2026-02-06T10:55:22.065571-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:22.065571-08:00","dependencies":[{"issue_id":"pyright-9vm.5","depends_on_id":"pyright-9vm","type":"parent-child","created_at":"2026-02-06T10:55:22.066157-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-asn","title":"Epic: Special Type Handlers Test Coverage","status":"open","priority":2,"issue_type":"epic","created_at":"2026-02-06T10:55:06.195025-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:06.195025-08:00"} +{"id":"pyright-asn.1","title":"DataClass handler tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:56:10.019203-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:56:10.019203-08:00","dependencies":[{"issue_id":"pyright-asn.1","depends_on_id":"pyright-asn","type":"parent-child","created_at":"2026-02-06T10:56:10.019861-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-asn.2","title":"NamedTuple handler tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:56:10.103151-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:56:10.103151-08:00","dependencies":[{"issue_id":"pyright-asn.2","depends_on_id":"pyright-asn","type":"parent-child","created_at":"2026-02-06T10:56:10.103727-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-asn.3","title":"TypedDict handler tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:56:10.184499-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:56:10.184499-08:00","dependencies":[{"issue_id":"pyright-asn.3","depends_on_id":"pyright-asn","type":"parent-child","created_at":"2026-02-06T10:56:10.185031-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-asn.4","title":"Enum handler tests","status":"open","priority":2,"issue_type":"task","created_at":"2026-02-06T10:56:10.263988-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:56:10.263988-08:00","dependencies":[{"issue_id":"pyright-asn.4","depends_on_id":"pyright-asn","type":"parent-child","created_at":"2026-02-06T10:56:10.264534-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-asn.5","title":"Protocol handler tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:56:10.343861-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:56:10.343861-08:00","dependencies":[{"issue_id":"pyright-asn.5","depends_on_id":"pyright-asn","type":"parent-child","created_at":"2026-02-06T10:56:10.344407-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-asn.6","title":"Pattern matching type narrowing tests","status":"open","priority":2,"issue_type":"task","created_at":"2026-02-06T10:56:10.426064-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:56:10.426064-08:00","dependencies":[{"issue_id":"pyright-asn.6","depends_on_id":"pyright-asn","type":"parent-child","created_at":"2026-02-06T10:56:10.426628-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-cnp","title":"Epic: Program and Service Test Coverage","status":"open","priority":1,"issue_type":"epic","created_at":"2026-02-06T10:55:06.106391-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:06.106391-08:00"} +{"id":"pyright-cnp.1","title":"Program file management tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:55:52.748046-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:52.748046-08:00","dependencies":[{"issue_id":"pyright-cnp.1","depends_on_id":"pyright-cnp","type":"parent-child","created_at":"2026-02-06T10:55:52.748656-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-cnp.2","title":"Incremental analysis tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:55:52.832287-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:52.832287-08:00","dependencies":[{"issue_id":"pyright-cnp.2","depends_on_id":"pyright-cnp","type":"parent-child","created_at":"2026-02-06T10:55:52.832863-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-cnp.3","title":"SourceFile parsing and caching tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:55:52.921374-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:52.921374-08:00","dependencies":[{"issue_id":"pyright-cnp.3","depends_on_id":"pyright-cnp","type":"parent-child","created_at":"2026-02-06T10:55:52.921988-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-cnp.4","title":"Service configuration handling tests","status":"open","priority":2,"issue_type":"task","created_at":"2026-02-06T10:55:53.019698-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:53.019698-08:00","dependencies":[{"issue_id":"pyright-cnp.4","depends_on_id":"pyright-cnp","type":"parent-child","created_at":"2026-02-06T10:55:53.02029-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-d1f","title":"Epic: Checker Component Test Coverage","status":"open","priority":1,"issue_type":"epic","created_at":"2026-02-06T10:54:57.10327-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:54:57.10327-08:00"} +{"id":"pyright-d1f.1","title":"Checker diagnostic rule tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:55:37.6236-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:37.6236-08:00","dependencies":[{"issue_id":"pyright-d1f.1","depends_on_id":"pyright-d1f","type":"parent-child","created_at":"2026-02-06T10:55:37.628366-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-d1f.2","title":"Type annotation check tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:55:37.70315-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:37.70315-08:00","dependencies":[{"issue_id":"pyright-d1f.2","depends_on_id":"pyright-d1f","type":"parent-child","created_at":"2026-02-06T10:55:37.705041-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-d1f.3","title":"Function/method override check tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:55:37.778057-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:37.778057-08:00","dependencies":[{"issue_id":"pyright-d1f.3","depends_on_id":"pyright-d1f","type":"parent-child","created_at":"2026-02-06T10:55:37.778668-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-d1f.4","title":"Protocol conformance check tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:55:37.85039-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:37.85039-08:00","dependencies":[{"issue_id":"pyright-d1f.4","depends_on_id":"pyright-d1f","type":"parent-child","created_at":"2026-02-06T10:55:37.850904-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-rzw","title":"Epic: Parser Component Test Coverage","description":"Add comprehensive unit tests to all parser components to ensure full coverage before Rust port.\n\n## Components to Test\n- parser.ts (5415 lines) - Main parser\n- tokenizer.ts (1800 lines) - Tokenizer \n- characterStream.ts - Character stream handling\n- stringTokenUtils.ts - String token utilities\n- parseNodes.ts - Parse node types\n- parseNodeUtils.ts - Parse node utilities\n\n## Current Status\n- tokenizer.test.ts exists (basic tests)\n- parser.test.ts exists (very basic tests)\n\n## Goals\n- Unit tests for each parsing function\n- Edge cases for all Python syntax\n- Error recovery testing\n- Performance regression tests","status":"open","priority":1,"issue_type":"epic","created_at":"2026-02-06T10:54:12.20073-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:54:12.20073-08:00"} +{"id":"pyright-rzw.1","title":"Tokenizer unit tests for all token types","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:55:16.25374-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:16.25374-08:00","dependencies":[{"issue_id":"pyright-rzw.1","depends_on_id":"pyright-rzw","type":"parent-child","created_at":"2026-02-06T10:55:16.254313-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-rzw.2","title":"Parser unit tests for statement types","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:55:16.330956-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:16.330956-08:00","dependencies":[{"issue_id":"pyright-rzw.2","depends_on_id":"pyright-rzw","type":"parent-child","created_at":"2026-02-06T10:55:16.331515-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-rzw.3","title":"Parser unit tests for expression types","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:55:16.407928-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:16.407928-08:00","dependencies":[{"issue_id":"pyright-rzw.3","depends_on_id":"pyright-rzw","type":"parent-child","created_at":"2026-02-06T10:55:16.408503-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-rzw.4","title":"Parser error recovery tests","status":"open","priority":2,"issue_type":"task","created_at":"2026-02-06T10:55:16.487412-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:16.487412-08:00","dependencies":[{"issue_id":"pyright-rzw.4","depends_on_id":"pyright-rzw","type":"parent-child","created_at":"2026-02-06T10:55:16.487981-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-rzw.5","title":"String token utilities tests","status":"open","priority":2,"issue_type":"task","created_at":"2026-02-06T10:55:16.560323-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:16.560323-08:00","dependencies":[{"issue_id":"pyright-rzw.5","depends_on_id":"pyright-rzw","type":"parent-child","created_at":"2026-02-06T10:55:16.560866-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-vsr","title":"Epic: Constraint Solver Test Coverage","status":"open","priority":1,"issue_type":"epic","created_at":"2026-02-06T10:55:01.495592-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:01.495592-08:00"} +{"id":"pyright-vsr.1","title":"Basic TypeVar constraint solving tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:55:42.584029-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:42.584029-08:00","dependencies":[{"issue_id":"pyright-vsr.1","depends_on_id":"pyright-vsr","type":"parent-child","created_at":"2026-02-06T10:55:42.584596-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-vsr.2","title":"ParamSpec constraint solving tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:55:42.656139-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:42.656139-08:00","dependencies":[{"issue_id":"pyright-vsr.2","depends_on_id":"pyright-vsr","type":"parent-child","created_at":"2026-02-06T10:55:42.656748-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-vsr.3","title":"TypeVarTuple constraint solving tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:55:42.727521-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:42.727521-08:00","dependencies":[{"issue_id":"pyright-vsr.3","depends_on_id":"pyright-vsr","type":"parent-child","created_at":"2026-02-06T10:55:42.728056-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-vsr.4","title":"Constraint widening and narrowing tests","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T10:55:42.81354-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:42.81354-08:00","dependencies":[{"issue_id":"pyright-vsr.4","depends_on_id":"pyright-vsr","type":"parent-child","created_at":"2026-02-06T10:55:42.814072-08:00","created_by":"Graham Wheeler"}]} +{"id":"pyright-vsr.5","title":"Multiple constraint unification tests","status":"open","priority":2,"issue_type":"task","created_at":"2026-02-06T10:55:42.894068-08:00","created_by":"Graham Wheeler","updated_at":"2026-02-06T10:55:42.894068-08:00","dependencies":[{"issue_id":"pyright-vsr.5","depends_on_id":"pyright-vsr","type":"parent-child","created_at":"2026-02-06T10:55:42.894606-08:00","created_by":"Graham Wheeler"}]} diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 000000000000..df7a4af984b3 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,40 @@ +# Agent Instructions + +This project uses **bd** (beads) for issue tracking. Run `bd onboard` to get started. + +## Quick Reference + +```bash +bd ready # Find available work +bd show # View issue details +bd update --status in_progress # Claim work +bd close # Complete work +bd sync # Sync with git +``` + +## Landing the Plane (Session Completion) + +**When ending a work session**, you MUST complete ALL steps below. Work is NOT complete until `git push` succeeds. + +**MANDATORY WORKFLOW:** + +1. **File issues for remaining work** - Create issues for anything that needs follow-up +2. **Run quality gates** (if code changed) - Tests, linters, builds +3. **Update issue status** - Close finished work, update in-progress items +4. **PUSH TO REMOTE** - This is MANDATORY: + ```bash + git pull --rebase + bd sync + git push + git status # MUST show "up to date with origin" + ``` +5. **Clean up** - Clear stashes, prune remote branches +6. **Verify** - All changes committed AND pushed +7. **Hand off** - Provide context for next session + +**CRITICAL RULES:** +- Work is NOT complete until `git push` succeeds +- NEVER stop before pushing - that leaves work stranded locally +- NEVER say "ready to push when you are" - YOU must push +- If push fails, resolve and retry until it succeeds + diff --git a/package-lock.json b/package-lock.json index b718543f2098..9d6751a817f3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3778,6 +3778,31 @@ "dev": true, "license": "MIT" }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/end-of-stream": { "version": "1.4.5", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", diff --git a/packages/pyright-internal/package-lock.json b/packages/pyright-internal/package-lock.json index 80d2c8d3e77d..5bbf9509b8b4 100644 --- a/packages/pyright-internal/package-lock.json +++ b/packages/pyright-internal/package-lock.json @@ -36,6 +36,7 @@ "esbuild-loader": "^4.4.0", "jest": "^30.2.0", "jest-junit": "^16.0.0", + "jest-util": "^30.2.0", "shx": "^0.4.0", "ts-jest": "^29.4.5", "ts-loader": "^9.5.4", @@ -1213,92 +1214,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/console/node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/console/node_modules/@jest/types": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/console/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jest/console/node_modules/ci-info": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", - "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console/node_modules/jest-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", - "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "30.2.0", - "@types/node": "*", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "graceful-fs": "^4.2.11", - "picomatch": "^4.0.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/console/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/@jest/console/node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -1357,19 +1272,6 @@ } } }, - "node_modules/@jest/core/node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/@jest/core/node_modules/@jest/transform": { "version": "30.2.0", "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.2.0.tgz", @@ -1397,32 +1299,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/core/node_modules/@jest/types": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/core/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", - "dev": true, - "license": "MIT" - }, "node_modules/@jest/core/node_modules/babel-plugin-istanbul": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz", @@ -1443,22 +1319,6 @@ "node": ">=12" } }, - "node_modules/@jest/core/node_modules/ci-info": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", - "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/core/node_modules/jest-haste-map": { "version": "30.2.0", "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.2.0.tgz", @@ -1494,24 +1354,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/core/node_modules/jest-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", - "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "30.2.0", - "@types/node": "*", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "graceful-fs": "^4.2.11", - "picomatch": "^4.0.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/@jest/core/node_modules/jest-worker": { "version": "30.2.0", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.2.0.tgz", @@ -1529,19 +1371,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/core/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/@jest/core/node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", @@ -1621,45 +1450,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/environment/node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/environment/node_modules/@jest/types": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/environment/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", - "dev": true, - "license": "MIT" - }, "node_modules/@jest/expect": { "version": "30.2.0", "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.2.0.tgz", @@ -1705,199 +1495,74 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/fake-timers/node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", + "node_modules/@jest/get-type": { + "version": "30.1.0", + "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz", + "integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==", "dev": true, "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/fake-timers/node_modules/@jest/types": { + "node_modules/@jest/globals": { "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.2.0.tgz", + "integrity": "sha512-b63wmnKPaK+6ZZfpYhz9K61oybvbI1aMcIs80++JI1O1rR1vaxHUCNqo3ITu6NU0d4V34yZFoHMn/uoKr/Rwfw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" + "@jest/environment": "30.2.0", + "@jest/expect": "30.2.0", + "@jest/types": "30.2.0", + "jest-mock": "30.2.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/fake-timers/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", + "node_modules/@jest/pattern": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz", + "integrity": "sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-regex-util": "30.0.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } }, - "node_modules/@jest/fake-timers/node_modules/ci-info": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", - "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", + "node_modules/@jest/pattern/node_modules/jest-regex-util": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz", + "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], "license": "MIT", "engines": { - "node": ">=8" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/fake-timers/node_modules/jest-util": { + "node_modules/@jest/reporters": { "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", - "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.2.0.tgz", + "integrity": "sha512-DRyW6baWPqKMa9CzeiBjHwjd8XeAyco2Vt8XbcLFjiwCOEKOvy82GJ8QQnJE9ofsxCMPjH4MfH8fCWIHHDKpAQ==", "dev": true, "license": "MIT", "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "30.2.0", + "@jest/test-result": "30.2.0", + "@jest/transform": "30.2.0", "@jest/types": "30.2.0", + "@jridgewell/trace-mapping": "^0.3.25", "@types/node": "*", "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "graceful-fs": "^4.2.11", - "picomatch": "^4.0.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/fake-timers/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/@jest/get-type": { - "version": "30.1.0", - "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz", - "integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/globals": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.2.0.tgz", - "integrity": "sha512-b63wmnKPaK+6ZZfpYhz9K61oybvbI1aMcIs80++JI1O1rR1vaxHUCNqo3ITu6NU0d4V34yZFoHMn/uoKr/Rwfw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "30.2.0", - "@jest/expect": "30.2.0", - "@jest/types": "30.2.0", - "jest-mock": "30.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/globals/node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/globals/node_modules/@jest/types": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/globals/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jest/pattern": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz", - "integrity": "sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-regex-util": "30.0.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/pattern/node_modules/jest-regex-util": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz", - "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/reporters": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.2.0.tgz", - "integrity": "sha512-DRyW6baWPqKMa9CzeiBjHwjd8XeAyco2Vt8XbcLFjiwCOEKOvy82GJ8QQnJE9ofsxCMPjH4MfH8fCWIHHDKpAQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "30.2.0", - "@jest/test-result": "30.2.0", - "@jest/transform": "30.2.0", - "@jest/types": "30.2.0", - "@jridgewell/trace-mapping": "^0.3.25", - "@types/node": "*", - "chalk": "^4.1.2", - "collect-v8-coverage": "^1.0.2", - "exit-x": "^0.2.2", - "glob": "^10.3.10", + "collect-v8-coverage": "^1.0.2", + "exit-x": "^0.2.2", + "glob": "^10.3.10", "graceful-fs": "^4.2.11", "istanbul-lib-coverage": "^3.0.0", "istanbul-lib-instrument": "^6.0.0", @@ -1923,19 +1588,6 @@ } } }, - "node_modules/@jest/reporters/node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/@jest/reporters/node_modules/@jest/transform": { "version": "30.2.0", "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.2.0.tgz", @@ -1963,32 +1615,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/reporters/node_modules/@jest/types": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/reporters/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", - "dev": true, - "license": "MIT" - }, "node_modules/@jest/reporters/node_modules/babel-plugin-istanbul": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz", @@ -2019,22 +1645,6 @@ "balanced-match": "^1.0.0" } }, - "node_modules/@jest/reporters/node_modules/ci-info": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", - "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/reporters/node_modules/glob": { "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", @@ -2091,24 +1701,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/reporters/node_modules/jest-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", - "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "30.2.0", - "@types/node": "*", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "graceful-fs": "^4.2.11", - "picomatch": "^4.0.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/@jest/reporters/node_modules/jest-worker": { "version": "30.2.0", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.2.0.tgz", @@ -2142,19 +1734,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@jest/reporters/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/@jest/reporters/node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", @@ -2209,18 +1788,16 @@ } }, "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", + "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { - "@sinclair/typebox": "^0.27.8" + "@sinclair/typebox": "^0.34.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/snapshot-utils": { @@ -2239,45 +1816,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/snapshot-utils/node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/snapshot-utils/node_modules/@jest/types": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/snapshot-utils/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", - "dev": true, - "license": "MIT" - }, "node_modules/@jest/source-map": { "version": "30.0.1", "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-30.0.1.tgz", @@ -2309,124 +1847,30 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/test-result/node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", + "node_modules/@jest/test-sequencer": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.2.0.tgz", + "integrity": "sha512-wXKgU/lk8fKXMu/l5Hog1R61bL4q5GCdT6OJvdAFz1P+QrpoFuLU68eoKuVc4RbrTtNnTL5FByhWdLgOPSph+Q==", "dev": true, "license": "MIT", "dependencies": { - "@sinclair/typebox": "^0.34.0" + "@jest/test-result": "30.2.0", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.2.0", + "slash": "^3.0.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/test-result/node_modules/@jest/types": { + "node_modules/@jest/test-sequencer/node_modules/jest-haste-map": { "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.2.0.tgz", + "integrity": "sha512-sQA/jCb9kNt+neM0anSj6eZhLZUIhQgwDt7cPGjumgLM4rXsfb9kpnlacmvZz3Q5tb80nS+oG/if+NBKrHC+Xw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/test-result/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jest/test-sequencer": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.2.0.tgz", - "integrity": "sha512-wXKgU/lk8fKXMu/l5Hog1R61bL4q5GCdT6OJvdAFz1P+QrpoFuLU68eoKuVc4RbrTtNnTL5FByhWdLgOPSph+Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/test-result": "30.2.0", - "graceful-fs": "^4.2.11", - "jest-haste-map": "30.2.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/test-sequencer/node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/test-sequencer/node_modules/@jest/types": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/test-sequencer/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jest/test-sequencer/node_modules/ci-info": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", - "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/test-sequencer/node_modules/jest-haste-map": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.2.0.tgz", - "integrity": "sha512-sQA/jCb9kNt+neM0anSj6eZhLZUIhQgwDt7cPGjumgLM4rXsfb9kpnlacmvZz3Q5tb80nS+oG/if+NBKrHC+Xw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "30.2.0", + "@jest/types": "30.2.0", "@types/node": "*", "anymatch": "^3.1.3", "fb-watchman": "^2.0.2", @@ -2454,24 +1898,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/test-sequencer/node_modules/jest-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", - "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "30.2.0", - "@types/node": "*", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "graceful-fs": "^4.2.11", - "picomatch": "^4.0.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/@jest/test-sequencer/node_modules/jest-worker": { "version": "30.2.0", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.2.0.tgz", @@ -2489,19 +1915,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/test-sequencer/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/@jest/test-sequencer/node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -2528,65 +1941,23 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/@jest/transform": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", - "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.2" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/transform/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/types": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", + "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", + "@jest/pattern": "30.0.1", + "@jest/schemas": "30.0.5", + "@types/istanbul-lib-coverage": "^2.0.6", + "@types/istanbul-reports": "^3.0.4", "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" + "@types/yargs": "^17.0.33", + "chalk": "^4.1.2" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jridgewell/gen-mapping": { @@ -2715,13 +2086,11 @@ } }, "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "version": "0.34.48", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", + "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", "dev": true, - "license": "MIT", - "optional": true, - "peer": true + "license": "MIT" }, "node_modules/@sindresorhus/merge-streams": { "version": "2.3.0", @@ -2873,18 +2242,6 @@ "@types/node": "*" } }, - "node_modules/@types/graceful-fs": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", - "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", @@ -3659,98 +3016,6 @@ "node": ">=6" } }, - "node_modules/babel-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", - "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "@jest/transform": "^29.7.0", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.6.3", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.8.0" - } - }, - "node_modules/babel-jest/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "license": "BSD-3-Clause", - "optional": true, - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", - "dev": true, - "license": "BSD-3-Clause", - "optional": true, - "peer": true, - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-jest-hoist": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", - "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/babel-preset-current-node-syntax": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", @@ -3778,25 +3043,6 @@ "@babel/core": "^7.0.0 || ^8.0.0-0" } }, - "node_modules/babel-preset-jest": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", - "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "babel-plugin-jest-hoist": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -4024,9 +3270,9 @@ } }, "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", "dev": true, "funding": [ { @@ -4035,8 +3281,6 @@ } ], "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">=8" } @@ -4565,127 +3809,41 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/expect/node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } + "license": "MIT" }, - "node_modules/expect/node_modules/@jest/types": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "dev": true, "license": "MIT", "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=8.6.0" } }, - "node_modules/expect/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true, "license": "MIT" }, - "node_modules/expect/node_modules/ci-info": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", - "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/expect/node_modules/jest-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", - "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "30.2.0", - "@types/node": "*", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "graceful-fs": "^4.2.11", - "picomatch": "^4.0.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/expect/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-uri": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", - "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "node_modules/fast-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", "dev": true, "funding": [ { @@ -5363,92 +4521,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-changed-files/node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-changed-files/node_modules/@jest/types": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-changed-files/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", - "dev": true, - "license": "MIT" - }, - "node_modules/jest-changed-files/node_modules/ci-info": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", - "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-changed-files/node_modules/jest-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", - "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "30.2.0", - "@types/node": "*", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "graceful-fs": "^4.2.11", - "picomatch": "^4.0.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-changed-files/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/jest-circus": { "version": "30.2.0", "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.2.0.tgz", @@ -5481,92 +4553,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-circus/node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-circus/node_modules/@jest/types": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-circus/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", - "dev": true, - "license": "MIT" - }, - "node_modules/jest-circus/node_modules/ci-info": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", - "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-circus/node_modules/jest-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", - "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "30.2.0", - "@types/node": "*", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "graceful-fs": "^4.2.11", - "picomatch": "^4.0.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-circus/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/jest-circus/node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -5610,101 +4596,15 @@ } } }, - "node_modules/jest-cli/node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-cli/node_modules/@jest/types": { + "node_modules/jest-config": { "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.2.0.tgz", + "integrity": "sha512-g4WkyzFQVWHtu6uqGmQR4CQxz/CH3yDSlhzXMWzNjDx843gYjReZnMRanjRCq5XZFuQrGDxgUaiYWE8BRfVckA==", "dev": true, "license": "MIT", "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-cli/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", - "dev": true, - "license": "MIT" - }, - "node_modules/jest-cli/node_modules/ci-info": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", - "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-cli/node_modules/jest-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", - "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "30.2.0", - "@types/node": "*", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "graceful-fs": "^4.2.11", - "picomatch": "^4.0.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-cli/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/jest-config": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.2.0.tgz", - "integrity": "sha512-g4WkyzFQVWHtu6uqGmQR4CQxz/CH3yDSlhzXMWzNjDx843gYjReZnMRanjRCq5XZFuQrGDxgUaiYWE8BRfVckA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.27.4", - "@jest/get-type": "30.1.0", + "@babel/core": "^7.27.4", + "@jest/get-type": "30.1.0", "@jest/pattern": "30.0.1", "@jest/test-sequencer": "30.2.0", "@jest/types": "30.2.0", @@ -5748,19 +4648,6 @@ } } }, - "node_modules/jest-config/node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/jest-config/node_modules/@jest/transform": { "version": "30.2.0", "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.2.0.tgz", @@ -5788,32 +4675,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-config/node_modules/@jest/types": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-config/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", - "dev": true, - "license": "MIT" - }, "node_modules/jest-config/node_modules/babel-jest": { "version": "30.2.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.2.0.tgz", @@ -5896,22 +4757,6 @@ "balanced-match": "^1.0.0" } }, - "node_modules/jest-config/node_modules/ci-info": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", - "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/jest-config/node_modules/glob": { "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", @@ -5968,24 +4813,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-config/node_modules/jest-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", - "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "30.2.0", - "@types/node": "*", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "graceful-fs": "^4.2.11", - "picomatch": "^4.0.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/jest-config/node_modules/jest-worker": { "version": "30.2.0", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.2.0.tgz", @@ -6019,19 +4846,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/jest-config/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/jest-config/node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", @@ -6131,92 +4945,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-each/node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-each/node_modules/@jest/types": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-each/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", - "dev": true, - "license": "MIT" - }, - "node_modules/jest-each/node_modules/ci-info": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", - "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-each/node_modules/jest-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", - "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "30.2.0", - "@types/node": "*", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "graceful-fs": "^4.2.11", - "picomatch": "^4.0.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-each/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/jest-environment-node": { "version": "30.2.0", "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.2.0.tgz", @@ -6236,120 +4964,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-environment-node/node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-environment-node/node_modules/@jest/types": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-environment-node/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", - "dev": true, - "license": "MIT" - }, - "node_modules/jest-environment-node/node_modules/ci-info": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", - "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-environment-node/node_modules/jest-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", - "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "30.2.0", - "@types/node": "*", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "graceful-fs": "^4.2.11", - "picomatch": "^4.0.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-environment-node/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/jest-haste-map": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", - "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "@jest/types": "^29.6.3", - "@types/graceful-fs": "^4.1.3", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "micromatch": "^4.0.4", - "walker": "^1.0.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" - } - }, "node_modules/jest-junit": { "version": "16.0.0", "resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-16.0.0.tgz", @@ -6417,45 +5031,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-message-util/node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-message-util/node_modules/@jest/types": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-message-util/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", - "dev": true, - "license": "MIT" - }, "node_modules/jest-message-util/node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -6481,92 +5056,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-mock/node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-mock/node_modules/@jest/types": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-mock/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", - "dev": true, - "license": "MIT" - }, - "node_modules/jest-mock/node_modules/ci-info": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", - "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-mock/node_modules/jest-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", - "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "30.2.0", - "@types/node": "*", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "graceful-fs": "^4.2.11", - "picomatch": "^4.0.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-mock/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/jest-pnp-resolver": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", @@ -6585,18 +5074,6 @@ } } }, - "node_modules/jest-regex-util": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", - "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/jest-resolve": { "version": "30.2.0", "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.2.0.tgz", @@ -6619,81 +5096,26 @@ }, "node_modules/jest-resolve-dependencies": { "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.2.0.tgz", - "integrity": "sha512-xTOIGug/0RmIe3mmCqCT95yO0vj6JURrn1TKWlNbhiAefJRWINNPgwVkrVgt/YaerPzY3iItufd80v3lOrFJ2w==", - "dev": true, - "license": "MIT", - "dependencies": { - "jest-regex-util": "30.0.1", - "jest-snapshot": "30.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-resolve-dependencies/node_modules/jest-regex-util": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz", - "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-resolve/node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-resolve/node_modules/@jest/types": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.2.0.tgz", + "integrity": "sha512-xTOIGug/0RmIe3mmCqCT95yO0vj6JURrn1TKWlNbhiAefJRWINNPgwVkrVgt/YaerPzY3iItufd80v3lOrFJ2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-regex-util": "30.0.1", + "jest-snapshot": "30.2.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-resolve/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", - "dev": true, - "license": "MIT" - }, - "node_modules/jest-resolve/node_modules/ci-info": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", - "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", + "node_modules/jest-resolve-dependencies/node_modules/jest-regex-util": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz", + "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], "license": "MIT", "engines": { - "node": ">=8" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-resolve/node_modules/jest-haste-map": { @@ -6731,24 +5153,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-resolve/node_modules/jest-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", - "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "30.2.0", - "@types/node": "*", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "graceful-fs": "^4.2.11", - "picomatch": "^4.0.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/jest-resolve/node_modules/jest-worker": { "version": "30.2.0", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.2.0.tgz", @@ -6766,19 +5170,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-resolve/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/jest-resolve/node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -6839,19 +5230,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-runner/node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/jest-runner/node_modules/@jest/transform": { "version": "30.2.0", "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.2.0.tgz", @@ -6879,32 +5257,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-runner/node_modules/@jest/types": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-runner/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", - "dev": true, - "license": "MIT" - }, "node_modules/jest-runner/node_modules/babel-plugin-istanbul": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz", @@ -6925,22 +5277,6 @@ "node": ">=12" } }, - "node_modules/jest-runner/node_modules/ci-info": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", - "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/jest-runner/node_modules/jest-haste-map": { "version": "30.2.0", "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.2.0.tgz", @@ -6976,24 +5312,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-runner/node_modules/jest-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", - "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "30.2.0", - "@types/node": "*", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "graceful-fs": "^4.2.11", - "picomatch": "^4.0.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/jest-runner/node_modules/jest-worker": { "version": "30.2.0", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.2.0.tgz", @@ -7011,19 +5329,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-runner/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/jest-runner/node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", @@ -7122,19 +5427,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-runtime/node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/jest-runtime/node_modules/@jest/transform": { "version": "30.2.0", "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.2.0.tgz", @@ -7162,32 +5454,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-runtime/node_modules/@jest/types": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-runtime/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", - "dev": true, - "license": "MIT" - }, "node_modules/jest-runtime/node_modules/babel-plugin-istanbul": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz", @@ -7218,22 +5484,6 @@ "balanced-match": "^1.0.0" } }, - "node_modules/jest-runtime/node_modules/ci-info": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", - "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/jest-runtime/node_modules/glob": { "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", @@ -7290,24 +5540,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-runtime/node_modules/jest-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", - "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "30.2.0", - "@types/node": "*", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "graceful-fs": "^4.2.11", - "picomatch": "^4.0.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/jest-runtime/node_modules/jest-worker": { "version": "30.2.0", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.2.0.tgz", @@ -7341,19 +5573,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/jest-runtime/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/jest-runtime/node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", @@ -7440,19 +5659,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-snapshot/node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/jest-snapshot/node_modules/@jest/transform": { "version": "30.2.0", "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.2.0.tgz", @@ -7480,66 +5686,24 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-snapshot/node_modules/@jest/types": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-snapshot/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", - "dev": true, - "license": "MIT" - }, "node_modules/jest-snapshot/node_modules/babel-plugin-istanbul": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz", "integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==", "dev": true, "license": "BSD-3-Clause", - "workspaces": [ - "test/babel-8" - ], - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.3", - "istanbul-lib-instrument": "^6.0.2", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/jest-snapshot/node_modules/ci-info": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", - "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } + "workspaces": [ + "test/babel-8" ], - "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-instrument": "^6.0.2", + "test-exclude": "^6.0.0" + }, "engines": { - "node": ">=8" + "node": ">=12" } }, "node_modules/jest-snapshot/node_modules/jest-haste-map": { @@ -7577,24 +5741,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-snapshot/node_modules/jest-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", - "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "30.2.0", - "@types/node": "*", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "graceful-fs": "^4.2.11", - "picomatch": "^4.0.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/jest-snapshot/node_modules/jest-worker": { "version": "30.2.0", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.2.0.tgz", @@ -7612,19 +5758,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-snapshot/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/jest-snapshot/node_modules/semver": { "version": "7.7.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", @@ -7692,23 +5825,34 @@ } }, "node_modules/jest-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", + "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { - "@jest/types": "^29.6.3", + "@jest/types": "30.2.0", "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "graceful-fs": "^4.2.11", + "picomatch": "^4.0.2" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-util/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/jest-validate": { @@ -7729,45 +5873,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-validate/node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-validate/node_modules/@jest/types": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-validate/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", - "dev": true, - "license": "MIT" - }, "node_modules/jest-validate/node_modules/camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", @@ -7801,167 +5906,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-watcher/node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-watcher/node_modules/@jest/types": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-watcher/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", - "dev": true, - "license": "MIT" - }, - "node_modules/jest-watcher/node_modules/ci-info": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", - "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-watcher/node_modules/jest-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", - "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "30.2.0", - "@types/node": "*", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "graceful-fs": "^4.2.11", - "picomatch": "^4.0.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-watcher/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/jest-worker": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", - "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "@types/node": "*", - "jest-util": "^29.7.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/jest/node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest/node_modules/@jest/types": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", - "dev": true, - "license": "MIT" - }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -8601,26 +6545,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/pretty-format/node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/pretty-format/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", - "dev": true, - "license": "MIT" - }, "node_modules/pretty-format/node_modules/ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", @@ -10091,22 +8015,6 @@ "dev": true, "license": "ISC" }, - "node_modules/write-file-atomic": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", - "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", - "dev": true, - "license": "ISC", - "optional": true, - "peer": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, "node_modules/xml": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", diff --git a/packages/pyright-internal/package.json b/packages/pyright-internal/package.json index 990232d58b82..4ea3a9db86b9 100644 --- a/packages/pyright-internal/package.json +++ b/packages/pyright-internal/package.json @@ -46,6 +46,7 @@ "esbuild-loader": "^4.4.0", "jest": "^30.2.0", "jest-junit": "^16.0.0", + "jest-util": "^30.2.0", "shx": "^0.4.0", "ts-jest": "^29.4.5", "ts-loader": "^9.5.4", diff --git a/packages/pyright-internal/src/tests/tokenizer.test.ts b/packages/pyright-internal/src/tests/tokenizer.test.ts index d755a972498f..6482413e1890 100644 --- a/packages/pyright-internal/src/tests/tokenizer.test.ts +++ b/packages/pyright-internal/src/tests/tokenizer.test.ts @@ -1857,3 +1857,439 @@ test('Last empty line', () => { assert.equal(eofToken.type, TokenType.EndOfStream); assert.equal(eofToken.length, 0); }); + +test('Strings: template string (t-string) single quoted', () => { + const t = new Tokenizer(); + const results = t.tokenize("t'hello {name}'"); + // Tokens: FStringStart, FStringMiddle('hello '), OpenCurlyBrace, Identifier(name), CloseCurlyBrace, FStringEnd + assert.equal(results.tokens.count, 6 + _implicitTokenCount); + + const startToken = results.tokens.getItemAt(0) as FStringStartToken; + assert.equal(startToken.type, TokenType.FStringStart); + assert.equal(startToken.flags & StringTokenFlags.Template, StringTokenFlags.Template); + assert.equal(startToken.flags & StringTokenFlags.SingleQuote, StringTokenFlags.SingleQuote); + assert.equal(startToken.prefixLength, 1); + + const middleToken1 = results.tokens.getItemAt(1) as FStringMiddleToken; + assert.equal(middleToken1.type, TokenType.FStringMiddle); + assert.equal(middleToken1.escapedValue, 'hello '); + + assert.equal(results.tokens.getItemAt(2).type, TokenType.OpenCurlyBrace); + + const identToken = results.tokens.getItemAt(3) as IdentifierToken; + assert.equal(identToken.type, TokenType.Identifier); + assert.equal(identToken.value, 'name'); + + assert.equal(results.tokens.getItemAt(4).type, TokenType.CloseCurlyBrace); + + const endToken = results.tokens.getItemAt(5) as FStringEndToken; + assert.equal(endToken.type, TokenType.FStringEnd); + assert.equal(endToken.flags & StringTokenFlags.Template, StringTokenFlags.Template); +}); + +test('Strings: template string (t-string) double quoted', () => { + const t = new Tokenizer(); + const results = t.tokenize('T"value: {x}"'); + // Tokens: FStringStart, FStringMiddle('value: '), OpenCurlyBrace, Identifier(x), CloseCurlyBrace, FStringEnd + assert.equal(results.tokens.count, 6 + _implicitTokenCount); + + const startToken = results.tokens.getItemAt(0) as FStringStartToken; + assert.equal(startToken.type, TokenType.FStringStart); + assert.equal(startToken.flags & StringTokenFlags.Template, StringTokenFlags.Template); + assert.equal(startToken.flags & StringTokenFlags.DoubleQuote, StringTokenFlags.DoubleQuote); +}); + +test('Strings: raw template string (rt-string)', () => { + const t = new Tokenizer(); + const results = t.tokenize('rt"path: {p}\\n"'); + // Tokens: FStringStart, FStringMiddle('path: '), OpenCurlyBrace, Identifier(p), CloseCurlyBrace, FStringMiddle('\n'), FStringEnd + assert.equal(results.tokens.count, 7 + _implicitTokenCount); + + const startToken = results.tokens.getItemAt(0) as FStringStartToken; + assert.equal(startToken.type, TokenType.FStringStart); + assert.equal(startToken.flags & StringTokenFlags.Template, StringTokenFlags.Template); + assert.equal(startToken.flags & StringTokenFlags.Raw, StringTokenFlags.Raw); + assert.equal(startToken.prefixLength, 2); +}); + +test('Strings: template raw string (tr-string)', () => { + const t = new Tokenizer(); + const results = t.tokenize('TR"data: {d}\\t"'); + // Tokens: FStringStart, FStringMiddle('data: '), OpenCurlyBrace, Identifier(d), CloseCurlyBrace, FStringMiddle('\t'), FStringEnd + assert.equal(results.tokens.count, 7 + _implicitTokenCount); + + const startToken = results.tokens.getItemAt(0) as FStringStartToken; + assert.equal(startToken.type, TokenType.FStringStart); + assert.equal(startToken.flags & StringTokenFlags.Template, StringTokenFlags.Template); + assert.equal(startToken.flags & StringTokenFlags.Raw, StringTokenFlags.Raw); +}); + +test('Strings: multiline template string', () => { + const t = new Tokenizer(); + const results = t.tokenize('t"""multi\nline {x}"""'); + + const startToken = results.tokens.getItemAt(0) as FStringStartToken; + assert.equal(startToken.type, TokenType.FStringStart); + assert.equal(startToken.flags & StringTokenFlags.Template, StringTokenFlags.Template); + assert.equal(startToken.flags & StringTokenFlags.Triplicate, StringTokenFlags.Triplicate); +}); + +test('Matrix multiply operator', () => { + const t = new Tokenizer(); + const results = t.tokenize('a @ b'); + assert.equal(results.tokens.count, 3 + _implicitTokenCount); + + assert.equal(results.tokens.getItemAt(0).type, TokenType.Identifier); + const opToken = results.tokens.getItemAt(1) as OperatorToken; + assert.equal(opToken.type, TokenType.Operator); + assert.equal(opToken.operatorType, OperatorType.MatrixMultiply); + assert.equal(results.tokens.getItemAt(2).type, TokenType.Identifier); +}); + +test('Matrix multiply assignment operator', () => { + const t = new Tokenizer(); + const results = t.tokenize('a @= b'); + assert.equal(results.tokens.count, 3 + _implicitTokenCount); + + assert.equal(results.tokens.getItemAt(0).type, TokenType.Identifier); + const opToken = results.tokens.getItemAt(1) as OperatorToken; + assert.equal(opToken.type, TokenType.Operator); + assert.equal(opToken.operatorType, OperatorType.MatrixMultiplyEqual); + assert.equal(results.tokens.getItemAt(2).type, TokenType.Identifier); +}); + +test('All keywords', () => { + const t = new Tokenizer(); + const keywords = [ + 'and', + 'as', + 'assert', + 'async', + 'await', + 'break', + 'case', + 'class', + 'continue', + '__debug__', + 'def', + 'del', + 'elif', + 'else', + 'except', + 'finally', + 'for', + 'from', + 'global', + 'if', + 'import', + 'in', + 'is', + 'lambda', + 'match', + 'nonlocal', + 'not', + 'or', + 'pass', + 'raise', + 'return', + 'try', + 'type', + 'while', + 'with', + 'yield', + 'False', + 'None', + 'True', + ]; + const text = keywords.join(' '); + const results = t.tokenize(text); + + // All should be keyword tokens (soft keywords like match/case/type are still keywords) + for (let i = 0; i < keywords.length; i++) { + const token = results.tokens.getItemAt(i); + assert.equal(token.type, TokenType.Keyword, `Expected keyword for "${keywords[i]}" at index ${i}`); + } +}); + +test('Soft keywords as identifiers', () => { + const t = new Tokenizer(); + // Soft keywords (match, case, type) can be used as identifiers + const results = t.tokenize('match = 1\ncase = 2\ntype = 3'); + + // First 'match' - will be tokenized as keyword initially + // (context determines if it's a soft keyword) + assert.equal(results.tokens.getItemAt(0).type, TokenType.Keyword); +}); + +test('Unicode identifiers', () => { + const t = new Tokenizer(); + const results = t.tokenize('ฯ€ = 3.14\nใ“ใ‚“ใซใกใฏ = "hello"\nๅ˜้‡ = 42'); + + // Tokens: ฯ€, =, 3.14, NewLine, ใ“ใ‚“ใซใกใฏ, =, "hello", NewLine, ๅ˜้‡, =, 42, NewLine, EOF + const piToken = results.tokens.getItemAt(0) as IdentifierToken; + assert.equal(piToken.type, TokenType.Identifier); + assert.equal(piToken.value, 'ฯ€'); + + const japaneseToken = results.tokens.getItemAt(4) as IdentifierToken; + assert.equal(japaneseToken.type, TokenType.Identifier); + assert.equal(japaneseToken.value, 'ใ“ใ‚“ใซใกใฏ'); + + const chineseToken = results.tokens.getItemAt(8) as IdentifierToken; + assert.equal(chineseToken.type, TokenType.Identifier); + assert.equal(chineseToken.value, 'ๅ˜้‡'); +}); + +test('Complex number literals', () => { + const t = new Tokenizer(); + const results = t.tokenize('1j 2.5j 1e10j 0x1fj'); + + const token1 = results.tokens.getItemAt(0) as NumberToken; + assert.equal(token1.type, TokenType.Number); + assert.equal(token1.isImaginary, true); + + const token2 = results.tokens.getItemAt(1) as NumberToken; + assert.equal(token2.type, TokenType.Number); + assert.equal(token2.isImaginary, true); + + const token3 = results.tokens.getItemAt(2) as NumberToken; + assert.equal(token3.type, TokenType.Number); + assert.equal(token3.isImaginary, true); +}); + +test('Number with leading zeros', () => { + const t = new Tokenizer(); + const results = t.tokenize('0 00 000 0.0 0e0'); + + for (let i = 0; i < 5; i++) { + assert.equal(results.tokens.getItemAt(i).type, TokenType.Number); + } +}); + +test('String with all escape sequences', () => { + const t = new Tokenizer(); + // Test all standard escape sequences + const results = t.tokenize('"\\n\\r\\t\\\\\\\'\\"\\\\\\"'); + + const stringToken = results.tokens.getItemAt(0) as StringToken; + assert.equal(stringToken.type, TokenType.String); +}); + +test('Continuation line in expression', () => { + const t = new Tokenizer(); + const results = t.tokenize('a = 1 + \\\n 2 + \\\n 3'); + + // Should have: a, =, 1, +, 2, +, 3 (continuation lines should be handled) + assert.equal(results.tokens.getItemAt(0).type, TokenType.Identifier); + assert.equal(results.tokens.getItemAt(1).type, TokenType.Operator); + assert.equal(results.tokens.getItemAt(2).type, TokenType.Number); + assert.equal(results.tokens.getItemAt(3).type, TokenType.Operator); + assert.equal(results.tokens.getItemAt(4).type, TokenType.Number); + assert.equal(results.tokens.getItemAt(5).type, TokenType.Operator); + assert.equal(results.tokens.getItemAt(6).type, TokenType.Number); +}); + +test('Mixed indent tabs and spaces', () => { + const t = new Tokenizer(); + const results = t.tokenize('if True:\n x = 1\n\ty = 2'); + + // Should still produce valid tokens even with mixed indentation + assert.equal(results.tokens.getItemAt(0).type, TokenType.Keyword); // if + assert.equal(results.tokens.getItemAt(1).type, TokenType.Keyword); // True + assert.equal(results.tokens.getItemAt(2).type, TokenType.Colon); +}); + +test('Empty f-string', () => { + const t = new Tokenizer(); + const results = t.tokenize('f""'); + + const startToken = results.tokens.getItemAt(0) as FStringStartToken; + assert.equal(startToken.type, TokenType.FStringStart); + assert.equal(startToken.flags & StringTokenFlags.Format, StringTokenFlags.Format); + + const endToken = results.tokens.getItemAt(1) as FStringEndToken; + assert.equal(endToken.type, TokenType.FStringEnd); +}); + +test('Empty template string', () => { + const t = new Tokenizer(); + const results = t.tokenize('t""'); + + const startToken = results.tokens.getItemAt(0) as FStringStartToken; + assert.equal(startToken.type, TokenType.FStringStart); + assert.equal(startToken.flags & StringTokenFlags.Template, StringTokenFlags.Template); + + const endToken = results.tokens.getItemAt(1) as FStringEndToken; + assert.equal(endToken.type, TokenType.FStringEnd); +}); + +test('Deeply nested f-string', () => { + const t = new Tokenizer(); + const results = t.tokenize('f"{f\'{f\\"{x}\\"}\'}"'); + + // Should handle nested f-strings with different quote styles + const startToken = results.tokens.getItemAt(0) as FStringStartToken; + assert.equal(startToken.type, TokenType.FStringStart); +}); + +test('F-string with expression containing colon', () => { + const t = new Tokenizer(); + const results = t.tokenize('f"{d[\'key\']}"'); + + const startToken = results.tokens.getItemAt(0) as FStringStartToken; + assert.equal(startToken.type, TokenType.FStringStart); +}); + +test('Very long identifier', () => { + const t = new Tokenizer(); + const longName = 'a'.repeat(1000); + const results = t.tokenize(longName); + + const identToken = results.tokens.getItemAt(0) as IdentifierToken; + assert.equal(identToken.type, TokenType.Identifier); + assert.equal(identToken.value, longName); + assert.equal(identToken.length, 1000); +}); + +test('Very long string', () => { + const t = new Tokenizer(); + const longContent = 'x'.repeat(10000); + const results = t.tokenize(`"${longContent}"`); + + const stringToken = results.tokens.getItemAt(0) as StringToken; + assert.equal(stringToken.type, TokenType.String); + assert.equal(stringToken.escapedValue, longContent); +}); + +test('Very long number', () => { + const t = new Tokenizer(); + const longNumber = '9'.repeat(100); + const results = t.tokenize(longNumber); + + const numToken = results.tokens.getItemAt(0) as NumberToken; + assert.equal(numToken.type, TokenType.Number); + assert.equal(numToken.isInteger, true); +}); + +test('Special Unicode in string', () => { + const t = new Tokenizer(); + const results = t.tokenize('"\\N{GREEK SMALL LETTER PI}"'); + + const stringToken = results.tokens.getItemAt(0) as StringToken; + assert.equal(stringToken.type, TokenType.String); + assert.equal(stringToken.flags & StringTokenFlags.NamedUnicodeEscape, StringTokenFlags.NamedUnicodeEscape); +}); + +test('Multiple operators without spaces', () => { + const t = new Tokenizer(); + const results = t.tokenize('a+b-c*d/e//f%g**h'); + + // Should correctly tokenize all operators + const expectedTypes = [ + TokenType.Identifier, + TokenType.Operator, // a + + TokenType.Identifier, + TokenType.Operator, // b - + TokenType.Identifier, + TokenType.Operator, // c * + TokenType.Identifier, + TokenType.Operator, // d / + TokenType.Identifier, + TokenType.Operator, // e // + TokenType.Identifier, + TokenType.Operator, // f % + TokenType.Identifier, + TokenType.Operator, // g ** + TokenType.Identifier, // h + ]; + + for (let i = 0; i < expectedTypes.length; i++) { + assert.equal(results.tokens.getItemAt(i).type, expectedTypes[i], `Token ${i} type mismatch`); + } +}); + +test('Comparison operators chain', () => { + const t = new Tokenizer(); + const results = t.tokenize('a < b <= c == d != e >= f > g'); + + const operators = [ + OperatorType.LessThan, + OperatorType.LessThanOrEqual, + OperatorType.Equals, + OperatorType.NotEquals, + OperatorType.GreaterThanOrEqual, + OperatorType.GreaterThan, + ]; + + let opIndex = 0; + for (let i = 0; i < results.tokens.count - _implicitTokenCount; i++) { + const token = results.tokens.getItemAt(i); + if (token.type === TokenType.Operator) { + assert.equal((token as OperatorToken).operatorType, operators[opIndex], `Operator ${opIndex} mismatch`); + opIndex++; + } + } + assert.equal(opIndex, operators.length, 'Not all operators were found'); +}); + +test('Bitwise operators', () => { + const t = new Tokenizer(); + const results = t.tokenize('a & b | c ^ d ~ e << f >> g'); + + const expectedOperators = [ + OperatorType.BitwiseAnd, + OperatorType.BitwiseOr, + OperatorType.BitwiseXor, + OperatorType.BitwiseInvert, + OperatorType.LeftShift, + OperatorType.RightShift, + ]; + + let opIndex = 0; + for (let i = 0; i < results.tokens.count - _implicitTokenCount; i++) { + const token = results.tokens.getItemAt(i); + if (token.type === TokenType.Operator) { + assert.equal( + (token as OperatorToken).operatorType, + expectedOperators[opIndex], + `Bitwise operator ${opIndex} mismatch` + ); + opIndex++; + } + } +}); + +test('Assignment operators', () => { + const t = new Tokenizer(); + const results = t.tokenize('a = b += c -= d *= e /= f //= g %= h **= i &= j |= k ^= l <<= m >>= n @= o'); + + const expectedOperators = [ + OperatorType.Assign, + OperatorType.AddEqual, + OperatorType.SubtractEqual, + OperatorType.MultiplyEqual, + OperatorType.DivideEqual, + OperatorType.FloorDivideEqual, + OperatorType.ModEqual, + OperatorType.PowerEqual, + OperatorType.BitwiseAndEqual, + OperatorType.BitwiseOrEqual, + OperatorType.BitwiseXorEqual, + OperatorType.LeftShiftEqual, + OperatorType.RightShiftEqual, + OperatorType.MatrixMultiplyEqual, + ]; + + let opIndex = 0; + for (let i = 0; i < results.tokens.count - _implicitTokenCount; i++) { + const token = results.tokens.getItemAt(i); + if (token.type === TokenType.Operator) { + assert.equal( + (token as OperatorToken).operatorType, + expectedOperators[opIndex], + `Assignment operator ${opIndex} mismatch` + ); + opIndex++; + } + } + assert.equal(opIndex, expectedOperators.length, 'Not all assignment operators were found'); +}); From 68b0d86792351b38d25849eff551be40848f3819 Mon Sep 17 00:00:00 2001 From: Graham Wheeler <> Date: Fri, 6 Feb 2026 11:22:41 -0800 Subject: [PATCH 3/4] Add 85 parser statement type tests for Rust port preparation --- .../pyright-internal/src/tests/parser.test.ts | 862 ++++++++++++++++++ 1 file changed, 862 insertions(+) diff --git a/packages/pyright-internal/src/tests/parser.test.ts b/packages/pyright-internal/src/tests/parser.test.ts index ce22bd985ee9..77f22206c53f 100644 --- a/packages/pyright-internal/src/tests/parser.test.ts +++ b/packages/pyright-internal/src/tests/parser.test.ts @@ -167,3 +167,865 @@ test('TrailingBackslashCRAtEOF', () => { assert.strictEqual(errors.length > 0, true); assert.ok(errors.some((e) => e.message.includes('Unexpected EOF'))); }); + +// ============================================================================ +// Statement Type Tests +// ============================================================================ + +test('Statement: if/elif/else', () => { + const code = ` +if x: + pass +elif y: + pass +else: + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); + assert.equal(result.parserOutput.parseTree.d.statements.length, 1); + assert.equal(result.parserOutput.parseTree.d.statements[0].nodeType, ParseNodeType.If); +}); + +test('Statement: nested if', () => { + const code = ` +if x: + if y: + pass + else: + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: while loop', () => { + const code = ` +while True: + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); + assert.equal(result.parserOutput.parseTree.d.statements[0].nodeType, ParseNodeType.While); +}); + +test('Statement: while with else', () => { + const code = ` +while x: + pass +else: + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: for loop', () => { + const code = ` +for i in range(10): + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); + assert.equal(result.parserOutput.parseTree.d.statements[0].nodeType, ParseNodeType.For); +}); + +test('Statement: for with else', () => { + const code = ` +for i in items: + pass +else: + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: for with tuple unpacking', () => { + const code = ` +for a, b, c in items: + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: async for', () => { + const code = ` +async def f(): + async for i in items: + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: try/except', () => { + const code = ` +try: + pass +except: + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); + assert.equal(result.parserOutput.parseTree.d.statements[0].nodeType, ParseNodeType.Try); +}); + +test('Statement: try/except with type', () => { + const code = ` +try: + pass +except ValueError: + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: try/except with type and binding', () => { + const code = ` +try: + pass +except ValueError as e: + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: try/except multiple', () => { + const code = ` +try: + pass +except ValueError: + pass +except TypeError: + pass +except: + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: try/except/else/finally', () => { + const code = ` +try: + pass +except: + pass +else: + pass +finally: + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: try/finally', () => { + const code = ` +try: + pass +finally: + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: except* (exception groups)', () => { + const code = ` +try: + pass +except* ValueError: + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: function definition', () => { + const code = ` +def foo(): + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); + assert.equal(result.parserOutput.parseTree.d.statements[0].nodeType, ParseNodeType.Function); +}); + +test('Statement: function with parameters', () => { + const code = ` +def foo(a, b, c=1, *args, **kwargs): + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: function with type annotations', () => { + const code = ` +def foo(a: int, b: str = "") -> None: + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: function with positional-only parameters', () => { + const code = ` +def foo(a, b, /, c, d): + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: function with keyword-only parameters', () => { + const code = ` +def foo(a, *, b, c): + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: async function', () => { + const code = ` +async def foo(): + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: class definition', () => { + const code = ` +class Foo: + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); + assert.equal(result.parserOutput.parseTree.d.statements[0].nodeType, ParseNodeType.Class); +}); + +test('Statement: class with inheritance', () => { + const code = ` +class Foo(Bar, Baz): + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: class with metaclass', () => { + const code = ` +class Foo(metaclass=ABCMeta): + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: class with type parameters', () => { + const code = ` +class Foo[T]: + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: with statement', () => { + const code = ` +with open("file") as f: + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); + assert.equal(result.parserOutput.parseTree.d.statements[0].nodeType, ParseNodeType.With); +}); + +test('Statement: with multiple items', () => { + const code = ` +with open("a") as a, open("b") as b: + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: with parenthesized items', () => { + const code = ` +with ( + open("a") as a, + open("b") as b +): + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: async with', () => { + const code = ` +async def f(): + async with resource: + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: decorator', () => { + const code = ` +@decorator +def foo(): + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: decorator with arguments', () => { + const code = ` +@decorator(arg1, arg2) +def foo(): + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: multiple decorators', () => { + const code = ` +@decorator1 +@decorator2 +@decorator3 +class Foo: + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: import', () => { + const code = `import os`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); + assert.equal(result.parserOutput.parseTree.d.statements[0].nodeType, ParseNodeType.StatementList); +}); + +test('Statement: import multiple', () => { + const code = `import os, sys, json`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: import as', () => { + const code = `import numpy as np`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: import from', () => { + const code = `from os import path`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: import from multiple', () => { + const code = `from os import path, getcwd, chdir`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: import from with alias', () => { + const code = `from os import path as p`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: import from relative', () => { + const code = `from . import module`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: import from parent', () => { + const code = `from .. import module`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: import star', () => { + const code = `from os import *`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: import with parentheses', () => { + const code = `from os import ( + path, + getcwd, + chdir, +)`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: assert', () => { + const code = `assert x`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: assert with message', () => { + const code = `assert x, "error message"`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: assignment', () => { + const code = `x = 1`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: multiple assignment', () => { + const code = `x = y = z = 1`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: tuple unpacking', () => { + const code = `a, b, c = (1, 2, 3)`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: augmented assignment', () => { + const code = `x += 1`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: all augmented assignments', () => { + const code = ` +x += 1 +x -= 1 +x *= 1 +x /= 1 +x //= 1 +x %= 1 +x **= 1 +x &= 1 +x |= 1 +x ^= 1 +x <<= 1 +x >>= 1 +x @= 1 +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: annotated assignment', () => { + const code = `x: int = 1`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: annotated without value', () => { + const code = `x: int`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: del', () => { + const code = `del x`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: del multiple', () => { + const code = `del x, y, z`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: pass', () => { + const code = `pass`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: break', () => { + const code = ` +while True: + break +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: continue', () => { + const code = ` +while True: + continue +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: return', () => { + const code = ` +def foo(): + return +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: return with value', () => { + const code = ` +def foo(): + return 42 +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: raise', () => { + const code = `raise`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: raise with exception', () => { + const code = `raise ValueError()`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: raise from', () => { + const code = `raise ValueError() from original`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: global', () => { + const code = ` +def foo(): + global x +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: global multiple', () => { + const code = ` +def foo(): + global x, y, z +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: nonlocal', () => { + const code = ` +def outer(): + x = 1 + def inner(): + nonlocal x +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: match/case basic', () => { + const code = ` +match x: + case 1: + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); + assert.equal(result.parserOutput.parseTree.d.statements[0].nodeType, ParseNodeType.Match); +}); + +test('Statement: match/case multiple', () => { + const code = ` +match x: + case 1: + pass + case 2: + pass + case _: + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: match/case with guard', () => { + const code = ` +match x: + case n if n > 0: + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: match/case sequence pattern', () => { + const code = ` +match x: + case [a, b, c]: + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: match/case mapping pattern', () => { + const code = ` +match x: + case {"key": value}: + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: match/case class pattern', () => { + const code = ` +match x: + case Point(x=0, y=0): + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: match/case OR pattern', () => { + const code = ` +match x: + case 1 | 2 | 3: + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: match/case AS pattern', () => { + const code = ` +match x: + case [a, b] as whole: + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: type alias', () => { + const code = `type IntList = list[int]`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: type alias with type parameters', () => { + const code = `type Vector[T] = list[T]`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: function with type parameters', () => { + const code = ` +def foo[T](x: T) -> T: + return x +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: yield', () => { + const code = ` +def gen(): + yield 1 +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: yield from', () => { + const code = ` +def gen(): + yield from other_gen() +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: await', () => { + const code = ` +async def foo(): + await bar() +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: lambda', () => { + const code = `f = lambda x: x + 1`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: lambda with multiple parameters', () => { + const code = `f = lambda a, b, c=1: a + b + c`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: lambda with no parameters', () => { + const code = `f = lambda: 42`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: multiple statements on one line', () => { + const code = `a = 1; b = 2; c = 3`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: empty lines and comments', () => { + const code = ` +# This is a comment +x = 1 + +# Another comment + +y = 2 +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: line continuation', () => { + const code = ` +x = 1 + \\ + 2 + \\ + 3 +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: implicit line continuation in parens', () => { + const code = ` +x = (1 + + 2 + + 3) +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); + +test('Statement: walrus operator', () => { + const code = ` +if (n := len(items)) > 0: + pass +`; + const diagSink = new DiagnosticSink(); + const result = TestUtils.parseText(code, diagSink); + assert.equal(diagSink.getErrors().length, 0); +}); From ad09b4291b2788cead0c13c5cfea7ef85280fe47 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Feb 2026 19:24:06 +0000 Subject: [PATCH 4/4] Bump lodash from 4.17.21 to 4.17.23 Bumps [lodash](https://github.com/lodash/lodash) from 4.17.21 to 4.17.23. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23) --- updated-dependencies: - dependency-name: lodash dependency-version: 4.17.23 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9d6751a817f3..2160e149e987 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6363,9 +6363,9 @@ } }, "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", "dev": true, "license": "MIT" },