@contractspec/bundle.workspace 1.45.3 → 1.45.5

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.
Files changed (54) hide show
  1. package/dist/adapters/fs.d.ts +2 -1
  2. package/dist/adapters/fs.d.ts.map +1 -1
  3. package/dist/adapters/fs.js +1 -1
  4. package/dist/adapters/fs.js.map +1 -1
  5. package/dist/adapters/git.js +29 -0
  6. package/dist/adapters/git.js.map +1 -1
  7. package/dist/adapters/index.d.ts +1 -1
  8. package/dist/adapters/index.js +1 -1
  9. package/dist/index.d.ts +10 -7
  10. package/dist/index.js +4 -2
  11. package/dist/ports/git.d.ts +14 -1
  12. package/dist/ports/git.d.ts.map +1 -1
  13. package/dist/ports/index.d.ts +1 -1
  14. package/dist/services/doctor/checks/config.js +132 -0
  15. package/dist/services/doctor/checks/config.js.map +1 -1
  16. package/dist/services/hooks/hooks-service.d.ts +24 -0
  17. package/dist/services/hooks/hooks-service.d.ts.map +1 -0
  18. package/dist/services/hooks/hooks-service.js +126 -0
  19. package/dist/services/hooks/hooks-service.js.map +1 -0
  20. package/dist/services/hooks/index.d.ts +10 -0
  21. package/dist/services/hooks/index.d.ts.map +1 -0
  22. package/dist/services/hooks/index.js +12 -0
  23. package/dist/services/hooks/index.js.map +1 -0
  24. package/dist/services/hooks/types.d.ts +56 -0
  25. package/dist/services/hooks/types.d.ts.map +1 -0
  26. package/dist/services/index.d.ts +4 -1
  27. package/dist/services/index.js +2 -0
  28. package/dist/services/setup/config-generators.d.ts.map +1 -1
  29. package/dist/services/setup/config-generators.js +14 -0
  30. package/dist/services/setup/config-generators.js.map +1 -1
  31. package/dist/services/upgrade/index.d.ts +10 -0
  32. package/dist/services/upgrade/index.d.ts.map +1 -0
  33. package/dist/services/upgrade/index.js +15 -0
  34. package/dist/services/upgrade/index.js.map +1 -0
  35. package/dist/services/upgrade/types.d.ts +78 -0
  36. package/dist/services/upgrade/types.d.ts.map +1 -0
  37. package/dist/services/upgrade/upgrade-service.d.ts +38 -0
  38. package/dist/services/upgrade/upgrade-service.d.ts.map +1 -0
  39. package/dist/services/upgrade/upgrade-service.js +201 -0
  40. package/dist/services/upgrade/upgrade-service.js.map +1 -0
  41. package/dist/services/versioning/conventional-commits.d.ts +95 -0
  42. package/dist/services/versioning/conventional-commits.d.ts.map +1 -0
  43. package/dist/services/versioning/conventional-commits.js +184 -0
  44. package/dist/services/versioning/conventional-commits.js.map +1 -0
  45. package/dist/services/versioning/index.d.ts +4 -3
  46. package/dist/services/versioning/index.js +13 -2
  47. package/dist/services/versioning/index.js.map +1 -1
  48. package/dist/services/versioning/types.d.ts +9 -7
  49. package/dist/services/versioning/types.d.ts.map +1 -1
  50. package/dist/services/versioning/versioning-service.d.ts +43 -1
  51. package/dist/services/versioning/versioning-service.d.ts.map +1 -1
  52. package/dist/services/versioning/versioning-service.js +144 -2
  53. package/dist/services/versioning/versioning-service.js.map +1 -1
  54. package/package.json +7 -7
