From be1298e30e47d1da882a56ad176fe7df9626b7dc Mon Sep 17 00:00:00 2001 From: nyaomaru Date: Sun, 25 Jan 2026 16:49:46 +0100 Subject: [PATCH 1/5] fix: keep dependency updates in Chore during categorization --- src/constants/markdown.ts | 1 + src/utils/category-tune.ts | 25 +++- src/utils/dependency-update.ts | 39 ++++++ src/utils/release.ts | 2 +- src/utils/section-postprocess.ts | 159 ++++++++++++++++++++++++ tests/utils/category-tune.test.ts | 21 ++++ tests/utils/dependency-update.test.ts | 31 +++++ tests/utils/section-postprocess.test.ts | 42 ++++--- 8 files changed, 300 insertions(+), 20 deletions(-) create mode 100644 src/utils/dependency-update.ts create mode 100644 tests/utils/dependency-update.test.ts diff --git a/src/constants/markdown.ts b/src/constants/markdown.ts index 4edb983..8f003b4 100644 --- a/src/constants/markdown.ts +++ b/src/constants/markdown.ts @@ -4,3 +4,4 @@ export const ANY_H2_HEADING_RE = /^##\s.*$/m; export const H3_SUBHEADER_CAPTURE_RE = /^###\s+(.+?)\s*$/; export const RELEASE_HEADER_CAPTURE_RE = /^##\s*\[([^\]]+)\](.*)$/; +export const BULLET_PREFIX_RE = /^[*-]\s+/; diff --git a/src/utils/category-tune.ts b/src/utils/category-tune.ts index d345d5d..b2fd203 100644 --- a/src/utils/category-tune.ts +++ b/src/utils/category-tune.ts @@ -18,6 +18,7 @@ import { scoreCategories, SCORE_THRESHOLDS, } from '@/utils/category-score.js'; +import { isDependencyUpdateTitle } from '@/utils/dependency-update.js'; import { isBucketName } from '@/utils/is.js'; import type { BucketName } from '@/types/changelog.js'; @@ -182,9 +183,23 @@ export function tuneCategoriesByTitle( if (!adjusted[SECTION_CHANGED]) adjusted[SECTION_CHANGED] = []; if (!adjusted[SECTION_ADDED]) adjusted[SECTION_ADDED] = []; + const allKnownTitles = Array.from(knownTitles); + + // Rule: Dependency-only updates should remain in Chore to avoid noise in Changed. + const dependencyUpdates: string[] = []; + for (const title of allKnownTitles) { + if (isDependencyUpdateTitle(title)) dependencyUpdates.push(title); + } + if (dependencyUpdates.length) + moveTitlesToCategory(adjusted, dependencyUpdates, SECTION_CHORE); + const dependencyUpdateSet = new Set(dependencyUpdates); + const nonDependencyTitles = allKnownTitles.filter( + (title) => !dependencyUpdateSet.has(title), + ); + // Collect titles that should be moved. const toMove: string[] = []; - for (const title of knownTitles) { + for (const title of nonDependencyTitles) { if (isImplicitFixTitle(title)) toMove.push(title); } @@ -196,7 +211,7 @@ export function tuneCategoriesByTitle( // Examples: fix: msg, fix!: msg, fix(scope): msg, fix(scope)!: msg const FIX_PREFIX_RE = /^fix(?:!:|(?:\([^)]*\))?!?:)/i; const conventionalFixes: string[] = []; - for (const title of knownTitles) { + for (const title of nonDependencyTitles) { if (FIX_PREFIX_RE.test(title)) conventionalFixes.push(title); } if (conventionalFixes.length) @@ -217,7 +232,7 @@ export function tuneCategoriesByTitle( }; const toChanged: string[] = []; - for (const title of knownTitles) { + for (const title of nonDependencyTitles) { if (!isRefactorLike(title) && !isChangeLike(title)) continue; const current = findCategory(title); if (current === SECTION_FIXED) continue; // don't override explicit/implicit fixes @@ -234,7 +249,7 @@ export function tuneCategoriesByTitle( // Examples: feat: msg, feat!: msg, feat(scope): msg, feat(scope)!: msg const FEAT_PREFIX_RE = /^feat(?:!:|(?:\([^)]*\))?!?:)/i; const toAdded: string[] = []; - for (const title of knownTitles) { + for (const title of nonDependencyTitles) { if (FEAT_PREFIX_RE.test(title)) toAdded.push(title); } if (toAdded.length) moveTitlesToCategory(adjusted, toAdded, SECTION_ADDED); @@ -245,7 +260,7 @@ export function tuneCategoriesByTitle( SECTION_DOCS, SECTION_TEST, ]); - for (const title of knownTitles) { + for (const title of nonDependencyTitles) { const current = findCategory(title); if (!current || !WEAK_BUCKETS.has(current)) continue; const scores = scoreCategories(title); diff --git a/src/utils/dependency-update.ts b/src/utils/dependency-update.ts new file mode 100644 index 0000000..54589cf --- /dev/null +++ b/src/utils/dependency-update.ts @@ -0,0 +1,39 @@ +import { CONVENTIONAL_PREFIX_RE } from '@/constants/conventional.js'; +import { BULLET_PREFIX_RE } from '@/constants/markdown.js'; +import { BUMP_OR_UPGRADE_RE, VERSION_FROM_TO_RE } from '@/constants/scoring.js'; + +const CONVENTIONAL_SCOPE_RE = /^[a-z]+(?:\(([^)]+)\))?!?:/i; +const DEP_SCOPE_RE = /\bdeps(?:-dev|-prod)?\b|\bdependencies?\b/i; +const DEP_BOT_RE = /\brenovate\b|\bdependabot\b|\bdeps?bot\b/i; +const DEP_ACTION_RE = /\b(bump|upgrade|update|pin|refresh|lockfile)\b/i; +const DEP_VERSION_RE = /\bto\s+v?\d+(?:\.\d+){0,3}\b/i; + +/** + * Detect whether a title represents a dependency-only update. + * @param rawTitle PR title or changelog bullet text to inspect. + * @returns True when the title looks like a dependency update. + */ +export function isDependencyUpdateTitle(rawTitle: string): boolean { + if (!rawTitle) return false; + const trimmedTitle = rawTitle.replace(BULLET_PREFIX_RE, '').trim(); + if (!trimmedTitle) return false; + + const scopeMatch = trimmedTitle.match(CONVENTIONAL_SCOPE_RE); + const scope = scopeMatch?.[1]; + if (scope && DEP_SCOPE_RE.test(scope)) return true; + + const lower = trimmedTitle.toLowerCase(); + if (DEP_BOT_RE.test(lower)) return true; + + const core = lower.replace(CONVENTIONAL_PREFIX_RE, '').trim(); + const hasDepPlural = /\bdeps\b|\bdependencies\b/.test(core); + const hasDepSingular = /\bdependency\b/.test(core); + const hasAction = DEP_ACTION_RE.test(core) || BUMP_OR_UPGRADE_RE.test(core); + const hasVersionHint = + VERSION_FROM_TO_RE.test(core) || DEP_VERSION_RE.test(core); + + if (hasDepPlural && hasAction) return true; + if (hasDepSingular && hasAction && hasVersionHint) return true; + + return false; +} diff --git a/src/utils/release.ts b/src/utils/release.ts index af44726..05b1c92 100644 --- a/src/utils/release.ts +++ b/src/utils/release.ts @@ -10,9 +10,9 @@ import { normalizeTitle, } from '@/utils/title-normalize.js'; import { FULL_CHANGELOG_RE } from '@/constants/release.js'; +import { BULLET_PREFIX_RE } from '@/constants/markdown.js'; const H2_HEADING_RE = /^##\s+(.*)$/; -const BULLET_PREFIX_RE = /^[*-]\s+/; const PR_URL_RE = /https?:\/\/\S+\/pull\/(\d+)/; // captures PR number const PR_REF_RE = /\(#?(\d+)\)|#(\d+)/; // (#123) or #123 const AUTHOR_RE = /@([A-Za-z0-9_-]+)/; diff --git a/src/utils/section-postprocess.ts b/src/utils/section-postprocess.ts index 87c1e96..ca8233c 100644 --- a/src/utils/section-postprocess.ts +++ b/src/utils/section-postprocess.ts @@ -1,5 +1,163 @@ import { removeMergedPRs } from '@/utils/remove-merged-prs.js'; import { attachPrNumbers } from '@/utils/attach-pr.js'; +import { isDependencyUpdateTitle } from '@/utils/dependency-update.js'; +import { + SECTION_CHANGED, + SECTION_CHORE, + SECTION_ORDER, +} from '@/constants/changelog.js'; +import { + BULLET_PREFIX_RE, + H3_SUBHEADER_CAPTURE_RE, +} from '@/constants/markdown.js'; + +const SECTION_ORDER_INDEX = new Map( + SECTION_ORDER.map((sectionName, index) => [sectionName.toLowerCase(), index]), +); + +type SectionBlock = { + headingLine: string; + name: string; + lines: string[]; +}; + +function parseSectionName(line: string): string | null { + const match = line.match(H3_SUBHEADER_CAPTURE_RE); + return match ? match[1].trim() : null; +} + +function splitSections(markdown: string): { + preamble: string[]; + sections: SectionBlock[]; +} { + const lines = markdown.split('\n'); + const preamble: string[] = []; + const sections: SectionBlock[] = []; + let current: SectionBlock | null = null; + + for (const line of lines) { + const heading = parseSectionName(line); + if (heading) { + if (current) sections.push(current); + current = { headingLine: line, name: heading, lines: [] }; + continue; + } + if (current) { + current.lines.push(line); + } else { + preamble.push(line); + } + } + + if (current) sections.push(current); + return { preamble, sections }; +} + +function hasMeaningfulContent(lines: string[]): boolean { + return lines.some((line) => line.trim().length > 0); +} + +function appendBulletLines(section: SectionBlock, bullets: string[]): void { + if (!bullets.length) return; + const existing = new Set( + section.lines + .filter((line) => BULLET_PREFIX_RE.test(line)) + .map((line) => line.trim()), + ); + const uniqueBullets = bullets.filter((line) => !existing.has(line.trim())); + if (!uniqueBullets.length) return; + + const hasContent = section.lines.some((line) => line.trim().length > 0); + if (!hasContent) { + section.lines = ['', ...uniqueBullets, '']; + return; + } + + if (!section.lines.length || section.lines[0].trim() !== '') { + section.lines.unshift(''); + } + + let insertIndex = section.lines.length; + while (insertIndex > 0 && section.lines[insertIndex - 1].trim() === '') { + insertIndex -= 1; + } + section.lines.splice(insertIndex, 0, ...uniqueBullets); + + if (!section.lines.length || section.lines[section.lines.length - 1].trim()) { + section.lines.push(''); + } +} + +function moveDependencyUpdatesToChore(markdown: string): string { + if (!markdown) return markdown; + const { preamble, sections } = splitSections(markdown); + if (!sections.length) return markdown; + + const changedIndex = sections.findIndex( + (section) => section.name.toLowerCase() === SECTION_CHANGED.toLowerCase(), + ); + if (changedIndex === -1) return markdown; + + const changedSection = sections[changedIndex]; + const movedBullets: string[] = []; + const retainedLines: string[] = []; + + for (const line of changedSection.lines) { + if (!BULLET_PREFIX_RE.test(line)) { + retainedLines.push(line); + continue; + } + const title = line.replace(BULLET_PREFIX_RE, '').trim(); + if (isDependencyUpdateTitle(title)) { + movedBullets.push(line); + } else { + retainedLines.push(line); + } + } + + if (!movedBullets.length) return markdown; + changedSection.lines = retainedLines; + + if (!hasMeaningfulContent(changedSection.lines)) { + sections.splice(changedIndex, 1); + } + + let choreSection = sections.find( + (section) => section.name.toLowerCase() === SECTION_CHORE.toLowerCase(), + ); + if (!choreSection) { + const choreOrder = + SECTION_ORDER_INDEX.get(SECTION_CHORE.toLowerCase()) ?? + Number.POSITIVE_INFINITY; + let insertIndex = sections.length; + for (let i = 0; i < sections.length; i += 1) { + const currentOrder = + SECTION_ORDER_INDEX.get(sections[i].name.toLowerCase()) ?? + Number.POSITIVE_INFINITY; + if (currentOrder > choreOrder) { + insertIndex = i; + break; + } + } + choreSection = { + headingLine: `### ${SECTION_CHORE}`, + name: SECTION_CHORE, + lines: [], + }; + sections.splice(insertIndex, 0, choreSection); + } + + appendBulletLines(choreSection, movedBullets); + + const output: string[] = []; + output.push(...preamble); + for (const section of sections) { + output.push(section.headingLine); + output.push(...section.lines); + } + + return output.join('\n').replace(/\n{3,}/g, '\n\n'); +} /** * Apply standard post-processing to a generated changelog section. @@ -17,5 +175,6 @@ export function postprocessSection( // WHY: Keep the section concise and link-rich for reviewers. let processedMarkdown = removeMergedPRs(markdown); processedMarkdown = attachPrNumbers(processedMarkdown, titleToPr, repo); + processedMarkdown = moveDependencyUpdatesToChore(processedMarkdown); return processedMarkdown; } diff --git a/tests/utils/category-tune.test.ts b/tests/utils/category-tune.test.ts index 5679151..cf52660 100644 --- a/tests/utils/category-tune.test.ts +++ b/tests/utils/category-tune.test.ts @@ -53,4 +53,25 @@ describe('tuneCategoriesByTitle', () => { expect(out.Added).toContain('feat(core)!: new something'); expect(out.Fixed).toContain('fix(api)!: patch issue'); }); + + test('keeps dependency-only updates in Chore', () => { + const items: ReleaseItem[] = [ + { + title: 'Update dependency prettier to v3.8.0', + rawTitle: 'chore(deps): Update dependency prettier to v3.8.0', + }, + ]; + const categories: CategoryMap = { + Changed: ['chore(deps): Update dependency prettier to v3.8.0'], + }; + const out = tuneCategoriesByTitle(items, categories); + expect(out.Chore).toContain( + 'chore(deps): Update dependency prettier to v3.8.0', + ); + expect( + out.Changed?.includes( + 'chore(deps): Update dependency prettier to v3.8.0', + ), + ).toBeFalsy(); + }); }); diff --git a/tests/utils/dependency-update.test.ts b/tests/utils/dependency-update.test.ts new file mode 100644 index 0000000..1541ec3 --- /dev/null +++ b/tests/utils/dependency-update.test.ts @@ -0,0 +1,31 @@ +import { describe, expect, test } from '@jest/globals'; +import { isDependencyUpdateTitle } from '@/utils/dependency-update.js'; + +describe('isDependencyUpdateTitle', () => { + test('detects conventional deps scope updates', () => { + expect( + isDependencyUpdateTitle( + 'chore(deps): Update dependency prettier to v3.8.0 #113', + ), + ).toBe(true); + expect( + isDependencyUpdateTitle( + 'chore(deps-dev): bump @types/node from 18 to 20', + ), + ).toBe(true); + }); + + test('detects dependency keywords with action and version hints', () => { + expect(isDependencyUpdateTitle('deps: update lockfile')).toBe(true); + expect( + isDependencyUpdateTitle('chore: bump dependency lodash from 4 to 5'), + ).toBe(true); + }); + + test('ignores non-dependency updates without version hints', () => { + expect(isDependencyUpdateTitle('chore: update dependency resolver')).toBe( + false, + ); + expect(isDependencyUpdateTitle('docs: update README')).toBe(false); + }); +}); diff --git a/tests/utils/section-postprocess.test.ts b/tests/utils/section-postprocess.test.ts index 678070f..38ed4ca 100644 --- a/tests/utils/section-postprocess.test.ts +++ b/tests/utils/section-postprocess.test.ts @@ -1,24 +1,38 @@ -// @ts-nocheck -import { describe, test, expect } from '@jest/globals'; +import { describe, expect, test } from '@jest/globals'; import { postprocessSection } from '@/utils/section-postprocess.js'; -describe('section-postprocess', () => { - test('removes merged PRs and attaches missing PR numbers', () => { - const input = [ - '## [v1.0.0] - 2024-01-01', +function extractSection(md: string, heading: string): string { + const pattern = new RegExp(`###\\s+${heading}[\\s\\S]*?(?=###\\s+|$)`, 'i'); + const match = md.match(pattern); + return match ? match[0] : ''; +} + +describe('postprocessSection', () => { + test('moves dependency update bullets from Changed to Chore', () => { + const markdown = [ + '## [v1.2.3] - 2025-01-01', + '', + '### Changed', + '', + '- chore(deps): Update dependency prettier to v3.8.0', + '- Refactor core pipeline', '', - '### Added', - '- Add Login', + '### Fixed', '', - '### Merged PRs', - '- Merge pull request #1 from foo', + '- Fix bug', '', ].join('\n'); - const titleToPr = { 'Add Login': 123 }; - const out = postprocessSection(input, titleToPr); + const out = postprocessSection(markdown, {}); + const changedSection = extractSection(out, 'Changed'); + const choreSection = extractSection(out, 'Chore'); - expect(out).toContain('- Add Login (#123)'); - expect(out).not.toContain('### Merged PRs'); + expect(changedSection).toContain('- Refactor core pipeline'); + expect(changedSection).not.toContain( + 'chore(deps): Update dependency prettier to v3.8.0', + ); + expect(choreSection).toContain( + '- chore(deps): Update dependency prettier to v3.8.0', + ); }); }); From 8f3e09f2f0fe7fc72eed216e09d099652d638dc2 Mon Sep 17 00:00:00 2001 From: nyaomaru Date: Sun, 25 Jan 2026 17:30:36 +0100 Subject: [PATCH 2/5] test: fix error --- package.json | 1 + pnpm-lock.yaml | 426 ++++++++++++++++++++++++++++---- tests/utils/github-auth.test.ts | 44 +++- 3 files changed, 410 insertions(+), 61 deletions(-) diff --git a/package.json b/package.json index 839564f..f73f6e2 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,7 @@ }, "devDependencies": { "@eslint/js": "^9.38.0", + "@jest/globals": "^30.2.0", "@types/jest": "^29.5.14", "@types/node": "^22.5.2", "@types/yargs": "^17.0.33", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e20dc98..8d549cc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,6 +23,9 @@ importers: '@eslint/js': specifier: ^9.38.0 version: 9.38.0 + '@jest/globals': + specifier: ^30.2.0 + version: 30.2.0 '@types/jest': specifier: ^29.5.14 version: 29.5.14 @@ -52,7 +55,7 @@ importers: version: 3.7.4 ts-jest: specifier: '29' - version: 29.4.1(@babel/core@7.28.5)(@jest/transform@30.1.2)(@jest/types@30.0.5)(babel-jest@30.1.2(@babel/core@7.28.5))(jest-util@30.0.5)(jest@29.7.0(@types/node@22.17.2)(ts-node@10.9.2(@types/node@22.17.2)(typescript@5.9.2)))(typescript@5.9.2) + version: 29.4.1(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.1.2(@babel/core@7.28.5))(jest-util@30.2.0)(jest@29.7.0(@types/node@22.17.2)(ts-node@10.9.2(@types/node@22.17.2)(typescript@5.9.2)))(typescript@5.9.2) ts-node: specifier: ^10.9.2 version: 10.9.2(@types/node@22.17.2)(typescript@5.9.2) @@ -513,6 +516,13 @@ packages: node-notifier: optional: true + '@jest/diff-sequences@30.0.1': + resolution: + { + integrity: sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + '@jest/environment@29.7.0': resolution: { @@ -520,6 +530,13 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + '@jest/environment@30.2.0': + resolution: + { + integrity: sha512-/QPTL7OBJQ5ac09UDRa3EQes4gt1FTEG/8jZ/4v5IVzx+Cv7dLxlVIvfvSVRiiX2drWyXeBjkMSR8hvOWSog5g==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + '@jest/expect-utils@29.7.0': resolution: { @@ -527,6 +544,13 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + '@jest/expect-utils@30.2.0': + resolution: + { + integrity: sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + '@jest/expect@29.7.0': resolution: { @@ -534,6 +558,13 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + '@jest/expect@30.2.0': + resolution: + { + integrity: sha512-V9yxQK5erfzx99Sf+7LbhBwNWEZ9eZay8qQ9+JSC0TrMR1pMDHLMY+BnVPacWU6Jamrh252/IKo4F1Xn/zfiqA==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + '@jest/fake-timers@29.7.0': resolution: { @@ -541,6 +572,20 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + '@jest/fake-timers@30.2.0': + resolution: + { + integrity: sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + + '@jest/get-type@30.1.0': + resolution: + { + integrity: sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + '@jest/globals@29.7.0': resolution: { @@ -548,6 +593,13 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + '@jest/globals@30.2.0': + resolution: + { + integrity: sha512-b63wmnKPaK+6ZZfpYhz9K61oybvbI1aMcIs80++JI1O1rR1vaxHUCNqo3ITu6NU0d4V34yZFoHMn/uoKr/Rwfw==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + '@jest/pattern@30.0.1': resolution: { @@ -581,6 +633,13 @@ packages: } engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + '@jest/snapshot-utils@30.2.0': + resolution: + { + integrity: sha512-0aVxM3RH6DaiLcjj/b0KrIBZhSX1373Xci4l3cW5xiUWPctZ59zQ7jj4rqcJQ/Z8JuN/4wX3FpJSa3RssVvCug==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + '@jest/source-map@29.6.3': resolution: { @@ -616,6 +675,13 @@ packages: } engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + '@jest/transform@30.2.0': + resolution: + { + integrity: sha512-XsauDV82o5qXbhalKxD7p4TZYYdwcaEXC77PPD2HixEFF+6YGppjrAAQurTl2ECWcEomHBMMNS9AH3kcCFx8jA==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + '@jest/types@29.6.3': resolution: { @@ -630,6 +696,13 @@ packages: } engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + '@jest/types@30.2.0': + resolution: + { + integrity: sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + '@jridgewell/gen-mapping@0.3.13': resolution: { @@ -876,6 +949,13 @@ packages: } engines: { node: '>= 18' } + '@pkgr/core@0.2.9': + resolution: + { + integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==, + } + engines: { node: ^12.20.0 || ^14.18.0 || >=16.0.0 } + '@sinclair/typebox@0.27.8': resolution: { @@ -900,6 +980,12 @@ packages: integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==, } + '@sinonjs/fake-timers@13.0.5': + resolution: + { + integrity: sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==, + } + '@tsconfig/node10@1.0.11': resolution: { @@ -1720,6 +1806,13 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + expect@30.2.0: + resolution: + { + integrity: sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + fast-content-type-parse@2.0.1: resolution: { @@ -2161,6 +2254,13 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + jest-diff@30.2.0: + resolution: + { + integrity: sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + jest-docblock@29.7.0: resolution: { @@ -2203,6 +2303,13 @@ packages: } engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + jest-haste-map@30.2.0: + resolution: + { + integrity: sha512-sQA/jCb9kNt+neM0anSj6eZhLZUIhQgwDt7cPGjumgLM4rXsfb9kpnlacmvZz3Q5tb80nS+oG/if+NBKrHC+Xw==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + jest-leak-detector@29.7.0: resolution: { @@ -2217,6 +2324,13 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + jest-matcher-utils@30.2.0: + resolution: + { + integrity: sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + jest-message-util@29.7.0: resolution: { @@ -2224,6 +2338,13 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + jest-message-util@30.2.0: + resolution: + { + integrity: sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + jest-mock@29.7.0: resolution: { @@ -2231,6 +2352,13 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + jest-mock@30.2.0: + resolution: + { + integrity: sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + jest-pnp-resolver@1.2.3: resolution: { @@ -2292,6 +2420,13 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + jest-snapshot@30.2.0: + resolution: + { + integrity: sha512-5WEtTy2jXPFypadKNpbNkZ72puZCa6UjSr/7djeecHWOu7iYhSXSnHScT8wBz3Rn8Ena5d5RYRcsyKIeqG1IyA==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + jest-util@29.7.0: resolution: { @@ -2306,6 +2441,13 @@ packages: } engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + jest-util@30.2.0: + resolution: + { + integrity: sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + jest-validate@29.7.0: resolution: { @@ -2334,6 +2476,13 @@ packages: } engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + jest-worker@30.2.0: + resolution: + { + integrity: sha512-0Q4Uk8WF7BUwqXHuAjc23vmopWJw5WH7w2tqBoUOZpOjW/ZnR44GXXd1r82RvnmI2GZge3ivrYXk/BE2+VtW2g==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + jest@29.7.0: resolution: { @@ -2855,6 +3004,13 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + pretty-format@30.2.0: + resolution: + { + integrity: sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + prompts@2.4.2: resolution: { @@ -3107,6 +3263,13 @@ packages: } engines: { node: '>= 0.4' } + synckit@0.11.12: + resolution: + { + integrity: sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==, + } + engines: { node: ^14.18.0 || >=16.0.0 } + test-exclude@6.0.0: resolution: { @@ -3447,7 +3610,6 @@ snapshots: semver: 6.3.1 transitivePeerDependencies: - supports-color - optional: true '@babel/generator@7.28.3': dependencies: @@ -3464,7 +3626,6 @@ snapshots: '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 - optional: true '@babel/helper-compilation-targets@7.27.2': dependencies: @@ -3500,7 +3661,6 @@ snapshots: '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color - optional: true '@babel/helper-plugin-utils@7.27.1': {} @@ -3508,8 +3668,7 @@ snapshots: '@babel/helper-validator-identifier@7.27.1': {} - '@babel/helper-validator-identifier@7.28.5': - optional: true + '@babel/helper-validator-identifier@7.28.5': {} '@babel/helper-validator-option@7.27.1': {} @@ -3525,7 +3684,6 @@ snapshots: '@babel/parser@7.28.5': dependencies: '@babel/types': 7.28.5 - optional: true '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.28.4)': dependencies: @@ -3536,7 +3694,6 @@ snapshots: dependencies: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 - optional: true '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.28.4)': dependencies: @@ -3547,7 +3704,6 @@ snapshots: dependencies: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 - optional: true '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.28.4)': dependencies: @@ -3558,7 +3714,6 @@ snapshots: dependencies: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 - optional: true '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.28.4)': dependencies: @@ -3569,7 +3724,6 @@ snapshots: dependencies: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 - optional: true '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.4)': dependencies: @@ -3580,7 +3734,6 @@ snapshots: dependencies: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 - optional: true '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.28.4)': dependencies: @@ -3591,7 +3744,6 @@ snapshots: dependencies: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 - optional: true '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.28.4)': dependencies: @@ -3602,13 +3754,17 @@ snapshots: dependencies: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 - optional: true '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 @@ -3618,7 +3774,6 @@ snapshots: dependencies: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 - optional: true '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.28.4)': dependencies: @@ -3629,7 +3784,6 @@ snapshots: dependencies: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 - optional: true '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.28.4)': dependencies: @@ -3640,7 +3794,6 @@ snapshots: dependencies: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 - optional: true '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.28.4)': dependencies: @@ -3651,7 +3804,6 @@ snapshots: dependencies: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 - optional: true '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.28.4)': dependencies: @@ -3662,7 +3814,6 @@ snapshots: dependencies: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 - optional: true '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.28.4)': dependencies: @@ -3673,7 +3824,6 @@ snapshots: dependencies: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 - optional: true '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.28.4)': dependencies: @@ -3684,7 +3834,6 @@ snapshots: dependencies: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 - optional: true '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.28.4)': dependencies: @@ -3695,13 +3844,17 @@ snapshots: dependencies: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 - optional: true '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/template@7.27.2': dependencies: '@babel/code-frame': 7.27.1 @@ -3731,7 +3884,6 @@ snapshots: debug: 4.4.3 transitivePeerDependencies: - supports-color - optional: true '@babel/types@7.28.4': dependencies: @@ -3742,7 +3894,6 @@ snapshots: dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 - optional: true '@bcoe/v8-coverage@0.2.3': {} @@ -3861,6 +4012,8 @@ snapshots: - supports-color - ts-node + '@jest/diff-sequences@30.0.1': {} + '@jest/environment@29.7.0': dependencies: '@jest/fake-timers': 29.7.0 @@ -3868,10 +4021,21 @@ snapshots: '@types/node': 22.17.2 jest-mock: 29.7.0 + '@jest/environment@30.2.0': + dependencies: + '@jest/fake-timers': 30.2.0 + '@jest/types': 30.2.0 + '@types/node': 22.19.1 + jest-mock: 30.2.0 + '@jest/expect-utils@29.7.0': dependencies: jest-get-type: 29.6.3 + '@jest/expect-utils@30.2.0': + dependencies: + '@jest/get-type': 30.1.0 + '@jest/expect@29.7.0': dependencies: expect: 29.7.0 @@ -3879,6 +4043,13 @@ snapshots: transitivePeerDependencies: - supports-color + '@jest/expect@30.2.0': + dependencies: + expect: 30.2.0 + jest-snapshot: 30.2.0 + transitivePeerDependencies: + - supports-color + '@jest/fake-timers@29.7.0': dependencies: '@jest/types': 29.6.3 @@ -3888,6 +4059,17 @@ snapshots: jest-mock: 29.7.0 jest-util: 29.7.0 + '@jest/fake-timers@30.2.0': + dependencies: + '@jest/types': 30.2.0 + '@sinonjs/fake-timers': 13.0.5 + '@types/node': 22.19.1 + jest-message-util: 30.2.0 + jest-mock: 30.2.0 + jest-util: 30.2.0 + + '@jest/get-type@30.1.0': {} + '@jest/globals@29.7.0': dependencies: '@jest/environment': 29.7.0 @@ -3897,11 +4079,19 @@ snapshots: transitivePeerDependencies: - supports-color + '@jest/globals@30.2.0': + dependencies: + '@jest/environment': 30.2.0 + '@jest/expect': 30.2.0 + '@jest/types': 30.2.0 + jest-mock: 30.2.0 + transitivePeerDependencies: + - supports-color + '@jest/pattern@30.0.1': dependencies: '@types/node': 22.19.1 jest-regex-util: 30.0.1 - optional: true '@jest/reporters@29.7.0': dependencies: @@ -3939,7 +4129,13 @@ snapshots: '@jest/schemas@30.0.5': dependencies: '@sinclair/typebox': 0.34.41 - optional: true + + '@jest/snapshot-utils@30.2.0': + dependencies: + '@jest/types': 30.2.0 + chalk: 4.1.2 + graceful-fs: 4.2.11 + natural-compare: 1.4.0 '@jest/source-map@29.6.3': dependencies: @@ -4002,6 +4198,26 @@ snapshots: - supports-color optional: true + '@jest/transform@30.2.0': + dependencies: + '@babel/core': 7.28.5 + '@jest/types': 30.2.0 + '@jridgewell/trace-mapping': 0.3.31 + babel-plugin-istanbul: 7.0.1 + chalk: 4.1.2 + convert-source-map: 2.0.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.11 + jest-haste-map: 30.2.0 + jest-regex-util: 30.0.1 + jest-util: 30.2.0 + micromatch: 4.0.8 + pirates: 4.0.7 + slash: 3.0.0 + write-file-atomic: 5.0.1 + transitivePeerDependencies: + - supports-color + '@jest/types@29.6.3': dependencies: '@jest/schemas': 29.6.3 @@ -4022,6 +4238,16 @@ snapshots: chalk: 4.1.2 optional: true + '@jest/types@30.2.0': + dependencies: + '@jest/pattern': 30.0.1 + '@jest/schemas': 30.0.5 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 22.19.1 + '@types/yargs': 17.0.35 + chalk: 4.1.2 + '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -4045,7 +4271,6 @@ snapshots: dependencies: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - optional: true '@jridgewell/trace-mapping@0.3.9': dependencies: @@ -4211,10 +4436,11 @@ snapshots: '@octokit/request-error': 6.1.8 '@octokit/webhooks-methods': 5.1.1 + '@pkgr/core@0.2.9': {} + '@sinclair/typebox@0.27.8': {} - '@sinclair/typebox@0.34.41': - optional: true + '@sinclair/typebox@0.34.41': {} '@sinonjs/commons@3.0.1': dependencies: @@ -4224,6 +4450,10 @@ snapshots: dependencies: '@sinonjs/commons': 3.0.1 + '@sinonjs/fake-timers@13.0.5': + dependencies: + '@sinonjs/commons': 3.0.1 + '@tsconfig/node10@1.0.11': {} '@tsconfig/node12@1.0.11': {} @@ -4285,7 +4515,6 @@ snapshots: '@types/node@22.19.1': dependencies: undici-types: 6.21.0 - optional: true '@types/stack-utils@2.0.3': {} @@ -4298,7 +4527,6 @@ snapshots: '@types/yargs@17.0.35': dependencies: '@types/yargs-parser': 21.0.3 - optional: true '@typescript-eslint/eslint-plugin@8.46.1(@typescript-eslint/parser@8.46.1(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.2))(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.2)': dependencies: @@ -4393,8 +4621,7 @@ snapshots: '@typescript-eslint/types': 8.46.1 eslint-visitor-keys: 4.2.1 - '@ungap/structured-clone@1.3.0': - optional: true + '@ungap/structured-clone@1.3.0': {} acorn-jsx@5.3.2(acorn@8.15.0): dependencies: @@ -4486,7 +4713,6 @@ snapshots: test-exclude: 6.0.0 transitivePeerDependencies: - supports-color - optional: true babel-plugin-jest-hoist@29.6.3: dependencies: @@ -4539,7 +4765,6 @@ snapshots: '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.28.5) '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.28.5) '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.28.5) - optional: true babel-preset-jest@29.6.3(@babel/core@7.28.4): dependencies: @@ -4621,8 +4846,7 @@ snapshots: ci-info@3.9.0: {} - ci-info@4.3.1: - optional: true + ci-info@4.3.1: {} cjs-module-lexer@1.4.3: {} @@ -4678,7 +4902,6 @@ snapshots: debug@4.4.3: dependencies: ms: 2.1.3 - optional: true dedent@1.7.0: {} @@ -4804,6 +5027,15 @@ snapshots: jest-message-util: 29.7.0 jest-util: 29.7.0 + expect@30.2.0: + dependencies: + '@jest/expect-utils': 30.2.0 + '@jest/get-type': 30.1.0 + jest-matcher-utils: 30.2.0 + jest-message-util: 30.2.0 + jest-mock: 30.2.0 + jest-util: 30.2.0 + fast-content-type-parse@2.0.1: {} fast-deep-equal@3.1.3: {} @@ -5106,6 +5338,13 @@ snapshots: jest-get-type: 29.6.3 pretty-format: 29.7.0 + jest-diff@30.2.0: + dependencies: + '@jest/diff-sequences': 30.0.1 + '@jest/get-type': 30.1.0 + chalk: 4.1.2 + pretty-format: 30.2.0 + jest-docblock@29.7.0: dependencies: detect-newline: 3.1.0 @@ -5161,6 +5400,21 @@ snapshots: fsevents: 2.3.3 optional: true + jest-haste-map@30.2.0: + dependencies: + '@jest/types': 30.2.0 + '@types/node': 22.19.1 + anymatch: 3.1.3 + fb-watchman: 2.0.2 + graceful-fs: 4.2.11 + jest-regex-util: 30.0.1 + jest-util: 30.2.0 + jest-worker: 30.2.0 + micromatch: 4.0.8 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.3 + jest-leak-detector@29.7.0: dependencies: jest-get-type: 29.6.3 @@ -5173,6 +5427,13 @@ snapshots: jest-get-type: 29.6.3 pretty-format: 29.7.0 + jest-matcher-utils@30.2.0: + dependencies: + '@jest/get-type': 30.1.0 + chalk: 4.1.2 + jest-diff: 30.2.0 + pretty-format: 30.2.0 + jest-message-util@29.7.0: dependencies: '@babel/code-frame': 7.27.1 @@ -5185,20 +5446,37 @@ snapshots: slash: 3.0.0 stack-utils: 2.0.6 + jest-message-util@30.2.0: + dependencies: + '@babel/code-frame': 7.27.1 + '@jest/types': 30.2.0 + '@types/stack-utils': 2.0.3 + chalk: 4.1.2 + graceful-fs: 4.2.11 + micromatch: 4.0.8 + pretty-format: 30.2.0 + slash: 3.0.0 + stack-utils: 2.0.6 + jest-mock@29.7.0: dependencies: '@jest/types': 29.6.3 '@types/node': 22.17.2 jest-util: 29.7.0 + jest-mock@30.2.0: + dependencies: + '@jest/types': 30.2.0 + '@types/node': 22.19.1 + jest-util: 30.2.0 + jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): optionalDependencies: jest-resolve: 29.7.0 jest-regex-util@29.6.3: {} - jest-regex-util@30.0.1: - optional: true + jest-regex-util@30.0.1: {} jest-resolve-dependencies@29.7.0: dependencies: @@ -5297,6 +5575,32 @@ snapshots: transitivePeerDependencies: - supports-color + jest-snapshot@30.2.0: + dependencies: + '@babel/core': 7.28.5 + '@babel/generator': 7.28.5 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.5) + '@babel/types': 7.28.5 + '@jest/expect-utils': 30.2.0 + '@jest/get-type': 30.1.0 + '@jest/snapshot-utils': 30.2.0 + '@jest/transform': 30.2.0 + '@jest/types': 30.2.0 + babel-preset-current-node-syntax: 1.2.0(@babel/core@7.28.5) + chalk: 4.1.2 + expect: 30.2.0 + graceful-fs: 4.2.11 + jest-diff: 30.2.0 + jest-matcher-utils: 30.2.0 + jest-message-util: 30.2.0 + jest-util: 30.2.0 + pretty-format: 30.2.0 + semver: 7.7.2 + synckit: 0.11.12 + transitivePeerDependencies: + - supports-color + jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 @@ -5316,6 +5620,15 @@ snapshots: picomatch: 4.0.3 optional: true + jest-util@30.2.0: + dependencies: + '@jest/types': 30.2.0 + '@types/node': 22.19.1 + chalk: 4.1.2 + ci-info: 4.3.1 + graceful-fs: 4.2.11 + picomatch: 4.0.3 + jest-validate@29.7.0: dependencies: '@jest/types': 29.6.3 @@ -5352,6 +5665,14 @@ snapshots: supports-color: 8.1.1 optional: true + jest-worker@30.2.0: + dependencies: + '@types/node': 22.19.1 + '@ungap/structured-clone': 1.3.0 + jest-util: 30.2.0 + merge-stream: 2.0.0 + supports-color: 8.1.1 + jest@29.7.0(@types/node@22.17.2)(ts-node@10.9.2(@types/node@22.17.2)(typescript@5.9.2)): dependencies: '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@22.17.2)(typescript@5.9.2)) @@ -5586,8 +5907,7 @@ snapshots: picomatch@2.3.1: {} - picomatch@4.0.3: - optional: true + picomatch@4.0.3: {} pirates@4.0.7: {} @@ -5609,6 +5929,12 @@ snapshots: ansi-styles: 5.2.0 react-is: 18.3.1 + pretty-format@30.2.0: + dependencies: + '@jest/schemas': 30.0.5 + ansi-styles: 5.2.0 + react-is: 18.3.1 + prompts@2.4.2: dependencies: kleur: 3.0.3 @@ -5666,8 +5992,7 @@ snapshots: signal-exit@3.0.7: {} - signal-exit@4.1.0: - optional: true + signal-exit@4.1.0: {} sisteransi@1.0.5: {} @@ -5717,6 +6042,10 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} + synckit@0.11.12: + dependencies: + '@pkgr/core': 0.2.9 + test-exclude@6.0.0: dependencies: '@istanbuljs/schema': 0.1.3 @@ -5735,7 +6064,7 @@ snapshots: dependencies: typescript: 5.9.2 - ts-jest@29.4.1(@babel/core@7.28.5)(@jest/transform@30.1.2)(@jest/types@30.0.5)(babel-jest@30.1.2(@babel/core@7.28.5))(jest-util@30.0.5)(jest@29.7.0(@types/node@22.17.2)(ts-node@10.9.2(@types/node@22.17.2)(typescript@5.9.2)))(typescript@5.9.2): + ts-jest@29.4.1(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.1.2(@babel/core@7.28.5))(jest-util@30.2.0)(jest@29.7.0(@types/node@22.17.2)(ts-node@10.9.2(@types/node@22.17.2)(typescript@5.9.2)))(typescript@5.9.2): dependencies: bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 @@ -5750,10 +6079,10 @@ snapshots: yargs-parser: 21.1.1 optionalDependencies: '@babel/core': 7.28.5 - '@jest/transform': 30.1.2 - '@jest/types': 30.0.5 + '@jest/transform': 30.2.0 + '@jest/types': 30.2.0 babel-jest: 30.1.2(@babel/core@7.28.5) - jest-util: 30.0.5 + jest-util: 30.2.0 ts-node@10.9.2(@types/node@22.17.2)(typescript@5.9.2): dependencies: @@ -5862,7 +6191,6 @@ snapshots: dependencies: imurmurhash: 0.1.4 signal-exit: 4.1.0 - optional: true y18n@5.0.8: {} diff --git a/tests/utils/github-auth.test.ts b/tests/utils/github-auth.test.ts index 39515cb..94cf141 100644 --- a/tests/utils/github-auth.test.ts +++ b/tests/utils/github-auth.test.ts @@ -21,6 +21,12 @@ type FetchOptions = { headers?: Record; } & Record; +type FetchMock = jest.MockedFunction; + +function createFetchMock(): FetchMock { + return jest.fn() as FetchMock; +} + describe('github-auth utils', () => { const originalEnv = { ...process.env }; const originalFetch = global.fetch; @@ -57,12 +63,15 @@ describe('github-auth utils', () => { const calls: Array<{ url: string; options: FetchOptions }> = []; // Mock fetch for: GET /repos/{owner}/{repo}/installation then POST /app/installations/{id}/access_tokens - global.fetch = jest - .fn() - .mockImplementation(async (url: string, options: FetchOptions) => { - calls.push({ url, options }); + const fetchMock = createFetchMock().mockImplementation( + async (url, options) => { + const fetchOptions = (options ?? {}) as FetchOptions; + calls.push({ url: String(url), options: fetchOptions }); if (String(url).includes('/repos/acme/repo/installation')) { - return { ok: true, text: async () => JSON.stringify({ id: 999 }) }; + return { + ok: true, + text: async () => JSON.stringify({ id: 999 }), + } as Response; } if (String(url).includes('/app/installations/999/access_tokens')) { return { @@ -72,10 +81,16 @@ describe('github-auth utils', () => { token: 'ghs_install_token', expires_at: '2030-01-01T00:00:00Z', }), - }; + } as Response; } - return { ok: false, status: 404, text: async () => 'not found' }; - }); + return { + ok: false, + status: 404, + text: async () => 'not found', + } as Response; + }, + ) as FetchMock; + global.fetch = fetchMock; const auth = await resolveGitHubAuth('acme', 'repo'); expect(auth?.source).toBe('app'); @@ -98,7 +113,7 @@ describe('github-auth utils', () => { process.env.CHANGELOG_BOT_APP_INSTALLATION_ID = '777'; let requestCount = 0; - global.fetch = jest.fn().mockImplementation(async (url: string) => { + const fetchMock = createFetchMock().mockImplementation(async (url) => { requestCount += 1; if (String(url).includes('/app/installations/777/access_tokens')) { return { @@ -108,10 +123,15 @@ describe('github-auth utils', () => { token: 'ghs_token_777', expires_at: '2029-12-31T00:00:00Z', }), - }; + } as Response; } - return { ok: false, status: 404, text: async () => 'not found' }; - }); + return { + ok: false, + status: 404, + text: async () => 'not found', + } as Response; + }) as FetchMock; + global.fetch = fetchMock; const auth = await resolveGitHubAuth('acme', 'repo'); expect(auth?.source).toBe('app'); From 7fcedaa5096c52a825a7018f67e157e28f76d8be Mon Sep 17 00:00:00 2001 From: nyaomaru Date: Sun, 25 Jan 2026 17:38:27 +0100 Subject: [PATCH 3/5] fix: tsconfig setting --- tests/tsconfig.json | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 tests/tsconfig.json diff --git a/tests/tsconfig.json b/tests/tsconfig.json new file mode 100644 index 0000000..35bb0ea --- /dev/null +++ b/tests/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "../tsconfig.tests.json", + "include": ["**/*.ts"] +} From b8b34488a1d156a03396cb42d0d66eaeb18d82d9 Mon Sep 17 00:00:00 2001 From: nyaomaru Date: Sun, 25 Jan 2026 17:41:57 +0100 Subject: [PATCH 4/5] Update package.json Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f73f6e2..ba9cdbc 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ }, "devDependencies": { "@eslint/js": "^9.38.0", - "@jest/globals": "^30.2.0", + "@jest/globals": "^29.7.0", "@types/jest": "^29.5.14", "@types/node": "^22.5.2", "@types/yargs": "^17.0.33", From 79d9e8dc8f35cd27c163a92abfa3652e2b89bcd6 Mon Sep 17 00:00:00 2001 From: nyaomaru Date: Sun, 25 Jan 2026 17:43:34 +0100 Subject: [PATCH 5/5] chore: update lock --- pnpm-lock.yaml | 325 ++++++++----------------------------------------- 1 file changed, 51 insertions(+), 274 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8d549cc..ae2d1ec 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -24,8 +24,8 @@ importers: specifier: ^9.38.0 version: 9.38.0 '@jest/globals': - specifier: ^30.2.0 - version: 30.2.0 + specifier: ^29.7.0 + version: 29.7.0 '@types/jest': specifier: ^29.5.14 version: 29.5.14 @@ -516,13 +516,6 @@ packages: node-notifier: optional: true - '@jest/diff-sequences@30.0.1': - resolution: - { - integrity: sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==, - } - engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } - '@jest/environment@29.7.0': resolution: { @@ -530,13 +523,6 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - '@jest/environment@30.2.0': - resolution: - { - integrity: sha512-/QPTL7OBJQ5ac09UDRa3EQes4gt1FTEG/8jZ/4v5IVzx+Cv7dLxlVIvfvSVRiiX2drWyXeBjkMSR8hvOWSog5g==, - } - engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } - '@jest/expect-utils@29.7.0': resolution: { @@ -544,13 +530,6 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - '@jest/expect-utils@30.2.0': - resolution: - { - integrity: sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA==, - } - engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } - '@jest/expect@29.7.0': resolution: { @@ -558,13 +537,6 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - '@jest/expect@30.2.0': - resolution: - { - integrity: sha512-V9yxQK5erfzx99Sf+7LbhBwNWEZ9eZay8qQ9+JSC0TrMR1pMDHLMY+BnVPacWU6Jamrh252/IKo4F1Xn/zfiqA==, - } - engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } - '@jest/fake-timers@29.7.0': resolution: { @@ -572,20 +544,6 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - '@jest/fake-timers@30.2.0': - resolution: - { - integrity: sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw==, - } - engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } - - '@jest/get-type@30.1.0': - resolution: - { - integrity: sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==, - } - engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } - '@jest/globals@29.7.0': resolution: { @@ -593,13 +551,6 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - '@jest/globals@30.2.0': - resolution: - { - integrity: sha512-b63wmnKPaK+6ZZfpYhz9K61oybvbI1aMcIs80++JI1O1rR1vaxHUCNqo3ITu6NU0d4V34yZFoHMn/uoKr/Rwfw==, - } - engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } - '@jest/pattern@30.0.1': resolution: { @@ -633,13 +584,6 @@ packages: } engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } - '@jest/snapshot-utils@30.2.0': - resolution: - { - integrity: sha512-0aVxM3RH6DaiLcjj/b0KrIBZhSX1373Xci4l3cW5xiUWPctZ59zQ7jj4rqcJQ/Z8JuN/4wX3FpJSa3RssVvCug==, - } - engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } - '@jest/source-map@29.6.3': resolution: { @@ -949,13 +893,6 @@ packages: } engines: { node: '>= 18' } - '@pkgr/core@0.2.9': - resolution: - { - integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==, - } - engines: { node: ^12.20.0 || ^14.18.0 || >=16.0.0 } - '@sinclair/typebox@0.27.8': resolution: { @@ -980,12 +917,6 @@ packages: integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==, } - '@sinonjs/fake-timers@13.0.5': - resolution: - { - integrity: sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==, - } - '@tsconfig/node10@1.0.11': resolution: { @@ -1806,13 +1737,6 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - expect@30.2.0: - resolution: - { - integrity: sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw==, - } - engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } - fast-content-type-parse@2.0.1: resolution: { @@ -2254,13 +2178,6 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - jest-diff@30.2.0: - resolution: - { - integrity: sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==, - } - engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } - jest-docblock@29.7.0: resolution: { @@ -2324,13 +2241,6 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - jest-matcher-utils@30.2.0: - resolution: - { - integrity: sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg==, - } - engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } - jest-message-util@29.7.0: resolution: { @@ -2338,13 +2248,6 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - jest-message-util@30.2.0: - resolution: - { - integrity: sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==, - } - engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } - jest-mock@29.7.0: resolution: { @@ -2352,13 +2255,6 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - jest-mock@30.2.0: - resolution: - { - integrity: sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==, - } - engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } - jest-pnp-resolver@1.2.3: resolution: { @@ -2420,13 +2316,6 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - jest-snapshot@30.2.0: - resolution: - { - integrity: sha512-5WEtTy2jXPFypadKNpbNkZ72puZCa6UjSr/7djeecHWOu7iYhSXSnHScT8wBz3Rn8Ena5d5RYRcsyKIeqG1IyA==, - } - engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } - jest-util@29.7.0: resolution: { @@ -3004,13 +2893,6 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - pretty-format@30.2.0: - resolution: - { - integrity: sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==, - } - engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } - prompts@2.4.2: resolution: { @@ -3263,13 +3145,6 @@ packages: } engines: { node: '>= 0.4' } - synckit@0.11.12: - resolution: - { - integrity: sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==, - } - engines: { node: ^14.18.0 || >=16.0.0 } - test-exclude@6.0.0: resolution: { @@ -3610,6 +3485,7 @@ snapshots: semver: 6.3.1 transitivePeerDependencies: - supports-color + optional: true '@babel/generator@7.28.3': dependencies: @@ -3626,6 +3502,7 @@ snapshots: '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 + optional: true '@babel/helper-compilation-targets@7.27.2': dependencies: @@ -3661,6 +3538,7 @@ snapshots: '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color + optional: true '@babel/helper-plugin-utils@7.27.1': {} @@ -3668,7 +3546,8 @@ snapshots: '@babel/helper-validator-identifier@7.27.1': {} - '@babel/helper-validator-identifier@7.28.5': {} + '@babel/helper-validator-identifier@7.28.5': + optional: true '@babel/helper-validator-option@7.27.1': {} @@ -3684,6 +3563,7 @@ snapshots: '@babel/parser@7.28.5': dependencies: '@babel/types': 7.28.5 + optional: true '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.28.4)': dependencies: @@ -3694,6 +3574,7 @@ snapshots: dependencies: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 + optional: true '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.28.4)': dependencies: @@ -3704,6 +3585,7 @@ snapshots: dependencies: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 + optional: true '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.28.4)': dependencies: @@ -3714,6 +3596,7 @@ snapshots: dependencies: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 + optional: true '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.28.4)': dependencies: @@ -3724,6 +3607,7 @@ snapshots: dependencies: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 + optional: true '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.4)': dependencies: @@ -3734,6 +3618,7 @@ snapshots: dependencies: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 + optional: true '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.28.4)': dependencies: @@ -3744,6 +3629,7 @@ snapshots: dependencies: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 + optional: true '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.28.4)': dependencies: @@ -3754,17 +3640,13 @@ snapshots: dependencies: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 + optional: true '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.5)': - dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 @@ -3774,6 +3656,7 @@ snapshots: dependencies: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 + optional: true '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.28.4)': dependencies: @@ -3784,6 +3667,7 @@ snapshots: dependencies: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 + optional: true '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.28.4)': dependencies: @@ -3794,6 +3678,7 @@ snapshots: dependencies: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 + optional: true '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.28.4)': dependencies: @@ -3804,6 +3689,7 @@ snapshots: dependencies: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 + optional: true '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.28.4)': dependencies: @@ -3814,6 +3700,7 @@ snapshots: dependencies: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 + optional: true '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.28.4)': dependencies: @@ -3824,6 +3711,7 @@ snapshots: dependencies: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 + optional: true '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.28.4)': dependencies: @@ -3834,6 +3722,7 @@ snapshots: dependencies: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 + optional: true '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.28.4)': dependencies: @@ -3844,17 +3733,13 @@ snapshots: dependencies: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 + optional: true '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.5)': - dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/template@7.27.2': dependencies: '@babel/code-frame': 7.27.1 @@ -3884,6 +3769,7 @@ snapshots: debug: 4.4.3 transitivePeerDependencies: - supports-color + optional: true '@babel/types@7.28.4': dependencies: @@ -3894,6 +3780,7 @@ snapshots: dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 + optional: true '@bcoe/v8-coverage@0.2.3': {} @@ -4012,8 +3899,6 @@ snapshots: - supports-color - ts-node - '@jest/diff-sequences@30.0.1': {} - '@jest/environment@29.7.0': dependencies: '@jest/fake-timers': 29.7.0 @@ -4021,21 +3906,10 @@ snapshots: '@types/node': 22.17.2 jest-mock: 29.7.0 - '@jest/environment@30.2.0': - dependencies: - '@jest/fake-timers': 30.2.0 - '@jest/types': 30.2.0 - '@types/node': 22.19.1 - jest-mock: 30.2.0 - '@jest/expect-utils@29.7.0': dependencies: jest-get-type: 29.6.3 - '@jest/expect-utils@30.2.0': - dependencies: - '@jest/get-type': 30.1.0 - '@jest/expect@29.7.0': dependencies: expect: 29.7.0 @@ -4043,13 +3917,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@jest/expect@30.2.0': - dependencies: - expect: 30.2.0 - jest-snapshot: 30.2.0 - transitivePeerDependencies: - - supports-color - '@jest/fake-timers@29.7.0': dependencies: '@jest/types': 29.6.3 @@ -4059,17 +3926,6 @@ snapshots: jest-mock: 29.7.0 jest-util: 29.7.0 - '@jest/fake-timers@30.2.0': - dependencies: - '@jest/types': 30.2.0 - '@sinonjs/fake-timers': 13.0.5 - '@types/node': 22.19.1 - jest-message-util: 30.2.0 - jest-mock: 30.2.0 - jest-util: 30.2.0 - - '@jest/get-type@30.1.0': {} - '@jest/globals@29.7.0': dependencies: '@jest/environment': 29.7.0 @@ -4079,19 +3935,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@jest/globals@30.2.0': - dependencies: - '@jest/environment': 30.2.0 - '@jest/expect': 30.2.0 - '@jest/types': 30.2.0 - jest-mock: 30.2.0 - transitivePeerDependencies: - - supports-color - '@jest/pattern@30.0.1': dependencies: '@types/node': 22.19.1 jest-regex-util: 30.0.1 + optional: true '@jest/reporters@29.7.0': dependencies: @@ -4129,13 +3977,7 @@ snapshots: '@jest/schemas@30.0.5': dependencies: '@sinclair/typebox': 0.34.41 - - '@jest/snapshot-utils@30.2.0': - dependencies: - '@jest/types': 30.2.0 - chalk: 4.1.2 - graceful-fs: 4.2.11 - natural-compare: 1.4.0 + optional: true '@jest/source-map@29.6.3': dependencies: @@ -4217,6 +4059,7 @@ snapshots: write-file-atomic: 5.0.1 transitivePeerDependencies: - supports-color + optional: true '@jest/types@29.6.3': dependencies: @@ -4247,6 +4090,7 @@ snapshots: '@types/node': 22.19.1 '@types/yargs': 17.0.35 chalk: 4.1.2 + optional: true '@jridgewell/gen-mapping@0.3.13': dependencies: @@ -4271,6 +4115,7 @@ snapshots: dependencies: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + optional: true '@jridgewell/trace-mapping@0.3.9': dependencies: @@ -4436,11 +4281,10 @@ snapshots: '@octokit/request-error': 6.1.8 '@octokit/webhooks-methods': 5.1.1 - '@pkgr/core@0.2.9': {} - '@sinclair/typebox@0.27.8': {} - '@sinclair/typebox@0.34.41': {} + '@sinclair/typebox@0.34.41': + optional: true '@sinonjs/commons@3.0.1': dependencies: @@ -4450,10 +4294,6 @@ snapshots: dependencies: '@sinonjs/commons': 3.0.1 - '@sinonjs/fake-timers@13.0.5': - dependencies: - '@sinonjs/commons': 3.0.1 - '@tsconfig/node10@1.0.11': {} '@tsconfig/node12@1.0.11': {} @@ -4515,6 +4355,7 @@ snapshots: '@types/node@22.19.1': dependencies: undici-types: 6.21.0 + optional: true '@types/stack-utils@2.0.3': {} @@ -4527,6 +4368,7 @@ snapshots: '@types/yargs@17.0.35': dependencies: '@types/yargs-parser': 21.0.3 + optional: true '@typescript-eslint/eslint-plugin@8.46.1(@typescript-eslint/parser@8.46.1(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.2))(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.2)': dependencies: @@ -4621,7 +4463,8 @@ snapshots: '@typescript-eslint/types': 8.46.1 eslint-visitor-keys: 4.2.1 - '@ungap/structured-clone@1.3.0': {} + '@ungap/structured-clone@1.3.0': + optional: true acorn-jsx@5.3.2(acorn@8.15.0): dependencies: @@ -4713,6 +4556,7 @@ snapshots: test-exclude: 6.0.0 transitivePeerDependencies: - supports-color + optional: true babel-plugin-jest-hoist@29.6.3: dependencies: @@ -4765,6 +4609,7 @@ snapshots: '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.28.5) '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.28.5) '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.28.5) + optional: true babel-preset-jest@29.6.3(@babel/core@7.28.4): dependencies: @@ -4846,7 +4691,8 @@ snapshots: ci-info@3.9.0: {} - ci-info@4.3.1: {} + ci-info@4.3.1: + optional: true cjs-module-lexer@1.4.3: {} @@ -4902,6 +4748,7 @@ snapshots: debug@4.4.3: dependencies: ms: 2.1.3 + optional: true dedent@1.7.0: {} @@ -5027,15 +4874,6 @@ snapshots: jest-message-util: 29.7.0 jest-util: 29.7.0 - expect@30.2.0: - dependencies: - '@jest/expect-utils': 30.2.0 - '@jest/get-type': 30.1.0 - jest-matcher-utils: 30.2.0 - jest-message-util: 30.2.0 - jest-mock: 30.2.0 - jest-util: 30.2.0 - fast-content-type-parse@2.0.1: {} fast-deep-equal@3.1.3: {} @@ -5338,13 +5176,6 @@ snapshots: jest-get-type: 29.6.3 pretty-format: 29.7.0 - jest-diff@30.2.0: - dependencies: - '@jest/diff-sequences': 30.0.1 - '@jest/get-type': 30.1.0 - chalk: 4.1.2 - pretty-format: 30.2.0 - jest-docblock@29.7.0: dependencies: detect-newline: 3.1.0 @@ -5414,6 +5245,7 @@ snapshots: walker: 1.0.8 optionalDependencies: fsevents: 2.3.3 + optional: true jest-leak-detector@29.7.0: dependencies: @@ -5427,13 +5259,6 @@ snapshots: jest-get-type: 29.6.3 pretty-format: 29.7.0 - jest-matcher-utils@30.2.0: - dependencies: - '@jest/get-type': 30.1.0 - chalk: 4.1.2 - jest-diff: 30.2.0 - pretty-format: 30.2.0 - jest-message-util@29.7.0: dependencies: '@babel/code-frame': 7.27.1 @@ -5446,37 +5271,20 @@ snapshots: slash: 3.0.0 stack-utils: 2.0.6 - jest-message-util@30.2.0: - dependencies: - '@babel/code-frame': 7.27.1 - '@jest/types': 30.2.0 - '@types/stack-utils': 2.0.3 - chalk: 4.1.2 - graceful-fs: 4.2.11 - micromatch: 4.0.8 - pretty-format: 30.2.0 - slash: 3.0.0 - stack-utils: 2.0.6 - jest-mock@29.7.0: dependencies: '@jest/types': 29.6.3 '@types/node': 22.17.2 jest-util: 29.7.0 - jest-mock@30.2.0: - dependencies: - '@jest/types': 30.2.0 - '@types/node': 22.19.1 - jest-util: 30.2.0 - jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): optionalDependencies: jest-resolve: 29.7.0 jest-regex-util@29.6.3: {} - jest-regex-util@30.0.1: {} + jest-regex-util@30.0.1: + optional: true jest-resolve-dependencies@29.7.0: dependencies: @@ -5575,32 +5383,6 @@ snapshots: transitivePeerDependencies: - supports-color - jest-snapshot@30.2.0: - dependencies: - '@babel/core': 7.28.5 - '@babel/generator': 7.28.5 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.5) - '@babel/types': 7.28.5 - '@jest/expect-utils': 30.2.0 - '@jest/get-type': 30.1.0 - '@jest/snapshot-utils': 30.2.0 - '@jest/transform': 30.2.0 - '@jest/types': 30.2.0 - babel-preset-current-node-syntax: 1.2.0(@babel/core@7.28.5) - chalk: 4.1.2 - expect: 30.2.0 - graceful-fs: 4.2.11 - jest-diff: 30.2.0 - jest-matcher-utils: 30.2.0 - jest-message-util: 30.2.0 - jest-util: 30.2.0 - pretty-format: 30.2.0 - semver: 7.7.2 - synckit: 0.11.12 - transitivePeerDependencies: - - supports-color - jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 @@ -5628,6 +5410,7 @@ snapshots: ci-info: 4.3.1 graceful-fs: 4.2.11 picomatch: 4.0.3 + optional: true jest-validate@29.7.0: dependencies: @@ -5672,6 +5455,7 @@ snapshots: jest-util: 30.2.0 merge-stream: 2.0.0 supports-color: 8.1.1 + optional: true jest@29.7.0(@types/node@22.17.2)(ts-node@10.9.2(@types/node@22.17.2)(typescript@5.9.2)): dependencies: @@ -5907,7 +5691,8 @@ snapshots: picomatch@2.3.1: {} - picomatch@4.0.3: {} + picomatch@4.0.3: + optional: true pirates@4.0.7: {} @@ -5929,12 +5714,6 @@ snapshots: ansi-styles: 5.2.0 react-is: 18.3.1 - pretty-format@30.2.0: - dependencies: - '@jest/schemas': 30.0.5 - ansi-styles: 5.2.0 - react-is: 18.3.1 - prompts@2.4.2: dependencies: kleur: 3.0.3 @@ -5992,7 +5771,8 @@ snapshots: signal-exit@3.0.7: {} - signal-exit@4.1.0: {} + signal-exit@4.1.0: + optional: true sisteransi@1.0.5: {} @@ -6042,10 +5822,6 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - synckit@0.11.12: - dependencies: - '@pkgr/core': 0.2.9 - test-exclude@6.0.0: dependencies: '@istanbuljs/schema': 0.1.3 @@ -6191,6 +5967,7 @@ snapshots: dependencies: imurmurhash: 0.1.4 signal-exit: 4.1.0 + optional: true y18n@5.0.8: {}