From 3f4af09db53756763cf5548c02cb0b441cf85eb2 Mon Sep 17 00:00:00 2001 From: Eli Bosley Date: Fri, 12 Sep 2025 14:24:49 -0400 Subject: [PATCH] chore(deps): update conventional commit (#1693) ## Summary by CodeRabbit * **Chores** * Updated changelog tooling dependencies and CI to fetch full Git history; added conventional-changelog-conventionalcommits. * **Tests** * Added comprehensive tests for changelog output, header/tag handling, fallback behavior, and compatibility with the updated changelog API. * **Refactor** * Reworked changelog generation to use the newer changelog API, improve tag-aware headers, and support deriving PR-style changelogs with graceful fallbacks. --- .github/workflows/main.yml | 2 + plugin/builder/utils/changelog.test.ts | 181 ++++++++++++++++ plugin/builder/utils/changelog.ts | 181 +++++++++++++--- plugin/package.json | 3 +- pnpm-lock.yaml | 275 +++++++------------------ 5 files changed, 419 insertions(+), 223 deletions(-) create mode 100644 plugin/builder/utils/changelog.test.ts diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a46861ee5..b4f217d9c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -20,6 +20,8 @@ jobs: steps: - name: Checkout repo uses: actions/checkout@v5 + with: + fetch-depth: 0 - name: Install Node uses: actions/setup-node@v4 diff --git a/plugin/builder/utils/changelog.test.ts b/plugin/builder/utils/changelog.test.ts new file mode 100644 index 000000000..2dbadcae8 --- /dev/null +++ b/plugin/builder/utils/changelog.test.ts @@ -0,0 +1,181 @@ +import { describe, it, expect, beforeAll } from "vitest"; +import { execSync } from "child_process"; +import { getStagingChangelogFromGit } from "./changelog.js"; + +describe.sequential("getStagingChangelogFromGit", () => { + let currentCommitMessage: string | null = null; + + beforeAll(() => { + // Get the current commit message to validate it appears in changelog + try { + currentCommitMessage = execSync('git log -1 --pretty=%s', { encoding: 'utf8' }).trim(); + } catch (e) { + // Ignore if we can't get commit + } + }); + + it("should generate changelog header with version", { timeout: 20000 }, async () => { + const result = await getStagingChangelogFromGit({ + pluginVersion: "99.99.99", + tag: undefined as any, + }); + + expect(result).toBeDefined(); + expect(typeof result).toBe("string"); + // Should contain version header + expect(result).toContain("99.99.99"); + // Should have markdown header formatting + expect(result).toMatch(/##\s+/); + }); + + it("should generate changelog with tag parameter", { timeout: 20000 }, async () => { + // When tag is provided, it should generate changelog with tag in header + const result = await getStagingChangelogFromGit({ + pluginVersion: "99.99.99", + tag: "test-tag-99", + }); + + expect(result).toBeDefined(); + expect(typeof result).toBe("string"); + expect(result).toContain("test-tag-99"); + + // Should have a version header + expect(result).toMatch(/##\s+/); + + // IMPORTANT: Verify that actual commits are included in the changelog + // This ensures the gitRawCommitsOpts is working correctly + // The changelog should include commits if there are any between origin/main and HEAD + // We check for common changelog patterns that indicate actual content + if (result.length > 100) { + // If we have a substantial changelog, it should contain commit information + expect( + result.includes("### Features") || + result.includes("### Bug Fixes") || + result.includes("### ") || + result.includes("* ") // Commit entries typically start with asterisk + ).toBe(true); + } + }); + + it("should handle error gracefully and return tag", { timeout: 20000 }, async () => { + // The function catches errors and returns the tag + // An empty version might not cause an error, so let's just verify + // the function completes without throwing + const result = await getStagingChangelogFromGit({ + pluginVersion: "test-version", + tag: "fallback-tag", + }); + + expect(result).toBeDefined(); + expect(typeof result).toBe("string"); + // Should either return a changelog or the fallback tag + expect(result.length).toBeGreaterThan(0); + }); + + it("should use conventional-changelog v7 API correctly", { timeout: 20000 }, async () => { + // This test validates that the v7 API is being called correctly + // by checking that the function executes without throwing + let error: any = null; + + try { + await getStagingChangelogFromGit({ + pluginVersion: "99.99.99", + tag: undefined as any, + }); + } catch (e) { + error = e; + } + + // The v7 API should work without errors + expect(error).toBeNull(); + }); + + it("should validate changelog structure", { timeout: 20000 }, async () => { + // Create a changelog with high version number to avoid conflicts + const result = await getStagingChangelogFromGit({ + pluginVersion: "999.0.0", + tag: "v999-test", + }); + + expect(result).toBeDefined(); + expect(typeof result).toBe("string"); + + // Verify basic markdown structure + if (result.length > 50) { + // Should have tag in header when tag is provided + expect(result).toMatch(/##\s+\[?v999-test/); + // Should be valid markdown with proper line breaks + expect(result).toMatch(/\n/); + } + }); + + it("should include actual commits when using gitRawCommitsOpts with tag", { timeout: 20000 }, async () => { + // This test ensures that gitRawCommitsOpts is working correctly + // and actually fetching commits between origin/main and HEAD + const result = await getStagingChangelogFromGit({ + pluginVersion: "99.99.99", + tag: "CI-TEST", + }); + + expect(result).toBeDefined(); + expect(typeof result).toBe("string"); + + // The header should contain the tag + expect(result).toContain("CI-TEST"); + + // Critical: The changelog should NOT be just the tag (error fallback) + expect(result).not.toBe("CI-TEST"); + + // The changelog should have a proper markdown header + expect(result).toMatch(/^##\s+/); + + // Check if we're in a git repo with commits ahead of the base branch + let commitCount = 0; + try { + // Try to detect the base branch (same logic as in changelog.ts) + let baseBranch = "origin/main"; + try { + const originHead = execSync("git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null", { + encoding: "utf8", + stdio: ["ignore", "pipe", "ignore"] + }).trim(); + if (originHead) { + baseBranch = originHead.replace("refs/remotes/", ""); + } + } catch { + // Try common branches + const branches = ["origin/main", "origin/master", "origin/develop"]; + for (const branch of branches) { + try { + execSync(`git rev-parse --verify ${branch} 2>/dev/null`, { stdio: "ignore" }); + baseBranch = branch; + break; + } catch { + // Continue to next branch + } + } + } + commitCount = parseInt(execSync(`git rev-list --count ${baseBranch}..HEAD`, { encoding: "utf8" }).trim()); + } catch { + // If we can't determine, we'll check for minimal content + } + + // If there are commits on this branch, the changelog MUST include them + if (commitCount > 0) { + // The changelog must be more than just a header + // A minimal header is "## CI-TEST (2025-09-12)\n\n" which is ~30 chars + expect(result.length).toBeGreaterThan(50); + + // Should have actual commit content + const hasCommitContent = + result.includes("### ") || // Section headers like ### Features + result.includes("* ") || // Commit bullet points + result.includes("- "); // Alternative bullet style + + if (!hasCommitContent) { + throw new Error(`Expected changelog to contain commits but got only: ${result.substring(0, 100)}...`); + } + expect(hasCommitContent).toBe(true); + } + }); +}); \ No newline at end of file diff --git a/plugin/builder/utils/changelog.ts b/plugin/builder/utils/changelog.ts index a7e084f75..66d551fd4 100644 --- a/plugin/builder/utils/changelog.ts +++ b/plugin/builder/utils/changelog.ts @@ -1,40 +1,167 @@ -import conventionalChangelog from "conventional-changelog"; +import { ConventionalChangelog } from "conventional-changelog"; +import { execSync } from "child_process"; -import { PluginEnv } from "../cli/setup-plugin-environment"; +import { PluginEnv } from "../cli/setup-plugin-environment.js"; + +/** + * Detects the base branch and finds the merge base for PR changelog generation + * Returns the merge-base commit to only show commits from the current PR + */ +function getMergeBase(): string | null { + try { + // First, find the base branch + let baseBranch: string | null = null; + + // Try to get the default branch from origin/HEAD + try { + const originHead = execSync("git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null", { + encoding: "utf8", + stdio: ["ignore", "pipe", "ignore"] + }).trim(); + if (originHead) { + baseBranch = originHead.replace("refs/remotes/", ""); + } + } catch { + // origin/HEAD not set, continue to next strategy + } + + // Try common default branch names if origin/HEAD didn't work + if (!baseBranch) { + const commonBranches = ["origin/main", "origin/master", "origin/develop"]; + for (const branch of commonBranches) { + try { + execSync(`git rev-parse --verify ${branch} 2>/dev/null`, { stdio: "ignore" }); + baseBranch = branch; + break; + } catch { + // Branch doesn't exist, try next + } + } + } + + if (!baseBranch) { + return null; + } + + // Find the merge-base between the current branch and the base branch + // This gives us the commit where the PR branch diverged from main + try { + const mergeBase = execSync(`git merge-base ${baseBranch} HEAD`, { + encoding: "utf8", + stdio: ["ignore", "pipe", "ignore"] + }).trim(); + + return mergeBase; + } catch { + // If merge-base fails, fall back to the base branch itself + return baseBranch; + } + } catch { + // Git command failed entirely, return null + return null; + } +} + +/** + * Generate a simple changelog for PR builds + */ +function generatePRChangelog(tag: string, mergeBase: string): string | null { + try { + // Get commits from this PR only with conventional commit parsing + const commits = execSync( + `git log ${mergeBase}..HEAD --pretty=format:"%s|%h" --reverse`, + { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] } + ).trim(); + + if (!commits) { + return null; + } + + const lines = commits.split('\n').filter(Boolean); + const features: string[] = []; + const fixes: string[] = []; + const other: string[] = []; + + for (const line of lines) { + const [message, hash] = line.split('|'); + const formatted = `* ${message} (${hash})`; + + if (message.startsWith('feat')) { + features.push(formatted); + } else if (message.startsWith('fix')) { + fixes.push(formatted); + } else { + other.push(formatted); + } + } + + let changelog = `## [${tag}](https://github.com/unraid/api/${tag})\n\n`; + + if (features.length > 0) { + changelog += `### Features\n\n${features.join('\n')}\n\n`; + } + if (fixes.length > 0) { + changelog += `### Bug Fixes\n\n${fixes.join('\n')}\n\n`; + } + if (other.length > 0) { + changelog += `### Other Changes\n\n${other.join('\n')}\n\n`; + } + + return changelog; + } catch { + return null; + } +} export const getStagingChangelogFromGit = async ({ pluginVersion, tag, }: Pick): Promise => { try { - const changelogStream = conventionalChangelog( - { - preset: "conventionalcommits", - }, - { - version: pluginVersion, - }, - tag - ? { - from: "origin/main", - to: "HEAD", - } - : {}, - undefined, - tag - ? { - headerPartial: `## [${tag}](https://github.com/unraid/api/${tag})\n\n`, - } - : undefined - ); + // For PR builds with a tag, try to generate a simple PR-specific changelog + if (tag) { + const mergeBase = getMergeBase(); + if (mergeBase) { + const prChangelog = generatePRChangelog(tag, mergeBase); + if (prChangelog) { + return prChangelog; + } + } + } + + // Fall back to conventional-changelog for non-PR builds or if PR detection fails + const options: any = { + releaseCount: 1, + }; + + if (tag) { + options.writerOpts = { + headerPartial: `## [${tag}](https://github.com/unraid/api/${tag})\n\n`, + }; + } + + const generator = new ConventionalChangelog() + .loadPreset("conventionalcommits") + .context({ + version: tag || pluginVersion, + ...(tag && { + linkCompare: false, + }), + }) + .options(options); + let changelog = ""; - for await (const chunk of changelogStream) { + for await (const chunk of generator.write()) { changelog += chunk; } - // Encode HTML entities using the 'he' library - return changelog ?? ""; + + return changelog || ""; } catch (err) { console.log('Non-fatal error: Failed to get changelog from git:', err); - return tag; + // Return a properly formatted fallback with markdown header + if (tag) { + return `## [${tag}](https://github.com/unraid/api/${tag})\n\n`; + } + return `## ${pluginVersion}\n\n`; } -}; +}; \ No newline at end of file diff --git a/plugin/package.json b/plugin/package.json index 2c9d47b4a..ec1d97cf3 100644 --- a/plugin/package.json +++ b/plugin/package.json @@ -4,7 +4,8 @@ "private": true, "dependencies": { "commander": "14.0.0", - "conventional-changelog": "6.0.0", + "conventional-changelog": "7.1.1", + "conventional-changelog-conventionalcommits": "^9.1.0", "date-fns": "4.1.0", "glob": "11.0.3", "html-sloppy-escaper": "0.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b97f04c99..6595dd3aa 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -810,8 +810,11 @@ importers: specifier: 14.0.0 version: 14.0.0 conventional-changelog: - specifier: 6.0.0 - version: 6.0.0(conventional-commits-filter@5.0.0) + specifier: 7.1.1 + version: 7.1.1(conventional-commits-filter@5.0.0) + conventional-changelog-conventionalcommits: + specifier: ^9.1.0 + version: 9.1.0 date-fns: specifier: 4.1.0 version: 4.1.0 @@ -1926,12 +1929,12 @@ packages: cpu: [x64] os: [win32] - '@conventional-changelog/git-client@1.0.1': - resolution: {integrity: sha512-PJEqBwAleffCMETaVm/fUgHldzBE35JFk3/9LL6NUA5EXa3qednu+UT6M7E5iBu3zIQZCULYIiZ90fBYHt6xUw==} + '@conventional-changelog/git-client@2.5.1': + resolution: {integrity: sha512-lAw7iA5oTPWOLjiweb7DlGEMDEvzqzLLa6aWOly2FSZ64IwLE8T458rC+o+WvI31Doz6joM7X2DoNog7mX8r4A==} engines: {node: '>=18'} peerDependencies: conventional-commits-filter: ^5.0.0 - conventional-commits-parser: ^6.0.0 + conventional-commits-parser: ^6.1.0 peerDependenciesMeta: conventional-commits-filter: optional: true @@ -2922,10 +2925,6 @@ packages: resolution: {integrity: sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==} engines: {node: '>=18.18'} - '@hutson/parse-repository-url@5.0.0': - resolution: {integrity: sha512-e5+YUKENATs1JgYHMzTr2MW/NDcXGfYFAuOQU8gJgF/kEh4EqKgfGrfLI67bMD4tbhZVlkigz/9YYwWcbOFthg==} - engines: {node: '>=10.13.0'} - '@ianvs/prettier-plugin-sort-imports@4.6.3': resolution: {integrity: sha512-lgETjWKuWgdu7CIKMrnaP9STvYDga42+A2ff8hMIployvkLYqT3xUt6Dqw0NpKp3qcqxBOCpwqbaYJEXXrhPQA==} peerDependencies: @@ -4447,6 +4446,14 @@ packages: '@sec-ant/readable-stream@0.4.1': resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + '@simple-libs/child-process-utils@1.0.1': + resolution: {integrity: sha512-3nWd8irxvDI6v856wpPCHZ+08iQR0oHTZfzAZmnbsLzf+Sf1odraP6uKOHDZToXq3RPRV/LbqGVlSCogm9cJjg==} + engines: {node: '>=18'} + + '@simple-libs/stream-utils@1.1.0': + resolution: {integrity: sha512-6rsHTjodIn/t90lv5snQjRPVtOosM7Vp0AKdrObymq45ojlgVwnpAqdc+0OBBrpEiy31zZ6/TKeIVqV1HwvnuQ==} + engines: {node: '>=18'} + '@sindresorhus/is@7.0.2': resolution: {integrity: sha512-d9xRovfKNz1SKieM0qJdO+PQonjnnIfSNWfHYnBSJ9hkjm0ZPw6HlxscDXYstp3z+7V2GOFHc+J0CYrYTjqCJw==} engines: {node: '>=18'} @@ -5742,9 +5749,6 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - add-stream@1.0.0: - resolution: {integrity: sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==} - agent-base@7.1.3: resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==} engines: {node: '>= 14'} @@ -6540,65 +6544,30 @@ packages: resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} engines: {node: '>= 0.6'} - conventional-changelog-angular@8.0.0: - resolution: {integrity: sha512-CLf+zr6St0wIxos4bmaKHRXWAcsCXrJU6F4VdNDrGRK3B8LDLKoX3zuMV5GhtbGkVR/LohZ6MT6im43vZLSjmA==} - engines: {node: '>=18'} - - conventional-changelog-atom@5.0.0: - resolution: {integrity: sha512-WfzCaAvSCFPkznnLgLnfacRAzjgqjLUjvf3MftfsJzQdDICqkOOpcMtdJF3wTerxSpv2IAAjX8doM3Vozqle3g==} - engines: {node: '>=18'} - - conventional-changelog-codemirror@5.0.0: - resolution: {integrity: sha512-8gsBDI5Y3vrKUCxN6Ue8xr6occZ5nsDEc4C7jO/EovFGozx8uttCAyfhRrvoUAWi2WMm3OmYs+0mPJU7kQdYWQ==} - engines: {node: '>=18'} - - conventional-changelog-conventionalcommits@8.0.0: - resolution: {integrity: sha512-eOvlTO6OcySPyyyk8pKz2dP4jjElYunj9hn9/s0OB+gapTO8zwS9UQWrZ1pmF2hFs3vw1xhonOLGcGjy/zgsuA==} - engines: {node: '>=18'} - - conventional-changelog-core@8.0.0: - resolution: {integrity: sha512-EATUx5y9xewpEe10UEGNpbSHRC6cVZgO+hXQjofMqpy+gFIrcGvH3Fl6yk2VFKh7m+ffenup2N7SZJYpyD9evw==} - engines: {node: '>=18'} - - conventional-changelog-ember@5.0.0: - resolution: {integrity: sha512-RPflVfm5s4cSO33GH/Ey26oxhiC67akcxSKL8CLRT3kQX2W3dbE19sSOM56iFqUJYEwv9mD9r6k79weWe1urfg==} - engines: {node: '>=18'} - - conventional-changelog-eslint@6.0.0: - resolution: {integrity: sha512-eiUyULWjzq+ybPjXwU6NNRflApDWlPEQEHvI8UAItYW/h22RKkMnOAtfCZxMmrcMO1OKUWtcf2MxKYMWe9zJuw==} - engines: {node: '>=18'} - - conventional-changelog-express@5.0.0: - resolution: {integrity: sha512-D8Q6WctPkQpvr2HNCCmwU5GkX22BVHM0r4EW8vN0230TSyS/d6VQJDAxGb84lbg0dFjpO22MwmsikKL++Oo/oQ==} - engines: {node: '>=18'} - - conventional-changelog-jquery@6.0.0: - resolution: {integrity: sha512-2kxmVakyehgyrho2ZHBi90v4AHswkGzHuTaoH40bmeNqUt20yEkDOSpw8HlPBfvEQBwGtbE+5HpRwzj6ac2UfA==} - engines: {node: '>=18'} - - conventional-changelog-jshint@5.0.0: - resolution: {integrity: sha512-gGNphSb/opc76n2eWaO6ma4/Wqu3tpa2w7i9WYqI6Cs2fncDSI2/ihOfMvXveeTTeld0oFvwMVNV+IYQIk3F3g==} + conventional-changelog-conventionalcommits@9.1.0: + resolution: {integrity: sha512-MnbEysR8wWa8dAEvbj5xcBgJKQlX/m0lhS8DsyAAWDHdfs2faDJxTgzRYlRYpXSe7UiKrIIlB4TrBKU9q9DgkA==} engines: {node: '>=18'} conventional-changelog-preset-loader@5.0.0: resolution: {integrity: sha512-SetDSntXLk8Jh1NOAl1Gu5uLiCNSYenB5tm0YVeZKePRIgDW9lQImromTwLa3c/Gae298tsgOM+/CYT9XAl0NA==} engines: {node: '>=18'} - conventional-changelog-writer@8.0.0: - resolution: {integrity: sha512-TQcoYGRatlAnT2qEWDON/XSfnVG38JzA7E0wcGScu7RElQBkg9WWgZd1peCWFcWDh1xfb2CfsrcvOn1bbSzztA==} + conventional-changelog-writer@8.2.0: + resolution: {integrity: sha512-Y2aW4596l9AEvFJRwFGJGiQjt2sBYTjPD18DdvxX9Vpz0Z7HQ+g1Z+6iYDAm1vR3QOJrDBkRHixHK/+FhkR6Pw==} engines: {node: '>=18'} hasBin: true - conventional-changelog@6.0.0: - resolution: {integrity: sha512-tuUH8H/19VjtD9Ig7l6TQRh+Z0Yt0NZ6w/cCkkyzUbGQTnUEmKfGtkC9gGfVgCfOL1Rzno5NgNF4KY8vR+Jo3w==} + conventional-changelog@7.1.1: + resolution: {integrity: sha512-rlqa8Lgh8YzT3Akruk05DR79j5gN9NCglHtJZwpi6vxVeaoagz+84UAtKQj/sT+RsfGaZkt3cdFCjcN6yjr5sw==} engines: {node: '>=18'} + hasBin: true conventional-commits-filter@5.0.0: resolution: {integrity: sha512-tQMagCOC59EVgNZcC5zl7XqO30Wki9i9J3acbUvkaosCT6JX3EeFwJD7Qqp4MCikRnzS18WXV3BLIQ66ytu6+Q==} engines: {node: '>=18'} - conventional-commits-parser@6.0.0: - resolution: {integrity: sha512-TbsINLp48XeMXR8EvGjTnKGsZqBemisPoyWESlpRyR8lif0lcwzqz+NMtYSj1ooF/WYjSuu7wX0CtdeeMEQAmA==} + conventional-commits-parser@6.2.0: + resolution: {integrity: sha512-uLnoLeIW4XaoFtH37qEcg/SXMJmKF4vi7V0H2rnPueg+VEtFGA/asSCNTcq4M/GQ6QmlzchAEtOoDTtKqWeHag==} engines: {node: '>=18'} hasBin: true @@ -7814,6 +7783,9 @@ packages: fclone@1.0.11: resolution: {integrity: sha512-GDqVQezKzRABdeqflsgMr7ktzgF9CyS+p2oe0jJqUY6izSSbhPIQJDpoU4PtGcD7VPM9xh/dVrTu6z1nwgmEGw==} + fd-package-json@2.0.0: + resolution: {integrity: sha512-jKmm9YtsNXN789RS/0mSzOC1NUq9mkVd65vbSSVsKdjGvYXBuE4oWe2QOEoFeRmJg+lPuZxpmrfFclNhoRMneQ==} + fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} engines: {node: '>=12.0.0'} @@ -7872,10 +7844,6 @@ packages: find-package-json@1.2.0: resolution: {integrity: sha512-+SOGcLGYDJHtyqHd87ysBhmaeQ95oWspDKnMXBrnQ9Eq4OkLNqejgoaD8xVWu6GPa0B6roa6KinCMEMcVeqONw==} - find-up-simple@1.0.1: - resolution: {integrity: sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==} - engines: {node: '>=18'} - find-up@3.0.0: resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==} engines: {node: '>=6'} @@ -8073,16 +8041,6 @@ packages: js-git: optional: true - git-raw-commits@5.0.0: - resolution: {integrity: sha512-I2ZXrXeOc0KrCvC7swqtIFXFN+rbjnC7b2T943tvemIOVNl+XP8YnA9UVwqFhzzLClnSA60KR/qEjLpXzs73Qg==} - engines: {node: '>=18'} - hasBin: true - - git-semver-tags@8.0.0: - resolution: {integrity: sha512-N7YRIklvPH3wYWAR2vysaqGLPRcpwQ0GKdlqTiVN5w1UmCdaeY3K8s6DMKRCh54DDdzyt/OAB6C8jgVtb7Y2Fg==} - engines: {node: '>=18'} - hasBin: true - git-sha1@0.1.2: resolution: {integrity: sha512-2e/nZezdVlyCopOCYHeW0onkbZg7xP1Ad6pndPy1rCygeRykefUS6r7oA5cJRGEFvseiaz5a/qUHFVX1dd6Isg==} @@ -8345,9 +8303,9 @@ packages: hookable@5.5.3: resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} - hosted-git-info@7.0.2: - resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} - engines: {node: ^16.14.0 || >=18.0.0} + hosted-git-info@8.1.0: + resolution: {integrity: sha512-Rw/B2DNQaPBICNXEm8balFz9a6WpZrkCGpcWFpy7nCj+NyhSdqXipmfvtmWt9xGfp0wZnBxB+iVpLmQMYt47Tw==} + engines: {node: ^18.17.0 || >=20.5.0} html-encoding-sniffer@3.0.0: resolution: {integrity: sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==} @@ -8476,10 +8434,6 @@ packages: resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} engines: {node: '>=8'} - index-to-position@0.1.2: - resolution: {integrity: sha512-MWDKS3AS1bGCHLBA2VLImJz42f7bJh8wQsTGCzI3j519/CASStoDONUBVz2I/VID0MpiX3SGSnbOD2xUalbE5g==} - engines: {node: '>=18'} - inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. @@ -9744,9 +9698,9 @@ packages: engines: {node: ^18.17.0 || >=20.5.0} hasBin: true - normalize-package-data@6.0.2: - resolution: {integrity: sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==} - engines: {node: ^16.14.0 || >=18.0.0} + normalize-package-data@7.0.1: + resolution: {integrity: sha512-linxNAT6M0ebEYZOx2tO6vBEFsVgnPpv+AVjk0wJHfaUIbq31Jm3T6vvZaarnOeWDh8ShnwXuaAyM7WT3RzErA==} + engines: {node: ^18.17.0 || >=20.5.0} normalize-path@2.1.1: resolution: {integrity: sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==} @@ -10043,10 +9997,6 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} - parse-json@8.1.0: - resolution: {integrity: sha512-rum1bPifK5SSar35Z6EKZuYPJx85pkNaFrxBK3mwdfSJ1/WKbYrjoW/zTPSjRRamfmVX1ACBIdFAO0VRErW/EA==} - engines: {node: '>=18'} - parse-ms@4.0.0: resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} engines: {node: '>=18'} @@ -10738,14 +10688,6 @@ packages: read-cache@1.0.0: resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} - read-package-up@11.0.0: - resolution: {integrity: sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ==} - engines: {node: '>=18'} - - read-pkg@9.0.1: - resolution: {integrity: sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==} - engines: {node: '>=18'} - read@1.0.7: resolution: {integrity: sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==} engines: {node: '>=0.8'} @@ -12521,6 +12463,9 @@ packages: vue-component-type-helpers@3.0.6: resolution: {integrity: sha512-6CRM8X7EJqWCJOiKPvSLQG+hJPb/Oy2gyJx3pLjUEhY7PuaCthQu3e0zAGI1lqUBobrrk9IT0K8sG2GsCluxoQ==} + vue-component-type-helpers@3.0.7: + resolution: {integrity: sha512-TvyUcFXmjZcXUvU+r1MOyn4/vv4iF+tPwg5Ig33l/FJ3myZkxeQpzzQMLMFWcQAjr6Xs7BRwVy/TwbmNZUA/4w==} + vue-demi@0.14.10: resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==} engines: {node: '>=12'} @@ -12615,6 +12560,10 @@ packages: resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} engines: {node: '>=18'} + walk-up-path@4.0.0: + resolution: {integrity: sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==} + engines: {node: 20 || >=22} + wcwidth@1.0.1: resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} @@ -13816,13 +13765,14 @@ snapshots: '@cloudflare/workerd-windows-64@1.20250823.0': optional: true - '@conventional-changelog/git-client@1.0.1(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0)': + '@conventional-changelog/git-client@2.5.1(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.2.0)': dependencies: - '@types/semver': 7.7.0 + '@simple-libs/child-process-utils': 1.0.1 + '@simple-libs/stream-utils': 1.1.0 semver: 7.7.2 optionalDependencies: conventional-commits-filter: 5.0.0 - conventional-commits-parser: 6.0.0 + conventional-commits-parser: 6.2.0 '@cspotcode/source-map-support@0.8.1': dependencies: @@ -14859,8 +14809,6 @@ snapshots: '@humanwhocodes/retry@0.4.2': {} - '@hutson/parse-repository-url@5.0.0': {} - '@ianvs/prettier-plugin-sort-imports@4.6.3(@vue/compiler-sfc@3.5.20)(prettier@3.6.2)': dependencies: '@babel/generator': 7.28.0 @@ -16562,6 +16510,15 @@ snapshots: '@sec-ant/readable-stream@0.4.1': {} + '@simple-libs/child-process-utils@1.0.1': + dependencies: + '@simple-libs/stream-utils': 1.1.0 + '@types/node': 22.18.0 + + '@simple-libs/stream-utils@1.1.0': + dependencies: + '@types/node': 22.18.0 + '@sindresorhus/is@7.0.2': {} '@sindresorhus/merge-streams@2.3.0': {} @@ -16639,7 +16596,7 @@ snapshots: storybook: 9.1.3(@testing-library/dom@10.4.0)(prettier@3.6.2)(vite@7.1.3(@types/node@22.18.0)(jiti@2.5.1)(lightningcss@1.30.1)(stylus@0.57.0)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1)) type-fest: 2.19.0 vue: 3.5.20(typescript@5.9.2) - vue-component-type-helpers: 3.0.6 + vue-component-type-helpers: 3.0.7 '@swc/core-darwin-arm64@1.13.5': optional: true @@ -16873,7 +16830,7 @@ snapshots: dependencies: minimatch: 9.0.5 path-browserify: 1.0.1 - tinyglobby: 0.2.14 + tinyglobby: 0.2.15 optional: true '@ts-morph/common@0.27.0': @@ -18029,8 +17986,6 @@ snapshots: acorn@8.15.0: {} - add-stream@1.0.0: {} - agent-base@7.1.3: {} aggregate-error@3.1.0: @@ -18919,74 +18874,35 @@ snapshots: content-type@1.0.5: {} - conventional-changelog-angular@8.0.0: - dependencies: - compare-func: 2.0.0 - - conventional-changelog-atom@5.0.0: {} - - conventional-changelog-codemirror@5.0.0: {} - - conventional-changelog-conventionalcommits@8.0.0: - dependencies: - compare-func: 2.0.0 - - conventional-changelog-core@8.0.0(conventional-commits-filter@5.0.0): - dependencies: - '@hutson/parse-repository-url': 5.0.0 - add-stream: 1.0.0 - conventional-changelog-writer: 8.0.0 - conventional-commits-parser: 6.0.0 - git-raw-commits: 5.0.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0) - git-semver-tags: 8.0.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0) - hosted-git-info: 7.0.2 - normalize-package-data: 6.0.2 - read-package-up: 11.0.0 - read-pkg: 9.0.1 - transitivePeerDependencies: - - conventional-commits-filter - - conventional-changelog-ember@5.0.0: {} - - conventional-changelog-eslint@6.0.0: {} - - conventional-changelog-express@5.0.0: {} - - conventional-changelog-jquery@6.0.0: {} - - conventional-changelog-jshint@5.0.0: + conventional-changelog-conventionalcommits@9.1.0: dependencies: compare-func: 2.0.0 conventional-changelog-preset-loader@5.0.0: {} - conventional-changelog-writer@8.0.0: + conventional-changelog-writer@8.2.0: dependencies: - '@types/semver': 7.7.0 conventional-commits-filter: 5.0.0 handlebars: 4.7.8 meow: 13.2.0 semver: 7.7.2 - conventional-changelog@6.0.0(conventional-commits-filter@5.0.0): + conventional-changelog@7.1.1(conventional-commits-filter@5.0.0): dependencies: - conventional-changelog-angular: 8.0.0 - conventional-changelog-atom: 5.0.0 - conventional-changelog-codemirror: 5.0.0 - conventional-changelog-conventionalcommits: 8.0.0 - conventional-changelog-core: 8.0.0(conventional-commits-filter@5.0.0) - conventional-changelog-ember: 5.0.0 - conventional-changelog-eslint: 6.0.0 - conventional-changelog-express: 5.0.0 - conventional-changelog-jquery: 6.0.0 - conventional-changelog-jshint: 5.0.0 + '@conventional-changelog/git-client': 2.5.1(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.2.0) + '@types/normalize-package-data': 2.4.4 conventional-changelog-preset-loader: 5.0.0 + conventional-changelog-writer: 8.2.0 + conventional-commits-parser: 6.2.0 + fd-package-json: 2.0.0 + meow: 13.2.0 + normalize-package-data: 7.0.1 transitivePeerDependencies: - conventional-commits-filter conventional-commits-filter@5.0.0: {} - conventional-commits-parser@6.0.0: + conventional-commits-parser@6.2.0: dependencies: meow: 13.2.0 @@ -20386,6 +20302,10 @@ snapshots: fclone@1.0.11: {} + fd-package-json@2.0.0: + dependencies: + walk-up-path: 4.0.0 + fdir@6.5.0(picomatch@4.0.3): optionalDependencies: picomatch: 4.0.3 @@ -20450,8 +20370,6 @@ snapshots: find-package-json@1.2.0: {} - find-up-simple@1.0.1: {} - find-up@3.0.0: dependencies: locate-path: 3.0.0 @@ -20669,22 +20587,6 @@ snapshots: optionalDependencies: js-git: 0.7.8 - git-raw-commits@5.0.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0): - dependencies: - '@conventional-changelog/git-client': 1.0.1(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0) - meow: 13.2.0 - transitivePeerDependencies: - - conventional-commits-filter - - conventional-commits-parser - - git-semver-tags@8.0.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0): - dependencies: - '@conventional-changelog/git-client': 1.0.1(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0) - meow: 13.2.0 - transitivePeerDependencies: - - conventional-commits-filter - - conventional-commits-parser - git-sha1@0.1.2: {} git-up@8.1.1: @@ -20966,7 +20868,7 @@ snapshots: hookable@5.5.3: {} - hosted-git-info@7.0.2: + hosted-git-info@8.1.0: dependencies: lru-cache: 10.4.3 @@ -21101,8 +21003,6 @@ snapshots: indent-string@4.0.0: {} - index-to-position@0.1.2: {} - inflight@1.0.6: dependencies: once: 1.4.0 @@ -22422,9 +22322,9 @@ snapshots: dependencies: abbrev: 3.0.0 - normalize-package-data@6.0.2: + normalize-package-data@7.0.1: dependencies: - hosted-git-info: 7.0.2 + hosted-git-info: 8.1.0 semver: 7.7.2 validate-npm-package-license: 3.0.4 @@ -22930,12 +22830,6 @@ snapshots: json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 - parse-json@8.1.0: - dependencies: - '@babel/code-frame': 7.27.1 - index-to-position: 0.1.2 - type-fest: 4.41.0 - parse-ms@4.0.0: {} parse-path@7.1.0: @@ -23653,20 +23547,6 @@ snapshots: dependencies: pify: 2.3.0 - read-package-up@11.0.0: - dependencies: - find-up-simple: 1.0.1 - read-pkg: 9.0.1 - type-fest: 4.41.0 - - read-pkg@9.0.1: - dependencies: - '@types/normalize-package-data': 2.4.4 - normalize-package-data: 6.0.2 - parse-json: 8.1.0 - type-fest: 4.41.0 - unicorn-magic: 0.1.0 - read@1.0.7: dependencies: mute-stream: 0.0.8 @@ -25049,7 +24929,8 @@ snapshots: pako: 0.2.9 tiny-inflate: 1.0.3 - unicorn-magic@0.1.0: {} + unicorn-magic@0.1.0: + optional: true unicorn-magic@0.3.0: {} @@ -25647,6 +25528,8 @@ snapshots: vue-component-type-helpers@3.0.6: {} + vue-component-type-helpers@3.0.7: {} + vue-demi@0.14.10(vue@3.5.20(typescript@5.9.2)): dependencies: vue: 3.5.20(typescript@5.9.2) @@ -25827,6 +25710,8 @@ snapshots: dependencies: xml-name-validator: 5.0.0 + walk-up-path@4.0.0: {} + wcwidth@1.0.1: dependencies: defaults: 1.0.4