@muverse/core 0.2.11 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,27 +1,12 @@
1
1
  import { ModuleChangeResult } from "../services/version-applier.js";
2
- import { CommitInfo } from "../git/index.js";
3
- export type ChangelogEntry = {
4
- readonly moduleResult: ModuleChangeResult;
5
- readonly version: string;
6
- readonly date: string;
7
- readonly changes: {
8
- readonly breaking: CommitInfo[];
9
- readonly features: CommitInfo[];
10
- readonly fixes: CommitInfo[];
11
- readonly other: CommitInfo[];
12
- };
13
- };
14
- export type ChangelogOptions = {
15
- readonly includeCommitHashes: boolean;
16
- readonly includeScopes: boolean;
17
- readonly groupByType: boolean;
18
- };
19
- /** Generate changelog content for a module. */
20
- export declare function generateChangelog(moduleResult: ModuleChangeResult, commits: CommitInfo[], options?: ChangelogOptions): Promise<string>;
2
+ import { Commit } from "conventional-commits-parser";
21
3
  /** Update or create a changelog file for a module. */
22
- export declare function updateChangelogFile(moduleResult: ModuleChangeResult, changelogContent: string, repoRoot: string): Promise<string>;
4
+ export declare function updateChangelogFile(changelogContent: string, changelogPath: string, prependPlaceholder: string): Promise<void>;
23
5
  /** Generate changelog for multiple modules. */
24
- export declare function generateChangelogsForModules(moduleResults: ModuleChangeResult[], getCommitsForModule: (moduleId: string) => Promise<CommitInfo[]>, repoRoot: string, options?: ChangelogOptions): Promise<string[]>;
6
+ export declare function generateChangelogsForModules(moduleResults: ModuleChangeResult[], getCommitsForModule: (moduleId: string) => Promise<{
7
+ commits: Commit[];
8
+ lastTag: string | null;
9
+ }>, repoRoot: string): Promise<string[]>;
25
10
  /** Generate a root changelog that summarizes all module changes. */
26
11
  export declare function generateRootChangelog(moduleResults: ModuleChangeResult[], repoRoot: string): Promise<string>;
27
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/changelog/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,YAAY,EAAE,kBAAkB,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE;QAChB,QAAQ,CAAC,QAAQ,EAAE,UAAU,EAAE,CAAC;QAChC,QAAQ,CAAC,QAAQ,EAAE,UAAU,EAAE,CAAC;QAChC,QAAQ,CAAC,KAAK,EAAE,UAAU,EAAE,CAAC;QAC7B,QAAQ,CAAC,KAAK,EAAE,UAAU,EAAE,CAAC;KAC9B,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAC;IACtC,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;CAC/B,CAAC;AAEF,+CAA+C;AAC/C,wBAAsB,iBAAiB,CACrC,YAAY,EAAE,kBAAkB,EAChC,OAAO,EAAE,UAAU,EAAE,EACrB,OAAO,GAAE,gBAIR,GACA,OAAO,CAAC,MAAM,CAAC,CA2BjB;AA4ED,sDAAsD;AACtD,wBAAsB,mBAAmB,CACvC,YAAY,EAAE,kBAAkB,EAChC,gBAAgB,EAAE,MAAM,EACxB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,CAqDjB;AAED,+CAA+C;AAC/C,wBAAsB,4BAA4B,CAChD,aAAa,EAAE,kBAAkB,EAAE,EACnC,mBAAmB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,EAAE,CAAC,EAChE,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,MAAM,EAAE,CAAC,CAqBnB;AAED,oEAAoE;AACpE,wBAAsB,qBAAqB,CACzC,aAAa,EAAE,kBAAkB,EAAE,EACnC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,CA4DjB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/changelog/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAGpE,OAAO,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAKrD,sDAAsD;AACtD,wBAAsB,mBAAmB,CACvC,gBAAgB,EAAE,MAAM,EACxB,aAAa,EAAE,MAAM,EACrB,kBAAkB,EAAE,MAAM,GACzB,OAAO,CAAC,IAAI,CAAC,CAWf;AAsBD,+CAA+C;AAC/C,wBAAsB,4BAA4B,CAChD,aAAa,EAAE,kBAAkB,EAAE,EACnC,mBAAmB,EAAE,CACnB,QAAQ,EAAE,MAAM,KACb,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,EAC3D,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,EAAE,CAAC,CAiFnB;AAED,oEAAoE;AACpE,wBAAsB,qBAAqB,CACzC,aAAa,EAAE,kBAAkB,EAAE,EACnC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,CA4DjB"}
@@ -1,150 +1,78 @@
1
1
  import { promises as fs } from "fs";
2
- import { join } from "path";
3
- /** Generate changelog content for a module. */
4
- export async function generateChangelog(moduleResult, commits, options = {
5
- includeCommitHashes: false,
6
- includeScopes: true,
7
- groupByType: true,
8
- }) {
9
- const entry = {
10
- moduleResult,
11
- version: moduleResult.to,
12
- date: new Date().toISOString().split("T")[0], // YYYY-MM-DD format
13
- changes: {
14
- breaking: [],
15
- features: [],
16
- fixes: [],
17
- other: [],
18
- },
19
- };
20
- // Categorize commits
21
- for (const commit of commits) {
22
- if (commit.breaking) {
23
- entry.changes.breaking.push(commit);
24
- }
25
- else if (commit.type === "feat") {
26
- entry.changes.features.push(commit);
27
- }
28
- else if (commit.type === "fix") {
29
- entry.changes.fixes.push(commit);
30
- }
31
- else if (["perf", "refactor", "style"].includes(commit.type)) {
32
- entry.changes.other.push(commit);
33
- }
34
- }
35
- return formatChangelogEntry(entry, options);
36
- }
37
- /**
38
- * Format changelog entry as markdown
39
- */
40
- function formatChangelogEntry(entry, options) {
41
- const version = entry.version;
42
- let changelog = `## [${version}] - ${entry.date}\n\n`;
43
- // Breaking changes first
44
- if (entry.changes.breaking.length > 0) {
45
- changelog += "### 💥 BREAKING CHANGES\n\n";
46
- for (const commit of entry.changes.breaking) {
47
- changelog += formatCommitLine(commit, options) + "\n";
48
- }
49
- changelog += "\n";
50
- }
51
- // Features
52
- if (entry.changes.features.length > 0) {
53
- changelog += "### ✨ Features\n\n";
54
- for (const commit of entry.changes.features) {
55
- changelog += formatCommitLine(commit, options) + "\n";
56
- }
57
- changelog += "\n";
58
- }
59
- // Bug fixes
60
- if (entry.changes.fixes.length > 0) {
61
- changelog += "### 🐛 Bug Fixes\n\n";
62
- for (const commit of entry.changes.fixes) {
63
- changelog += formatCommitLine(commit, options) + "\n";
64
- }
65
- changelog += "\n";
66
- }
67
- // Other changes
68
- if (entry.changes.other.length > 0) {
69
- changelog += "### 🔧 Other Changes\n\n";
70
- for (const commit of entry.changes.other) {
71
- changelog += formatCommitLine(commit, options) + "\n";
72
- }
73
- changelog += "\n";
74
- }
75
- return changelog;
76
- }
77
- /**
78
- * Format a single commit line
79
- */
80
- function formatCommitLine(commit, options) {
81
- let line = "- ";
82
- // Add scope if available and enabled
83
- if (options.includeScopes && commit.scope) {
84
- line += `**${commit.scope}**: `;
85
- }
86
- // Add subject
87
- line += commit.subject;
88
- // Add hash if enabled
89
- if (options.includeCommitHashes) {
90
- line += ` (${commit.hash.substring(0, 7)})`;
91
- }
92
- return line;
93
- }
2
+ import path, { join } from "path";
3
+ import { writeChangelogString } from "conventional-changelog-writer";
4
+ import { logger } from "../utils/logger.js";
5
+ import { exists } from "../utils/file.js";
6
+ import { getCurrentRepoUrl, parseRepoUrl } from "../git/index.js";
7
+ import { isReleaseVersion } from "../semver/index.js";
94
8
  /** Update or create a changelog file for a module. */
