@hyperfrontend/versioning 0.1.0 → 0.3.0

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 (167) hide show
  1. package/ARCHITECTURE.md +50 -1
  2. package/CHANGELOG.md +37 -23
  3. package/README.md +19 -14
  4. package/changelog/index.cjs.js +38 -6
  5. package/changelog/index.cjs.js.map +1 -1
  6. package/changelog/index.esm.js +38 -6
  7. package/changelog/index.esm.js.map +1 -1
  8. package/changelog/models/entry.d.ts +5 -0
  9. package/changelog/models/entry.d.ts.map +1 -1
  10. package/changelog/models/index.cjs.js +2 -0
  11. package/changelog/models/index.cjs.js.map +1 -1
  12. package/changelog/models/index.esm.js +2 -0
  13. package/changelog/models/index.esm.js.map +1 -1
  14. package/changelog/operations/index.cjs.js.map +1 -1
  15. package/changelog/operations/index.esm.js.map +1 -1
  16. package/changelog/parse/index.cjs.js +85 -6
  17. package/changelog/parse/index.cjs.js.map +1 -1
  18. package/changelog/parse/index.esm.js +85 -6
  19. package/changelog/parse/index.esm.js.map +1 -1
  20. package/changelog/parse/line.d.ts.map +1 -1
  21. package/changelog/parse/parser.d.ts +0 -6
  22. package/changelog/parse/parser.d.ts.map +1 -1
  23. package/commits/classify/classifier.d.ts +73 -0
  24. package/commits/classify/classifier.d.ts.map +1 -0
  25. package/commits/classify/index.cjs.js +707 -0
  26. package/commits/classify/index.cjs.js.map +1 -0
  27. package/commits/classify/index.d.ts +8 -0
  28. package/commits/classify/index.d.ts.map +1 -0
  29. package/commits/classify/index.esm.js +679 -0
  30. package/commits/classify/index.esm.js.map +1 -0
  31. package/commits/classify/infrastructure.d.ts +205 -0
  32. package/commits/classify/infrastructure.d.ts.map +1 -0
  33. package/commits/classify/models.d.ts +108 -0
  34. package/commits/classify/models.d.ts.map +1 -0
  35. package/commits/classify/project-scopes.d.ts +69 -0
  36. package/commits/classify/project-scopes.d.ts.map +1 -0
  37. package/commits/index.cjs.js +704 -0
  38. package/commits/index.cjs.js.map +1 -1
  39. package/commits/index.d.ts +1 -0
  40. package/commits/index.d.ts.map +1 -1
  41. package/commits/index.esm.js +678 -1
  42. package/commits/index.esm.js.map +1 -1
  43. package/flow/executor/execute.d.ts +6 -0
  44. package/flow/executor/execute.d.ts.map +1 -1
  45. package/flow/executor/index.cjs.js +1617 -43
  46. package/flow/executor/index.cjs.js.map +1 -1
  47. package/flow/executor/index.esm.js +1623 -49
  48. package/flow/executor/index.esm.js.map +1 -1
  49. package/flow/index.cjs.js +6749 -2938
  50. package/flow/index.cjs.js.map +1 -1
  51. package/flow/index.esm.js +6751 -2944
  52. package/flow/index.esm.js.map +1 -1
  53. package/flow/models/index.cjs.js +138 -0
  54. package/flow/models/index.cjs.js.map +1 -1
  55. package/flow/models/index.d.ts +1 -1
  56. package/flow/models/index.d.ts.map +1 -1
  57. package/flow/models/index.esm.js +138 -1
  58. package/flow/models/index.esm.js.map +1 -1
  59. package/flow/models/types.d.ts +180 -3
  60. package/flow/models/types.d.ts.map +1 -1
  61. package/flow/presets/conventional.d.ts +9 -8
  62. package/flow/presets/conventional.d.ts.map +1 -1
  63. package/flow/presets/independent.d.ts.map +1 -1
  64. package/flow/presets/index.cjs.js +3641 -303
  65. package/flow/presets/index.cjs.js.map +1 -1
  66. package/flow/presets/index.esm.js +3641 -303
  67. package/flow/presets/index.esm.js.map +1 -1
  68. package/flow/presets/synced.d.ts.map +1 -1
  69. package/flow/steps/analyze-commits.d.ts +9 -6
  70. package/flow/steps/analyze-commits.d.ts.map +1 -1
  71. package/flow/steps/calculate-bump.d.ts.map +1 -1
  72. package/flow/steps/fetch-registry.d.ts.map +1 -1
  73. package/flow/steps/generate-changelog.d.ts +5 -0
  74. package/flow/steps/generate-changelog.d.ts.map +1 -1
  75. package/flow/steps/index.cjs.js +3663 -328
  76. package/flow/steps/index.cjs.js.map +1 -1
  77. package/flow/steps/index.d.ts +2 -1
  78. package/flow/steps/index.d.ts.map +1 -1
  79. package/flow/steps/index.esm.js +3661 -329
  80. package/flow/steps/index.esm.js.map +1 -1
  81. package/flow/steps/resolve-repository.d.ts +36 -0
  82. package/flow/steps/resolve-repository.d.ts.map +1 -0
  83. package/flow/steps/update-packages.d.ts.map +1 -1
  84. package/git/factory.d.ts +14 -0
  85. package/git/factory.d.ts.map +1 -1
  86. package/git/index.cjs.js +65 -0
  87. package/git/index.cjs.js.map +1 -1
  88. package/git/index.esm.js +66 -2
  89. package/git/index.esm.js.map +1 -1
  90. package/git/operations/index.cjs.js +40 -0
  91. package/git/operations/index.cjs.js.map +1 -1
  92. package/git/operations/index.d.ts +1 -1
  93. package/git/operations/index.d.ts.map +1 -1
  94. package/git/operations/index.esm.js +41 -2
  95. package/git/operations/index.esm.js.map +1 -1
  96. package/git/operations/log.d.ts +23 -0
  97. package/git/operations/log.d.ts.map +1 -1
  98. package/index.cjs.js +7547 -4947
  99. package/index.cjs.js.map +1 -1
  100. package/index.d.ts +3 -1
  101. package/index.d.ts.map +1 -1
  102. package/index.esm.js +7550 -4954
  103. package/index.esm.js.map +1 -1
  104. package/package.json +39 -1
  105. package/registry/index.cjs.js +3 -3
  106. package/registry/index.cjs.js.map +1 -1
  107. package/registry/index.esm.js +3 -3
  108. package/registry/index.esm.js.map +1 -1
  109. package/registry/models/index.cjs.js +2 -0
  110. package/registry/models/index.cjs.js.map +1 -1
  111. package/registry/models/index.esm.js +2 -0
  112. package/registry/models/index.esm.js.map +1 -1
  113. package/registry/models/version-info.d.ts +10 -0
  114. package/registry/models/version-info.d.ts.map +1 -1
  115. package/registry/npm/client.d.ts.map +1 -1
  116. package/registry/npm/index.cjs.js +1 -3
  117. package/registry/npm/index.cjs.js.map +1 -1
  118. package/registry/npm/index.esm.js +1 -3
  119. package/registry/npm/index.esm.js.map +1 -1
  120. package/repository/index.cjs.js +998 -0
  121. package/repository/index.cjs.js.map +1 -0
  122. package/repository/index.d.ts +4 -0
  123. package/repository/index.d.ts.map +1 -0
  124. package/repository/index.esm.js +981 -0
  125. package/repository/index.esm.js.map +1 -0
  126. package/repository/models/index.cjs.js +301 -0
  127. package/repository/models/index.cjs.js.map +1 -0
  128. package/repository/models/index.d.ts +7 -0
  129. package/repository/models/index.d.ts.map +1 -0
  130. package/repository/models/index.esm.js +290 -0
  131. package/repository/models/index.esm.js.map +1 -0
  132. package/repository/models/platform.d.ts +58 -0
  133. package/repository/models/platform.d.ts.map +1 -0
  134. package/repository/models/repository-config.d.ts +132 -0
  135. package/repository/models/repository-config.d.ts.map +1 -0
  136. package/repository/models/resolution.d.ts +121 -0
  137. package/repository/models/resolution.d.ts.map +1 -0
  138. package/repository/parse/index.cjs.js +755 -0
  139. package/repository/parse/index.cjs.js.map +1 -0
  140. package/repository/parse/index.d.ts +5 -0
  141. package/repository/parse/index.d.ts.map +1 -0
  142. package/repository/parse/index.esm.js +749 -0
  143. package/repository/parse/index.esm.js.map +1 -0
  144. package/repository/parse/package-json.d.ts +100 -0
  145. package/repository/parse/package-json.d.ts.map +1 -0
  146. package/repository/parse/url.d.ts +81 -0
  147. package/repository/parse/url.d.ts.map +1 -0
  148. package/repository/url/compare.d.ts +84 -0
  149. package/repository/url/compare.d.ts.map +1 -0
  150. package/repository/url/index.cjs.js +178 -0
  151. package/repository/url/index.cjs.js.map +1 -0
  152. package/repository/url/index.d.ts +3 -0
  153. package/repository/url/index.d.ts.map +1 -0
  154. package/repository/url/index.esm.js +176 -0
  155. package/repository/url/index.esm.js.map +1 -0
  156. package/workspace/discovery/changelog-path.d.ts +3 -7
  157. package/workspace/discovery/changelog-path.d.ts.map +1 -1
  158. package/workspace/discovery/index.cjs.js +408 -335
  159. package/workspace/discovery/index.cjs.js.map +1 -1
  160. package/workspace/discovery/index.esm.js +408 -335
  161. package/workspace/discovery/index.esm.js.map +1 -1
  162. package/workspace/discovery/packages.d.ts +0 -6
  163. package/workspace/discovery/packages.d.ts.map +1 -1
  164. package/workspace/index.cjs.js +84 -11
  165. package/workspace/index.cjs.js.map +1 -1
  166. package/workspace/index.esm.js +84 -11
  167. package/workspace/index.esm.js.map +1 -1