@@ -0,0 +1,201 @@
1
+ import { detectPackageManager, findWorkspaceRoot } from "../../adapters/workspace.js";
2
+
3
+ //#region src/services/upgrade/upgrade-service.ts
4
+ const LATEST_SCHEMA_URL = `https://${process.env["CONTRACTSPEC_API_HOST"] ?? "api.contractspec.io"}/schemas/contractsrc.json`;
5
+ /**
6
+ * Analyze what upgrades are available.
7
+ */
8
+ async function analyzeUpgrades(adapters, options) {
9
+ const { fs, logger } = adapters;
10
+ const workspaceRoot = findWorkspaceRoot(options.workspaceRoot);
11
+ const packageManager = detectPackageManager(workspaceRoot);
12
+ logger.info("Analyzing available upgrades...", {
13
+ workspaceRoot,
14
+ packageManager
15
+ });
16
+ const packages = await analyzePackages(fs, workspaceRoot);
17
+ const configUpgrades = await analyzeConfig(fs, workspaceRoot);
18
+ return {
19
+ packageManager,
20
+ packages,
21
+ configUpgrades,
22
+ hasUpgrades: packages.length > 0 || configUpgrades.length > 0
23
+ };
24
+ }
25
+ /**
26
+ * Analyze installed packages for potential updates.
27
+ * Checks for all packages in the workspace that match ContractSpec patterns.
28
+ */
29
+ async function analyzePackages(fs, workspaceRoot) {
30
+ const packageJsonPath = fs.join(workspaceRoot, "package.json");
31
+ if (!await fs.exists(packageJsonPath)) return [];
32
+ try {
33
+ const content = await fs.readFile(packageJsonPath);
34
+ const packageJson = JSON.parse(content);
35
+ const deps = packageJson.dependencies ?? {};
36
+ const devDeps = packageJson.devDependencies ?? {};
37
+ const packages = [];
38
+ const allDeps = {
39
+ ...deps,
40
+ ...devDeps
41
+ };
42
+ for (const [name, version] of Object.entries(allDeps)) if (name.startsWith("@contractspec/") || name === "contractspec" || name.startsWith("@lssm/")) packages.push({
43
+ name,
44
+ currentVersion: version,
45
+ isDevDependency: !!devDeps[name]
46
+ });
47
+ return packages;
48
+ } catch {
49
+ return [];
50
+ }
51
+ }
52
+ /**
53
+ * Analyze configuration for upgrade opportunities.
54
+ */
55
+ async function analyzeConfig(fs, workspaceRoot) {
56
+ const configPath = fs.join(workspaceRoot, ".contractsrc.json");
57
+ if (!await fs.exists(configPath)) return [];
58
+ try {
59
+ const content = await fs.readFile(configPath);
60
+ const config = JSON.parse(content);
61
+ const upgrades = [];
62
+ const currentSchema = config["$schema"];
63
+ if (!currentSchema || currentSchema !== LATEST_SCHEMA_URL) upgrades.push({
64
+ key: "$schema",
65
+ currentValue: currentSchema,
66
+ suggestedValue: LATEST_SCHEMA_URL,
67
+ isNew: !currentSchema
68
+ });
69
+ if (!config["versioning"]) upgrades.push({
70
+ key: "versioning",
71
+ currentValue: void 0,
72
+ suggestedValue: getDefaultVersioningConfig(),
73
+ isNew: true
74
+ });
75
+ else if (config["versioning"]["integrateWithChangesets"] === void 0) upgrades.push({
76
+ key: "versioning.integrateWithChangesets",
77
+ currentValue: void 0,
78
+ suggestedValue: false,
79
+ isNew: true
80
+ });
81
+ if (!config["hooks"]) upgrades.push({
82
+ key: "hooks",
83
+ currentValue: void 0,
84
+ suggestedValue: getDefaultHooksConfig(),
85
+ isNew: true
86
+ });
87
+ return upgrades;
88
+ } catch {
89
+ return [];
90
+ }
91
+ }
92
+ /**
93
+ * Apply configuration upgrades.
94
+ *
95
+ * Note: Package upgrades must be applied by the app layer (CLI, VSCode)
96
+ * since they require running npm/bun/yarn commands which is platform-specific.
97
+ */
98
+ async function applyConfigUpgrades(adapters, options) {
99
+ const { fs, logger } = adapters;
100
+ const workspaceRoot = findWorkspaceRoot(options.workspaceRoot);
101
+ if (options.dryRun) logger.info("Dry run - no changes will be made");
102
+ const configPath = fs.join(workspaceRoot, ".contractsrc.json");
103
+ if (!await fs.exists(configPath)) return {
104
+ success: false,
105
+ packagesUpgraded: 0,
106
+ configSectionsUpgraded: 0,
107
+ error: "No .contractsrc.json found",
108
+ summary: "No configuration file to upgrade"
109
+ };
110
+ try {
111
+ const content = await fs.readFile(configPath);
112
+ const config = JSON.parse(content);
113
+ let sectionsUpgraded = 0;
114
+ const currentSchema = config["$schema"];
115
+ if (!currentSchema || currentSchema !== LATEST_SCHEMA_URL) {
116
+ config["$schema"] = LATEST_SCHEMA_URL;
117
+ sectionsUpgraded++;
118
+ }
119
+ if (!config["versioning"]) {
120
+ config["versioning"] = getDefaultVersioningConfig();
121
+ sectionsUpgraded++;
122
+ } else {
123
+ const versioning = config["versioning"];
124
+ if (versioning["integrateWithChangesets"] === void 0) {
125
+ versioning["integrateWithChangesets"] = false;
126
+ sectionsUpgraded++;
127
+ }
128
+ }
129
+ if (!config["hooks"]) {
130
+ config["hooks"] = getDefaultHooksConfig();
131
+ sectionsUpgraded++;
132
+ }
133
+ if (sectionsUpgraded === 0) return {
134
+ success: true,
135
+ packagesUpgraded: 0,
136
+ configSectionsUpgraded: 0,
137
+ summary: "Configuration is already up to date"
138
+ };
139
+ if (!options.dryRun) {
140
+ await fs.writeFile(configPath, JSON.stringify(config, null, 2) + "\n");
141
+ logger.info("Configuration upgraded", { sectionsUpgraded });
142
+ }
143
+ return {
144
+ success: true,
145
+ packagesUpgraded: 0,
146
+ configSectionsUpgraded: sectionsUpgraded,
147
+ summary: options.dryRun ? `Would upgrade ${sectionsUpgraded} config section(s)` : `Upgraded ${sectionsUpgraded} config section(s)`
148
+ };
149
+ } catch (error) {
150
+ const msg = error instanceof Error ? error.message : String(error);
151
+ return {
152
+ success: false,
153
+ packagesUpgraded: 0,
154
+ configSectionsUpgraded: 0,
155
+ error: msg,
156
+ summary: `Failed to upgrade config: ${msg}`
157
+ };
158
+ }
159
+ }
160
+ /**
161
+ * Get the command to upgrade packages.
162
+ *
163
+ * Returns the shell command string that the app layer should execute.
164
+ */
165
+ function getPackageUpgradeCommand(packageManager, packages, useLatest) {
166
+ const pkgList = useLatest ? packages.map((p) => `${p.name}@latest`).join(" ") : packages.map((p) => p.name).join(" ");
167
+ switch (packageManager) {
168
+ case "bun": return `bun add ${pkgList}`;
169
+ case "pnpm": return `pnpm add ${pkgList}`;
170
+ case "yarn": return `yarn add ${pkgList}`;
171
+ default: return `npm install ${pkgList}`;
172
+ }
173
+ }
174
+ /**
175
+ * Get default versioning configuration.
176
+ */
177
+ function getDefaultVersioningConfig() {
178
+ return {
179
+ autoBump: false,
180
+ bumpStrategy: "impact",
181
+ changelogTiers: [
182
+ "spec",
183
+ "library",
184
+ "monorepo"
185
+ ],
186
+ format: "keep-a-changelog",
187
+ commitChanges: false,
188
+ createTags: false,
189
+ integrateWithChangesets: true
190
+ };
191
+ }
192
+ /**
193
+ * Get default hooks configuration.
194
+ */
195
+ function getDefaultHooksConfig() {
196
+ return { "pre-commit": ["contractspec validate", "contractspec integrity check"] };
197
+ }
198
+
199
+ //#endregion
200
+ export { analyzeUpgrades, applyConfigUpgrades, getDefaultHooksConfig, getDefaultVersioningConfig, getPackageUpgradeCommand };
201
+ //# sourceMappingURL=upgrade-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upgrade-service.js","names":["packages: PackageUpgradeInfo[]","upgrades: ConfigUpgradeInfo[]"],"sources":["../../../src/services/upgrade/upgrade-service.ts"],"sourcesContent":["/**\n * Upgrade service.\n *\n * Analyzes and applies upgrades to ContractSpec SDK packages and configuration.\n * This service is platform-agnostic and can be used by CLI, VSCode, or other apps.\n *\n * @module services/upgrade\n */\n\nimport type { FsAdapter } from '../../ports/fs';\nimport type { LoggerAdapter } from '../../ports/logger';\nimport {\n detectPackageManager,\n findWorkspaceRoot,\n} from '../../adapters/workspace';\nimport type {\n UpgradeOptions,\n UpgradeAnalysisResult,\n UpgradeApplyResult,\n PackageUpgradeInfo,\n ConfigUpgradeInfo,\n} from './types';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Constants\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Latest schema URL. */\nconst API_HOST = process.env['CONTRACTSPEC_API_HOST'] ?? 'api.contractspec.io';\nconst LATEST_SCHEMA_URL = `https://${API_HOST}/schemas/contractsrc.json`;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Adapters Type\n// ─────────────────────────────────────────────────────────────────────────────\n\ninterface ServiceAdapters {\n fs: FsAdapter;\n logger: LoggerAdapter;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Analysis\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Analyze what upgrades are available.\n */\nexport async function analyzeUpgrades(\n adapters: ServiceAdapters,\n options: UpgradeOptions\n): Promise<UpgradeAnalysisResult> {\n const { fs, logger } = adapters;\n const workspaceRoot = findWorkspaceRoot(options.workspaceRoot);\n const packageManager = detectPackageManager(workspaceRoot);\n\n logger.info('Analyzing available upgrades...', {\n workspaceRoot,\n packageManager,\n });\n\n const packages = await analyzePackages(fs, workspaceRoot);\n const configUpgrades = await analyzeConfig(fs, workspaceRoot);\n\n const hasUpgrades = packages.length > 0 || configUpgrades.length > 0;\n\n return {\n packageManager,\n packages,\n configUpgrades,\n hasUpgrades,\n };\n}\n\n/**\n * Analyze installed packages for potential updates.\n * Checks for all packages in the workspace that match ContractSpec patterns.\n */\nasync function analyzePackages(\n fs: FsAdapter,\n workspaceRoot: string\n): Promise<PackageUpgradeInfo[]> {\n const packageJsonPath = fs.join(workspaceRoot, 'package.json');\n\n if (!(await fs.exists(packageJsonPath))) {\n return [];\n }\n\n try {\n const content = await fs.readFile(packageJsonPath);\n const packageJson = JSON.parse(content) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n\n const deps = packageJson.dependencies ?? {};\n const devDeps = packageJson.devDependencies ?? {};\n\n const packages: PackageUpgradeInfo[] = [];\n const allDeps = { ...deps, ...devDeps };\n\n for (const [name, version] of Object.entries(allDeps)) {\n // Check for ContractSpec related packages\n // Matches @contractspec/*, contractspec, @lssm/* (if internal)\n if (\n name.startsWith('@contractspec/') ||\n name === 'contractspec' ||\n name.startsWith('@lssm/')\n ) {\n packages.push({\n name,\n currentVersion: version,\n isDevDependency: !!devDeps[name],\n });\n }\n }\n\n return packages;\n } catch {\n return [];\n }\n}\n\n/**\n * Analyze configuration for upgrade opportunities.\n */\nasync function analyzeConfig(\n fs: FsAdapter,\n workspaceRoot: string\n): Promise<ConfigUpgradeInfo[]> {\n const configPath = fs.join(workspaceRoot, '.contractsrc.json');\n\n if (!(await fs.exists(configPath))) {\n return [];\n }\n\n try {\n const content = await fs.readFile(configPath);\n const config = JSON.parse(content) as Record<string, unknown>;\n\n const upgrades: ConfigUpgradeInfo[] = [];\n\n // Check $schema\n const currentSchema = config['$schema'] as string | undefined;\n if (!currentSchema || currentSchema !== LATEST_SCHEMA_URL) {\n upgrades.push({\n key: '$schema',\n currentValue: currentSchema,\n suggestedValue: LATEST_SCHEMA_URL,\n isNew: !currentSchema,\n });\n }\n\n // Check versioning\n if (!config['versioning']) {\n upgrades.push({\n key: 'versioning',\n currentValue: undefined,\n suggestedValue: getDefaultVersioningConfig(),\n isNew: true,\n });\n } else {\n const versioning = config['versioning'] as Record<string, unknown>;\n if (versioning['integrateWithChangesets'] === undefined) {\n upgrades.push({\n key: 'versioning.integrateWithChangesets',\n currentValue: undefined,\n suggestedValue: false,\n isNew: true,\n });\n }\n }\n\n // Check hooks\n if (!config['hooks']) {\n upgrades.push({\n key: 'hooks',\n currentValue: undefined,\n suggestedValue: getDefaultHooksConfig(),\n isNew: true,\n });\n }\n\n return upgrades;\n } catch {\n return [];\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Apply Upgrades\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Apply configuration upgrades.\n *\n * Note: Package upgrades must be applied by the app layer (CLI, VSCode)\n * since they require running npm/bun/yarn commands which is platform-specific.\n */\nexport async function applyConfigUpgrades(\n adapters: ServiceAdapters,\n options: UpgradeOptions\n): Promise<UpgradeApplyResult> {\n const { fs, logger } = adapters;\n const workspaceRoot = findWorkspaceRoot(options.workspaceRoot);\n\n if (options.dryRun) {\n logger.info('Dry run - no changes will be made');\n }\n\n const configPath = fs.join(workspaceRoot, '.contractsrc.json');\n\n if (!(await fs.exists(configPath))) {\n return {\n success: false,\n packagesUpgraded: 0,\n configSectionsUpgraded: 0,\n error: 'No .contractsrc.json found',\n summary: 'No configuration file to upgrade',\n };\n }\n\n try {\n const content = await fs.readFile(configPath);\n const config = JSON.parse(content) as Record<string, unknown>;\n\n let sectionsUpgraded = 0;\n\n // Update $schema\n const currentSchema = config['$schema'] as string | undefined;\n if (!currentSchema || currentSchema !== LATEST_SCHEMA_URL) {\n config['$schema'] = LATEST_SCHEMA_URL;\n sectionsUpgraded++;\n }\n\n // Add versioning if missing\n if (!config['versioning']) {\n config['versioning'] = getDefaultVersioningConfig();\n sectionsUpgraded++;\n } else {\n const versioning = config['versioning'] as Record<string, unknown>;\n if (versioning['integrateWithChangesets'] === undefined) {\n versioning['integrateWithChangesets'] = false;\n sectionsUpgraded++;\n }\n }\n\n // Add hooks if missing\n if (!config['hooks']) {\n config['hooks'] = getDefaultHooksConfig();\n sectionsUpgraded++;\n }\n\n if (sectionsUpgraded === 0) {\n return {\n success: true,\n packagesUpgraded: 0,\n configSectionsUpgraded: 0,\n summary: 'Configuration is already up to date',\n };\n }\n\n if (!options.dryRun) {\n await fs.writeFile(configPath, JSON.stringify(config, null, 2) + '\\n');\n logger.info('Configuration upgraded', { sectionsUpgraded });\n }\n\n return {\n success: true,\n packagesUpgraded: 0,\n configSectionsUpgraded: sectionsUpgraded,\n summary: options.dryRun\n ? `Would upgrade ${sectionsUpgraded} config section(s)`\n : `Upgraded ${sectionsUpgraded} config section(s)`,\n };\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n packagesUpgraded: 0,\n configSectionsUpgraded: 0,\n error: msg,\n summary: `Failed to upgrade config: ${msg}`,\n };\n }\n}\n\n/**\n * Get the command to upgrade packages.\n *\n * Returns the shell command string that the app layer should execute.\n */\nexport function getPackageUpgradeCommand(\n packageManager: string,\n packages: PackageUpgradeInfo[],\n useLatest: boolean\n): string {\n const pkgList = useLatest\n ? packages.map((p) => `${p.name}@latest`).join(' ')\n : packages.map((p) => p.name).join(' ');\n\n switch (packageManager) {\n case 'bun':\n return `bun add ${pkgList}`;\n case 'pnpm':\n return `pnpm add ${pkgList}`;\n case 'yarn':\n return `yarn add ${pkgList}`;\n default:\n return `npm install ${pkgList}`;\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Default Configs\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Get default versioning configuration.\n */\nexport function getDefaultVersioningConfig(): Record<string, unknown> {\n return {\n autoBump: false,\n bumpStrategy: 'impact',\n changelogTiers: ['spec', 'library', 'monorepo'],\n format: 'keep-a-changelog',\n commitChanges: false,\n createTags: false,\n integrateWithChangesets: true,\n };\n}\n\n/**\n * Get default hooks configuration.\n */\nexport function getDefaultHooksConfig(): Record<string, string[]> {\n return {\n 'pre-commit': ['contractspec validate', 'contractspec integrity check'],\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,95 @@
1
+ import { ChangeEntry, VersionBumpType } from "@contractspec/lib.contracts";
2
+
3
+ //#region src/services/versioning/conventional-commits.d.ts
4
+
5
+ /**
6
+ * Parsed conventional commit message.
7
+ */
8
+ interface ConventionalCommit {
9
+ /** Commit type (feat, fix, chore, etc.) */
10
+ type: string;
11
+ /** Optional scope (e.g., auth, api) */
12
+ scope?: string;
13
+ /** Whether this is a breaking change */
14
+ breaking: boolean;
15
+ /** Commit description */
16
+ description: string;
17
+ /** Commit body (optional) */
18
+ body?: string;
19
+ /** Breaking change description (if any) */
20
+ breakingDescription?: string;
21
+ /** Full original message */
22
+ raw: string;
23
+ }
24
+ /**
25
+ * Commit type to bump type mapping.
26
+ */
27
+ type CommitTypeBumpMap = Record<string, VersionBumpType | null>;
28
+ /**
29
+ * Default mapping of commit types to version bump types.
30
+ *
31
+ * - `feat` → minor (new feature)
32
+ * - `fix` → patch (bug fix)
33
+ * - `perf` → patch (performance improvement)
34
+ * - `refactor` → patch (code refactoring)
35
+ * - `docs` → null (no version bump)
36
+ * - `style` → null (no version bump)
37
+ * - `test` → null (no version bump)
38
+ * - `chore` → null (no version bump)
39
+ * - `ci` → null (no version bump)
40
+ * - `build` → null (no version bump)
41
+ */
42
+ declare const DEFAULT_COMMIT_TYPE_MAP: CommitTypeBumpMap;
43
+ /**
44
+ * Parse a conventional commit message.
45
+ *
46
+ * @param message - Full commit message (may include body)
47
+ * @returns Parsed commit or null if not a valid conventional commit
48
+ */
49
+ declare function parseConventionalCommit(message: string): ConventionalCommit | null;
50
+ /**
51
+ * Check if a commit message follows conventional commit format.
52
+ */
53
+ declare function isConventionalCommit(message: string): boolean;
54
+ /**
55
+ * Determine the version bump type from a conventional commit.
56
+ *
57
+ * @param commit - Parsed conventional commit
58
+ * @param typeMap - Optional custom type-to-bump mapping
59
+ * @returns Version bump type or null if no bump needed
60
+ */
61
+ declare function getBumpTypeFromCommit(commit: ConventionalCommit, typeMap?: CommitTypeBumpMap): VersionBumpType | null;
62
+ /**
63
+ * Determine the highest bump type from multiple commits.
64
+ *
65
+ * @param commits - Array of parsed conventional commits
66
+ * @param typeMap - Optional custom type-to-bump mapping
67
+ * @returns Highest version bump type or null if no bump needed
68
+ */
69
+ declare function getHighestBumpType(commits: ConventionalCommit[], typeMap?: CommitTypeBumpMap): VersionBumpType | null;
70
+ /**
71
+ * Convert a conventional commit to a changelog ChangeEntry.
72
+ *
73
+ * @param commit - Parsed conventional commit
74
+ * @returns ChangeEntry for changelog
75
+ */
76
+ declare function commitToChangeEntry(commit: ConventionalCommit): ChangeEntry;
77
+ /**
78
+ * Convert multiple commits to an array of ChangeEntries.
79
+ */
80
+ declare function commitsToChangeEntries(commits: ConventionalCommit[]): ChangeEntry[];
81
+ /**
82
+ * Filter commits by scope (for spec-level changes).
83
+ *
84
+ * @param commits - Array of parsed conventional commits
85
+ * @param scope - Scope to filter by (e.g., "auth", "api")
86
+ * @returns Commits matching the scope
87
+ */
88
+ declare function filterCommitsByScope(commits: ConventionalCommit[], scope: string): ConventionalCommit[];
89
+ /**
90
+ * Filter commits that trigger version bumps.
91
+ */
92
+ declare function filterBumpableCommits(commits: ConventionalCommit[], typeMap?: CommitTypeBumpMap): ConventionalCommit[];
93
+ //#endregion
94
+ export { CommitTypeBumpMap, ConventionalCommit, DEFAULT_COMMIT_TYPE_MAP, commitToChangeEntry, commitsToChangeEntries, filterBumpableCommits, filterCommitsByScope, getBumpTypeFromCommit, getHighestBumpType, isConventionalCommit, parseConventionalCommit };
95
+ //# sourceMappingURL=conventional-commits.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conventional-commits.d.ts","names":[],"sources":["../../../src/services/versioning/conventional-commits.ts"],"sourcesContent":[],"mappings":";;;;;;;AAwLkB,UAjKD,kBAAA,CAiKC;EAqCF;EAoDA,IAAA,EAAA,MAAA;EAiBA;EAUA,KAAA,CAAA,EAAA,MAAA;EACL;EACA,QAAA,EAAA,OAAA;EACR;EAAkB,WAAA,EAAA,MAAA;;;;;;;;;;;KApQT,iBAAA,GAAoB,eAAe;;;;;;;;;;;;;;;cAoBlC,yBAAyB;;;;;;;iBAyCtB,uBAAA,mBAEb;;;;iBAwCa,oBAAA;;;;;;;;iBAeA,qBAAA,SACN,8BACC,oBACR;;;;;;;;iBAiBa,kBAAA,UACL,gCACA,oBACR;;;;;;;iBAqCa,mBAAA,SAA4B,qBAAqB;;;;iBAoDjD,sBAAA,UACL,uBACR;;;;;;;;iBAea,oBAAA,UACL,sCAER;;;;iBAOa,qBAAA,UACL,gCACA,oBACR"}
@@ -0,0 +1,184 @@
1
+ //#region src/services/versioning/conventional-commits.ts
2
+ /**
3
+ * Default mapping of commit types to version bump types.
4
+ *
5
+ * - `feat` → minor (new feature)
6
+ * - `fix` → patch (bug fix)
7
+ * - `perf` → patch (performance improvement)
8
+ * - `refactor` → patch (code refactoring)
9
+ * - `docs` → null (no version bump)
10
+ * - `style` → null (no version bump)
11
+ * - `test` → null (no version bump)
12
+ * - `chore` → null (no version bump)
13
+ * - `ci` → null (no version bump)
14
+ * - `build` → null (no version bump)
15
+ */
16
+ const DEFAULT_COMMIT_TYPE_MAP = {
17
+ feat: "minor",
18
+ fix: "patch",
19
+ perf: "patch",
20
+ refactor: "patch",
21
+ docs: null,
22
+ style: null,
23
+ test: null,
24
+ chore: null,
25
+ ci: null,
26
+ build: null,
27
+ revert: "patch"
28
+ };
29
+ /**
30
+ * Regex pattern for parsing conventional commit messages.
31
+ *
32
+ * Matches: type(scope)!: description
33
+ * Groups:
34
+ * 1. type
35
+ * 2. scope (optional)
36
+ * 3. breaking indicator (optional !)
37
+ * 4. description
38
+ */
39
+ const CONVENTIONAL_COMMIT_PATTERN = /^(\w+)(?:\(([^)]+)\))?(!)?\s*:\s*(.+)$/;
40
+ /**
41
+ * Pattern for detecting BREAKING CHANGE in commit body/footer.
42
+ */
43
+ const BREAKING_CHANGE_PATTERN = /^BREAKING[ -]CHANGE:\s*(.+)$/im;
44
+ /**
45
+ * Parse a conventional commit message.
46
+ *
47
+ * @param message - Full commit message (may include body)
48
+ * @returns Parsed commit or null if not a valid conventional commit
49
+ */
50
+ function parseConventionalCommit(message) {
51
+ const lines = message.split("\n");
52
+ const firstLine = lines[0]?.trim();
53
+ if (!firstLine) return null;
54
+ const match = firstLine.match(CONVENTIONAL_COMMIT_PATTERN);
55
+ if (!match) return null;
56
+ const [, type, scope, breakingIndicator, description] = match;
57
+ if (!type || !description) return null;
58
+ const body = lines.slice(1).join("\n").trim() || void 0;
59
+ const breakingMatch = body?.match(BREAKING_CHANGE_PATTERN);
60
+ const breakingDescription = breakingMatch?.[1];
61
+ return {
62
+ type: type.toLowerCase(),
63
+ scope: scope?.toLowerCase(),
64
+ breaking: !!breakingIndicator || !!breakingMatch,
65
+ description: description.trim(),
66
+ body,
67
+ breakingDescription,
68
+ raw: message
69
+ };
70
+ }
71
+ /**
72
+ * Check if a commit message follows conventional commit format.
73
+ */
74
+ function isConventionalCommit(message) {
75
+ return parseConventionalCommit(message) !== null;
76
+ }
77
+ /**
78
+ * Determine the version bump type from a conventional commit.
79
+ *
80
+ * @param commit - Parsed conventional commit
81
+ * @param typeMap - Optional custom type-to-bump mapping
82
+ * @returns Version bump type or null if no bump needed
83
+ */
84
+ function getBumpTypeFromCommit(commit, typeMap = DEFAULT_COMMIT_TYPE_MAP) {
85
+ if (commit.breaking) return "major";
86
+ return typeMap[commit.type] ?? null;
87
+ }
88
+ /**
89
+ * Determine the highest bump type from multiple commits.
90
+ *
91
+ * @param commits - Array of parsed conventional commits
92
+ * @param typeMap - Optional custom type-to-bump mapping
93
+ * @returns Highest version bump type or null if no bump needed
94
+ */
95
+ function getHighestBumpType(commits, typeMap = DEFAULT_COMMIT_TYPE_MAP) {
96
+ const bumpOrder = [
97
+ "major",
98
+ "minor",
99
+ "patch"
100
+ ];
101
+ let highest = null;
102
+ for (const commit of commits) {
103
+ const bumpType = getBumpTypeFromCommit(commit, typeMap);
104
+ if (!bumpType) continue;
105
+ if (!highest) {
106
+ highest = bumpType;
107
+ continue;
108
+ }
109
+ const currentIndex = bumpOrder.indexOf(highest);
110
+ if (bumpOrder.indexOf(bumpType) < currentIndex) highest = bumpType;
111
+ }
112
+ return highest;
113
+ }
114
+ /**
115
+ * Convert a conventional commit to a changelog ChangeEntry.
116
+ *
117
+ * @param commit - Parsed conventional commit
118
+ * @returns ChangeEntry for changelog
119
+ */
120
+ function commitToChangeEntry(commit) {
121
+ if (commit.breaking) return {
122
+ type: "breaking",
123
+ description: commit.breakingDescription ?? commit.description,
124
+ path: commit.scope
125
+ };
126
+ switch (commit.type) {
127
+ case "feat": return {
128
+ type: "added",
129
+ description: commit.description,
130
+ path: commit.scope
131
+ };
132
+ case "fix": return {
133
+ type: "fixed",
134
+ description: commit.description,
135
+ path: commit.scope
136
+ };
137
+ case "deprecate": return {
138
+ type: "deprecated",
139
+ description: commit.description,
140
+ path: commit.scope
141
+ };
142
+ case "remove": return {
143
+ type: "removed",
144
+ description: commit.description,
145
+ path: commit.scope
146
+ };
147
+ case "security": return {
148
+ type: "security",
149
+ description: commit.description,
150
+ path: commit.scope
151
+ };
152
+ default: return {
153
+ type: "changed",
154
+ description: commit.description,
155
+ path: commit.scope
156
+ };
157
+ }
158
+ }
159
+ /**
160
+ * Convert multiple commits to an array of ChangeEntries.
161
+ */
162
+ function commitsToChangeEntries(commits) {
163
+ return commits.map(commitToChangeEntry);
164
+ }
165
+ /**
166
+ * Filter commits by scope (for spec-level changes).
167
+ *
168
+ * @param commits - Array of parsed conventional commits
169
+ * @param scope - Scope to filter by (e.g., "auth", "api")
170
+ * @returns Commits matching the scope
171
+ */
172
+ function filterCommitsByScope(commits, scope) {
173
+ return commits.filter((c) => c.scope?.toLowerCase() === scope.toLowerCase());
174
+ }
175
+ /**
176
+ * Filter commits that trigger version bumps.
177
+ */
178
+ function filterBumpableCommits(commits, typeMap = DEFAULT_COMMIT_TYPE_MAP) {
179
+ return commits.filter((c) => getBumpTypeFromCommit(c, typeMap) !== null);
180
+ }
181
+
182
+ //#endregion
183
+ export { DEFAULT_COMMIT_TYPE_MAP, commitToChangeEntry, commitsToChangeEntries, filterBumpableCommits, filterCommitsByScope, getBumpTypeFromCommit, getHighestBumpType, isConventionalCommit, parseConventionalCommit };
184
+ //# sourceMappingURL=conventional-commits.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conventional-commits.js","names":["DEFAULT_COMMIT_TYPE_MAP: CommitTypeBumpMap","bumpOrder: VersionBumpType[]","highest: VersionBumpType | null"],"sources":["../../../src/services/versioning/conventional-commits.ts"],"sourcesContent":["/**\n * Conventional commits parser and utilities.\n *\n * Parses conventional commit messages to determine version bump types\n * and extract change information for changelog generation.\n *\n * Supports:\n * - Standard conventional commits (feat, fix, chore, etc.)\n * - Breaking change detection (BREAKING CHANGE: or !)\n * - Scope extraction for spec-level changes\n *\n * @module versioning/conventional-commits\n */\n\nimport type { VersionBumpType, ChangeEntry } from '@contractspec/lib.contracts';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Types\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Parsed conventional commit message.\n */\nexport interface ConventionalCommit {\n /** Commit type (feat, fix, chore, etc.) */\n type: string;\n /** Optional scope (e.g., auth, api) */\n scope?: string;\n /** Whether this is a breaking change */\n breaking: boolean;\n /** Commit description */\n description: string;\n /** Commit body (optional) */\n body?: string;\n /** Breaking change description (if any) */\n breakingDescription?: string;\n /** Full original message */\n raw: string;\n}\n\n/**\n * Commit type to bump type mapping.\n */\nexport type CommitTypeBumpMap = Record<string, VersionBumpType | null>;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Constants\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Default mapping of commit types to version bump types.\n *\n * - `feat` → minor (new feature)\n * - `fix` → patch (bug fix)\n * - `perf` → patch (performance improvement)\n * - `refactor` → patch (code refactoring)\n * - `docs` → null (no version bump)\n * - `style` → null (no version bump)\n * - `test` → null (no version bump)\n * - `chore` → null (no version bump)\n * - `ci` → null (no version bump)\n * - `build` → null (no version bump)\n */\nexport const DEFAULT_COMMIT_TYPE_MAP: CommitTypeBumpMap = {\n feat: 'minor',\n fix: 'patch',\n perf: 'patch',\n refactor: 'patch',\n docs: null,\n style: null,\n test: null,\n chore: null,\n ci: null,\n build: null,\n revert: 'patch',\n};\n\n/**\n * Regex pattern for parsing conventional commit messages.\n *\n * Matches: type(scope)!: description\n * Groups:\n * 1. type\n * 2. scope (optional)\n * 3. breaking indicator (optional !)\n * 4. description\n */\nconst CONVENTIONAL_COMMIT_PATTERN = /^(\\w+)(?:\\(([^)]+)\\))?(!)?\\s*:\\s*(.+)$/;\n\n/**\n * Pattern for detecting BREAKING CHANGE in commit body/footer.\n */\nconst BREAKING_CHANGE_PATTERN = /^BREAKING[ -]CHANGE:\\s*(.+)$/im;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Parser\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Parse a conventional commit message.\n *\n * @param message - Full commit message (may include body)\n * @returns Parsed commit or null if not a valid conventional commit\n */\nexport function parseConventionalCommit(\n message: string\n): ConventionalCommit | null {\n const lines = message.split('\\n');\n const firstLine = lines[0]?.trim();\n\n if (!firstLine) {\n return null;\n }\n\n const match = firstLine.match(CONVENTIONAL_COMMIT_PATTERN);\n if (!match) {\n return null;\n }\n\n const [, type, scope, breakingIndicator, description] = match;\n\n if (!type || !description) {\n return null;\n }\n\n // Extract body (everything after first line)\n const body = lines.slice(1).join('\\n').trim() || undefined;\n\n // Check for breaking change in body\n const breakingMatch = body?.match(BREAKING_CHANGE_PATTERN);\n const breakingDescription = breakingMatch?.[1];\n\n return {\n type: type.toLowerCase(),\n scope: scope?.toLowerCase(),\n breaking: !!breakingIndicator || !!breakingMatch,\n description: description.trim(),\n body,\n breakingDescription,\n raw: message,\n };\n}\n\n/**\n * Check if a commit message follows conventional commit format.\n */\nexport function isConventionalCommit(message: string): boolean {\n return parseConventionalCommit(message) !== null;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Bump Type Determination\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Determine the version bump type from a conventional commit.\n *\n * @param commit - Parsed conventional commit\n * @param typeMap - Optional custom type-to-bump mapping\n * @returns Version bump type or null if no bump needed\n */\nexport function getBumpTypeFromCommit(\n commit: ConventionalCommit,\n typeMap: CommitTypeBumpMap = DEFAULT_COMMIT_TYPE_MAP\n): VersionBumpType | null {\n // Breaking changes always trigger major bump\n if (commit.breaking) {\n return 'major';\n }\n\n // Use type mapping\n return typeMap[commit.type] ?? null;\n}\n\n/**\n * Determine the highest bump type from multiple commits.\n *\n * @param commits - Array of parsed conventional commits\n * @param typeMap - Optional custom type-to-bump mapping\n * @returns Highest version bump type or null if no bump needed\n */\nexport function getHighestBumpType(\n commits: ConventionalCommit[],\n typeMap: CommitTypeBumpMap = DEFAULT_COMMIT_TYPE_MAP\n): VersionBumpType | null {\n const bumpOrder: VersionBumpType[] = ['major', 'minor', 'patch'];\n\n let highest: VersionBumpType | null = null;\n\n for (const commit of commits) {\n const bumpType = getBumpTypeFromCommit(commit, typeMap);\n\n if (!bumpType) continue;\n\n if (!highest) {\n highest = bumpType;\n continue;\n }\n\n // Check if this bump is higher precedence\n const currentIndex = bumpOrder.indexOf(highest);\n const newIndex = bumpOrder.indexOf(bumpType);\n\n if (newIndex < currentIndex) {\n highest = bumpType;\n }\n }\n\n return highest;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Change Entry Conversion\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Convert a conventional commit to a changelog ChangeEntry.\n *\n * @param commit - Parsed conventional commit\n * @returns ChangeEntry for changelog\n */\nexport function commitToChangeEntry(commit: ConventionalCommit): ChangeEntry {\n if (commit.breaking) {\n return {\n type: 'breaking',\n description: commit.breakingDescription ?? commit.description,\n path: commit.scope,\n };\n }\n\n switch (commit.type) {\n case 'feat':\n return {\n type: 'added',\n description: commit.description,\n path: commit.scope,\n };\n case 'fix':\n return {\n type: 'fixed',\n description: commit.description,\n path: commit.scope,\n };\n case 'deprecate':\n return {\n type: 'deprecated',\n description: commit.description,\n path: commit.scope,\n };\n case 'remove':\n return {\n type: 'removed',\n description: commit.description,\n path: commit.scope,\n };\n case 'security':\n return {\n type: 'security',\n description: commit.description,\n path: commit.scope,\n };\n default:\n return {\n type: 'changed',\n description: commit.description,\n path: commit.scope,\n };\n }\n}\n\n/**\n * Convert multiple commits to an array of ChangeEntries.\n */\nexport function commitsToChangeEntries(\n commits: ConventionalCommit[]\n): ChangeEntry[] {\n return commits.map(commitToChangeEntry);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Filtering\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Filter commits by scope (for spec-level changes).\n *\n * @param commits - Array of parsed conventional commits\n * @param scope - Scope to filter by (e.g., \"auth\", \"api\")\n * @returns Commits matching the scope\n */\nexport function filterCommitsByScope(\n commits: ConventionalCommit[],\n scope: string\n): ConventionalCommit[] {\n return commits.filter((c) => c.scope?.toLowerCase() === scope.toLowerCase());\n}\n\n/**\n * Filter commits that trigger version bumps.\n */\nexport function filterBumpableCommits(\n commits: ConventionalCommit[],\n typeMap: CommitTypeBumpMap = DEFAULT_COMMIT_TYPE_MAP\n): ConventionalCommit[] {\n return commits.filter((c) => getBumpTypeFromCommit(c, typeMap) !== null);\n}\n"],"mappings":";;;;;;;;;;;;;;;AA+DA,MAAaA,0BAA6C;CACxD,MAAM;CACN,KAAK;CACL,MAAM;CACN,UAAU;CACV,MAAM;CACN,OAAO;CACP,MAAM;CACN,OAAO;CACP,IAAI;CACJ,OAAO;CACP,QAAQ;CACT;;;;;;;;;;;AAYD,MAAM,8BAA8B;;;;AAKpC,MAAM,0BAA0B;;;;;;;AAYhC,SAAgB,wBACd,SAC2B;CAC3B,MAAM,QAAQ,QAAQ,MAAM,KAAK;CACjC,MAAM,YAAY,MAAM,IAAI,MAAM;AAElC,KAAI,CAAC,UACH,QAAO;CAGT,MAAM,QAAQ,UAAU,MAAM,4BAA4B;AAC1D,KAAI,CAAC,MACH,QAAO;CAGT,MAAM,GAAG,MAAM,OAAO,mBAAmB,eAAe;AAExD,KAAI,CAAC,QAAQ,CAAC,YACZ,QAAO;CAIT,MAAM,OAAO,MAAM,MAAM,EAAE,CAAC,KAAK,KAAK,CAAC,MAAM,IAAI;CAGjD,MAAM,gBAAgB,MAAM,MAAM,wBAAwB;CAC1D,MAAM,sBAAsB,gBAAgB;AAE5C,QAAO;EACL,MAAM,KAAK,aAAa;EACxB,OAAO,OAAO,aAAa;EAC3B,UAAU,CAAC,CAAC,qBAAqB,CAAC,CAAC;EACnC,aAAa,YAAY,MAAM;EAC/B;EACA;EACA,KAAK;EACN;;;;;AAMH,SAAgB,qBAAqB,SAA0B;AAC7D,QAAO,wBAAwB,QAAQ,KAAK;;;;;;;;;AAc9C,SAAgB,sBACd,QACA,UAA6B,yBACL;AAExB,KAAI,OAAO,SACT,QAAO;AAIT,QAAO,QAAQ,OAAO,SAAS;;;;;;;;;AAUjC,SAAgB,mBACd,SACA,UAA6B,yBACL;CACxB,MAAMC,YAA+B;EAAC;EAAS;EAAS;EAAQ;CAEhE,IAAIC,UAAkC;AAEtC,MAAK,MAAM,UAAU,SAAS;EAC5B,MAAM,WAAW,sBAAsB,QAAQ,QAAQ;AAEvD,MAAI,CAAC,SAAU;AAEf,MAAI,CAAC,SAAS;AACZ,aAAU;AACV;;EAIF,MAAM,eAAe,UAAU,QAAQ,QAAQ;AAG/C,MAFiB,UAAU,QAAQ,SAAS,GAE7B,aACb,WAAU;;AAId,QAAO;;;;;;;;AAaT,SAAgB,oBAAoB,QAAyC;AAC3E,KAAI,OAAO,SACT,QAAO;EACL,MAAM;EACN,aAAa,OAAO,uBAAuB,OAAO;EAClD,MAAM,OAAO;EACd;AAGH,SAAQ,OAAO,MAAf;EACE,KAAK,OACH,QAAO;GACL,MAAM;GACN,aAAa,OAAO;GACpB,MAAM,OAAO;GACd;EACH,KAAK,MACH,QAAO;GACL,MAAM;GACN,aAAa,OAAO;GACpB,MAAM,OAAO;GACd;EACH,KAAK,YACH,QAAO;GACL,MAAM;GACN,aAAa,OAAO;GACpB,MAAM,OAAO;GACd;EACH,KAAK,SACH,QAAO;GACL,MAAM;GACN,aAAa,OAAO;GACpB,MAAM,OAAO;GACd;EACH,KAAK,WACH,QAAO;GACL,MAAM;GACN,aAAa,OAAO;GACpB,MAAM,OAAO;GACd;EACH,QACE,QAAO;GACL,MAAM;GACN,aAAa,OAAO;GACpB,MAAM,OAAO;GACd;;;;;;AAOP,SAAgB,uBACd,SACe;AACf,QAAO,QAAQ,IAAI,oBAAoB;;;;;;;;;AAczC,SAAgB,qBACd,SACA,OACsB;AACtB,QAAO,QAAQ,QAAQ,MAAM,EAAE,OAAO,aAAa,KAAK,MAAM,aAAa,CAAC;;;;;AAM9E,SAAgB,sBACd,SACA,UAA6B,yBACP;AACtB,QAAO,QAAQ,QAAQ,MAAM,sBAAsB,GAAG,QAAQ,KAAK,KAAK"}
@@ -1,10 +1,11 @@
1
- import { ChangeEntry, ChangelogDocBlock, ChangelogEntry, ChangelogGenerateOptions, ChangelogGenerateResult, ChangelogJsonExport, ChangelogTier, LibraryChangelogJson, SpecChangelogJson, SpecVersionAnalysis, VersionAnalyzeOptions, VersionAnalyzeResult, VersionBumpOptions, VersionBumpResult, VersionBumpType } from "./types.js";
2
- import { analyzeVersions, applyVersionBump, generateChangelogs } from "./versioning-service.js";
1
+ import { ChangeEntry, ChangelogDocBlock, ChangelogEntry, ChangelogGenerateOptions, ChangelogGenerateResult, ChangelogJsonExport, ChangelogTier, LibraryChangelogJson, SpecChangelogJson, SpecVersionAnalysis, VersionAnalyzeOptions, VersionAnalyzeResult, VersionBumpOptions, VersionBumpResult, VersionBumpType, VersioningConfig } from "./types.js";
2
+ import { analyzeVersions, analyzeVersionsFromCommits, applyVersionBump, generateChangelogs } from "./versioning-service.js";
3
3
  import { formatChangelogJson, formatConventionalChangelog, formatKeepAChangelog } from "./changelog-formatter.js";