95
- export async function updateChangelogFile(moduleResult, changelogContent, repoRoot) {
96
- const changelogPath = join(repoRoot, moduleResult.path, "CHANGELOG.md");
97
- try {
9
+ export async function updateChangelogFile(changelogContent, changelogPath, prependPlaceholder) {
10
+ let fileContent = changelogContent;
11
+ if (await exists(changelogPath)) {
12
+ logger.info(`Updating existing changelog at ${changelogPath}...`);
98
13
  // Try to read existing changelog
99
14
  const existingContent = await fs.readFile(changelogPath, "utf8");
100
- // Insert new content after the first heading
101
- const lines = existingContent.split("\n");
102
- let insertIndex = 0;
103
- // Find the first ## heading or the end of initial content
104
- for (let i = 0; i < lines.length; i++) {
105
- if (lines[i].startsWith("## ")) {
106
- insertIndex = i;
107
- break;
108
- }
109
- if (i === 0 && lines[i].startsWith("# ")) {
110
- // Skip the main heading
111
- continue;
112
- }
113
- }
114
- // Insert the new changelog entry
115
- const beforeInsert = lines.slice(0, insertIndex);
116
- const afterInsert = lines.slice(insertIndex);
117
- const updatedContent = [
118
- ...beforeInsert,
119
- changelogContent.trim(),
120
- "",
121
- ...afterInsert,
122
- ].join("\n");
123
- await fs.writeFile(changelogPath, updatedContent, "utf8");
124
- }
125
- catch (error) {
126
- if (error instanceof Error &&
127
- "code" in error &&
128
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
129
- error.code === "ENOENT") {
130
- // Create new changelog file
131
- const moduleName = moduleResult.id === "root" ? "Root Module" : moduleResult.id;
132
- const newContent = `# Changelog - ${moduleName}\n\n${changelogContent}`;
133
- await fs.writeFile(changelogPath, newContent, "utf8");
134
- }
135
- else {
136
- throw error;
137
- }
15
+ const newContent = `${prependPlaceholder}\n\n${changelogContent.trimEnd()}`;
16
+ fileContent = existingContent.replace(prependPlaceholder, newContent);
138
17
  }
139
- return changelogPath;
18
+ await fs.writeFile(changelogPath, fileContent, "utf8");
19
+ }
20
+ async function buildContextRepository(options = {}) {
21
+ const repoUrl = await getCurrentRepoUrl(options);
22
+ const { host, owner, repo } = parseRepoUrl(repoUrl);
23
+ return {
24
+ repoUrl: `https://${host}/${owner}/${repo}`,
25
+ host: `https://${host}`,
26
+ owner,
27
+ repository: repo,
28
+ };
140
29
  }
141
30
  /** Generate changelog for multiple modules. */
142
- export async function generateChangelogsForModules(moduleResults, getCommitsForModule, repoRoot, options) {
31
+ export async function generateChangelogsForModules(moduleResults, getCommitsForModule, repoRoot) {
143
32
  const changelogPaths = [];
33
+ const configPath = path.resolve(repoRoot, "changelog.config.js");
34
+ if (!(await exists(configPath))) {
35
+ throw new Error(`Missing required changelog configuration file at ${configPath}`);
36
+ }
37
+ logger.info(`Loading changelog configuration from ${configPath}...`);
38
+ const userConfig = (await import(configPath)).default;
39
+ const prependPlaceholder = userConfig.context.prependPlaceholder;
40
+ if (!prependPlaceholder) {
41
+ throw new Error("Missing required context property 'prependPlaceholder' in changelog.config.js");
42
+ }
43
+ const contextRepository = await buildContextRepository({ cwd: repoRoot });
144
44
  for (const moduleResult of moduleResults) {
145
- const commits = await getCommitsForModule(moduleResult.id);
146
- const changelogContent = await generateChangelog(moduleResult, commits, options);
147
- const changelogPath = await updateChangelogFile(moduleResult, changelogContent, repoRoot);
45
+ if (!moduleResult.declaredVersion) {
46
+ logger.info(`Module ${moduleResult.id} has no declared version, skipping changelog generation...`);
47
+ continue;
48
+ }
49
+ const { commits, lastTag } = await getCommitsForModule(moduleResult.id);
50
+ if (commits.length === 0) {
51
+ logger.info(`No commits to include in changelog for module ${moduleResult.id}, skipping...`);
52
+ continue;
53
+ }
54
+ const changelogPath = join(repoRoot, moduleResult.path, "CHANGELOG.md");
55
+ let prepend = true;
56
+ if (await exists(changelogPath)) {
57
+ prepend = false;
58
+ }
59
+ const isRelease = isReleaseVersion(moduleResult.to);
60
+ const version = isRelease ? moduleResult.to : undefined;
61
+ const currentTag = isRelease
62
+ ? `${moduleResult.name}@${moduleResult.to}`
63
+ : undefined;
64
+ const previousTag = lastTag || undefined;
65
+ const changelogContent = await writeChangelogString(commits, {
66
+ version: version,
67
+ previousTag: previousTag,
68
+ currentTag: currentTag,
69
+ linkCompare: previousTag && currentTag ? true : false,
70
+ ...contextRepository,
71
+ ...userConfig.context,
72
+ prepend,
73
+ }, userConfig.options);
74
+ logger.info(changelogContent);
75
+ await updateChangelogFile(changelogContent, changelogPath, prependPlaceholder);
148
76
  changelogPaths.push(changelogPath);
149
77
  }
150
78
  return changelogPaths;
@@ -1,5 +1,6 @@
1
1
  import { z } from "zod";
2
2
  import { BumpType } from "../semver/index.js";
3
+ import { Commit } from "conventional-commits-parser";
3
4
  /**
4
5
  * Zod schema for DependencyRules configuration.
5
6
  * Validates that dependency cascade rules use valid bump types.
@@ -97,12 +98,11 @@ export type NodeJSConfig = z.infer<typeof nodeJSConfigSchema>;
97
98
  export declare const DEFAULT_CONFIG: Config;
98
99
  /**
99
100
  * Determines the bump type for a commit based on its type and breaking change flag.
100
- * @param commitType - The Conventional Commit type (e.g., 'feat', 'fix', 'chore')
101
- * @param isBreaking - Whether the commit contains breaking changes
101
+ * @param commit - The commit to evaluate
102
102
  * @param config - Configuration containing commit type mappings
103
103
  * @returns The bump type to apply ('major', 'minor', 'patch', or 'none')
104
104
  */
105
- export declare function getBumpTypeForCommit(commitType: string, isBreaking: boolean, config: Config): BumpType;
105
+ export declare function getBumpTypeForCommit(commit: Commit, config: Config): BumpType;
106
106
  /**
107
107
  * Determines how a module should be bumped when one of its dependencies changes.
108
108
  * Uses dependency cascade rules from configuration to propagate version changes.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAoB9C;;;GAGG;AACH,QAAA,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;iBAIzB,CAAC;AAEH;;;GAGG;AACH,QAAA,MAAM,kBAAkB;;;iBAGtB,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAKvB,CAAC;AAEH;;;GAGG;AACH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAElD;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,MAmB5B,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,OAAO,EACnB,MAAM,EAAE,MAAM,GACb,QAAQ,CAYV;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,kBAAkB,EAAE,QAAQ,EAC5B,MAAM,EAAE,MAAM,GACb,QAAQ,CAaV;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,MAAM,EACrD,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,CAAC,GACb,MAAM,CAAC,CAAC,CAAC,CAEX"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAqBrD;;;GAGG;AACH,QAAA,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;iBAIzB,CAAC;AAEH;;;GAGG;AACH,QAAA,MAAM,kBAAkB;;;iBAGtB,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAKvB,CAAC;AAEH;;;GAGG;AACH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAElD;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,MAmB5B,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,QAAQ,CAe7E;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,kBAAkB,EAAE,QAAQ,EAC5B,MAAM,EAAE,MAAM,GACb,QAAQ,CAaV;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,MAAM,EACrD,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,CAAC,GACb,MAAM,CAAC,CAAC,CAAC,CAEX"}
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import { isBreakingCommit } from "../git/index.js";
2
3
  /**
3
4
  * Zod schema for BumpType values.
4
5
  * Used for validation in configuration files.
@@ -69,15 +70,16 @@ export const DEFAULT_CONFIG = {
69
70
  };
70
71
  /**
71
72
  * Determines the bump type for a commit based on its type and breaking change flag.
72
- * @param commitType - The Conventional Commit type (e.g., 'feat', 'fix', 'chore')
73
- * @param isBreaking - Whether the commit contains breaking changes
73
+ * @param commit - The commit to evaluate
74
74
  * @param config - Configuration containing commit type mappings
75
75
  * @returns The bump type to apply ('major', 'minor', 'patch', or 'none')
76
76
  */
77
- export function getBumpTypeForCommit(commitType, isBreaking, config) {
77
+ export function getBumpTypeForCommit(commit, config) {
78
+ const isBreaking = isBreakingCommit(commit);
78
79
  if (isBreaking) {
79
80
  return "major";
80
81
  }
82
+ const commitType = commit.type || "unknown";
81
83
  const configuredBump = config.commitTypes[commitType];
82
84
  if (configuredBump === "ignore") {
83
85
  return "none";
@@ -3,6 +3,7 @@
3
3
  * Provides interfaces for commit analysis, tagging, and conventional commit parsing.
4
4
  * Supports monorepo and multi-module projects with module-specific tag management.
5
5
  */
6
+ import { Commit } from "conventional-commits-parser";
6
7
  import { Module } from "../index.js";
7
8
  /**
8
9
  * Represents a parsed git tag with extracted module and version metadata.
@@ -76,6 +77,7 @@ export type CommitInfo = {
76
77
  * Not currently extracted by the parser but reserved for future use.
77
78
  */
78
79
  readonly module?: string;
80
+ readonly parsed?: Commit;
79
81
  };
80
82
  /**
81
83
  * Retrieves all commits for a module since its last release tag.
@@ -85,7 +87,10 @@ export type CommitInfo = {
85
87
  * @param excludePaths - Paths to exclude using git pathspec syntax
86
88
  * @returns Promise resolving to array of parsed commits (oldest to newest)
87
89
  */
88
- export declare function getCommitsSinceLastTag(projectInfo: Module, options?: GitOptions, excludePaths?: string[]): Promise<CommitInfo[]>;
90
+ export declare function getCommitsSinceLastTag(projectInfo: Module, options?: GitOptions, excludePaths?: string[]): Promise<{
91
+ commits: Commit[];
92
+ lastTag: string | null;
93
+ }>;
89
94
  /**
90
95
  * Retrieves commits within a specific git revision range with path filtering.
91
96
  * Uses git's native pathspec syntax for efficient filtering in monorepos.
@@ -95,7 +100,8 @@ export declare function getCommitsSinceLastTag(projectInfo: Module, options?: Gi
95
100
  * @param excludePaths - Paths to exclude using ':(exclude)path' syntax
96
101
  * @returns Promise resolving to array of parsed commits (oldest to newest)
97
102
  */
98
- export declare function getCommitsInRange(range: string, pathFilter?: string, options?: GitOptions, excludePaths?: string[]): Promise<CommitInfo[]>;
103
+ export declare function getCommitsInRange(range: string, pathFilter?: string, options?: GitOptions, excludePaths?: string[]): Promise<Commit[]>;
104
+ export declare function isBreakingCommit(commit: Commit): boolean;
99
105
  /**
100
106
  * Finds the most recent git tag for a specific module with fallback to general tags.
101
107
  * Searches module-specific tags first (moduleName@*), then falls back to general tags.
@@ -248,4 +254,102 @@ export declare function pushCommits(options?: GitOptions): Promise<void>;
248
254
  * Unlike `isWorkingDirectoryClean()`, this function throws on errors.
249
255
  */
250
256
  export declare function hasChangesToCommit(options?: GitOptions): Promise<boolean>;
257
+ export declare function getCurrentRepoUrl(options?: GitOptions): Promise<string>;
258
+ /**
259
+ * Parses a git repository URL (SSH or HTTP/HTTPS) and extracts its components.
260
+ *
261
+ * Supports multiple URL formats:
262
+ * - SSH: `git@github.com:owner/repo.git`
263
+ * - HTTPS: `https://github.com/owner/repo.git`
264
+ * - HTTP: `http://github.com/owner/repo.git`
265
+ *
266
+ * @param repoUrl - The repository URL to parse
267
+ * @returns Object containing host, owner, and repo name
268
+ * @throws {Error} If URL format is invalid or cannot be parsed
269
+ * @internal
270
+ */
271
+ export declare function parseRepoUrl(repoUrl: string): {
272
+ host: string;
273
+ owner: string;
274
+ repo: string;
275
+ };
276
+ /**
277
+ * Retrieves the current repository URL and converts it to HTTPS format.
278
+ *
279
+ * This function is useful for:
280
+ * - Generating consistent HTTPS URLs for documentation
281
+ * - Creating web links to the repository
282
+ * - CI/CD systems that prefer HTTPS over SSH
283
+ *
284
+ * Converts SSH URLs (git@github.com:owner/repo.git) to HTTPS format
285
+ * (https://github.com/owner/repo.git).
286
+ *
287
+ * @param options - Git operation options, primarily for specifying working directory.
288
+ *
289
+ * @returns Promise resolving to the repository URL in HTTPS format.
290
+ *
291
+ * @throws {Error} If:
292
+ * - Unable to get remote URL
293
+ * - URL format is invalid
294
+ * - Not in a git repository
295
+ */
296
+ export declare function getRepoUrlAsHttps(options?: GitOptions): Promise<string>;
297
+ /**
298
+ * Extracts the hostname from the current repository's remote URL.
299
+ *
300
+ * Returns the hosting service domain (e.g., 'github.com', 'gitlab.com',
301
+ * 'bitbucket.org', or custom Git server hostname).
302
+ *
303
+ * Supports both SSH and HTTP/HTTPS URL formats.
304
+ *
305
+ * @param options - Git operation options, primarily for specifying working directory.
306
+ *
307
+ * @returns Promise resolving to the repository host (e.g., 'github.com').
308
+ *
309
+ * @throws {Error} If:
310
+ * - Unable to get remote URL
311
+ * - URL format is invalid
312
+ * - Not in a git repository
313
+ */
314
+ export declare function getRepoHost(options?: GitOptions): Promise<string>;
315
+ /**
316
+ * Extracts the repository owner/organization name from the current repository's remote URL.
317
+ *
318
+ * Returns the account or organization that owns the repository.
319
+ * For example:
320
+ * - `git@github.com:microsoft/vscode.git` → 'microsoft'
321
+ * - `https://github.com/facebook/react.git` → 'facebook'
322
+ *
323
+ * Supports both SSH and HTTP/HTTPS URL formats.
324
+ *
325
+ * @param options - Git operation options, primarily for specifying working directory.
326
+ *
327
+ * @returns Promise resolving to the repository owner name.
328
+ *
329
+ * @throws {Error} If:
330
+ * - Unable to get remote URL
331
+ * - URL format is invalid
332
+ * - Not in a git repository
333
+ */
334
+ export declare function getRepoOwner(options?: GitOptions): Promise<string>;
335
+ /**
336
+ * Extracts the repository name from the current repository's remote URL.
337
+ *
338
+ * Returns the name of the repository without the owner prefix or .git suffix.
339
+ * For example:
340
+ * - `git@github.com:microsoft/vscode.git` → 'vscode'
341
+ * - `https://github.com/facebook/react.git` → 'react'
342
+ *
343
+ * Supports both SSH and HTTP/HTTPS URL formats.
344
+ *
345
+ * @param options - Git operation options, primarily for specifying working directory.
346
+ *
347
+ * @returns Promise resolving to the repository name.
348
+ *
349
+ * @throws {Error} If:
350
+ * - Unable to get remote URL
351
+ * - URL format is invalid
352
+ * - Not in a git repository
353
+ */
354
+ export declare function getRepoName(options?: GitOptions): Promise<string>;
251
355
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/git/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/git/index.ts"],"names":[],"mappings":"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"}
package/dist/git/index.js CHANGED
@@ -35,12 +35,14 @@ export async function getCommitsSinceLastTag(projectInfo, options = {}, excludeP
35
35
  // If tag exists: 'tag..HEAD' means commits after tag up to HEAD
36
36
  // If no tag: empty string means all commits in history
37
37
  const range = lastTag ? `${lastTag}..HEAD` : "";
38
- return getCommitsInRange(range, projectInfo.path, { cwd }, excludePaths);
38
+ const commits = await getCommitsInRange(range, projectInfo.path, { cwd }, excludePaths);
39
+ return { commits, lastTag };
39
40
  }
40
41
  catch (error) {
41
42
  // If tag lookup fails for any reason, fall back to all commits
42
43
  // This ensures we always have commit history for version determination
43
- return getCommitsInRange("", projectInfo.path, { cwd }, excludePaths);
44
+ const commits = await getCommitsInRange("", projectInfo.path, { cwd }, excludePaths);
45
+ return { commits, lastTag: null };
44
46
  }
45
47
  }
46
48
  /**
@@ -59,7 +61,10 @@ export async function getCommitsInRange(range, pathFilter, options = {}, exclude
59
61
  try {
60
62
  // Build git log command with custom format for easy parsing
61
63
  // Format: hash, subject, body, delimiter
62
- const args = ["log", "--format=%H%n%s%n%b%n---COMMIT-END---"];
64
+ const args = [
65
+ "log",
66
+ "--format=%s%n%b%n-hash-%n%H%n-decorations-%n%D%n-authorName-%n%an%n-authorEmail-%n%ae%n-committerName-%n%cn%n-committerEmail-%n%ce%n---COMMIT-END---",
67
+ ];
63
68
  // Only add range if it's not empty
64
69
  // Empty range means "all commits" which is valid
65
70
  if (range.trim()) {
@@ -98,10 +103,10 @@ export async function getCommitsInRange(range, pathFilter, options = {}, exclude
98
103
  }
99
104
  }
100
105
  /**
101
- * Parses raw git log output into structured CommitInfo objects with Conventional Commits analysis.
106
+ * Parses raw git log output into structured Commit objects with Conventional Commits analysis.
102
107
  * Resilient to parsing failures - classifies non-conventional commits as 'unknown' type.
103
108
  * @param output - Raw git log output using custom format
104
- * @returns Array of parsed CommitInfo objects (empty if no valid commits)
109
+ * @returns Array of parsed Commit objects (empty if no valid commits)
105
110
  * @internal
106
111
  */
107
112
  function parseGitLog(output) {
@@ -117,50 +122,18 @@ function parseGitLog(output) {
117
122
  .split("---COMMIT-END---")
118
123
  .filter((block) => block.trim());
119
124
  for (const block of commitBlocks) {
120
- // Split block into lines: [hash, subject, body...]
121
- const lines = block.trim().split("\n");
122
- // Skip malformed blocks (need at least hash and subject)
123
- if (lines.length < 2) {
124
- logger.debug(`Skipping malformed commit block:\n${block}`);
125
- continue;
126
- }
127
- // Extract structured data from the block
128
- const hash = lines[0]; // Line 1: commit SHA
129
- const subject = lines[1]; // Line 2: commit message subject
130
- const body = lines.slice(2).join("\n").trim(); // Remaining: commit body
131
- logger.debug(`Processing commit ${hash} with subject: ${subject}`);
132
- logger.debug(`Commit body:\n${body}`);
133
- try {
134
- // Parse using Conventional Commits specification
135
- // Combines subject and body for full context (breaking changes may be in body)
136
- const parsed = commitParser.parse(subject + "\n\n" + body);
137
- logger.debug(`Parsed commit ${hash}: ${JSON.stringify(parsed)}`);
138
- // Build CommitInfo from parsed data
139
- commits.push({
140
- hash,
141
- type: parsed.type || "unknown", // Default to 'unknown' if type missing
142
- scope: parsed.scope || undefined,
143
- subject: parsed.subject || subject, // Fallback to raw subject if parsing fails
144
- body: body || undefined,
145
- // Check if any note has title 'BREAKING CHANGE'
146
- breaking: parsed.notes?.some((note) => note.title === "BREAKING CHANGE") ||
147
- false,
148
- });
149
- }
150
- catch (error) {
151
- // If conventional commits parsing fails, treat as unknown type
152
- // This ensures non-conventional commits don't break the system
153
- commits.push({
154
- hash,
155
- type: "unknown",
156
- subject,
157
- body: body || undefined,
158
- breaking: false,
159
- });
125
+ const parsed = commitParser.parse(block);
126
+ if (!parsed.hash) {
127
+ throw new Error("Parsed commit is missing hash");
160
128
  }
129
+ logger.debug(`Parsed commit ${parsed.hash}: ${JSON.stringify(parsed)}`);
130
+ commits.push(parsed);
161
131
  }
162
132
  return commits;
163
133
  }
134
+ export function isBreakingCommit(commit) {
135
+ return (commit?.notes?.some((note) => note.title === "BREAKING CHANGE") || false);
136
+ }
164
137
  /**
165
138
  * Finds the most recent git tag for a specific module with fallback to general tags.
166
139
  * Searches module-specific tags first (moduleName@*), then falls back to general tags.
@@ -584,3 +557,146 @@ export async function hasChangesToCommit(options = {}) {
584
557
  throw new Error(`Failed to check git status: ${error}`);
585
558
  }
586
559
  }
560
+ export async function getCurrentRepoUrl(options = {}) {
561
+ // Resolve working directory
562
+ const cwd = options.cwd || process.cwd();
563
+ try {
564
+ // Get the URL of the 'origin' remote
565
+ const { stdout } = await execa("git", ["remote", "get-url", "origin"], {
566
+ cwd,
567
+ });
568
+ return stdout.trim();
569
+ }
570
+ catch (error) {
571
+ throw new Error(`Failed to get repository URL: ${error}`);
572
+ }
573
+ }
574
+ /**
575
+ * Parses a git repository URL (SSH or HTTP/HTTPS) and extracts its components.
576
+ *
577
+ * Supports multiple URL formats:
578
+ * - SSH: `git@github.com:owner/repo.git`
579
+ * - HTTPS: `https://github.com/owner/repo.git`
580
+ * - HTTP: `http://github.com/owner/repo.git`
581
+ *
582
+ * @param repoUrl - The repository URL to parse
583
+ * @returns Object containing host, owner, and repo name
584
+ * @throws {Error} If URL format is invalid or cannot be parsed
585
+ * @internal
586
+ */
587
+ export function parseRepoUrl(repoUrl) {
588
+ // Handle SSH format: git@github.com:owner/repo.git
589
+ const sshMatch = repoUrl.match(/^git@([^:]+):(.+?)\/([^/]+?)(\.git)?$/);
590
+ if (sshMatch) {
591
+ return {
592
+ host: sshMatch[1],
593
+ owner: sshMatch[2],
594
+ repo: sshMatch[3],
595
+ };
596
+ }
597
+ // Handle HTTP/HTTPS format: https://github.com/owner/repo.git
598
+ const httpsMatch = repoUrl.match(/^https?:\/\/([^/]+)\/(.+?)\/([^/]+?)(\.git)?$/);
599
+ if (httpsMatch) {
600
+ return {
601
+ host: httpsMatch[1],
602
+ owner: httpsMatch[2],
603
+ repo: httpsMatch[3],
604
+ };
605
+ }
606
+ throw new Error(`Invalid repository URL format: ${repoUrl}`);
607
+ }
608
+ /**
609
+ * Retrieves the current repository URL and converts it to HTTPS format.
610
+ *
611
+ * This function is useful for:
612
+ * - Generating consistent HTTPS URLs for documentation
613
+ * - Creating web links to the repository
614
+ * - CI/CD systems that prefer HTTPS over SSH
615
+ *
616
+ * Converts SSH URLs (git@github.com:owner/repo.git) to HTTPS format
617
+ * (https://github.com/owner/repo.git).
618
+ *
619
+ * @param options - Git operation options, primarily for specifying working directory.
620
+ *
621
+ * @returns Promise resolving to the repository URL in HTTPS format.
622
+ *
623
+ * @throws {Error} If:
624
+ * - Unable to get remote URL
625
+ * - URL format is invalid
626
+ * - Not in a git repository
627
+ */
628
+ export async function getRepoUrlAsHttps(options = {}) {
629
+ const repoUrl = await getCurrentRepoUrl(options);
630
+ const { host, owner, repo } = parseRepoUrl(repoUrl);
631
+ return `https://${host}/${owner}/${repo}.git`;
632
+ }
633
+ /**
634
+ * Extracts the hostname from the current repository's remote URL.
635
+ *
636
+ * Returns the hosting service domain (e.g., 'github.com', 'gitlab.com',
637
+ * 'bitbucket.org', or custom Git server hostname).
638
+ *
639
+ * Supports both SSH and HTTP/HTTPS URL formats.
640
+ *
641
+ * @param options - Git operation options, primarily for specifying working directory.
642
+ *
643
+ * @returns Promise resolving to the repository host (e.g., 'github.com').
644
+ *
645
+ * @throws {Error} If:
646
+ * - Unable to get remote URL
647
+ * - URL format is invalid
648
+ * - Not in a git repository
649
+ */
650
+ export async function getRepoHost(options = {}) {
651
+ const repoUrl = await getCurrentRepoUrl(options);
652
+ const { host } = parseRepoUrl(repoUrl);
653
+ return host;
654
+ }
655
+ /**
656
+ * Extracts the repository owner/organization name from the current repository's remote URL.
657
+ *
658
+ * Returns the account or organization that owns the repository.
659
+ * For example:
660
+ * - `git@github.com:microsoft/vscode.git` → 'microsoft'
661
+ * - `https://github.com/facebook/react.git` → 'facebook'
662
+ *
663
+ * Supports both SSH and HTTP/HTTPS URL formats.
664
+ *
665
+ * @param options - Git operation options, primarily for specifying working directory.
666
+ *
667
+ * @returns Promise resolving to the repository owner name.
668
+ *
669
+ * @throws {Error} If:
670
+ * - Unable to get remote URL
671
+ * - URL format is invalid
672
+ * - Not in a git repository
673
+ */
674
+ export async function getRepoOwner(options = {}) {
675
+ const repoUrl = await getCurrentRepoUrl(options);
676
+ const { owner } = parseRepoUrl(repoUrl);
677
+ return owner;
678
+ }
679
+ /**
680
+ * Extracts the repository name from the current repository's remote URL.
681
+ *
682
+ * Returns the name of the repository without the owner prefix or .git suffix.
683
+ * For example:
684
+ * - `git@github.com:microsoft/vscode.git` → 'vscode'
685
+ * - `https://github.com/facebook/react.git` → 'react'
686
+ *
687
+ * Supports both SSH and HTTP/HTTPS URL formats.
688
+ *
689
+ * @param options - Git operation options, primarily for specifying working directory.
690
+ *
691
+ * @returns Promise resolving to the repository name.
692
+ *
693
+ * @throws {Error} If:
694
+ * - Unable to get remote URL
695
+ * - URL format is invalid
696
+ * - Not in a git repository
697
+ */
698
+ export async function getRepoName(options = {}) {
699
+ const repoUrl = await getCurrentRepoUrl(options);
700
+ const { repo } = parseRepoUrl(repoUrl);
701
+ return repo;
702
+ }
@@ -82,4 +82,5 @@ export declare function addBuildMetadata(version: SemVer, buildMetadata: string)
82
82
  * @returns A prerelease identifier string (e.g., 'alpha.20230515.1430')
83
83
  */
84
84
  export declare function generateTimestampPrereleaseId(baseId: string, timestamp?: Date): string;
85
+ export declare function isReleaseVersion(version: SemVer | string): boolean;
85
86
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/semver/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;AAE5D;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAQzD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAatE;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,QAAQ,CAc9D;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,QAAQ,CAM3D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAEnE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,QAAQ,EAClB,YAAY,EAAE,MAAM,GACnB,MAAM,CAkDR;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,MAAM,GACpB,MAAM,CAMR;AAED;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,IAAI,GACf,MAAM,CAeR"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/semver/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;AAE5D;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAQzD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAatE;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,QAAQ,CAc9D;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,QAAQ,CAM3D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAEnE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,QAAQ,EAClB,YAAY,EAAE,MAAM,GACnB,MAAM,CAkDR;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,MAAM,GACpB,MAAM,CAMR;AAED;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,IAAI,GACf,MAAM,CAeR;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CASlE"}
@@ -174,3 +174,13 @@ export function generateTimestampPrereleaseId(baseId, timestamp) {
174
174
  const timeString = `${hours}${minutes}`;
175
175
  return `${baseId}.${dateString}.${timeString}`;
176
176
  }
177
+ export function isReleaseVersion(version) {
178
+ if (typeof version === "string") {
179
+ const parsed = semver.parse(version);
180
+ if (!parsed)
181
+ return false;
182
+ version = parsed;
183
+ }
184
+ // A release version has no prerelease identifiers
185
+ return version.prerelease.length === 0;
186
+ }
@@ -1,5 +1,5 @@
1
1
  import { ModuleChangeResult } from "./version-applier.js";
2
- import { CommitInfo } from "../git/index.js";
2
+ import { Commit } from "conventional-commits-parser";
3
3
  export type ChangelogGeneratorOptions = {
4
4
  generateChangelog: boolean;
5
5
  repoRoot: string;
@@ -8,6 +8,9 @@ export type ChangelogGeneratorOptions = {
8
8
  export declare class ChangelogGenerator {
9
9
  private readonly options;
10
10
  constructor(options: ChangelogGeneratorOptions);
11
- generateChangelogs(moduleResults: ModuleChangeResult[], moduleCommits: Map<string, CommitInfo[]>): Promise<string[]>;
11
+ generateChangelogs(moduleResults: ModuleChangeResult[], moduleCommits: Map<string, {
12
+ commits: Commit[];
13
+ lastTag: string | null;
14
+ }>): Promise<string[]>;
12
15
  }
13
16
  //# sourceMappingURL=changelog-generator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"changelog-generator.d.ts","sourceRoot":"","sources":["../../src/services/changelog-generator.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,MAAM,MAAM,yBAAyB,GAAG;IACtC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,qBAAa,kBAAkB;IACjB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,yBAAyB;IAEzD,kBAAkB,CACtB,aAAa,EAAE,kBAAkB,EAAE,EACnC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,GACvC,OAAO,CAAC,MAAM,EAAE,CAAC;CAgCrB"}
1
+ {"version":3,"file":"changelog-generator.d.ts","sourceRoot":"","sources":["../../src/services/changelog-generator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAErD,MAAM,MAAM,yBAAyB,GAAG;IACtC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,qBAAa,kBAAkB;IACjB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,yBAAyB;IAEzD,kBAAkB,CACtB,aAAa,EAAE,kBAAkB,EAAE,EACnC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,GACxE,OAAO,CAAC,MAAM,EAAE,CAAC;CAiCrB"}
@@ -1,5 +1,5 @@
1
1
  import { logger } from "../utils/logger.js";
2
- import { generateChangelogsForModules, generateRootChangelog, } from "../changelog/index.js";
2
+ import { generateChangelogsForModules } from "../changelog/index.js";
3
3
  export class ChangelogGenerator {
4
4
  options;
5
5
  constructor(options) {
@@ -11,15 +11,18 @@ export class ChangelogGenerator {
11
11
  return [];
12
12
  }
13
13
  logger.info("📚 Generating changelogs...");
14
- if (this.options.dryRun) {
15
- logger.info("🏃‍♂️ Dry run mode - changelogs will not be written to files");
16
- return [];
17
- }
14
+ /*if (this.options.dryRun) {
15
+ logger.info("🏃‍♂️ Dry run mode - changelogs will not be written to files");
16
+ return [];
17
+ }*/
18
18
  // Generate individual module changelogs
19
- const changelogPaths = await generateChangelogsForModules(moduleResults, async (moduleId) => moduleCommits.get(moduleId) || [], this.options.repoRoot);
20
- // Generate root changelog
21
- const rootChangelogPath = await generateRootChangelog(moduleResults, this.options.repoRoot);
22
- changelogPaths.push(rootChangelogPath);
19
+ const changelogPaths = await generateChangelogsForModules(moduleResults, async (moduleId) => moduleCommits.get(moduleId) || { commits: [], lastTag: null }, this.options.repoRoot);
20
+ /*// Generate root changelog
21
+ const rootChangelogPath = await generateRootChangelog(
22
+ moduleResults,
23
+ this.options.repoRoot,
24
+ );
25
+ changelogPaths.push(rootChangelogPath);*/
23
26
  logger.info(`📝 Generated ${changelogPaths.length} changelog files`);
24
27
  return changelogPaths;
25
28
  }
@@ -1,5 +1,5 @@
1
- import { CommitInfo } from "../git/index.js";
2
1
  import { ModuleRegistry } from "./module-registry.js";
2
+ import { Commit } from "conventional-commits-parser";
3
3
  /**
4
4
  * Analyzes git commits for each module, preventing double-counting in hierarchical structures.
5
5
  *
@@ -20,10 +20,13 @@ export declare class CommitAnalyzer {
20
20
  /**
21
21
  * Analyzes commits since the last release for all modules.
22
22
  *
23
- * @returns Map of module ID to array of {@link CommitInfo} objects
23
+ * @returns Map of module ID to array of {@link Commit} objects
24
24
  * @throws {Error} If git operations fail
25
25
  */
26
- analyzeCommitsSinceLastRelease(): Promise<Map<string, CommitInfo[]>>;
26
+ analyzeCommitsSinceLastRelease(): Promise<Map<string, {
27
+ commits: Commit[];
28
+ lastTag: string | null;
29
+ }>>;
27
30
  /**
28
31
  * Finds all child module paths for exclusion during commit analysis.
29
32
  *
@@ -1 +1 @@
1
- {"version":3,"file":"commit-analyzer.d.ts","sourceRoot":"","sources":["../../src/services/commit-analyzer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAA0B,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD;;;;;;GAMG;AACH,qBAAa,cAAc;IAQvB,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAR3B;;;;;OAKG;gBAEgB,cAAc,EAAE,cAAc,EAC9B,QAAQ,EAAE,MAAM;IAGnC;;;;;OAKG;IACG,8BAA8B,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;IA4C1E;;;;;;OAMG;IACH,OAAO,CAAC,oBAAoB;IA2B5B;;;;;;OAMG;IACH,OAAO,CAAC,WAAW;CAUpB"}
1
+ {"version":3,"file":"commit-analyzer.d.ts","sourceRoot":"","sources":["../../src/services/commit-analyzer.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAErD;;;;;;GAMG;AACH,qBAAa,cAAc;IAQvB,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAR3B;;;;;OAKG;gBAEgB,cAAc,EAAE,cAAc,EAC9B,QAAQ,EAAE,MAAM;IAGnC;;;;;OAKG;IACG,8BAA8B,IAAI,OAAO,CAC7C,GAAG,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAC3D;IA+CD;;;;;;OAMG;IACH,OAAO,CAAC,oBAAoB;IA2B5B;;;;;;OAMG;IACH,OAAO,CAAC,WAAW;CAUpB"}
@@ -23,7 +23,7 @@ export class CommitAnalyzer {
23
23
  /**
24
24
  * Analyzes commits since the last release for all modules.
25
25
  *
26
- * @returns Map of module ID to array of {@link CommitInfo} objects
26
+ * @returns Map of module ID to array of {@link Commit} objects
27
27
  * @throws {Error} If git operations fail
28
28
  */
29
29
  async analyzeCommitsSinceLastRelease() {
@@ -35,16 +35,16 @@ export class CommitAnalyzer {
35
35
  // This prevents double-counting commits in the module hierarchy
36
36
  const childModulePaths = this.findChildModulePaths(projectInfo.path, projectId);
37
37
  // Retrieve commits for this module, excluding child modules
38
- const commits = await getCommitsSinceLastTag(projectInfo, { cwd: this.repoRoot }, childModulePaths);
38
+ const { commits, lastTag } = await getCommitsSinceLastTag(projectInfo, { cwd: this.repoRoot }, childModulePaths);
39
39
  // Store commits for this module
40
- moduleCommits.set(projectId, commits);
40
+ moduleCommits.set(projectId, { commits, lastTag });
41
41
  // Log exclusions for debugging
42
42
  if (childModulePaths.length > 0) {
43
43
  logger.debug(`🔍 Module ${projectInfo.id} excludes ${childModulePaths.length} child module(s): ${childModulePaths.join(", ")}`);
44
44
  }
45
45
  }
46
46
  // Calculate and log summary statistics
47
- const totalCommits = Array.from(moduleCommits.values()).reduce((sum, commits) => sum + commits.length, 0);
47
+ const totalCommits = Array.from(moduleCommits.values()).reduce((sum, info) => sum + info.commits.length, 0);
48
48
  logger.info(`📊 Analyzed ${totalCommits} commits across ${moduleCommits.size} modules`);
49
49
  return moduleCommits;
50
50
  }
@@ -6,10 +6,10 @@
6
6
  import { Config } from "../config/index.js";
7
7
  import { ModuleRegistry } from "./module-registry.js";
8
8
  import { BumpType } from "../semver/index.js";
9
- import { CommitInfo } from "../git/index.js";
10
9
  import { SemVer } from "semver";
11
10
  import { AdapterMetadata } from "./adapter-identifier.js";
12
11
  import { Module } from "../adapters/project-information.js";
12
+ import { Commit } from "conventional-commits-parser";
13
13
  /**
14
14
  * Configuration options for the version bumper service.
15
15
  */
@@ -75,7 +75,10 @@ export declare class VersionBumper {
75
75
  * @returns Promise resolving to array of processed module changes (only modules that need updates)
76
76
  * @throws {Error} If git operations fail
77
77
  */
78
- calculateVersionBumps(moduleCommits: Map<string, CommitInfo[]>): Promise<ProcessedModuleChange[]>;
78
+ calculateVersionBumps(moduleCommits: Map<string, {
79
+ commits: Commit[];
80
+ lastTag: string | null;
81
+ }>): Promise<ProcessedModuleChange[]>;
79
82
  /**
80
83
  * Calculates initial version bump types for all modules based on commits.
81
84
  *
@@ -1 +1 @@
1
- {"version":3,"file":"version-bumper.d.ts","sourceRoot":"","sources":["../../src/services/version-bumper.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,MAAM,EAAyB,MAAM,oBAAoB,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EAOL,QAAQ,EACT,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,UAAU,EAA4B,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE1D,OAAO,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAE5D;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,qEAAqE;IACrE,cAAc,EAAE,OAAO,CAAC;IACxB,wEAAwE;IACxE,aAAa,EAAE,OAAO,CAAC;IACvB,8DAA8D;IAC9D,gBAAgB,EAAE,OAAO,CAAC;IAC1B,8DAA8D;IAC9D,cAAc,EAAE,OAAO,CAAC;IACxB,gEAAgE;IAChE,OAAO,EAAE,eAAe,CAAC;IACzB,+DAA+D;IAC/D,iBAAiB,EAAE,OAAO,CAAC;IAC3B,gEAAgE;IAChE,YAAY,EAAE,MAAM,CAAC;IACrB,sDAAsD;IACtD,QAAQ,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAsBF;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,iDAAiD;IACjD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,gDAAgD;IAChD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,wFAAwF;IACxF,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,sEAAsE;IACtE,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,iCAAiC;IACjC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;CAC/B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,YAAY,GACpB,SAAS,GACT,YAAY,GACZ,SAAS,GACT,sBAAsB,GACtB,gBAAgB,GAChB,iBAAiB,CAAC;AAEtB;;;;GAIG;AACH,qBAAa,aAAa;IAOtB,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAP1B;;;;OAIG;gBAEgB,cAAc,EAAE,cAAc,EAC9B,OAAO,EAAE,oBAAoB;IAGhD;;;;;;;OAOG;IACG,qBAAqB,CACzB,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,GACvC,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAuCnC;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,OAAO,CAAC,qBAAqB;IA6C7B;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,OAAO,CAAC,uBAAuB;IAgG/B;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,OAAO,CAAC,wBAAwB;CAgFjC"}
1
+ {"version":3,"file":"version-bumper.d.ts","sourceRoot":"","sources":["../../src/services/version-bumper.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,MAAM,EAAyB,MAAM,oBAAoB,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EAOL,QAAQ,EACT,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE1D,OAAO,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAErD;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,qEAAqE;IACrE,cAAc,EAAE,OAAO,CAAC;IACxB,wEAAwE;IACxE,aAAa,EAAE,OAAO,CAAC;IACvB,8DAA8D;IAC9D,gBAAgB,EAAE,OAAO,CAAC;IAC1B,8DAA8D;IAC9D,cAAc,EAAE,OAAO,CAAC;IACxB,gEAAgE;IAChE,OAAO,EAAE,eAAe,CAAC;IACzB,+DAA+D;IAC/D,iBAAiB,EAAE,OAAO,CAAC;IAC3B,gEAAgE;IAChE,YAAY,EAAE,MAAM,CAAC;IACrB,sDAAsD;IACtD,QAAQ,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAsBF;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,iDAAiD;IACjD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,gDAAgD;IAChD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,wFAAwF;IACxF,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,sEAAsE;IACtE,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,iCAAiC;IACjC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;CAC/B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,YAAY,GACpB,SAAS,GACT,YAAY,GACZ,SAAS,GACT,sBAAsB,GACtB,gBAAgB,GAChB,iBAAiB,CAAC;AAEtB;;;;GAIG;AACH,qBAAa,aAAa;IAOtB,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAP1B;;;;OAIG;gBAEgB,cAAc,EAAE,cAAc,EAC9B,OAAO,EAAE,oBAAoB;IAGhD;;;;;;;OAOG;IACG,qBAAqB,CACzB,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,GACxE,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAuCnC;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,OAAO,CAAC,qBAAqB;IA6C7B;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,OAAO,CAAC,uBAAuB;IAgG/B;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,OAAO,CAAC,wBAAwB;CAgFjC"}
@@ -82,7 +82,7 @@ export class VersionBumper {
82
82
  const processingModuleChanges = [];
83
83
  // Iterate through ALL modules in the registry
84
84
  for (const [projectId, projectInfo] of this.moduleRegistry.getModules()) {
85
- const commits = moduleCommits.get(projectId) || [];
85
+ const commits = moduleCommits.get(projectId)?.commits || [];
86
86
  // Determine bump type from commits only
87
87
  // Uses Conventional Commits spec to analyze commit types
88
88
  const bumpType = calculateBumpFromCommits(commits, this.options.config);
@@ -1,5 +1,5 @@
1
+ import { Commit } from "conventional-commits-parser";
1
2
  import { Config } from "../config/index.js";
2
- import { CommitInfo } from "../git/index.js";
3
3
  import { BumpType } from "../semver/index.js";
4
4
  /**
5
5
  * Calculates the overall semantic version bump type from a collection of commits.
@@ -8,5 +8,5 @@ import { BumpType } from "../semver/index.js";
8
8
  * @param config - Configuration containing commit type mappings
9
9
  * @returns The highest BumpType required across all commits
10
10
  */
11
- export declare function calculateBumpFromCommits(commits: CommitInfo[], config: Config): BumpType;
11
+ export declare function calculateBumpFromCommits(commits: Commit[], config: Config): BumpType;
12
12
  //# sourceMappingURL=commits.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"commits.d.ts","sourceRoot":"","sources":["../../src/utils/commits.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAe,MAAM,oBAAoB,CAAC;AAE3D;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,UAAU,EAAE,EACrB,MAAM,EAAE,MAAM,GACb,QAAQ,CAiBV"}
1
+ {"version":3,"file":"commits.d.ts","sourceRoot":"","sources":["../../src/utils/commits.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AACrD,OAAO,EAAwB,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAe,MAAM,oBAAoB,CAAC;AAE3D;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,MAAM,EAAE,EACjB,MAAM,EAAE,MAAM,GACb,QAAQ,CAiBV"}
@@ -12,7 +12,7 @@ export function calculateBumpFromCommits(commits, config) {
12
12
  const bumpTypes = [];
13
13
  // Analyze each commit and determine its version impact
14
14
  for (const commit of commits) {
15
- const bumpType = getBumpTypeForCommit(commit.type, commit.breaking, config);
15
+ const bumpType = getBumpTypeForCommit(commit, config);
16
16
  // Only include commits that require a version bump
17
17
  if (bumpType !== "none") {
18
18
  bumpTypes.push(bumpType);
@@ -1,3 +1,3 @@
1
- export declare const VERSION = "0.2.11";
1
+ export declare const VERSION = "0.3.1";
2
2
  export declare const PACKAGE_NAME = "@muverse/core";
3
3
  //# sourceMappingURL=version.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/utils/version.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,OAAO,WAAW,CAAC;AAChC,eAAO,MAAM,YAAY,kBAAkB,CAAC"}
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/utils/version.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,OAAO,UAAU,CAAC;AAC/B,eAAO,MAAM,YAAY,kBAAkB,CAAC"}
@@ -1,4 +1,4 @@
1
1
  // This file is auto-generated. Do not edit manually.
2
2
  // Run 'npm run generate-version' to update this file.
3
- export const VERSION = "0.2.11";
3
+ export const VERSION = "0.3.1";
4
4
  export const PACKAGE_NAME = "@muverse/core";
@@ -5,4 +5,5 @@
5
5
  * @returns Version string with '-SNAPSHOT' suffix
6
6
  */
7
7
  export declare function applySnapshotSuffix(version: string): string;
8
+ export declare function isSnapshotVersion(version: string): boolean;
8
9
  //# sourceMappingURL=versioning.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"versioning.d.ts","sourceRoot":"","sources":["../../src/utils/versioning.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAS3D"}
1
+ {"version":3,"file":"versioning.d.ts","sourceRoot":"","sources":["../../src/utils/versioning.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAS3D;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE1D"}
@@ -15,3 +15,6 @@ export function applySnapshotSuffix(version) {
15
15
  // Append the snapshot suffix to mark this as a development version
16
16
  return `${version}${SNAPSHOT_SUFFIX}`;
17
17
  }
18
+ export function isSnapshotVersion(version) {
19
+ return version.endsWith(SNAPSHOT_SUFFIX);
20
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@muverse/core",
3
- "version": "0.2.11",
3
+ "version": "0.3.1",
4
4
  "description": "Version Engine for Repo Semantic Evolution (Core Library)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -45,6 +45,7 @@
45
45
  ],
46
46
  "types": "dist/index.d.ts",
47
47
  "dependencies": {
48
+ "conventional-changelog-writer": "^8.2.0",
48
49
  "conventional-commits-parser": "^6.2.1",
49
50
  "cosmiconfig": "^9.0.0",
50
51
  "deepmerge": "^4.3.1",