package/ARCHITECTURE.md CHANGED
@@ -137,7 +137,7 @@ sequenceDiagram
137
137
  Flow->>Workspace: discoverProjects()
138
138
  Workspace-->>Flow: projects[]
139
139
 
140
- Flow->>Git: getCommitsSince(lastTag)
140
+ Flow->>Git: getCommitsSince(publishedCommit)
141
141
  Git-->>Flow: commits[]
142
142
 
143
143
  Flow->>Commits: parseConventionalCommits(commits)
@@ -214,6 +214,55 @@ flowchart TD
214
214
  breaking2 --> result
215
215
  ```
216
216
 
217
+ ### Commit Classification Pipeline
218
+
219
+ When generating changelogs for monorepo projects, commits must be classified to determine which project(s) they belong to:
220
+
221
+ ```mermaid
222
+ flowchart TB
223
+ input["Raw Commits\n(git log)"]
224
+
225
+ subgraph engine["Commit Classification Engine"]
226
+ direction TB
227
+ subgraph filters["Filtering Strategies"]
228
+ scope["Scope-Based\nFiltering"]
229
+ file["File-Based\nFiltering"]
230
+ end
231
+ scope --> matrix
232
+ file --> matrix
233
+ matrix["Classification\nDecision Matrix"]
234
+ end
235
+
236
+ input --> engine
237
+
238
+ matrix --> direct
239
+ matrix --> indirect
240
+ matrix --> excluded
241
+
242
+ subgraph direct["DIRECT"]
243
+ d1["Matching scope OR\ntouches project files"]
244
+ d2["Scope: OMITTED\n(redundant)"]
245
+ end
246
+
247
+ subgraph indirect["INDIRECT"]
248
+ i1["Dependency changes OR\ninfrastructure changes"]
249
+ i2["Scope: PRESERVED\n(context)"]
250
+ end
251
+
252
+ subgraph excluded["EXCLUDED"]
253
+ e1["Unrelated to project"]
254
+ e2["Not in CHANGELOG"]
255
+ end
256
+
257
+ direct --> changelog["Project CHANGELOG"]
258
+ indirect --> changelog
259
+
260
+ style direct fill:#c8e6c9
261
+ style indirect fill:#fff3e0
262
+ style excluded fill:#ffcdd2
263
+ style engine fill:#e3f2fd
264
+ ```
265
+
217
266
  ---
218
267
 
219
268
  ## Core Types
package/CHANGELOG.md CHANGED
@@ -2,34 +2,48 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
- ## 0.1.0 - 2026-03-16
5
+ ## [0.3.0](https://github.com/AndrewRedican/hyperfrontend/compare/31943a4b39484dba86b358e4f361abe76edc4fe1...2737bb00792930010cd0161b87b4ca80b2c155e0) - 2026-03-21
6
6
 
7
7
  ### Features
8
8
 
9
- - **lib-versioning:** support commit amend no edit
10
- - **lib-versioning:** support force bump with release as config
11
- - **tool-package:** improve memory management and visibility on builder executor
12
- - **eslint-rules:** lib-ts-config-paths
13
- - **e2e-lib-versioning:** test cjs and esm builds
14
- - **eslint-rules:** lib-e2e-project-required
15
- - **lib-versioning:** implement project versioning
16
- - **eslint-rules:** ensure publishable libraries accounted for in docs
17
- - **eslint-rules:** add rule to ensure pipeline is ready for publishable libraries
18
- - **eslint-rules:** root readme.md rule to ensure packages are listed
19
- - **eslint-rules:** rules to align readme.md content format
20
- - **docs-site:** add project-scope
21
- - **tool-package:** build executor now takes unpkg and jsdelivr configuration
22
- - **lib-json-utils:** regex pattern safety
23
- - **eslint-rules:** no-unsafe-regex
24
- - **eslint-rules:** no-deprecated-tag
25
- - **lib-project-scope:** complete implementation
9
+ - add commit type to section config option
10
+ - add changelog file name config option
11
+ - export key configuration constants
12
+ - make project prefixes configurable
13
+ - add max commit fallback config option
26
14
 
27
15
  ### Bug Fixes
28
16
 
29
- - **lib-versioning:** remove unused %h format causing git log field misalignment
30
- - **lib-immutable-api-utils:** rename safe object to prevent variable shadowing on cjs module init
31
- - **@hyperfrontend/workspace:** prevent changelog corruption in pr ci
17
+ - **eslint-rules:** validate github urls via url parsing
18
+
19
+ ## [0.2.0](https://github.com/AndrewRedican/hyperfrontend/compare/a9185d9b783d7d8d51cc4ad91eb3178eba3e3930...bdcdfe00e5c9680e7a1eb925ef69997601d0f393) - 2026-03-20
20
+
21
+ ### Features
22
+
23
+ - support commit existence verification
24
+ - track commits to project dependencies
25
+ - support of indirect infra changes tht may be consider for semantic versioning
26
+ - add core commit classification engine
27
+ - git client now supports get remote url
28
+ - support remote repository url comparison
29
+ - support remote repository url parsing
30
+ - support repository models
31
+ - support jscutlery/semver style changelog entries
32
+
33
+ ### Bug Fixes
32
34
 
33
- ### Other
35
+ - idempotently update pre-existing unpublished change log entry
36
+ - update calculate bump process to account for unpublished versions
34
37
 
35
- - **eslint-rules:** disable angle bracket typecasting on eslint-rules project
38
+ ## 0.1.0 - 2026-03-16
39
+
40
+ ### Features
41
+
42
+ - support commit amend no edit
43
+ - support force bump with release as config
44
+ - implement project versioning
45
+
46
+ ### Bug Fixes
47
+
48
+ - remove unused %h format causing git log field misalignment
49
+ - **@hyperfrontend/workspace:** prevent changelog corruption in pr ci
package/README.md CHANGED
@@ -34,6 +34,7 @@
34
34
  Versioning library with changelog parsing, conventional commits, and semver flow orchestration.
35
35
 
36
36
  • 👉 See [**documentation**](https://www.hyperfrontend.dev/docs/libraries/versioning/)
37
+ • 👉 See [**roadmap**](https://github.com/AndrewRedican/hyperfrontend/blob/main/roadmap/versioning/)
37
38
 
38
39
  ## What is @hyperfrontend/versioning?
39
40
 
@@ -42,9 +43,11 @@ Versioning library with changelog parsing, conventional commits, and semver flow
42
43
  ### Key Features
43
44
 
44
45
  - **Changelog Parsing** - Parse CHANGELOG.md files into structured objects with lossless round-tripping
45
- - **Conventional Commits** - Parse commit messages following the conventional commits specification
46
- - **Semver Utilities** - Parse, compare, increment, and validate semantic versions
47
- - **Registry Client** - Query npm registry for published versions and package metadata
46
+ - **Conventional Commits** - Parse commit messages following the [Conventional Commits](https://www.conventionalcommits.org/) specification
47
+ - **Semver Utilities** - Parse, compare, increment, and validate [semantic versions](https://semver.org/)
48
+ - **Registry Client** - Query [npm](https://www.npmjs.com/) registry for published versions and package metadata
49
+ - **Compare URLs** - Generate platform-specific compare URLs for changelog entries ([GitHub](https://github.com/), [GitLab](https://about.gitlab.com/), [Bitbucket](https://bitbucket.org/), [Azure DevOps](https://azure.microsoft.com/en-us/products/devops))
50
+ - **Monorepo Scope Filtering** - Intelligent commit classification ensures changelogs only include relevant commits
48
51
  - **Composable Operations** - Build complex versioning workflows from simple, pure functions
49
52
  - **Zero External Dependencies** - Self-contained implementation with no third-party runtime dependencies
50
53
 
@@ -62,7 +65,7 @@ Working with CHANGELOG.md files programmatically typically involves fragile stri
62
65
 
63
66
  ### Unified Versioning Primitives
64
67
 
65
- Version management requires coordinating semver parsing, commit analysis, changelog generation, and registry queries. This library provides all these primitives in one cohesive package with consistent APIs. Query npm for published versions, parse commit history, calculate version bumps, and generate changelog entries — all composable into custom release workflows.
68
+ Version management requires coordinating [semver](https://semver.org/) parsing, commit analysis, changelog generation, and registry queries. This library provides all these primitives in one cohesive package with consistent APIs. Query [npm](https://www.npmjs.com/) for published versions, parse commit history, calculate version bumps, and generate changelog entries — all composable into custom release workflows.
66
69
 
67
70
  ### Zero-Dependency CI Integration
68
71
 
@@ -95,7 +98,8 @@ for (const entry of changelog.entries) {
95
98
  }
96
99
 
97
100
  // Access metadata
98
- console.log(changelog.metadata.format) // 'keep-a-changelog', 'conventional', etc.
101
+ // Formats: 'keep-a-changelog' (https://keepachangelog.com), 'conventional', etc.
102
+ console.log(changelog.metadata.format)
99
103
  ```
