@hyperfrontend/versioning 0.1.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 (353) hide show
  1. package/ARCHITECTURE.md +593 -0
  2. package/CHANGELOG.md +35 -0
  3. package/FUNDING.md +141 -0
  4. package/LICENSE.md +21 -0
  5. package/README.md +195 -0
  6. package/SECURITY.md +82 -0
  7. package/changelog/compare/diff.d.ts +128 -0
  8. package/changelog/compare/diff.d.ts.map +1 -0
  9. package/changelog/compare/index.cjs.js +628 -0
  10. package/changelog/compare/index.cjs.js.map +1 -0
  11. package/changelog/compare/index.d.ts +4 -0
  12. package/changelog/compare/index.d.ts.map +1 -0
  13. package/changelog/compare/index.esm.js +612 -0
  14. package/changelog/compare/index.esm.js.map +1 -0
  15. package/changelog/compare/is-equal.d.ts +114 -0
  16. package/changelog/compare/is-equal.d.ts.map +1 -0
  17. package/changelog/index.cjs.js +6448 -0
  18. package/changelog/index.cjs.js.map +1 -0
  19. package/changelog/index.d.ts +6 -0
  20. package/changelog/index.d.ts.map +1 -0
  21. package/changelog/index.esm.js +6358 -0
  22. package/changelog/index.esm.js.map +1 -0
  23. package/changelog/models/changelog.d.ts +86 -0
  24. package/changelog/models/changelog.d.ts.map +1 -0
  25. package/changelog/models/commit-ref.d.ts +51 -0
  26. package/changelog/models/commit-ref.d.ts.map +1 -0
  27. package/changelog/models/entry.d.ts +84 -0
  28. package/changelog/models/entry.d.ts.map +1 -0
  29. package/changelog/models/index.cjs.js +2043 -0
  30. package/changelog/models/index.cjs.js.map +1 -0
  31. package/changelog/models/index.d.ts +11 -0
  32. package/changelog/models/index.d.ts.map +1 -0
  33. package/changelog/models/index.esm.js +2026 -0
  34. package/changelog/models/index.esm.js.map +1 -0
  35. package/changelog/models/schema.d.ts +68 -0
  36. package/changelog/models/schema.d.ts.map +1 -0
  37. package/changelog/models/section.d.ts +25 -0
  38. package/changelog/models/section.d.ts.map +1 -0
  39. package/changelog/operations/add-entry.d.ts +56 -0
  40. package/changelog/operations/add-entry.d.ts.map +1 -0
  41. package/changelog/operations/add-item.d.ts +18 -0
  42. package/changelog/operations/add-item.d.ts.map +1 -0
  43. package/changelog/operations/filter-by-predicate.d.ts +81 -0
  44. package/changelog/operations/filter-by-predicate.d.ts.map +1 -0
  45. package/changelog/operations/filter-by-range.d.ts +63 -0
  46. package/changelog/operations/filter-by-range.d.ts.map +1 -0
  47. package/changelog/operations/filter-entries.d.ts +9 -0
  48. package/changelog/operations/filter-entries.d.ts.map +1 -0
  49. package/changelog/operations/index.cjs.js +2455 -0
  50. package/changelog/operations/index.cjs.js.map +1 -0
  51. package/changelog/operations/index.d.ts +15 -0
  52. package/changelog/operations/index.d.ts.map +1 -0
  53. package/changelog/operations/index.esm.js +2411 -0
  54. package/changelog/operations/index.esm.js.map +1 -0
  55. package/changelog/operations/merge.d.ts +88 -0
  56. package/changelog/operations/merge.d.ts.map +1 -0
  57. package/changelog/operations/remove-entry.d.ts +45 -0
  58. package/changelog/operations/remove-entry.d.ts.map +1 -0
  59. package/changelog/operations/remove-section.d.ts +50 -0
  60. package/changelog/operations/remove-section.d.ts.map +1 -0
  61. package/changelog/operations/transform.d.ts +143 -0
  62. package/changelog/operations/transform.d.ts.map +1 -0
  63. package/changelog/parse/index.cjs.js +1282 -0
  64. package/changelog/parse/index.cjs.js.map +1 -0
  65. package/changelog/parse/index.d.ts +5 -0
  66. package/changelog/parse/index.d.ts.map +1 -0
  67. package/changelog/parse/index.esm.js +1275 -0
  68. package/changelog/parse/index.esm.js.map +1 -0
  69. package/changelog/parse/line.d.ts +48 -0
  70. package/changelog/parse/line.d.ts.map +1 -0
  71. package/changelog/parse/parser.d.ts +16 -0
  72. package/changelog/parse/parser.d.ts.map +1 -0
  73. package/changelog/parse/tokenizer.d.ts +49 -0
  74. package/changelog/parse/tokenizer.d.ts.map +1 -0
  75. package/changelog/serialize/index.cjs.js +574 -0
  76. package/changelog/serialize/index.cjs.js.map +1 -0
  77. package/changelog/serialize/index.d.ts +6 -0
  78. package/changelog/serialize/index.d.ts.map +1 -0
  79. package/changelog/serialize/index.esm.js +564 -0
  80. package/changelog/serialize/index.esm.js.map +1 -0
  81. package/changelog/serialize/templates.d.ts +81 -0
  82. package/changelog/serialize/templates.d.ts.map +1 -0
  83. package/changelog/serialize/to-json.d.ts +57 -0
  84. package/changelog/serialize/to-json.d.ts.map +1 -0
  85. package/changelog/serialize/to-string.d.ts +30 -0
  86. package/changelog/serialize/to-string.d.ts.map +1 -0
  87. package/commits/index.cjs.js +648 -0
  88. package/commits/index.cjs.js.map +1 -0
  89. package/commits/index.d.ts +3 -0
  90. package/commits/index.d.ts.map +1 -0
  91. package/commits/index.esm.js +629 -0
  92. package/commits/index.esm.js.map +1 -0
  93. package/commits/models/breaking.d.ts +39 -0
  94. package/commits/models/breaking.d.ts.map +1 -0
  95. package/commits/models/commit-type.d.ts +32 -0
  96. package/commits/models/commit-type.d.ts.map +1 -0
  97. package/commits/models/conventional.d.ts +49 -0
  98. package/commits/models/conventional.d.ts.map +1 -0
  99. package/commits/models/index.cjs.js +207 -0
  100. package/commits/models/index.cjs.js.map +1 -0
  101. package/commits/models/index.d.ts +7 -0
  102. package/commits/models/index.d.ts.map +1 -0
  103. package/commits/models/index.esm.js +193 -0
  104. package/commits/models/index.esm.js.map +1 -0
  105. package/commits/parse/body.d.ts +18 -0
  106. package/commits/parse/body.d.ts.map +1 -0
  107. package/commits/parse/footer.d.ts +16 -0
  108. package/commits/parse/footer.d.ts.map +1 -0
  109. package/commits/parse/header.d.ts +15 -0
  110. package/commits/parse/header.d.ts.map +1 -0
  111. package/commits/parse/index.cjs.js +505 -0
  112. package/commits/parse/index.cjs.js.map +1 -0
  113. package/commits/parse/index.d.ts +5 -0
  114. package/commits/parse/index.d.ts.map +1 -0
  115. package/commits/parse/index.esm.js +499 -0
  116. package/commits/parse/index.esm.js.map +1 -0
  117. package/commits/parse/message.d.ts +17 -0
  118. package/commits/parse/message.d.ts.map +1 -0
  119. package/commits/utils/replace-char.d.ts +19 -0
  120. package/commits/utils/replace-char.d.ts.map +1 -0
  121. package/flow/executor/execute.d.ts +72 -0
  122. package/flow/executor/execute.d.ts.map +1 -0
  123. package/flow/executor/index.cjs.js +4402 -0
  124. package/flow/executor/index.cjs.js.map +1 -0
  125. package/flow/executor/index.d.ts +3 -0
  126. package/flow/executor/index.d.ts.map +1 -0
  127. package/flow/executor/index.esm.js +4398 -0
  128. package/flow/executor/index.esm.js.map +1 -0
  129. package/flow/factory.d.ts +58 -0
  130. package/flow/factory.d.ts.map +1 -0
  131. package/flow/index.cjs.js +8506 -0
  132. package/flow/index.cjs.js.map +1 -0
  133. package/flow/index.d.ts +7 -0
  134. package/flow/index.d.ts.map +1 -0
  135. package/flow/index.esm.js +8451 -0
  136. package/flow/index.esm.js.map +1 -0
  137. package/flow/models/flow.d.ts +130 -0
  138. package/flow/models/flow.d.ts.map +1 -0
  139. package/flow/models/index.cjs.js +285 -0
  140. package/flow/models/index.cjs.js.map +1 -0
  141. package/flow/models/index.d.ts +7 -0
  142. package/flow/models/index.d.ts.map +1 -0
  143. package/flow/models/index.esm.js +268 -0
  144. package/flow/models/index.esm.js.map +1 -0
  145. package/flow/models/step.d.ts +108 -0
  146. package/flow/models/step.d.ts.map +1 -0
  147. package/flow/models/types.d.ts +150 -0
  148. package/flow/models/types.d.ts.map +1 -0
  149. package/flow/presets/conventional.d.ts +59 -0
  150. package/flow/presets/conventional.d.ts.map +1 -0
  151. package/flow/presets/independent.d.ts +61 -0
  152. package/flow/presets/independent.d.ts.map +1 -0
  153. package/flow/presets/index.cjs.js +3903 -0
  154. package/flow/presets/index.cjs.js.map +1 -0
  155. package/flow/presets/index.d.ts +4 -0
  156. package/flow/presets/index.d.ts.map +1 -0
  157. package/flow/presets/index.esm.js +3889 -0
  158. package/flow/presets/index.esm.js.map +1 -0
  159. package/flow/presets/synced.d.ts +65 -0
  160. package/flow/presets/synced.d.ts.map +1 -0
  161. package/flow/steps/analyze-commits.d.ts +19 -0
  162. package/flow/steps/analyze-commits.d.ts.map +1 -0
  163. package/flow/steps/calculate-bump.d.ts +27 -0
  164. package/flow/steps/calculate-bump.d.ts.map +1 -0
  165. package/flow/steps/create-commit.d.ts +16 -0
  166. package/flow/steps/create-commit.d.ts.map +1 -0
  167. package/flow/steps/create-tag.d.ts +22 -0
  168. package/flow/steps/create-tag.d.ts.map +1 -0
  169. package/flow/steps/fetch-registry.d.ts +19 -0
  170. package/flow/steps/fetch-registry.d.ts.map +1 -0
  171. package/flow/steps/generate-changelog.d.ts +25 -0
  172. package/flow/steps/generate-changelog.d.ts.map +1 -0
  173. package/flow/steps/index.cjs.js +3523 -0
  174. package/flow/steps/index.cjs.js.map +1 -0
  175. package/flow/steps/index.d.ts +8 -0
  176. package/flow/steps/index.d.ts.map +1 -0
  177. package/flow/steps/index.esm.js +3504 -0
  178. package/flow/steps/index.esm.js.map +1 -0
  179. package/flow/steps/update-packages.d.ts +25 -0
  180. package/flow/steps/update-packages.d.ts.map +1 -0
  181. package/flow/utils/interpolate.d.ts +11 -0
  182. package/flow/utils/interpolate.d.ts.map +1 -0
  183. package/git/factory.d.ts +233 -0
  184. package/git/factory.d.ts.map +1 -0
  185. package/git/index.cjs.js +2863 -0
  186. package/git/index.cjs.js.map +1 -0
  187. package/git/index.d.ts +5 -0
  188. package/git/index.d.ts.map +1 -0
  189. package/git/index.esm.js +2785 -0
  190. package/git/index.esm.js.map +1 -0
  191. package/git/models/commit.d.ts +129 -0
  192. package/git/models/commit.d.ts.map +1 -0
  193. package/git/models/index.cjs.js +755 -0
  194. package/git/models/index.cjs.js.map +1 -0
  195. package/git/models/index.d.ts +7 -0
  196. package/git/models/index.d.ts.map +1 -0
  197. package/git/models/index.esm.js +729 -0
  198. package/git/models/index.esm.js.map +1 -0
  199. package/git/models/ref.d.ts +120 -0
  200. package/git/models/ref.d.ts.map +1 -0
  201. package/git/models/tag.d.ts +141 -0
  202. package/git/models/tag.d.ts.map +1 -0
  203. package/git/operations/commit.d.ts +97 -0
  204. package/git/operations/commit.d.ts.map +1 -0
  205. package/git/operations/head-info.d.ts +29 -0
  206. package/git/operations/head-info.d.ts.map +1 -0
  207. package/git/operations/index.cjs.js +1954 -0
  208. package/git/operations/index.cjs.js.map +1 -0
  209. package/git/operations/index.d.ts +14 -0
  210. package/git/operations/index.d.ts.map +1 -0
  211. package/git/operations/index.esm.js +1903 -0
  212. package/git/operations/index.esm.js.map +1 -0
  213. package/git/operations/log.d.ts +104 -0
  214. package/git/operations/log.d.ts.map +1 -0
  215. package/git/operations/manage-tags.d.ts +60 -0
  216. package/git/operations/manage-tags.d.ts.map +1 -0
  217. package/git/operations/query-tags.d.ts +88 -0
  218. package/git/operations/query-tags.d.ts.map +1 -0
  219. package/git/operations/stage.d.ts +66 -0
  220. package/git/operations/stage.d.ts.map +1 -0
  221. package/git/operations/status.d.ts +173 -0
  222. package/git/operations/status.d.ts.map +1 -0
  223. package/index.cjs.js +16761 -0
  224. package/index.cjs.js.map +1 -0
  225. package/index.d.ts +102 -0
  226. package/index.d.ts.map +1 -0
  227. package/index.esm.js +16427 -0
  228. package/index.esm.js.map +1 -0
  229. package/package.json +200 -0
  230. package/registry/factory.d.ts +18 -0
  231. package/registry/factory.d.ts.map +1 -0
  232. package/registry/index.cjs.js +543 -0
  233. package/registry/index.cjs.js.map +1 -0
  234. package/registry/index.d.ts +5 -0
  235. package/registry/index.d.ts.map +1 -0
  236. package/registry/index.esm.js +535 -0
  237. package/registry/index.esm.js.map +1 -0
  238. package/registry/models/index.cjs.js +69 -0
  239. package/registry/models/index.cjs.js.map +1 -0
  240. package/registry/models/index.d.ts +6 -0
  241. package/registry/models/index.d.ts.map +1 -0
  242. package/registry/models/index.esm.js +66 -0
  243. package/registry/models/index.esm.js.map +1 -0
  244. package/registry/models/package-info.d.ts +55 -0
  245. package/registry/models/package-info.d.ts.map +1 -0
  246. package/registry/models/registry.d.ts +62 -0
  247. package/registry/models/registry.d.ts.map +1 -0
  248. package/registry/models/version-info.d.ts +67 -0
  249. package/registry/models/version-info.d.ts.map +1 -0
  250. package/registry/npm/cache.d.ts +50 -0
  251. package/registry/npm/cache.d.ts.map +1 -0
  252. package/registry/npm/client.d.ts +30 -0
  253. package/registry/npm/client.d.ts.map +1 -0
  254. package/registry/npm/index.cjs.js +456 -0
  255. package/registry/npm/index.cjs.js.map +1 -0
  256. package/registry/npm/index.d.ts +4 -0
  257. package/registry/npm/index.d.ts.map +1 -0
  258. package/registry/npm/index.esm.js +451 -0
  259. package/registry/npm/index.esm.js.map +1 -0
  260. package/semver/compare/compare.d.ts +100 -0
  261. package/semver/compare/compare.d.ts.map +1 -0
  262. package/semver/compare/index.cjs.js +386 -0
  263. package/semver/compare/index.cjs.js.map +1 -0
  264. package/semver/compare/index.d.ts +3 -0
  265. package/semver/compare/index.d.ts.map +1 -0
  266. package/semver/compare/index.esm.js +370 -0
  267. package/semver/compare/index.esm.js.map +1 -0
  268. package/semver/compare/sort.d.ts +36 -0
  269. package/semver/compare/sort.d.ts.map +1 -0
  270. package/semver/format/index.cjs.js +58 -0
  271. package/semver/format/index.cjs.js.map +1 -0
  272. package/semver/format/index.d.ts +2 -0
  273. package/semver/format/index.d.ts.map +1 -0
  274. package/semver/format/index.esm.js +53 -0
  275. package/semver/format/index.esm.js.map +1 -0
  276. package/semver/format/to-string.d.ts +31 -0
  277. package/semver/format/to-string.d.ts.map +1 -0
  278. package/semver/increment/bump.d.ts +37 -0
  279. package/semver/increment/bump.d.ts.map +1 -0
  280. package/semver/increment/index.cjs.js +223 -0
  281. package/semver/increment/index.cjs.js.map +1 -0
  282. package/semver/increment/index.d.ts +2 -0
  283. package/semver/increment/index.d.ts.map +1 -0
  284. package/semver/increment/index.esm.js +219 -0
  285. package/semver/increment/index.esm.js.map +1 -0
  286. package/semver/index.cjs.js +1499 -0
  287. package/semver/index.cjs.js.map +1 -0
  288. package/semver/index.d.ts +6 -0
  289. package/semver/index.d.ts.map +1 -0
  290. package/semver/index.esm.js +1458 -0
  291. package/semver/index.esm.js.map +1 -0
  292. package/semver/models/index.cjs.js +153 -0
  293. package/semver/models/index.cjs.js.map +1 -0
  294. package/semver/models/index.d.ts +5 -0
  295. package/semver/models/index.d.ts.map +1 -0
  296. package/semver/models/index.esm.js +139 -0
  297. package/semver/models/index.esm.js.map +1 -0
  298. package/semver/models/range.d.ts +83 -0
  299. package/semver/models/range.d.ts.map +1 -0
  300. package/semver/models/version.d.ts +78 -0
  301. package/semver/models/version.d.ts.map +1 -0
  302. package/semver/parse/index.cjs.js +799 -0
  303. package/semver/parse/index.cjs.js.map +1 -0
  304. package/semver/parse/index.d.ts +5 -0
  305. package/semver/parse/index.d.ts.map +1 -0
  306. package/semver/parse/index.esm.js +793 -0
  307. package/semver/parse/index.esm.js.map +1 -0
  308. package/semver/parse/range.d.ts +38 -0
  309. package/semver/parse/range.d.ts.map +1 -0
  310. package/semver/parse/version.d.ts +49 -0
  311. package/semver/parse/version.d.ts.map +1 -0
  312. package/workspace/discovery/changelog-path.d.ts +21 -0
  313. package/workspace/discovery/changelog-path.d.ts.map +1 -0
  314. package/workspace/discovery/dependencies.d.ts +145 -0
  315. package/workspace/discovery/dependencies.d.ts.map +1 -0
  316. package/workspace/discovery/discover-changelogs.d.ts +76 -0
  317. package/workspace/discovery/discover-changelogs.d.ts.map +1 -0
  318. package/workspace/discovery/index.cjs.js +2300 -0
  319. package/workspace/discovery/index.cjs.js.map +1 -0
  320. package/workspace/discovery/index.d.ts +13 -0
  321. package/workspace/discovery/index.d.ts.map +1 -0
  322. package/workspace/discovery/index.esm.js +2283 -0
  323. package/workspace/discovery/index.esm.js.map +1 -0
  324. package/workspace/discovery/packages.d.ts +83 -0
  325. package/workspace/discovery/packages.d.ts.map +1 -0
  326. package/workspace/index.cjs.js +4445 -0
  327. package/workspace/index.cjs.js.map +1 -0
  328. package/workspace/index.d.ts +52 -0
  329. package/workspace/index.d.ts.map +1 -0
  330. package/workspace/index.esm.js +4394 -0
  331. package/workspace/index.esm.js.map +1 -0
  332. package/workspace/models/index.cjs.js +284 -0
  333. package/workspace/models/index.cjs.js.map +1 -0
  334. package/workspace/models/index.d.ts +10 -0
  335. package/workspace/models/index.d.ts.map +1 -0
  336. package/workspace/models/index.esm.js +261 -0
  337. package/workspace/models/index.esm.js.map +1 -0
  338. package/workspace/models/project.d.ts +118 -0
  339. package/workspace/models/project.d.ts.map +1 -0
  340. package/workspace/models/workspace.d.ts +139 -0
  341. package/workspace/models/workspace.d.ts.map +1 -0
  342. package/workspace/operations/batch-update.d.ts +99 -0
  343. package/workspace/operations/batch-update.d.ts.map +1 -0
  344. package/workspace/operations/cascade-bump.d.ts +125 -0
  345. package/workspace/operations/cascade-bump.d.ts.map +1 -0
  346. package/workspace/operations/index.cjs.js +2675 -0
  347. package/workspace/operations/index.cjs.js.map +1 -0
  348. package/workspace/operations/index.d.ts +12 -0
  349. package/workspace/operations/index.d.ts.map +1 -0
  350. package/workspace/operations/index.esm.js +2663 -0
  351. package/workspace/operations/index.esm.js.map +1 -0
  352. package/workspace/operations/validate.d.ts +85 -0
  353. package/workspace/operations/validate.d.ts.map +1 -0