4
+ import { CommitTypeBumpMap, ConventionalCommit, DEFAULT_COMMIT_TYPE_MAP, commitToChangeEntry, commitsToChangeEntries, filterBumpableCommits, filterCommitsByScope, getBumpTypeFromCommit, getHighestBumpType, isConventionalCommit, parseConventionalCommit } from "./conventional-commits.js";
4
5
 
5
6
  //#region src/services/versioning/index.d.ts
6
7
  declare namespace index_d_exports {
7
- export { ChangeEntry, ChangelogDocBlock, ChangelogEntry, ChangelogGenerateOptions, ChangelogGenerateResult, ChangelogJsonExport, ChangelogTier, LibraryChangelogJson, SpecChangelogJson, SpecVersionAnalysis, VersionAnalyzeOptions, VersionAnalyzeResult, VersionBumpOptions, VersionBumpResult, VersionBumpType, analyzeVersions, applyVersionBump, formatChangelogJson, formatConventionalChangelog, formatKeepAChangelog, generateChangelogs };
8
+ export { ChangeEntry, ChangelogDocBlock, ChangelogEntry, ChangelogGenerateOptions, ChangelogGenerateResult, ChangelogJsonExport, ChangelogTier, CommitTypeBumpMap, ConventionalCommit, DEFAULT_COMMIT_TYPE_MAP, LibraryChangelogJson, SpecChangelogJson, SpecVersionAnalysis, VersionAnalyzeOptions, VersionAnalyzeResult, VersionBumpOptions, VersionBumpResult, VersionBumpType, VersioningConfig, analyzeVersions, analyzeVersionsFromCommits, applyVersionBump, commitToChangeEntry, commitsToChangeEntries, filterBumpableCommits, filterCommitsByScope, formatChangelogJson, formatConventionalChangelog, formatKeepAChangelog, generateChangelogs, getBumpTypeFromCommit, getHighestBumpType, isConventionalCommit, parseConventionalCommit };
8
9
  }