100
104
 
101
105
  ### Parsing Conventional Commits
@@ -151,15 +155,16 @@ console.log(commit2.breakingDescription) // 'Response structure has changed'
151
155
 
152
156
  ## Module Documentation
153
157
 
154
- | Module | Description | Documentation |
155
- | ------------ | --------------------------------------- | ----------------------------------- |
156
- | `changelog/` | Parse and manipulate CHANGELOG.md files | [README](./src/changelog/README.md) |
157
- | `commits/` | Parse conventional commit messages | [README](./src/commits/README.md) |
158
- | `semver/` | Semantic version parsing and comparison | [README](./src/semver/README.md) |
159
- | `registry/` | npm registry client | [README](./src/registry/README.md) |
160
- | `git/` | Git operations abstraction | [README](./src/git/README.md) |
161
- | `workspace/` | Project discovery and package.json | [README](./src/workspace/README.md) |
162
- | `flow/` | Version release workflow orchestration | [README](./src/flow/README.md) |
158
+ | Module | Description | Documentation |
159
+ | ------------- | --------------------------------------- | ------------------------------------ |
160
+ | `changelog/` | Parse and manipulate CHANGELOG.md files | [README](./src/changelog/README.md) |
161
+ | `commits/` | Parse conventional commit messages | [README](./src/commits/README.md) |
162
+ | `semver/` | Semantic version parsing and comparison | [README](./src/semver/README.md) |
163
+ | `registry/` | npm registry client | [README](./src/registry/README.md) |
164
+ | `git/` | Git operations abstraction | [README](./src/git/README.md) |
165
+ | `workspace/` | Project discovery and package.json | [README](./src/workspace/README.md) |
166
+ | `flow/` | Version release workflow orchestration | [README](./src/flow/README.md) |
167
+ | `repository/` | Repository detection and compare URLs | [README](./src/repository/README.md) |
163
168
 