@@ -0,0 +1,729 @@
1
+ /**
2
+ * Creates a git commit model.
3
+ *
4
+ * @param options - Commit creation options
5
+ * @returns A new GitCommit object
6
+ *
7
+ * @example
8
+ * const commit = createGitCommit({
9
+ * hash: 'abc123...',
10
+ * authorName: 'John Doe',
11
+ * authorEmail: 'john@example.com',
12
+ * authorDate: '2026-03-12T10:00:00Z',
13
+ * subject: 'feat: add new feature',
14
+ * })
15
+ */
16
+ function createGitCommit(options) {
17
+ const body = options.body ?? '';
18
+ const subject = options.subject;
19
+ return {
20
+ hash: options.hash,
21
+ shortHash: getShortHash(options.hash),
22
+ authorName: options.authorName,
23
+ authorEmail: options.authorEmail,
24
+ authorDate: options.authorDate,
25
+ committerName: options.committerName ?? options.authorName,
26
+ committerEmail: options.committerEmail ?? options.authorEmail,
27
+ commitDate: options.commitDate ?? options.authorDate,
28
+ subject,
29
+ body,
30
+ message: body ? `${subject}\n\n${body}` : subject,
31
+ parents: options.parents ?? [],
32
+ refs: options.refs ?? [],
33
+ };
34
+ }
35
+ /**
36
+ * Gets a short hash (7 characters) from a full commit hash.
37
+ *
38
+ * @param hash - Full commit hash
39
+ * @returns Short hash (7 characters)
40
+ */
41
+ function getShortHash(hash) {
42
+ return hash.slice(0, 7);
43
+ }
44
+ /**
45
+ * Checks if two commits are the same based on their hash.
46
+ *
47
+ * @param a - First commit
48
+ * @param b - Second commit
49
+ * @returns True if commits have the same hash
50
+ */
51
+ function isSameCommit(a, b) {
52
+ return a.hash === b.hash;
53
+ }
54
+ /**
55
+ * Checks if a commit is a merge commit (has multiple parents).
56
+ *
57
+ * @param commit - Commit to check
58
+ * @returns True if commit has more than one parent
59
+ */
60
+ function isMergeCommit(commit) {
61
+ return commit.parents.length > 1;
62
+ }
63
+ /**
64
+ * Checks if a commit is a root commit (has no parents).
65
+ *
66
+ * @param commit - Commit to check
67
+ * @returns True if commit has no parents
68
+ */
69
+ function isRootCommit(commit) {
70
+ return commit.parents.length === 0;
71
+ }
72
+ /**
73
+ * Extracts the scope from a commit subject if it follows conventional commit format.
74
+ * Uses character-by-character parsing (no regex).
75
+ *
76
+ * @param subject - Commit subject line
77
+ * @returns Scope string or undefined if no scope found
78
+ *
79
+ * @example
80
+ * extractScope('feat(lib-versioning): add git support') // 'lib-versioning'
81
+ * extractScope('fix: resolve issue') // undefined
82
+ */
83
+ function extractScope(subject) {
84
+ // Look for pattern: type(scope): or type(scope)!:
85
+ let i = 0;
86
+ // Skip type characters (a-z)
87
+ while (i < subject.length) {
88
+ const code = subject.charCodeAt(i);
89
+ if (code >= 97 && code <= 122) {
90
+ // a-z
91
+ i++;
92
+ }
93
+ else {
94
+ break;
95
+ }
96
+ }
97
+ // Must find opening parenthesis
98
+ if (i >= subject.length || subject[i] !== '(') {
99
+ return undefined;
100
+ }
101
+ // Skip '('
102
+ i++;
103
+ const scopeStart = i;
104
+ // Find closing parenthesis
105
+ while (i < subject.length && subject[i] !== ')') {
106
+ i++;
107
+ }
108
+ if (i >= subject.length) {
109
+ return undefined;
110
+ }
111
+ const scope = subject.slice(scopeStart, i);
112
+ return scope || undefined;
113
+ }
114
+ /**
115
+ * Extracts the type from a commit subject if it follows conventional commit format.
116
+ * Uses character-by-character parsing (no regex).
117
+ *
118
+ * @param subject - Commit subject line
119
+ * @returns Type string or undefined if no valid type found
120
+ *
121
+ * @example
122
+ * extractType('feat(lib-versioning): add git support') // 'feat'
123
+ * extractType('fix: resolve issue') // 'fix'
124
+ * extractType('random message') // undefined
125
+ */
126
+ function extractType(subject) {
127
+ let i = 0;
128
+ // Collect type characters (a-z)
129
+ while (i < subject.length) {
130
+ const code = subject.charCodeAt(i);
131
+ if (code >= 97 && code <= 122) {
132
+ // a-z
133
+ i++;
134
+ }
135
+ else {
136
+ break;
137
+ }
138
+ }
139
+ if (i === 0) {
140
+ return undefined;
141
+ }
142
+ const type = subject.slice(0, i);
143
+ // Next character must be '(' , '!' or ':'
144
+ if (i >= subject.length) {
145
+ return undefined;
146
+ }
147
+ const next = subject[i];
148
+ if (next === '(' || next === ':' || next === '!') {
149
+ return type;
150
+ }
151
+ return undefined;
152
+ }
153
+
154
+ /**
155
+ * Safe copies of Math built-in methods.
156
+ *
157
+ * These references are captured at module initialization time to protect against
158
+ * prototype pollution attacks. Import only what you need for tree-shaking.
159
+ *
160
+ * @module @hyperfrontend/immutable-api-utils/built-in-copy/math
161
+ */
162
+ // Capture references at module initialization time
163
+ const _Math = globalThis.Math;
164
+ // ============================================================================
165
+ // Min/Max
166
+ // ============================================================================
167
+ /**
168
+ * (Safe copy) Returns the larger of zero or more numbers.
169
+ */
170
+ const max = _Math.max;
171
+
172
+ /**
173
+ * Creates a lightweight git tag.
174
+ *
175
+ * @param options - Tag creation options
176
+ * @returns A new GitTag object
177
+ *
178
+ * @example
179
+ * const tag = createLightweightTag({
180
+ * name: 'v1.0.0',
181
+ * commitHash: 'abc123...',
182
+ * })
183
+ */
184
+ function createLightweightTag(options) {
185
+ return {
186
+ name: options.name,
187
+ commitHash: options.commitHash,
188
+ type: 'lightweight',
189
+ };
190
+ }
191
+ /**
192
+ * Creates an annotated git tag.
193
+ *
194
+ * @param options - Tag creation options
195
+ * @returns A new GitTag object
196
+ *
197
+ * @example
198
+ * const tag = createAnnotatedTag({
199
+ * name: 'v1.0.0',
200
+ * commitHash: 'abc123...',
201
+ * message: 'Release v1.0.0',
202
+ * taggerName: 'John Doe',
203
+ * taggerEmail: 'john@example.com',
204
+ * tagDate: '2026-03-12T10:00:00Z',
205
+ * })
206
+ */
207
+ function createAnnotatedTag(options) {
208
+ return {
209
+ name: options.name,
210
+ commitHash: options.commitHash,
211
+ type: 'annotated',
212
+ message: options.message,
213
+ taggerName: options.taggerName,
214
+ taggerEmail: options.taggerEmail,
215
+ tagDate: options.tagDate,
216
+ };
217
+ }
218
+ /**
219
+ * Checks if a tag is annotated.
220
+ *
221
+ * @param tag - Tag to check
222
+ * @returns True if tag is annotated
223
+ */
224
+ function isAnnotatedTag(tag) {
225
+ return tag.type === 'annotated';
226
+ }
227
+ /**
228
+ * Checks if a tag is lightweight.
229
+ *
230
+ * @param tag - Tag to check
231
+ * @returns True if tag is lightweight
232
+ */
233
+ function isLightweightTag(tag) {
234
+ return tag.type === 'lightweight';
235
+ }
236
+ /**
237
+ * Extracts version from tag name.
238
+ * Handles common formats: v1.2.3, `@scope/package@1.2.3`, package@1.2.3
239
+ * Uses character-by-character parsing (no regex).
240
+ *
241
+ * @param tagName - Tag name to parse
242
+ * @returns The extracted version string or undefined if no version found
243
+ *
244
+ * @example
245
+ * extractVersionFromTag('v1.2.3') // '1.2.3'
246
+ * extractVersionFromTag('@scope/pkg@1.2.3') // '1.2.3'
247
+ * extractVersionFromTag('release-1.2.3') // '1.2.3'
248
+ */
249
+ function extractVersionFromTag(tagName) {
250
+ // Strategy: Find last occurrence of '@' followed by version, or 'v' followed by version
251
+ // Version starts with digit and contains digits, dots, and possibly prerelease identifiers
252
+ // First, try to find @version pattern (for scoped packages)
253
+ let i = tagName.length - 1;
254
+ // Find last '@'
255
+ while (i >= 0 && tagName[i] !== '@') {
256
+ i--;
257
+ }
258
+ if (i >= 0) {
259
+ // Found '@', check if followed by version
260
+ const afterAt = tagName.slice(i + 1);
261
+ const version = parseVersionPart(afterAt);
262
+ if (version) {
263
+ return version;
264
+ }
265
+ }
266
+ // Try to find 'v' followed by version
267
+ i = 0;
268
+ while (i < tagName.length) {
269
+ if ((tagName[i] === 'v' || tagName[i] === 'V') && i + 1 < tagName.length) {
270
+ const nextCode = tagName.charCodeAt(i + 1);
271
+ if (nextCode >= 48 && nextCode <= 57) {
272
+ // 0-9
273
+ const version = parseVersionPart(tagName.slice(i + 1));
274
+ if (version) {
275
+ return version;
276
+ }
277
+ }
278
+ }
279
+ i++;
280
+ }
281
+ // Try to find digit sequence after common separators (-, _)
282
+ i = 0;
283
+ while (i < tagName.length) {
284
+ const char = tagName[i];
285
+ if (char === '-' || char === '_') {
286
+ const afterSep = tagName.slice(i + 1);
287
+ const code = afterSep.charCodeAt(0);
288
+ if (code >= 48 && code <= 57) {
289
+ // 0-9
290
+ const version = parseVersionPart(afterSep);
291
+ if (version) {
292
+ return version;
293
+ }
294
+ }
295
+ }
296
+ i++;
297
+ }
298
+ // Last resort: if entire string is a version
299
+ return parseVersionPart(tagName);
300
+ }
301
+ /**
302
+ * Parses a version-like string from the start of input.
303
+ * Uses character-by-character parsing (no regex).
304
+ *
305
+ * @param input - String to parse
306
+ * @returns Version string or undefined
307
+ */
308
+ function parseVersionPart(input) {
309
+ if (!input)
310
+ return undefined;
311
+ // Must start with digit
312
+ const firstCode = input.charCodeAt(0);
313
+ if (firstCode < 48 || firstCode > 57) {
314
+ return undefined;
315
+ }
316
+ // Collect version characters: digits, dots, hyphens, plus, letters (for prerelease)
317
+ let i = 0;
318
+ let dotCount = 0;
319
+ while (i < input.length) {
320
+ const code = input.charCodeAt(i);
321
+ if (code >= 48 && code <= 57) {
322
+ // 0-9
323
+ i++;
324
+ }
325
+ else if (code === 46) {
326
+ // .
327
+ dotCount++;
328
+ i++;
329
+ }
330
+ else if (code === 45) {
331
+ // -
332
+ i++;
333
+ }
334
+ else if (code === 43) {
335
+ // +
336
+ i++;
337
+ }
338
+ else if ((code >= 97 && code <= 122) || (code >= 65 && code <= 90)) {
339
+ // a-z, A-Z
340
+ i++;
341
+ }
342
+ else {
343
+ break;
344
+ }
345
+ }
346
+ // Must have at least one dot (e.g., 1.0)
347
+ if (dotCount === 0) {
348
+ return undefined;
349
+ }
350
+ const version = input.slice(0, i);
351
+ // Basic validation: must contain at least two parts separated by dots
352
+ if (!version.includes('.')) {
353
+ return undefined;
354
+ }
355
+ return version;
356
+ }
357
+ /**
358
+ * Extracts package name from tag name.
359
+ * Handles formats like: `@scope/package@1.2.3`, package@1.2.3, package-v1.2.3
360
+ * Uses character-by-character parsing (no regex).
361
+ *
362
+ * @param tagName - Tag name to parse
363
+ * @returns The extracted package name or undefined if not found
364
+ *
365
+ * @example
366
+ * extractPackageFromTag('@scope/pkg@1.2.3') // '@scope/pkg'
367
+ * extractPackageFromTag('lib-utils@1.2.3') // 'lib-utils'
368
+ * extractPackageFromTag('v1.2.3') // undefined
369
+ */
370
+ function extractPackageFromTag(tagName) {
371
+ // Find the last '@' that's followed by a version number
372
+ let lastVersionAt = -1;
373
+ let i = tagName.length - 1;
374
+ while (i >= 0) {
375
+ if (tagName[i] === '@') {
376
+ // Check if followed by a digit
377
+ if (i + 1 < tagName.length) {
378
+ const nextCode = tagName.charCodeAt(i + 1);
379
+ if (nextCode >= 48 && nextCode <= 57) {
380
+ // 0-9
381
+ lastVersionAt = i;
382
+ break;
383
+ }
384
+ }
385
+ }
386
+ i--;
387
+ }
388
+ if (lastVersionAt > 0) {
389
+ return tagName.slice(0, lastVersionAt);
390
+ }
391
+ // Check for -v or _v pattern
392
+ i = tagName.length - 1;
393
+ while (i > 0) {
394
+ if (tagName[i] === 'v' || tagName[i] === 'V') {
395
+ const prev = tagName[i - 1];
396
+ if (prev === '-' || prev === '_') {
397
+ // Check if followed by digit
398
+ if (i + 1 < tagName.length) {
399
+ const nextCode = tagName.charCodeAt(i + 1);
400
+ if (nextCode >= 48 && nextCode <= 57) {
401
+ return tagName.slice(0, i - 1);
402
+ }
403
+ }
404
+ }
405
+ }
406
+ i--;
407
+ }
408
+ return undefined;
409
+ }
410
+ /**
411
+ * Builds a tag name from package name and version.
412
+ *
413
+ * @param packageName - Package name (e.g., '@scope/package' or 'package')
414
+ * @param version - Version string (e.g., '1.2.3')
415
+ * @param format - Tag format template, uses ${package} and ${version} placeholders
416
+ * @returns Formatted tag name
417
+ *
418
+ * @example
419
+ * buildTagName('@scope/pkg', '1.2.3') // '@scope/pkg@1.2.3'
420
+ * buildTagName('utils', '1.0.0', 'v${version}') // 'v1.0.0'
421
+ * buildTagName('pkg', '2.0.0', '${package}-v${version}') // 'pkg-v2.0.0'
422
+ */
423
+ function buildTagName(packageName, version, format = '${package}@${version}') {
424
+ // Simple character-by-character replacement (no regex)
425
+ let result = '';
426
+ let i = 0;
427
+ while (i < format.length) {
428
+ if (i + 9 < format.length && format.slice(i, i + 10) === '${package}') {
429
+ result += packageName;
430
+ i += 10;
431
+ }
432
+ else if (i + 9 < format.length && format.slice(i, i + 10) === '${version}') {
433
+ result += version;
434
+ i += 10;
435
+ }
436
+ else {
437
+ result += format[i];
438
+ i++;
439
+ }
440
+ }
441
+ return result;
442
+ }
443
+ /**
444
+ * Compares two tags by version (newest first).
445
+ * Useful for sorting tags.
446
+ *
447
+ * @param a - First tag
448
+ * @param b - Second tag
449
+ * @returns Comparison result (-1, 0, or 1)
450
+ */
451
+ function compareTagsByVersion(a, b) {
452
+ const versionA = extractVersionFromTag(a.name);
453
+ const versionB = extractVersionFromTag(b.name);
454
+ if (!versionA && !versionB)
455
+ return 0;
456
+ if (!versionA)
457
+ return 1;
458
+ if (!versionB)
459
+ return -1;
460
+ return compareVersionStrings(versionB, versionA); // Descending order
461
+ }
462
+ /**
463
+ * Simple version string comparison.
464
+ * Compares major.minor.patch numerically.
465
+ *
466
+ * @param a - First version
467
+ * @param b - Second version
468
+ * @returns Comparison result (-1, 0, or 1)
469
+ */
470
+ function compareVersionStrings(a, b) {
471
+ const partsA = a.split('.');
472
+ const partsB = b.split('.');
473
+ const maxLen = max(partsA.length, partsB.length);
474
+ for (let i = 0; i < maxLen; i++) {
475
+ const numA = parseNumericPart(partsA[i]);
476
+ const numB = parseNumericPart(partsB[i]);
477
+ if (numA < numB)
478
+ return -1;
479
+ if (numA > numB)
480
+ return 1;
481
+ }
482
+ return 0;
483
+ }
484
+ /**
485
+ * Parses numeric part of version segment.
486
+ *
487
+ * @param part - Version part to parse
488
+ * @returns Numeric value
489
+ */
490
+ function parseNumericPart(part) {
491
+ if (!part)
492
+ return 0;
493
+ // Extract leading digits only
494
+ let num = 0;
495
+ for (let i = 0; i < part.length; i++) {
496
+ const code = part.charCodeAt(i);
497
+ if (code >= 48 && code <= 57) {
498
+ num = num * 10 + (code - 48);
499
+ }
500
+ else {
501
+ break;
502
+ }
503
+ }
504
+ return num;
505
+ }
506
+
507
+ /**
508
+ * Creates a git reference from full name.
509
+ * Parses the reference type from the full name.
510
+ *
511
+ * @param options - Reference creation options
512
+ * @returns A new GitRef object
513
+ *
514
+ * @example
515
+ * const ref = createGitRef({
516
+ * fullName: 'refs/heads/main',
517
+ * commitHash: 'abc123...',
518
+ * })
519
+ */
520
+ function createGitRef(options) {
521
+ const { type, name, remote } = parseRefName(options.fullName);
522
+ return {
523
+ fullName: options.fullName,
524
+ name,
525
+ type,
526
+ commitHash: options.commitHash,
527
+ remote,
528
+ isHead: options.isHead,
529
+ };
530
+ }
531
+ /**
532
+ * Parses a full reference name into its components.
533
+ * Uses character-by-character parsing (no regex).
534
+ *
535
+ * @param fullName - Full reference name
536
+ * @returns Parsed components
537
+ *
538
+ * @example
539
+ * parseRefName('refs/heads/main') // { type: 'branch', name: 'main' }
540
+ * parseRefName('refs/remotes/origin/main') // { type: 'remote', name: 'main', remote: 'origin' }
541
+ */
542
+ function parseRefName(fullName) {
543
+ // Handle HEAD specially
544
+ if (fullName === 'HEAD') {
545
+ return { type: 'head', name: 'HEAD' };
546
+ }
547
+ // Split by '/' character
548
+ const parts = splitByChar(fullName, '/');
549
+ // refs/heads/... -> branch
550
+ if (parts.length >= 3 && parts[0] === 'refs' && parts[1] === 'heads') {
551
+ return {
552
+ type: 'branch',
553
+ name: parts.slice(2).join('/'),
554
+ };
555
+ }
556
+ // refs/tags/... -> tag
557
+ if (parts.length >= 3 && parts[0] === 'refs' && parts[1] === 'tags') {
558
+ return {
559
+ type: 'tag',
560
+ name: parts.slice(2).join('/'),
561
+ };
562
+ }
563
+ // refs/remotes/origin/... -> remote
564
+ if (parts.length >= 4 && parts[0] === 'refs' && parts[1] === 'remotes') {
565
+ return {
566
+ type: 'remote',
567
+ name: parts.slice(3).join('/'),
568
+ remote: parts[2],
569
+ };
570
+ }
571
+ // refs/stash -> stash
572
+ if (parts.length >= 2 && parts[0] === 'refs' && parts[1] === 'stash') {
573
+ return {
574
+ type: 'stash',
575
+ name: parts.slice(1).join('/'),
576
+ };
577
+ }
578
+ // Default to branch for unknown patterns
579
+ return {
580
+ type: 'branch',
581
+ name: fullName,
582
+ };
583
+ }
584
+ /**
585
+ * Splits a string by a character.
586
+ * Character-by-character implementation (no regex).
587
+ *
588
+ * @param str - String to split
589
+ * @param char - Character to split by
590
+ * @returns Array of parts
591
+ */
592
+ function splitByChar(str, char) {
593
+ const parts = [];
594
+ let current = '';
595
+ for (let i = 0; i < str.length; i++) {
596
+ if (str[i] === char) {
597
+ parts.push(current);
598
+ current = '';
599
+ }
600
+ else {
601
+ current += str[i];
602
+ }
603
+ }
604
+ parts.push(current);
605
+ return parts;
606
+ }
607
+ /**
608
+ * Checks if a reference is a branch.
609
+ *
610
+ * @param ref - Reference to check
611
+ * @returns True if reference is a branch
612
+ */
613
+ function isBranchRef(ref) {
614
+ return ref.type === 'branch';
615
+ }
616
+ /**
617
+ * Checks if a reference is a tag.
618
+ *
619
+ * @param ref - Reference to check
620
+ * @returns True if reference is a tag
621
+ */
622
+ function isTagRef(ref) {
623
+ return ref.type === 'tag';
624
+ }
625
+ /**
626
+ * Checks if a reference is a remote tracking branch.
627
+ *
628
+ * @param ref - Reference to check
629
+ * @returns True if reference is a remote
630
+ */
631
+ function isRemoteRef(ref) {
632
+ return ref.type === 'remote';
633
+ }
634
+ /**
635
+ * Checks if a reference points to the current HEAD.
636
+ *
637
+ * @param ref - Reference to check
638
+ * @returns True if reference is HEAD
639
+ */
640
+ function isHeadRef(ref) {
641
+ return ref.type === 'head' || ref.isHead === true;
642
+ }
643
+ /**
644
+ * Gets the tracking remote for a reference.
645
+ *
646
+ * @param ref - Reference to check
647
+ * @returns Remote name or undefined
648
+ */
649
+ function getRemote(ref) {
650
+ return ref.remote;
651
+ }
652
+ /**
653
+ * Builds a full reference name from type and name.
654
+ *
655
+ * @param type - Reference type
656
+ * @param name - Reference name
657
+ * @param remote - Remote name (for remote type)
658
+ * @returns Full reference name
659
+ *
660
+ * @example
661
+ * buildRefName('branch', 'main') // 'refs/heads/main'
662
+ * buildRefName('tag', 'v1.0.0') // 'refs/tags/v1.0.0'
663
+ * buildRefName('remote', 'main', 'origin') // 'refs/remotes/origin/main'
664
+ */
665
+ function buildRefName(type, name, remote) {
666
+ switch (type) {
667
+ case 'branch':
668
+ return `refs/heads/${name}`;
669
+ case 'tag':
670
+ return `refs/tags/${name}`;
671
+ case 'remote':
672
+ return remote ? `refs/remotes/${remote}/${name}` : `refs/remotes/${name}`;
673
+ case 'head':
674
+ return 'HEAD';
675
+ case 'stash':
676
+ return `refs/stash`;
677
+ default:
678
+ return name;
679
+ }
680
+ }
681
+ /**
682
+ * Compares two references by name (alphabetically).
683
+ *
684
+ * @param a - First reference
685
+ * @param b - Second reference
686
+ * @returns Comparison result (-1, 0, or 1)
687
+ */
688
+ function compareRefsByName(a, b) {
689
+ if (a.name < b.name)
690
+ return -1;
691
+ if (a.name > b.name)
692
+ return 1;
693
+ return 0;
694
+ }
695
+ /**
696
+ * Filters references by type.
697
+ *
698
+ * @param refs - References to filter
699
+ * @param type - Type to filter by
700
+ * @returns Filtered references
701
+ */
702
+ function filterRefsByType(refs, type) {
703
+ const result = [];
704
+ for (const ref of refs) {
705
+ if (ref.type === type) {
706
+ result.push(ref);
707
+ }
708
+ }
709
+ return result;
710
+ }
711
+ /**
712
+ * Filters references by remote.
713
+ *
714
+ * @param refs - References to filter
715
+ * @param remote - Remote name to filter by
716
+ * @returns Filtered references
717
+ */
718
+ function filterRefsByRemote(refs, remote) {
719
+ const result = [];
720
+ for (const ref of refs) {
721
+ if (ref.remote === remote) {
722
+ result.push(ref);
723
+ }
724
+ }
725
+ return result;
726
+ }
727
+
728
+ export { buildRefName, buildTagName, compareRefsByName, compareTagsByVersion, createAnnotatedTag, createGitCommit, createGitRef, createLightweightTag, extractPackageFromTag, extractScope, extractType, extractVersionFromTag, filterRefsByRemote, filterRefsByType, getRemote, getShortHash, isAnnotatedTag, isBranchRef, isHeadRef, isLightweightTag, isMergeCommit, isRemoteRef, isRootCommit, isSameCommit, isTagRef };
729
+ //# sourceMappingURL=index.esm.js.map