9
10
  //#endregion
10
11
  export { index_d_exports };
@@ -1,15 +1,26 @@
1
1
  import { __exportAll } from "../../_virtual/rolldown_runtime.js";
2
2
  import { formatChangelogJson, formatConventionalChangelog, formatKeepAChangelog } from "./changelog-formatter.js";
3
- import { analyzeVersions, applyVersionBump, generateChangelogs } from "./versioning-service.js";
3
+ import { DEFAULT_COMMIT_TYPE_MAP, commitToChangeEntry, commitsToChangeEntries, filterBumpableCommits, filterCommitsByScope, getBumpTypeFromCommit, getHighestBumpType, isConventionalCommit, parseConventionalCommit } from "./conventional-commits.js";
4
+ import { analyzeVersions, analyzeVersionsFromCommits, applyVersionBump, generateChangelogs } from "./versioning-service.js";
4
5
 
5
6
  //#region src/services/versioning/index.ts
6
7
  var versioning_exports = /* @__PURE__ */ __exportAll({
8
+ DEFAULT_COMMIT_TYPE_MAP: () => DEFAULT_COMMIT_TYPE_MAP,
7
9
  analyzeVersions: () => analyzeVersions,
10
+ analyzeVersionsFromCommits: () => analyzeVersionsFromCommits,
8
11
  applyVersionBump: () => applyVersionBump,
12
+ commitToChangeEntry: () => commitToChangeEntry,
13
+ commitsToChangeEntries: () => commitsToChangeEntries,
14
+ filterBumpableCommits: () => filterBumpableCommits,
15
+ filterCommitsByScope: () => filterCommitsByScope,
9
16
  formatChangelogJson: () => formatChangelogJson,
10
17
  formatConventionalChangelog: () => formatConventionalChangelog,
11
18
  formatKeepAChangelog: () => formatKeepAChangelog,
12
- generateChangelogs: () => generateChangelogs
19
+ generateChangelogs: () => generateChangelogs,
20
+ getBumpTypeFromCommit: () => getBumpTypeFromCommit,
21
+ getHighestBumpType: () => getHighestBumpType,
22
+ isConventionalCommit: () => isConventionalCommit,
23
+ parseConventionalCommit: () => parseConventionalCommit
13
24
  });