164
169
  👉 See [ARCHITECTURE.md](./ARCHITECTURE.md) for module composition diagrams and data flow.
165
170
 
@@ -72,6 +72,8 @@ function createChangelogItem(description, options) {
72
72
  commits: options?.commits ?? [],
73
73
  references: options?.references ?? [],
74
74
  breaking: options?.breaking ?? false,
75
+ source: options?.source,
76
+ indirect: options?.indirect,
75
77
  };
76
78
  }
77
79
  /**
@@ -2086,6 +2088,25 @@ function parseVersionFromHeading(heading) {
2086
2088
  if (trimmed[pos] === ']') {
2087
2089
  pos++;
2088
2090
  }
2091
+ // Handle markdown link format [version](url) - jscutlery/semver style
2092
+ // This extracts the compare URL from patterns like [0.0.4](https://github.com/.../compare/...)
2093
+ if (trimmed[pos] === '(') {
2094
+ const urlStart = pos + 1;
2095
+ let depth = 1;
2096
+ pos++;
2097
+ // Find matching closing parenthesis (handles nested parens in URLs)
2098
+ while (pos < trimmed.length && depth > 0) {
2099
+ if (trimmed[pos] === '(')
2100
+ depth++;
2101
+ else if (trimmed[pos] === ')')
2102
+ depth--;
2103
+ pos++;
2104
+ }
2105
+ // Extract URL if we found the closing paren
2106
+ if (depth === 0) {
2107
+ compareUrl = trimmed.slice(urlStart, pos - 1);
2108
+ }
2109
+ }
2089
2110
  // Skip whitespace and separator
2090
2111
  while (pos < trimmed.length && (trimmed[pos] === ' ' || trimmed[pos] === '-' || trimmed[pos] === '–')) {
2091
2112
  pos++;
@@ -2102,8 +2123,8 @@ function parseVersionFromHeading(heading) {
2102
2123
  while (pos < trimmed.length && trimmed[pos] === ' ') {
2103
2124
  pos++;
2104
2125
  }
2105
- // Check for link at end: [compare](url)
2106
- if (pos < trimmed.length) {
2126
+ // Check for link at end: [compare](url) - only if no URL was already extracted
2127
+ if (pos < trimmed.length && !compareUrl) {
2107
2128
  const linkMatch = extractLink(trimmed.slice(pos));
2108
2129
  if (linkMatch?.url) {
2109
2130
  compareUrl = linkMatch.url;
@@ -2821,11 +2842,22 @@ function isWhitespace$1(char) {
2821
2842
  }
2822
2843
 
2823
2844
  /**
2824
- * Changelog Parser
2845
+ * Validates that a URL is actually a GitHub URL by parsing it properly.
2846
+ * This prevents SSRF attacks where 'github.com' could appear in path/query.
2825
2847
  *
2826
- * Parses a changelog markdown string into a structured Changelog object.
2827
- * Uses a state machine tokenizer for ReDoS-safe parsing.
2848
+ * @param url - The URL string to validate
2849
+ * @returns True if the URL host is github.com or a subdomain
2828
2850
  */
2851
+ function isGitHubUrl(url) {
2852
+ try {
2853
+ const parsed = createURL(url);
2854
+ // Check that the host is exactly github.com or ends with .github.com
2855
+ return parsed.host === 'github.com' || parsed.host.endsWith('.github.com');
2856
+ }
2857
+ catch {
2858
+ return false;
2859
+ }
2860
+ }
2829
2861
  /**
2830
2862
  * Parses a changelog markdown string into a Changelog object.
2831
2863
  *
@@ -2893,7 +2925,7 @@ function parseHeader(state) {
2893
2925
  description.push(`[${token.value}](${nextToken.value})`);
2894
2926
  links.push({ label: token.value, url: nextToken.value });
2895
2927
  // Try to detect repository URL
2896
- if (!state.repositoryUrl && nextToken.value.includes('github.com')) {
2928
+ if (!state.repositoryUrl && isGitHubUrl(nextToken.value)) {
2897
2929
  state.repositoryUrl = extractRepoUrl(nextToken.value);
2898
2930
  }
2899
2931
  advance(state); // skip link-text