14
25
 
15
26
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/services/versioning/index.ts"],"sourcesContent":["/**\n * Versioning service module exports.\n *\n * Provides version analysis, version bumping, and changelog generation.\n */\n\nexport * from './types';\nexport {\n analyzeVersions,\n applyVersionBump,\n generateChangelogs,\n} from './versioning-service';\nexport {\n formatKeepAChangelog,\n formatConventionalChangelog,\n formatChangelogJson,\n} from './changelog-formatter';\n"],"mappings":""}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/services/versioning/index.ts"],"sourcesContent":["/**\n * Versioning service module exports.\n *\n * Provides version analysis, version bumping, and changelog generation.\n */\n\nexport * from './types';\nexport {\n analyzeVersions,\n applyVersionBump,\n generateChangelogs,\n analyzeVersionsFromCommits,\n} from './versioning-service';\nexport {\n formatKeepAChangelog,\n formatConventionalChangelog,\n formatChangelogJson,\n} from './changelog-formatter';\nexport * from './conventional-commits';\n"],"mappings":""}
@@ -1,4 +1,4 @@
1
- import { ChangeEntry, ChangelogDocBlock, ChangelogEntry as ChangelogEntry$1, ChangelogTier, VersionBumpType } from "@contractspec/lib.contracts";
1
+ import { ChangeEntry as ChangeEntry$1, ChangelogDocBlock, ChangelogEntry as ChangelogEntry$1, ChangelogTier, VersionBumpType as VersionBumpType$1, VersioningConfig } from "@contractspec/lib.contracts";
2
2
 
3
3
  //#region src/services/versioning/types.d.ts
4
4
 
@@ -20,13 +20,15 @@ interface VersionBumpOptions {
20
20
  /** Spec file path to bump */
21
21
  specPath: string;
22
22
  /** Bump type (auto-detected if not specified) */
23
- bumpType?: VersionBumpType;
23
+ bumpType?: VersionBumpType$1;
24
24
  /** Change description for changelog entry */
25
25
  changeDescription?: string;
26
26
  /** Additional change entries */
27
- changes?: ChangeEntry[];
27
+ changes?: ChangeEntry$1[];
28
28
  /** Dry run (don't write changes) */
29
29
  dryRun?: boolean;
30
+ /** Versioning config (for changesets integration) */
31
+ config?: VersioningConfig;
30
32
  }
31
33
  /** Options for changelog generation */
32
34
  interface ChangelogGenerateOptions {
@@ -52,9 +54,9 @@ interface SpecVersionAnalysis {
52
54
  /** Suggested new version based on changes */
53
55
  suggestedVersion: string;
54
56
  /** Suggested bump type */
55
- bumpType: VersionBumpType;
57
+ bumpType: VersionBumpType$1;
56
58
  /** Detected changes requiring version bump */
57
- changes: ChangeEntry[];
59
+ changes: ChangeEntry$1[];
58
60
  /** Whether breaking changes were detected */
59
61
  hasBreaking: boolean;
60
62
  /** Whether the spec needs a version bump */
@@ -88,7 +90,7 @@ interface VersionBumpResult {
88
90
  /** New version */
89
91
  newVersion: string;
90
92
  /** Bump type applied */
91
- bumpType: VersionBumpType;
93
+ bumpType: VersionBumpType$1;
92
94
  /** Changelog entry created */
93
95
  changelogEntry: ChangelogEntry$1;
94
96
  /** Error message if failed */
@@ -129,5 +131,5 @@ interface LibraryChangelogJson {
129
131
  entries: ChangelogEntry$1[];
130
132
  }
131
133
  //#endregion
132
- export { type ChangeEntry, type ChangelogDocBlock, type ChangelogEntry$1 as ChangelogEntry, ChangelogGenerateOptions, ChangelogGenerateResult, ChangelogJsonExport, type ChangelogTier, LibraryChangelogJson, SpecChangelogJson, SpecVersionAnalysis, VersionAnalyzeOptions, VersionAnalyzeResult, VersionBumpOptions, VersionBumpResult, type VersionBumpType };
134
+ export { type ChangeEntry$1 as ChangeEntry, type ChangelogDocBlock, type ChangelogEntry$1 as ChangelogEntry, ChangelogGenerateOptions, ChangelogGenerateResult, ChangelogJsonExport, type ChangelogTier, LibraryChangelogJson, SpecChangelogJson, SpecVersionAnalysis, VersionAnalyzeOptions, VersionAnalyzeResult, VersionBumpOptions, VersionBumpResult, type VersionBumpType$1 as VersionBumpType, type VersioningConfig };
133
135
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/services/versioning/types.ts"],"sourcesContent":[],"mappings":";;;;AA8GA;AAoBiB,UAtGA,qBAAA,CAsGuB;EAEtB;EAEC,QAAA,CAAA,EAAA,MAAA;EAIX;EAAmB,OAAA,CAAA,EAAA,MAAA;EAMV;EAQA,aAAA,CAAA,EAAA,MAAiB;EAQjB;;;;;;UAtHA,kBAAA;;;;aAIJ;;;;YAID;;;;;UAMK,wBAAA;;;;;;UAMP;;;;;;;UAYO,mBAAA;;;;;;;;;;YAUL;;WAED;;;;;;;UAQM,oBAAA;;YAEL;;;;;;;;;;;;;UAcK,iBAAA;;;;;;;;;;;;YAYL;;kBAEM;;;;;UAMD,uBAAA;;kBAEC;;mBAEC;;;;QAIX;;;;;UAMS,mBAAA;;;SAGR;aACI;;;UAII,iBAAA;;;;WAIN;;;UAIM,oBAAA;;;;WAIN"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/services/versioning/types.ts"],"sourcesContent":[],"mappings":";;;;;AA4DiB,UA9BA,qBAAA,CA8BwB;EAkBxB;EAoBA,QAAA,CAAA,EAAA,MAAA;EAgBA;EAoBA,OAAA,CAAA,EAAA,MAAA;EAEC;EAEC,aAAA,CAAA,EAAA,MAAA;EAIX;EAAmB,OAAA,CAAA,EAAA,MAAA,EAAA;EAMV;EAQA,OAAA,CAAA,EAAA,MAAA,EAAA;AAQjB;;UAxHiB,kBAAA;;;;aAIJ;;;;YAID;;;;WAID;;;UAIM,wBAAA;;;;;;UAMP;;;;;;;UAYO,mBAAA;;;;;;;;;;YAUL;;WAED;;;;;;;UAQM,oBAAA;;YAEL;;;;;;;;;;;;;UAcK,iBAAA;;;;;;;;;;;;YAYL;;kBAEM;;;;;UAMD,uBAAA;;kBAEC;;mBAEC;;;;QAIX;;;;;UAMS,mBAAA;;;SAGR;aACI;;;UAII,iBAAA;;;;WAIN;;;UAIM,oBAAA;;;;WAIN"}