@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,2043 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Creates a new changelog with default values.
5
+ *
6
+ * @param options - Optional configuration to customize the changelog
7
+ * @returns A new Changelog object with the specified options or defaults
8
+ */
9
+ function createChangelog(options) {
10
+ return {
11
+ source: options?.source,
12
+ header: options?.header ?? {
13
+ title: '# Changelog',
14
+ description: [],
15
+ links: [],
16
+ },
17
+ entries: options?.entries ?? [],
18
+ metadata: options?.metadata ?? {
19
+ format: 'unknown',
20
+ isConventional: false,
21
+ warnings: [],
22
+ },
23
+ };
24
+ }
25
+ /**
26
+ * Creates a new empty changelog with standard header.
27
+ *
28
+ * @returns A new empty Changelog with Keep a Changelog format
29
+ */
30
+ function createEmptyChangelog() {
31
+ return {
32
+ header: {
33
+ title: '# Changelog',
34
+ description: [
35
+ 'All notable changes to this project will be documented in this file.',
36
+ '',
37
+ 'The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),',
38
+ 'and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).',
39
+ ],
40
+ links: [],
41
+ },
42
+ entries: [],
43
+ metadata: {
44
+ format: 'keep-a-changelog',
45
+ isConventional: false,
46
+ warnings: [],
47
+ },
48
+ };
49
+ }
50
+ /**
51
+ * Creates a changelog link.
52
+ *
53
+ * @param label - The display text for the link
54
+ * @param url - The URL the link points to
55
+ * @returns A new ChangelogLink object
56
+ */
57
+ function createChangelogLink(label, url) {
58
+ return { label, url };
59
+ }
60
+
61
+ /**
62
+ * Creates a new changelog item.
63
+ *
64
+ * @param description - The description text of the change
65
+ * @param options - Optional configuration for scope, commits, references, and breaking flag
66
+ * @returns A new ChangelogItem object
67
+ */
68
+ function createChangelogItem(description, options) {
69
+ return {
70
+ description,
71
+ scope: options?.scope,
72
+ commits: options?.commits ?? [],
73
+ references: options?.references ?? [],
74
+ breaking: options?.breaking ?? false,
75
+ };
76
+ }
77
+ /**
78
+ * Creates a new changelog section.
79
+ *
80
+ * @param type - The type of section (features, fixes, breaking, etc.)
81
+ * @param heading - The display heading for the section
82
+ * @param items - Optional array of changelog items in this section
83
+ * @returns A new ChangelogSection object
84
+ */
85
+ function createChangelogSection(type, heading, items = []) {
86
+ return {
87
+ type,
88
+ heading,
89
+ items,
90
+ };
91
+ }
92
+ /**
93
+ * Creates a new changelog entry.
94
+ *
95
+ * @param version - The version string (e.g., '1.0.0')
96
+ * @param options - Optional configuration for date, sections, and other properties
97
+ * @returns A new ChangelogEntry object
98
+ */
99
+ function createChangelogEntry(version, options) {
100
+ return {
101
+ version,
102
+ date: options?.date ?? null,
103
+ unreleased: options?.unreleased ?? false,
104
+ compareUrl: options?.compareUrl,
105
+ sections: options?.sections ?? [],
106
+ rawContent: options?.rawContent,
107
+ };
108
+ }
109
+ /**
110
+ * Creates an unreleased changelog entry.
111
+ *
112
+ * @param sections - Optional array of changelog sections
113
+ * @returns A new ChangelogEntry object marked as unreleased
114
+ */
115
+ function createUnreleasedEntry(sections = []) {
116
+ return {
117
+ version: 'Unreleased',
118
+ date: null,
119
+ unreleased: true,
120
+ sections,
121
+ };
122
+ }
123
+
124
+ /**
125
+ * Maps section headings to their canonical types.
126
+ * Used during parsing to normalize different heading styles.
127
+ */
128
+ const SECTION_TYPE_MAP = {
129
+ // Breaking changes
130
+ 'breaking changes': 'breaking',
131
+ breaking: 'breaking',
132
+ 'breaking change': 'breaking',
133
+ // Features
134
+ features: 'features',
135
+ feature: 'features',
136
+ added: 'features',
137
+ new: 'features',
138
+ // Fixes
139
+ fixes: 'fixes',
140
+ fix: 'fixes',
141
+ 'bug fixes': 'fixes',
142
+ bugfixes: 'fixes',
143
+ fixed: 'fixes',
144
+ // Performance
145
+ performance: 'performance',
146
+ 'performance improvements': 'performance',
147
+ perf: 'performance',
148
+ // Documentation
149
+ documentation: 'documentation',
150
+ docs: 'documentation',
151
+ // Deprecations
152
+ deprecations: 'deprecations',
153
+ deprecated: 'deprecations',
154
+ // Refactoring
155
+ refactoring: 'refactoring',
156
+ refactor: 'refactoring',
157
+ 'code refactoring': 'refactoring',
158
+ // Tests
159
+ tests: 'tests',
160
+ test: 'tests',
161
+ testing: 'tests',
162
+ // Build
163
+ build: 'build',
164
+ 'build system': 'build',
165
+ dependencies: 'build',
166
+ // CI
167
+ ci: 'ci',
168
+ 'continuous integration': 'ci',
169
+ // Chores
170
+ chores: 'chores',
171
+ chore: 'chores',
172
+ maintenance: 'chores',
173
+ // Other
174
+ other: 'other',
175
+ miscellaneous: 'other',
176
+ misc: 'other',
177
+ changed: 'other',
178
+ changes: 'other',
179
+ removed: 'other',
180
+ security: 'other',
181
+ };
182
+ /**
183
+ * Standard section headings for serialization.
184
+ * Maps section types to their preferred heading text.
185
+ */
186
+ const SECTION_HEADINGS = {
187
+ breaking: 'Breaking Changes',
188
+ features: 'Features',
189
+ fixes: 'Bug Fixes',
190
+ performance: 'Performance',
191
+ documentation: 'Documentation',
192
+ deprecations: 'Deprecations',
193
+ refactoring: 'Refactoring',
194
+ tests: 'Tests',
195
+ build: 'Build',
196
+ ci: 'CI',
197
+ chores: 'Chores',
198
+ other: 'Other',
199
+ };
200
+ /**
201
+ * Determines the section type from a heading string.
202
+ * Returns 'other' if the heading is not recognized.
203
+ *
204
+ * @param heading - The heading string to parse
205
+ * @returns The corresponding ChangelogSectionType
206
+ */
207
+ function getSectionType(heading) {
208
+ const normalized = heading.toLowerCase().trim();
209
+ return SECTION_TYPE_MAP[normalized] ?? 'other';
210
+ }
211
+
212
+ /**
213
+ * Creates a commit reference from a full hash.
214
+ *
215
+ * @param hash - The full commit hash
216
+ * @param url - Optional URL to the commit
217
+ * @returns A new CommitRef object with both full and short hash
218
+ */
219
+ function createCommitRef(hash, url) {
220
+ return {
221
+ hash,
222
+ shortHash: hash.slice(0, 7),
223
+ url,
224
+ };
225
+ }
226
+ /**
227
+ * Creates an issue reference.
228
+ *
229
+ * @param number - The issue or PR number
230
+ * @param type - The type of reference ('issue' or 'pull-request')
231
+ * @param url - Optional URL to the issue or PR
232
+ * @returns A new IssueRef object
233
+ */
234
+ function createIssueRef(number, type = 'issue', url) {
235
+ return {
236
+ number,
237
+ type,
238
+ url,
239
+ };
240
+ }
241
+ /**
242
+ * Extracts the short hash from a full commit hash.
243
+ *
244
+ * @param hash - The full commit hash
245
+ * @returns The first 7 characters of the hash
246
+ */
247
+ function getShortHash(hash) {
248
+ return hash.slice(0, 7);
249
+ }
250
+
251
+ /**
252
+ * Safe copies of Set built-in via factory function.
253
+ *
254
+ * Since constructors cannot be safely captured via Object.assign, this module
255
+ * provides a factory function that uses Reflect.construct internally.
256
+ *
257
+ * These references are captured at module initialization time to protect against
258
+ * prototype pollution attacks. Import only what you need for tree-shaking.
259
+ *
260
+ * @module @hyperfrontend/immutable-api-utils/built-in-copy/set
261
+ */
262
+ // Capture references at module initialization time
263
+ const _Set = globalThis.Set;
264
+ const _Reflect$5 = globalThis.Reflect;
265
+ /**
266
+ * (Safe copy) Creates a new Set using the captured Set constructor.
267
+ * Use this instead of `new Set()`.
268
+ *
269
+ * @param iterable - Optional iterable of values.
270
+ * @returns A new Set instance.
271
+ */
272
+ const createSet = (iterable) => _Reflect$5.construct(_Set, iterable ? [iterable] : []);
273
+
274
+ /**
275
+ * Safe copies of Array built-in static methods.
276
+ *
277
+ * These references are captured at module initialization time to protect against
278
+ * prototype pollution attacks. Import only what you need for tree-shaking.
279
+ *
280
+ * @module @hyperfrontend/immutable-api-utils/built-in-copy/array
281
+ */
282
+ // Capture references at module initialization time
283
+ const _Array = globalThis.Array;
284
+ /**
285
+ * (Safe copy) Determines whether the passed value is an Array.
286
+ */
287
+ const isArray = _Array.isArray;
288
+
289
+ /**
290
+ * Safe copies of Map built-in via factory function.
291
+ *
292
+ * Since constructors cannot be safely captured via Object.assign, this module
293
+ * provides a factory function that uses Reflect.construct internally.
294
+ *
295
+ * These references are captured at module initialization time to protect against
296
+ * prototype pollution attacks. Import only what you need for tree-shaking.
297
+ *
298
+ * @module @hyperfrontend/immutable-api-utils/built-in-copy/map
299
+ */
300
+ // Capture references at module initialization time
301
+ const _Map = globalThis.Map;
302
+ const _Reflect$4 = globalThis.Reflect;
303
+ /**
304
+ * (Safe copy) Creates a new Map using the captured Map constructor.
305
+ * Use this instead of `new Map()`.
306
+ *
307
+ * @param iterable - Optional iterable of key-value pairs.
308
+ * @returns A new Map instance.
309
+ */
310
+ const createMap = (iterable) => _Reflect$4.construct(_Map, iterable ? [iterable] : []);
311
+
312
+ /**
313
+ * Safe copies of Object built-in methods.
314
+ *
315
+ * These references are captured at module initialization time to protect against
316
+ * prototype pollution attacks. Import only what you need for tree-shaking.
317
+ *
318
+ * @module @hyperfrontend/immutable-api-utils/built-in-copy/object
319
+ */
320
+ // Capture references at module initialization time
321
+ const _Object = globalThis.Object;
322
+ const _Reflect$3 = globalThis.Reflect;
323
+ const _ObjectPrototype = _Object.prototype;
324
+ const _hasOwnProperty = _ObjectPrototype.hasOwnProperty;
325
+ /**
326
+ * (Safe copy) Returns the names of the enumerable string properties and methods of an object.
327
+ */
328
+ const keys = _Object.keys;
329
+ /**
330
+ * (Safe copy) Returns an array of key/values of the enumerable own properties of an object.
331
+ */
332
+ const entries = _Object.entries;
333
+ /**
334
+ * (Safe copy) Adds a property to an object, or modifies attributes of an existing property.
335
+ */
336
+ const defineProperty = _Object.defineProperty;
337
+ /**
338
+ * (Safe copy) Safe wrapper for Object.prototype.hasOwnProperty.call().
339
+ * Checks if an object has a property as its own (not inherited) property.
340
+ *
341
+ * @param obj - The object to check.
342
+ * @param key - The property key to check.
343
+ * @returns True if the object has the property as its own property.
344
+ */
345
+ const hasOwn = (obj, key) => _Reflect$3.apply(_hasOwnProperty, obj, [key]);
346
+
347
+ /**
348
+ * Creates a new validation context.
349
+ *
350
+ * @param rootSchema - The root schema being validated against
351
+ * @param validator - The schema validator function
352
+ * @param collectAllErrors - Whether to collect all errors (default: true)
353
+ * @param strictPatterns - Whether to report errors for invalid regex patterns (default: false)
354
+ * @param patternSafetyChecker - Optional pattern safety checker for ReDoS detection
355
+ * @returns A new validation context
356
+ */
357
+ function createValidationContext(rootSchema, validator, collectAllErrors = true, strictPatterns = false, patternSafetyChecker) {
358
+ const definitions = createMap();
359
+ // Pre-populate definitions from root schema
360
+ if (rootSchema.definitions) {
361
+ for (const [name, schema] of entries(rootSchema.definitions)) {
362
+ definitions.set(`#/definitions/${name}`, schema);
363
+ }
364
+ }
365
+ return {
366
+ path: '',
367
+ errors: [],
368
+ rootSchema,
369
+ definitions,
370
+ collectAllErrors,
371
+ strictPatterns,
372
+ patternSafetyChecker,
373
+ validate: validator,
374
+ };
375
+ }
376
+ /**
377
+ * Creates a child context with updated path.
378
+ *
379
+ * @param ctx - Parent context
380
+ * @param segment - Path segment to append
381
+ * @returns New context with updated path
382
+ */
383
+ function pushPath(ctx, segment) {
384
+ const escapedSegment = String(segment).replace(/~/g, '~0').replace(/\//g, '~1');
385
+ return {
386
+ ...ctx,
387
+ path: `${ctx.path}/${escapedSegment}`,
388
+ };
389
+ }
390
+ /**
391
+ * Adds a validation error to the context.
392
+ *
393
+ * @param ctx - Validation context
394
+ * @param message - Human-readable error message
395
+ * @param instance - The failing value
396
+ * @param code - Optional error code for programmatic handling
397
+ * @param params - Optional additional parameters
398
+ */
399
+ function addError(ctx, message, instance, code, params) {
400
+ ctx.errors.push({
401
+ message,
402
+ path: ctx.path || '/',
403
+ instance,
404
+ code,
405
+ params,
406
+ });
407
+ }
408
+ /**
409
+ * Checks if we should continue validation after an error.
410
+ *
411
+ * @param ctx - Validation context
412
+ * @returns true if we should continue, false if we should stop
413
+ */
414
+ function shouldContinue(ctx) {
415
+ return ctx.collectAllErrors || ctx.errors.length === 0;
416
+ }
417
+
418
+ /**
419
+ * Performs deep equality check for JSON values.
420
+ *
421
+ * Used for enum validation and uniqueItems validation.
422
+ *
423
+ * @param a - First value to compare
424
+ * @param b - Second value to compare
425
+ * @returns true if values are deeply equal, false otherwise
426
+ */
427
+ function isEqual(a, b) {
428
+ if (a === b)
429
+ return true;
430
+ if (a === null || b === null)
431
+ return false;
432
+ if (typeof a !== typeof b)
433
+ return false;
434
+ if (typeof a === 'object') {
435
+ if (isArray(a) && isArray(b)) {
436
+ if (a.length !== b.length)
437
+ return false;
438
+ for (let i = 0; i < a.length; i++) {
439
+ if (!isEqual(a[i], b[i]))
440
+ return false;
441
+ }
442
+ return true;
443
+ }
444
+ if (isArray(a) || isArray(b))
445
+ return false;
446
+ const keysA = keys(a);
447
+ const keysB = keys(b);
448
+ if (keysA.length !== keysB.length)
449
+ return false;
450
+ for (const key of keysA) {
451
+ if (!hasOwn(b, key))
452
+ return false;
453
+ if (!isEqual(a[key], b[key]))
454
+ return false;
455
+ }
456
+ return true;
457
+ }
458
+ return false;
459
+ }
460
+
461
+ /**
462
+ * Validates array length and uniqueItems constraints.
463
+ *
464
+ * @param instance - Array being validated
465
+ * @param schema - Schema containing array bounds
466
+ * @param ctx - Validation context
467
+ * @returns true if validation passes, false otherwise
468
+ */
469
+ function validateArrayBounds(instance, schema, ctx) {
470
+ let valid = true;
471
+ if (schema.minItems !== undefined && instance.length < schema.minItems) {
472
+ addError(ctx, `Array must have at least ${schema.minItems} items, got ${instance.length}`, instance, 'minItems', {
473
+ limit: schema.minItems,
474
+ actual: instance.length,
475
+ });
476
+ valid = false;
477
+ if (!shouldContinue(ctx))
478
+ return false;
479
+ }
480
+ if (schema.maxItems !== undefined && instance.length > schema.maxItems) {
481
+ addError(ctx, `Array must have at most ${schema.maxItems} items, got ${instance.length}`, instance, 'maxItems', {
482
+ limit: schema.maxItems,
483
+ actual: instance.length,
484
+ });
485
+ valid = false;
486
+ if (!shouldContinue(ctx))
487
+ return false;
488
+ }
489
+ if (schema.uniqueItems === true) {
490
+ // Check for duplicates
491
+ for (let i = 0; i < instance.length; i++) {
492
+ for (let j = i + 1; j < instance.length; j++) {
493
+ if (isEqual(instance[i], instance[j])) {
494
+ addError(ctx, `Array items must be unique. Duplicate found at indices ${i} and ${j}`, instance, 'uniqueItems');
495
+ valid = false;
496
+ if (!shouldContinue(ctx))
497
+ return false;
498
+ }
499
+ }
500
+ }
501
+ }
502
+ return valid;
503
+ }
504
+
505
+ /**
506
+ * Validates 'allOf' keyword - all schemas must match.
507
+ *
508
+ * @param instance - Value being validated
509
+ * @param schema - Schema containing the allOf constraint
510
+ * @param ctx - Validation context
511
+ * @returns true if validation passes, false otherwise
512
+ */
513
+ function validateAllOf(instance, schema, ctx) {
514
+ const allOf = schema.allOf;
515
+ if (!allOf || allOf.length === 0) {
516
+ return true;
517
+ }
518
+ let valid = true;
519
+ for (let i = 0; i < allOf.length; i++) {
520
+ const subSchema = allOf[i];
521
+ /* istanbul ignore if -- defensive null check for sparse arrays */
522
+ if (!subSchema)
523
+ continue;
524
+ if (!ctx.validate(instance, subSchema, ctx)) {
525
+ valid = false;
526
+ if (!shouldContinue(ctx))
527
+ return false;
528
+ }
529
+ }
530
+ return valid;
531
+ }
532
+ /**
533
+ * Validates 'anyOf' keyword - at least one schema must match.
534
+ *
535
+ * @param instance - Value being validated
536
+ * @param schema - Schema containing the anyOf constraint
537
+ * @param ctx - Validation context
538
+ * @returns true if validation passes, false otherwise
539
+ */
540
+ function validateAnyOf(instance, schema, ctx) {
541
+ const anyOf = schema.anyOf;
542
+ if (!anyOf || anyOf.length === 0) {
543
+ return true;
544
+ }
545
+ // Try each schema - if any matches, we pass
546
+ for (const subSchema of anyOf) {
547
+ const subCtx = createValidationContext(ctx.rootSchema, ctx.validate, false);
548
+ // Copy path from parent context
549
+ defineProperty(subCtx, 'path', { value: ctx.path, writable: false });
550
+ if (ctx.validate(instance, subSchema, subCtx)) {
551
+ return true;
552
+ }
553
+ }
554
+ addError(ctx, 'Value does not match any of the allowed schemas (anyOf)', instance, 'anyOf');
555
+ return false;
556
+ }
557
+ /**
558
+ * Validates 'oneOf' keyword - exactly one schema must match.
559
+ *
560
+ * @param instance - Value being validated
561
+ * @param schema - Schema containing the oneOf constraint
562
+ * @param ctx - Validation context
563
+ * @returns true if validation passes, false otherwise
564
+ */
565
+ function validateOneOf(instance, schema, ctx) {
566
+ const oneOf = schema.oneOf;
567
+ if (!oneOf || oneOf.length === 0) {
568
+ return true;
569
+ }
570
+ let matchCount = 0;
571
+ for (const subSchema of oneOf) {
572
+ const subCtx = createValidationContext(ctx.rootSchema, ctx.validate, false);
573
+ defineProperty(subCtx, 'path', { value: ctx.path, writable: false });
574
+ if (ctx.validate(instance, subSchema, subCtx)) {
575
+ matchCount++;
576
+ if (matchCount > 1)
577
+ break; // Early exit if more than one match
578
+ }
579
+ }
580
+ if (matchCount === 1) {
581
+ return true;
582
+ }
583
+ if (matchCount === 0) {
584
+ addError(ctx, 'Value does not match any of the schemas (oneOf)', instance, 'oneOf');
585
+ }
586
+ else {
587
+ addError(ctx, `Value matches ${matchCount} schemas but must match exactly one (oneOf)`, instance, 'oneOf', {
588
+ matches: matchCount,
589
+ });
590
+ }
591
+ return false;
592
+ }
593
+ /**
594
+ * Validates 'not' keyword - schema must NOT match.
595
+ *
596
+ * @param instance - Value being validated
597
+ * @param schema - Schema containing the not constraint
598
+ * @param ctx - Validation context
599
+ * @returns true if validation passes, false otherwise
600
+ */
601
+ function validateNot(instance, schema, ctx) {
602
+ const not = schema.not;
603
+ if (!not) {
604
+ return true;
605
+ }
606
+ const subCtx = createValidationContext(ctx.rootSchema, ctx.validate, false);
607
+ defineProperty(subCtx, 'path', { value: ctx.path, writable: false });
608
+ if (ctx.validate(instance, not, subCtx)) {
609
+ // Schema matched when it shouldn't have
610
+ addError(ctx, 'Value should NOT match the schema', instance, 'not');
611
+ return false;
612
+ }
613
+ return true;
614
+ }
615
+
616
+ /**
617
+ * Validates object 'dependencies' keyword.
618
+ *
619
+ * @param instance - Object being validated
620
+ * @param schema - Schema containing the dependencies constraint
621
+ * @param ctx - Validation context
622
+ * @returns true if validation passes, false otherwise
623
+ */
624
+ function validateDependencies(instance, schema, ctx) {
625
+ if (!schema.dependencies) {
626
+ return true;
627
+ }
628
+ let valid = true;
629
+ for (const [key, dependency] of entries(schema.dependencies)) {
630
+ // Only check dependency if the key is present
631
+ /* istanbul ignore next -- key presence check */
632
+ if (!hasOwn(instance, key)) {
633
+ continue;
634
+ }
635
+ /* istanbul ignore next -- dependency type check */
636
+ if (isArray(dependency)) {
637
+ // Property dependency: if key is present, these properties must also be present
638
+ for (const requiredKey of dependency) {
639
+ /* istanbul ignore next -- required key check */
640
+ if (!hasOwn(instance, requiredKey)) {
641
+ addError(ctx, `Property '${key}' requires property '${requiredKey}' to also be present`, instance, 'dependencies', {
642
+ property: key,
643
+ /* istanbul ignore next -- required key assignment */
644
+ required: requiredKey,
645
+ });
646
+ valid = false;
647
+ /* istanbul ignore if -- early exit tested in validate.spec.ts */
648
+ if (!shouldContinue(ctx))
649
+ return false;
650
+ }
651
+ }
652
+ }
653
+ else {
654
+ // Schema dependency: if key is present, the object must also validate against this schema
655
+ /* istanbul ignore next -- schema dependency validation */
656
+ if (!ctx.validate(instance, dependency, ctx)) {
657
+ /* istanbul ignore next -- failure path */
658
+ valid = false;
659
+ /* istanbul ignore if -- early exit tested in validate.spec.ts */
660
+ if (!shouldContinue(ctx))
661
+ return false;
662
+ }
663
+ }
664
+ }
665
+ return valid;
666
+ }
667
+
668
+ /**
669
+ * Safe copies of JSON built-in methods.
670
+ *
671
+ * These references are captured at module initialization time to protect against
672
+ * prototype pollution attacks. Import only what you need for tree-shaking.
673
+ *
674
+ * @module @hyperfrontend/immutable-api-utils/built-in-copy/json
675
+ */
676
+ // Capture references at module initialization time
677
+ const _JSON = globalThis.JSON;
678
+ /**
679
+ * (Safe copy) Converts a JavaScript value to a JavaScript Object Notation (JSON) string.
680
+ */
681
+ const stringify = _JSON.stringify;
682
+
683
+ /**
684
+ * Validates enum constraint.
685
+ *
686
+ * @param instance - Value being validated
687
+ * @param schema - Schema containing the enum constraint
688
+ * @param ctx - Validation context
689
+ * @returns true if validation passes, false otherwise
690
+ */
691
+ function validateEnum(instance, schema, ctx) {
692
+ if (!schema.enum) {
693
+ return true;
694
+ }
695
+ for (const enumValue of schema.enum) {
696
+ if (isEqual(instance, enumValue)) {
697
+ return true;
698
+ }
699
+ }
700
+ const allowedValues = schema.enum.map((v) => stringify(v)).join(', ');
701
+ addError(ctx, `Value must be one of: ${allowedValues}`, instance, 'enum', {
702
+ allowedValues: schema.enum,
703
+ });
704
+ return false;
705
+ }
706
+
707
+ /**
708
+ * Safe copies of Date built-in via factory function and static methods.
709
+ *
710
+ * Since constructors cannot be safely captured via Object.assign, this module
711
+ * provides a factory function that uses Reflect.construct internally.
712
+ *
713
+ * These references are captured at module initialization time to protect against
714
+ * prototype pollution attacks. Import only what you need for tree-shaking.
715
+ *
716
+ * @module @hyperfrontend/immutable-api-utils/built-in-copy/date
717
+ */
718
+ // Capture references at module initialization time
719
+ const _Date = globalThis.Date;
720
+ const _Reflect$2 = globalThis.Reflect;
721
+ function createDate(...args) {
722
+ return _Reflect$2.construct(_Date, args);
723
+ }
724
+ /**
725
+ * (Safe copy) Parses a string representation of a date.
726
+ */
727
+ const dateParse = _Date.parse;
728
+ /**
729
+ * (Safe copy) Returns the number of milliseconds in a Date object since January 1, 1970 UTC.
730
+ */
731
+ const dateUTC = _Date.UTC;
732
+
733
+ /**
734
+ * Safe copies of Number built-in methods and constants.
735
+ *
736
+ * These references are captured at module initialization time to protect against
737
+ * prototype pollution attacks. Import only what you need for tree-shaking.
738
+ *
739
+ * @module @hyperfrontend/immutable-api-utils/built-in-copy/number
740
+ */
741
+ // Capture references at module initialization time
742
+ const _Number = globalThis.Number;
743
+ const _parseInt = globalThis.parseInt;
744
+ const _isNaN = globalThis.isNaN;
745
+ const _isFinite = globalThis.isFinite;
746
+ /**
747
+ * (Safe copy) Determines whether the passed value is an integer.
748
+ */
749
+ const isInteger = _Number.isInteger;
750
+ // ============================================================================
751
+ // Parsing
752
+ // ============================================================================
753
+ /**
754
+ * (Safe copy) Parses a string and returns an integer.
755
+ */
756
+ const parseInt = _parseInt;
757
+ // ============================================================================
758
+ // Global Type Checking (legacy, less strict)
759
+ // ============================================================================
760
+ /**
761
+ * (Safe copy) Global isNaN function (coerces to number first, less strict than Number.isNaN).
762
+ */
763
+ const globalIsNaN = _isNaN;
764
+ /**
765
+ * (Safe copy) Global isFinite function (coerces to number first, less strict than Number.isFinite).
766
+ */
767
+ const globalIsFinite = _isFinite;
768
+
769
+ /**
770
+ * Safe copies of RegExp built-in via factory function.
771
+ *
772
+ * Since constructors cannot be safely captured via Object.assign, this module
773
+ * provides a factory function that uses Reflect.construct internally.
774
+ *
775
+ * These references are captured at module initialization time to protect against
776
+ * prototype pollution attacks. Import only what you need for tree-shaking.
777
+ *
778
+ * @module @hyperfrontend/immutable-api-utils/built-in-copy/regexp
779
+ */
780
+ // Capture references at module initialization time
781
+ const _RegExp = globalThis.RegExp;
782
+ const _Reflect$1 = globalThis.Reflect;
783
+ /**
784
+ * (Safe copy) Creates a new RegExp using the captured RegExp constructor.
785
+ * Use this instead of `new RegExp()`.
786
+ *
787
+ * @param pattern - The pattern string or RegExp to copy.
788
+ * @param flags - Optional flags string.
789
+ * @returns A new RegExp instance.
790
+ */
791
+ const createRegExp = (pattern, flags) => _Reflect$1.construct(_RegExp, [pattern, flags]);
792
+
793
+ /**
794
+ * Safe copies of URL built-ins via factory functions.
795
+ *
796
+ * Provides safe references to URL and URLSearchParams.
797
+ * These references are captured at module initialization time to protect against
798
+ * prototype pollution attacks. Import only what you need for tree-shaking.
799
+ *
800
+ * @module @hyperfrontend/immutable-api-utils/built-in-copy/url
801
+ */
802
+ // Capture references at module initialization time
803
+ const _URL = globalThis.URL;
804
+ const _Reflect = globalThis.Reflect;
805
+ // ============================================================================
806
+ // URL
807
+ // ============================================================================
808
+ /**
809
+ * (Safe copy) Creates a new URL using the captured URL constructor.
810
+ * Use this instead of `new URL()`.
811
+ *
812
+ * @param url - The URL string to parse.
813
+ * @param base - Optional base URL for relative URLs.
814
+ * @returns A new URL instance.
815
+ */
816
+ const createURL = (url, base) => _Reflect.construct(_URL, [url, base]);
817
+ /**
818
+ * (Safe copy) Creates an object URL for the given object.
819
+ * Use this instead of `URL.createObjectURL()`.
820
+ *
821
+ * Note: This is a browser-only API. In Node.js environments, this will throw.
822
+ */
823
+ typeof _URL.createObjectURL === 'function'
824
+ ? _URL.createObjectURL.bind(_URL)
825
+ : () => {
826
+ throw new Error('URL.createObjectURL is not available in this environment');
827
+ };
828
+ /**
829
+ * (Safe copy) Revokes an object URL previously created with createObjectURL.
830
+ * Use this instead of `URL.revokeObjectURL()`.
831
+ *
832
+ * Note: This is a browser-only API. In Node.js environments, this will throw.
833
+ */
834
+ typeof _URL.revokeObjectURL === 'function'
835
+ ? _URL.revokeObjectURL.bind(_URL)
836
+ : () => {
837
+ throw new Error('URL.revokeObjectURL is not available in this environment');
838
+ };
839
+
840
+ /**
841
+ * Format validators for common string formats.
842
+ */
843
+ const formatValidators = {
844
+ 'date-time': (v) => {
845
+ // ISO 8601 date-time format - anchored to prevent matching at unexpected locations
846
+ if (!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/.test(v))
847
+ return false;
848
+ const date = dateParse(v);
849
+ return !globalIsNaN(date);
850
+ },
851
+ date: (v) => {
852
+ // ISO 8601 date format (YYYY-MM-DD)
853
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(v))
854
+ return false;
855
+ const [year, month, day] = v.split('-').map(Number);
856
+ const date = createDate(dateUTC(year, month - 1, day));
857
+ // Check that the date components match exactly
858
+ return date.getUTCFullYear() === year && date.getUTCMonth() === month - 1 && date.getUTCDate() === day;
859
+ },
860
+ time: (v) => {
861
+ // ISO 8601 time format (HH:MM:SS or HH:MM:SS.sss with optional timezone)
862
+ // Parse segments to avoid nested quantifiers
863
+ const mainMatch = v.match(/^(\d{2}):(\d{2}):(\d{2})/);
864
+ if (!mainMatch)
865
+ return false;
866
+ const hour = Number(mainMatch[1]);
867
+ const minute = Number(mainMatch[2]);
868
+ const second = Number(mainMatch[3]);
869
+ if (hour > 23 || minute > 59 || second > 59)
870
+ return false;
871
+ // Validate remaining part (fractional seconds and/or timezone)
872
+ const rest = v.slice(8);
873
+ if (rest === '')
874
+ return true;
875
+ // Fractional seconds: .ddd where d is digits (1-6 typically)
876
+ if (rest.match(/^\.\d{1,9}$/))
877
+ return true;
878
+ // Timezone only: Z or +HH:MM or -HH:MM
879
+ if (rest.match(/^(Z|[+-]\d{2}:\d{2})$/))
880
+ return true;
881
+ // Fractional + timezone
882
+ if (rest.match(/^\.\d{1,9}(Z|[+-]\d{2}:\d{2})$/))
883
+ return true;
884
+ return false;
885
+ },
886
+ email: (v) => {
887
+ // Basic email validation - fixed to prevent ReDoS by excluding dots from domain part
888
+ return /^[^\s@]+@[^\s@.]+\.[^\s@.]+$/.test(v);
889
+ },
890
+ hostname: (v) => {
891
+ // RFC 1123 hostname - validated per label to prevent ReDoS
892
+ if (v.length > 253 || v.length === 0)
893
+ return false; // Max hostname length per RFC
894
+ const labels = v.split('.');
895
+ for (const label of labels) {
896
+ if (label.length === 0 || label.length > 63)
897
+ return false;
898
+ // Start and end with alphanumeric
899
+ if (!/^[a-zA-Z0-9]$/.test(label[0]))
900
+ return false;
901
+ if (label.length > 1 && !/^[a-zA-Z0-9]$/.test(label[label.length - 1]))
902
+ return false;
903
+ // Middle can include hyphens
904
+ for (let i = 1; i < label.length - 1; i++) {
905
+ if (!/^[a-zA-Z0-9-]$/.test(label[i]))
906
+ return false;
907
+ }
908
+ }
909
+ return true;
910
+ },
911
+ ipv4: (v) => {
912
+ // IPv4 address
913
+ const parts = v.split('.');
914
+ if (parts.length !== 4)
915
+ return false;
916
+ return parts.every((part) => {
917
+ const num = parseInt(part, 10);
918
+ return !globalIsNaN(num) && num >= 0 && num <= 255 && part === String(num);
919
+ });
920
+ },
921
+ ipv6: (v) => {
922
+ // Simplified IPv6 validation - procedural approach to avoid ReDoS
923
+ if (v === '::')
924
+ return true;
925
+ // Check for double colon (compressed form)
926
+ const hasDoubleColon = v.includes('::');
927
+ if (!hasDoubleColon) {
928
+ // Full form: exactly 8 groups separated by single colons
929
+ const groups = v.split(':');
930
+ if (groups.length !== 8)
931
+ return false;
932
+ const hexGroup = /^[0-9a-fA-F]{1,4}$/;
933
+ return groups.every((g) => hexGroup.test(g));
934
+ }
935
+ // Compressed form: validate :: appears exactly once and total groups <= 8
936
+ const parts = v.split('::');
937
+ if (parts.length !== 2)
938
+ return false;
939
+ const left = parts[0] ? parts[0].split(':').filter(Boolean) : [];
940
+ const right = parts[1] ? parts[1].split(':').filter(Boolean) : [];
941
+ if (left.length + right.length > 7)
942
+ return false;
943
+ const hexGroup = /^[0-9a-fA-F]{1,4}$/;
944
+ return left.every((g) => hexGroup.test(g)) && right.every((g) => hexGroup.test(g));
945
+ },
946
+ uri: (v) => {
947
+ // Basic URI validation
948
+ try {
949
+ createURL(v);
950
+ return true;
951
+ /* istanbul ignore next -- URL constructor always throws for invalid URI */
952
+ }
953
+ catch {
954
+ return false;
955
+ }
956
+ },
957
+ 'uri-reference': (v) => {
958
+ // URI or relative reference
959
+ try {
960
+ createURL(v, 'http://example.com');
961
+ /* istanbul ignore next -- success path just returns true */
962
+ return true;
963
+ }
964
+ catch {
965
+ /* istanbul ignore next -- URL constructor is very permissive with base URL */
966
+ return false;
967
+ }
968
+ },
969
+ uuid: (v) => {
970
+ // UUID format
971
+ return /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/.test(v);
972
+ },
973
+ regex: (v) => {
974
+ // Valid regex pattern
975
+ try {
976
+ // eslint-disable-next-line workspace/no-unsafe-regex -- intentionally validating user-provided regex patterns
977
+ createRegExp(v);
978
+ return true;
979
+ }
980
+ catch {
981
+ return false;
982
+ }
983
+ },
984
+ 'json-pointer': (v) => {
985
+ // JSON Pointer format - validate segment by segment to avoid nested quantifiers
986
+ if (v === '')
987
+ return true;
988
+ if (!v.startsWith('/'))
989
+ return false;
990
+ const segments = v.slice(1).split('/');
991
+ const validSegment = /^([^/~]|~[01])*$/;
992
+ return segments.every((seg) => validSegment.test(seg));
993
+ },
994
+ };
995
+ /**
996
+ * Validates string format constraint.
997
+ *
998
+ * @param instance - String being validated
999
+ * @param schema - Schema containing the format constraint
1000
+ * @param ctx - Validation context
1001
+ * @returns true if validation passes, false otherwise
1002
+ */
1003
+ function validateFormat(instance, schema, ctx) {
1004
+ if (!schema.format) {
1005
+ return true;
1006
+ }
1007
+ const validator = formatValidators[schema.format];
1008
+ if (!validator) {
1009
+ // Unknown format - allow by default (as per JSON Schema spec)
1010
+ return true;
1011
+ }
1012
+ if (!validator(instance)) {
1013
+ addError(ctx, `String does not match format '${schema.format}'`, instance, 'format', {
1014
+ format: schema.format,
1015
+ });
1016
+ return false;
1017
+ }
1018
+ return true;
1019
+ }
1020
+
1021
+ /**
1022
+ * Validates array 'items' keyword.
1023
+ *
1024
+ * @param instance - Array being validated
1025
+ * @param schema - Schema containing the items constraint
1026
+ * @param ctx - Validation context
1027
+ * @returns true if validation passes, false otherwise
1028
+ */
1029
+ function validateItems(instance, schema, ctx) {
1030
+ const items = schema.items;
1031
+ if (items === undefined) {
1032
+ return true;
1033
+ }
1034
+ let valid = true;
1035
+ if (isArray(items)) {
1036
+ // Tuple validation
1037
+ for (let i = 0; i < items.length && i < instance.length; i++) {
1038
+ const itemSchema = items[i];
1039
+ /* istanbul ignore if -- defensive null check for sparse arrays */
1040
+ if (!itemSchema)
1041
+ continue;
1042
+ const itemCtx = pushPath(ctx, i);
1043
+ if (!ctx.validate(instance[i], itemSchema, itemCtx)) {
1044
+ valid = false;
1045
+ /* istanbul ignore if -- early exit already tested in validate.spec.ts */
1046
+ if (!shouldContinue(ctx))
1047
+ return false;
1048
+ }
1049
+ }
1050
+ // Handle additional items beyond the tuple
1051
+ if (instance.length > items.length) {
1052
+ if (!validateAdditionalItems(instance, schema, ctx, items.length)) {
1053
+ valid = false;
1054
+ }
1055
+ }
1056
+ }
1057
+ else {
1058
+ // All items must match the single schema
1059
+ for (let i = 0; i < instance.length; i++) {
1060
+ const itemCtx = pushPath(ctx, i);
1061
+ if (!ctx.validate(instance[i], items, itemCtx)) {
1062
+ valid = false;
1063
+ if (!shouldContinue(ctx))
1064
+ return false;
1065
+ }
1066
+ }
1067
+ }
1068
+ return valid;
1069
+ }
1070
+ /**
1071
+ * Validates 'additionalItems' keyword for tuple arrays.
1072
+ *
1073
+ * @param instance - Array being validated
1074
+ * @param schema - Schema containing the additionalItems constraint
1075
+ * @param ctx - Validation context
1076
+ * @param startIndex - Index from which to start checking additional items
1077
+ * @returns true if validation passes, false otherwise
1078
+ */
1079
+ function validateAdditionalItems(instance, schema, ctx, startIndex) {
1080
+ const additionalItems = schema.additionalItems;
1081
+ // If not specified, additional items are allowed
1082
+ /* istanbul ignore if -- default case handled in items.spec.ts */
1083
+ if (additionalItems === undefined) {
1084
+ return true;
1085
+ }
1086
+ /* istanbul ignore next -- additionalItems initialization and branching */
1087
+ let valid = true;
1088
+ /* istanbul ignore next -- additionalItems branching */
1089
+ if (additionalItems === false) {
1090
+ // No additional items allowed
1091
+ if (instance.length > startIndex) {
1092
+ addError(ctx, `Array has too many items. Expected at most ${startIndex}, got ${instance.length}`, instance, 'additionalItems', {
1093
+ limit: startIndex,
1094
+ actual: instance.length,
1095
+ });
1096
+ valid = false;
1097
+ }
1098
+ }
1099
+ else if (typeof additionalItems === 'object') {
1100
+ // Additional items must match the schema
1101
+ for (let i = startIndex; i < instance.length; i++) {
1102
+ const itemCtx = pushPath(ctx, i);
1103
+ /* istanbul ignore else -- validation failure tested in items.spec.ts */
1104
+ if (!ctx.validate(instance[i], additionalItems, itemCtx)) {
1105
+ valid = false;
1106
+ /* istanbul ignore if -- early exit tested in validate.spec.ts */
1107
+ if (!shouldContinue(ctx))
1108
+ return false;
1109
+ }
1110
+ }
1111
+ }
1112
+ // If additionalItems === true, any additional items are allowed
1113
+ return valid;
1114
+ }
1115
+
1116
+ /**
1117
+ * Safe copies of Math built-in methods.
1118
+ *
1119
+ * These references are captured at module initialization time to protect against
1120
+ * prototype pollution attacks. Import only what you need for tree-shaking.
1121
+ *
1122
+ * @module @hyperfrontend/immutable-api-utils/built-in-copy/math
1123
+ */
1124
+ // Capture references at module initialization time
1125
+ const _Math = globalThis.Math;
1126
+ // ============================================================================
1127
+ // Basic Operations
1128
+ // ============================================================================
1129
+ /**
1130
+ * (Safe copy) Returns the absolute value of a number.
1131
+ */
1132
+ const abs = _Math.abs;
1133
+
1134
+ /**
1135
+ * Validates number range and multipleOf constraints.
1136
+ *
1137
+ * @param instance - Number being validated
1138
+ * @param schema - Schema containing number constraints
1139
+ * @param ctx - Validation context
1140
+ * @returns true if validation passes, false otherwise
1141
+ */
1142
+ function validateNumberBounds(instance, schema, ctx) {
1143
+ let valid = true;
1144
+ if (schema.minimum !== undefined) {
1145
+ const isExclusive = schema.exclusiveMinimum === true;
1146
+ if (isExclusive ? instance <= schema.minimum : instance < schema.minimum) {
1147
+ const comparison = isExclusive ? 'greater than' : 'at least';
1148
+ addError(ctx, `Number must be ${comparison} ${schema.minimum}, got ${instance}`, instance, 'minimum', {
1149
+ limit: schema.minimum,
1150
+ exclusive: isExclusive,
1151
+ actual: instance,
1152
+ });
1153
+ valid = false;
1154
+ if (!shouldContinue(ctx))
1155
+ return false;
1156
+ }
1157
+ }
1158
+ if (schema.maximum !== undefined) {
1159
+ const isExclusive = schema.exclusiveMaximum === true;
1160
+ if (isExclusive ? instance >= schema.maximum : instance > schema.maximum) {
1161
+ const comparison = isExclusive ? 'less than' : 'at most';
1162
+ addError(ctx, `Number must be ${comparison} ${schema.maximum}, got ${instance}`, instance, 'maximum', {
1163
+ limit: schema.maximum,
1164
+ exclusive: isExclusive,
1165
+ actual: instance,
1166
+ });
1167
+ valid = false;
1168
+ if (!shouldContinue(ctx))
1169
+ return false;
1170
+ }
1171
+ }
1172
+ if (schema.multipleOf !== undefined && schema.multipleOf > 0) {
1173
+ // Use epsilon comparison for floating point precision
1174
+ const remainder = abs(instance % schema.multipleOf);
1175
+ const epsilon = 1e-10;
1176
+ if (remainder > epsilon && schema.multipleOf - remainder > epsilon) {
1177
+ addError(ctx, `Number must be a multiple of ${schema.multipleOf}, got ${instance}`, instance, 'multipleOf', {
1178
+ multipleOf: schema.multipleOf,
1179
+ actual: instance,
1180
+ });
1181
+ valid = false;
1182
+ if (!shouldContinue(ctx))
1183
+ return false;
1184
+ }
1185
+ }
1186
+ return valid;
1187
+ }
1188
+
1189
+ /**
1190
+ * Validates object bounds constraints (minProperties, maxProperties).
1191
+ *
1192
+ * @param instance - Object being validated
1193
+ * @param schema - Schema containing object bounds
1194
+ * @param ctx - Validation context
1195
+ * @returns true if validation passes, false otherwise
1196
+ */
1197
+ function validateObjectBounds(instance, schema, ctx) {
1198
+ let valid = true;
1199
+ const propertyCount = keys(instance).length;
1200
+ if (schema.minProperties !== undefined && propertyCount < schema.minProperties) {
1201
+ addError(ctx, `Object must have at least ${schema.minProperties} properties, got ${propertyCount}`, instance, 'minProperties', {
1202
+ limit: schema.minProperties,
1203
+ actual: propertyCount,
1204
+ });
1205
+ valid = false;
1206
+ if (!shouldContinue(ctx))
1207
+ return false;
1208
+ }
1209
+ if (schema.maxProperties !== undefined && propertyCount > schema.maxProperties) {
1210
+ addError(ctx, `Object must have at most ${schema.maxProperties} properties, got ${propertyCount}`, instance, 'maxProperties', {
1211
+ limit: schema.maxProperties,
1212
+ actual: propertyCount,
1213
+ });
1214
+ valid = false;
1215
+ if (!shouldContinue(ctx))
1216
+ return false;
1217
+ }
1218
+ return valid;
1219
+ }
1220
+
1221
+ /**
1222
+ * Validates object 'patternProperties' keyword.
1223
+ *
1224
+ * @param instance - Object being validated
1225
+ * @param schema - Schema containing the patternProperties constraint
1226
+ * @param ctx - Validation context
1227
+ * @returns true if validation passes, false otherwise
1228
+ */
1229
+ function validatePatternProperties(instance, schema, ctx) {
1230
+ if (!schema.patternProperties) {
1231
+ return true;
1232
+ }
1233
+ let valid = true;
1234
+ const patterns = [];
1235
+ // Pre-compile all patterns
1236
+ for (const [pattern, patternSchema] of entries(schema.patternProperties)) {
1237
+ // Check pattern safety if a checker is configured
1238
+ /* istanbul ignore if -- patternSafetyChecker branch tested in validate.spec.ts */
1239
+ if (ctx.patternSafetyChecker) {
1240
+ const safetyResult = ctx.patternSafetyChecker(pattern);
1241
+ if (!safetyResult.safe) {
1242
+ addError(ctx, `Unsafe regex pattern in patternProperties: ${safetyResult.reason ?? 'Pattern may cause ReDoS'}`, instance, 'patternProperties', {
1243
+ pattern,
1244
+ reason: safetyResult.reason,
1245
+ });
1246
+ valid = false;
1247
+ if (!shouldContinue(ctx))
1248
+ return false;
1249
+ continue; // Skip this unsafe pattern
1250
+ }
1251
+ }
1252
+ try {
1253
+ // eslint-disable-next-line workspace/no-unsafe-regex -- Pattern safety validated above when safePatterns enabled
1254
+ patterns.push({ regex: createRegExp(pattern), schema: patternSchema });
1255
+ }
1256
+ catch (e) {
1257
+ // Invalid regex
1258
+ /* istanbul ignore next -- strictPatterns mode verified in validate.spec.ts */
1259
+ if (ctx.strictPatterns) {
1260
+ /* istanbul ignore next -- error reporting for invalid regex */
1261
+ addError(ctx, `Invalid regex pattern in patternProperties: ${pattern}`, instance, 'patternProperties', {
1262
+ /* istanbul ignore next -- error message extraction */
1263
+ pattern,
1264
+ /* istanbul ignore next -- ternary expression */
1265
+ error: e instanceof Error ? e.message : 'Invalid regex',
1266
+ });
1267
+ valid = false;
1268
+ /* istanbul ignore if -- early exit tested in validate.spec.ts */
1269
+ if (!shouldContinue(ctx))
1270
+ return false;
1271
+ }
1272
+ // Otherwise skip silently
1273
+ }
1274
+ }
1275
+ // Check each property against matching patterns
1276
+ for (const key of keys(instance)) {
1277
+ for (const { regex, schema: patternSchema } of patterns) {
1278
+ if (regex.test(key)) {
1279
+ const propCtx = pushPath(ctx, key);
1280
+ if (!ctx.validate(instance[key], patternSchema, propCtx)) {
1281
+ valid = false;
1282
+ if (!shouldContinue(ctx))
1283
+ return false;
1284
+ }
1285
+ }
1286
+ }
1287
+ }
1288
+ return valid;
1289
+ }
1290
+
1291
+ /**
1292
+ * Validates object 'properties' keyword.
1293
+ *
1294
+ * @param instance - Object being validated
1295
+ * @param schema - Schema containing the properties constraint
1296
+ * @param ctx - Validation context
1297
+ * @returns true if validation passes, false otherwise
1298
+ */
1299
+ function validateProperties(instance, schema, ctx) {
1300
+ if (!schema.properties) {
1301
+ return true;
1302
+ }
1303
+ let valid = true;
1304
+ for (const [key, propSchema] of entries(schema.properties)) {
1305
+ if (hasOwn(instance, key)) {
1306
+ const propCtx = pushPath(ctx, key);
1307
+ if (!ctx.validate(instance[key], propSchema, propCtx)) {
1308
+ valid = false;
1309
+ if (!shouldContinue(ctx))
1310
+ return false;
1311
+ }
1312
+ }
1313
+ }
1314
+ return valid;
1315
+ }
1316
+ /**
1317
+ * Validates object 'required' keyword.
1318
+ *
1319
+ * @param instance - Object being validated
1320
+ * @param schema - Schema containing the required constraint
1321
+ * @param ctx - Validation context
1322
+ * @returns true if validation passes, false otherwise
1323
+ */
1324
+ function validateRequired(instance, schema, ctx) {
1325
+ if (!schema.required) {
1326
+ return true;
1327
+ }
1328
+ let valid = true;
1329
+ for (const key of schema.required) {
1330
+ if (!hasOwn(instance, key)) {
1331
+ addError(ctx, `Missing required property: ${key}`, undefined, 'required', { missing: key });
1332
+ valid = false;
1333
+ if (!shouldContinue(ctx))
1334
+ return false;
1335
+ }
1336
+ }
1337
+ return valid;
1338
+ }
1339
+ /**
1340
+ * Validates object 'additionalProperties' keyword.
1341
+ *
1342
+ * @param instance - Object being validated
1343
+ * @param schema - Schema containing the additionalProperties constraint
1344
+ * @param ctx - Validation context
1345
+ * @returns true if validation passes, false otherwise
1346
+ */
1347
+ function validateAdditionalProperties(instance, schema, ctx) {
1348
+ const additionalProperties = schema.additionalProperties;
1349
+ if (additionalProperties === undefined) {
1350
+ return true;
1351
+ }
1352
+ /* istanbul ignore next -- definedKeys initialization */
1353
+ // Collect defined property names
1354
+ const definedKeys = createSet();
1355
+ /* istanbul ignore next -- schema.properties may not exist */
1356
+ if (schema.properties) {
1357
+ for (const key of keys(schema.properties)) {
1358
+ definedKeys.add(key);
1359
+ }
1360
+ }
1361
+ // Collect pattern property regexes
1362
+ const patterns = [];
1363
+ /* istanbul ignore next -- patternProperties may not always be present */
1364
+ if (schema.patternProperties) {
1365
+ for (const pattern of keys(schema.patternProperties)) {
1366
+ // Skip unsafe patterns if a checker is configured (already reported in patternProperties validator)
1367
+ if (ctx.patternSafetyChecker) {
1368
+ const safetyResult = ctx.patternSafetyChecker(pattern);
1369
+ if (!safetyResult.safe) {
1370
+ continue; // Skip this unsafe pattern
1371
+ }
1372
+ }
1373
+ try {
1374
+ // eslint-disable-next-line workspace/no-unsafe-regex -- Pattern safety validated above when safePatterns enabled
1375
+ patterns.push(createRegExp(pattern));
1376
+ /* istanbul ignore next -- invalid regex patterns handled in patternProperties validator */
1377
+ }
1378
+ catch {
1379
+ // Invalid regex, skip
1380
+ }
1381
+ }
1382
+ }
1383
+ let valid = true;
1384
+ for (const key of keys(instance)) {
1385
+ // Skip if property is defined in 'properties'
1386
+ if (definedKeys.has(key)) {
1387
+ continue;
1388
+ }
1389
+ // Skip if property matches any pattern in 'patternProperties'
1390
+ if (patterns.some((p) => p.test(key))) {
1391
+ continue;
1392
+ }
1393
+ // This is an additional property
1394
+ if (additionalProperties === false) {
1395
+ addError(ctx, `Additional property not allowed: ${key}`, instance[key], 'additionalProperties', {
1396
+ property: key,
1397
+ });
1398
+ valid = false;
1399
+ /* istanbul ignore if -- early exit tested in validate.spec.ts */
1400
+ if (!shouldContinue(ctx))
1401
+ return false;
1402
+ }
1403
+ else if (typeof additionalProperties === 'object') {
1404
+ const propCtx = pushPath(ctx, key);
1405
+ if (!ctx.validate(instance[key], additionalProperties, propCtx)) {
1406
+ valid = false;
1407
+ /* istanbul ignore if -- early exit tested in validate.spec.ts */
1408
+ if (!shouldContinue(ctx))
1409
+ return false;
1410
+ }
1411
+ }
1412
+ // If additionalProperties === true, any additional property is allowed
1413
+ }
1414
+ return valid;
1415
+ }
1416
+
1417
+ /**
1418
+ * Validates string length and pattern constraints.
1419
+ *
1420
+ * @param instance - String being validated
1421
+ * @param schema - Schema containing string constraints
1422
+ * @param ctx - Validation context
1423
+ * @returns true if validation passes, false otherwise
1424
+ */
1425
+ function validateStringBounds(instance, schema, ctx) {
1426
+ let valid = true;
1427
+ if (schema.minLength !== undefined && instance.length < schema.minLength) {
1428
+ addError(ctx, `String must be at least ${schema.minLength} characters, got ${instance.length}`, instance, 'minLength', {
1429
+ limit: schema.minLength,
1430
+ actual: instance.length,
1431
+ });
1432
+ valid = false;
1433
+ if (!shouldContinue(ctx))
1434
+ return false;
1435
+ }
1436
+ if (schema.maxLength !== undefined && instance.length > schema.maxLength) {
1437
+ addError(ctx, `String must be at most ${schema.maxLength} characters, got ${instance.length}`, instance, 'maxLength', {
1438
+ limit: schema.maxLength,
1439
+ actual: instance.length,
1440
+ });
1441
+ valid = false;
1442
+ if (!shouldContinue(ctx))
1443
+ return false;
1444
+ }
1445
+ if (schema.pattern !== undefined) {
1446
+ // Check pattern safety if a checker is configured
1447
+ if (ctx.patternSafetyChecker) {
1448
+ const safetyResult = ctx.patternSafetyChecker(schema.pattern);
1449
+ if (!safetyResult.safe) {
1450
+ addError(ctx, `Unsafe regex pattern: ${safetyResult.reason ?? 'Pattern may cause ReDoS'}`, instance, 'pattern', {
1451
+ pattern: schema.pattern,
1452
+ reason: safetyResult.reason,
1453
+ });
1454
+ valid = false;
1455
+ if (!shouldContinue(ctx))
1456
+ return false;
1457
+ // Skip executing the unsafe pattern
1458
+ return valid;
1459
+ }
1460
+ }
1461
+ try {
1462
+ // eslint-disable-next-line workspace/no-unsafe-regex -- Pattern safety validated above when safePatterns enabled
1463
+ const regex = createRegExp(schema.pattern);
1464
+ if (!regex.test(instance)) {
1465
+ addError(ctx, `String does not match pattern: ${schema.pattern}`, instance, 'pattern', {
1466
+ pattern: schema.pattern,
1467
+ });
1468
+ valid = false;
1469
+ if (!shouldContinue(ctx))
1470
+ return false;
1471
+ }
1472
+ }
1473
+ catch (e) {
1474
+ // Invalid regex pattern
1475
+ /* istanbul ignore next -- strictPatterns mode verified in validate.spec.ts */
1476
+ if (ctx.strictPatterns) {
1477
+ /* istanbul ignore next -- error reporting for invalid regex */
1478
+ addError(ctx, `Invalid regex pattern: ${schema.pattern}`, instance, 'pattern', {
1479
+ pattern: schema.pattern,
1480
+ /* istanbul ignore next -- error message extraction ternary */
1481
+ error: e instanceof Error ? e.message : 'Invalid regex',
1482
+ });
1483
+ valid = false;
1484
+ /* istanbul ignore if -- early exit tested in validate.spec.ts */
1485
+ if (!shouldContinue(ctx))
1486
+ return false;
1487
+ }
1488
+ // Otherwise skip validation silently
1489
+ }
1490
+ }
1491
+ return valid;
1492
+ }
1493
+
1494
+ /**
1495
+ * Type checking functions for JSON Schema types.
1496
+ */
1497
+ const typeCheckers = {
1498
+ string: (v) => typeof v === 'string',
1499
+ number: (v) => typeof v === 'number' && globalIsFinite(v),
1500
+ integer: (v) => typeof v === 'number' && globalIsFinite(v) && isInteger(v),
1501
+ boolean: (v) => typeof v === 'boolean',
1502
+ array: (v) => isArray(v),
1503
+ object: (v) => v !== null && typeof v === 'object' && !isArray(v),
1504
+ null: (v) => v === null,
1505
+ };
1506
+ /**
1507
+ * Gets the actual JSON type of a value for error messages.
1508
+ *
1509
+ * @param value - The value to get the type of
1510
+ * @returns The JSON type as a string
1511
+ */
1512
+ function getActualType(value) {
1513
+ if (value === null)
1514
+ return 'null';
1515
+ if (isArray(value))
1516
+ return 'array';
1517
+ const t = typeof value;
1518
+ if (t === 'number') {
1519
+ const num = value;
1520
+ /* istanbul ignore next -- NaN/Infinity edge case */
1521
+ if (!globalIsFinite(num))
1522
+ return 'number'; // NaN/Infinity
1523
+ return isInteger(num) ? 'integer' : 'number';
1524
+ }
1525
+ return t;
1526
+ }
1527
+ /**
1528
+ * Validates the 'type' keyword.
1529
+ *
1530
+ * @param instance - Value being validated
1531
+ * @param schema - Schema containing the type constraint
1532
+ * @param ctx - Validation context
1533
+ * @returns true if validation passes, false otherwise
1534
+ */
1535
+ function validateType(instance, schema, ctx) {
1536
+ const schemaType = schema.type;
1537
+ if (schemaType === undefined) {
1538
+ return true;
1539
+ }
1540
+ const types = isArray(schemaType) ? schemaType : [schemaType];
1541
+ for (const type of types) {
1542
+ const checker = typeCheckers[type];
1543
+ /* istanbul ignore if -- defensive check for unknown type */
1544
+ if (checker && checker(instance)) {
1545
+ // Special case: 'integer' should also pass 'number' check
1546
+ return true;
1547
+ }
1548
+ // If type is 'number' and value is an integer, it's still valid
1549
+ /* istanbul ignore if -- defensive fallback for integer/number coercion */
1550
+ if (type === 'number' && typeCheckers['integer']?.(instance)) {
1551
+ return true;
1552
+ }
1553
+ }
1554
+ const actualType = getActualType(instance);
1555
+ const expectedTypes = types.join(' or ');
1556
+ addError(ctx, `Expected type ${expectedTypes} but got ${actualType}`, instance, 'type', {
1557
+ expected: types,
1558
+ actual: actualType,
1559
+ });
1560
+ return false;
1561
+ }
1562
+
1563
+ /**
1564
+ * Resolves a $ref JSON Pointer to its target schema.
1565
+ *
1566
+ * @param ref - The $ref string (e.g., '#/definitions/Address')
1567
+ * @param ctx - Validation context containing root schema and definitions
1568
+ * @returns The resolved schema, or undefined if not found
1569
+ */
1570
+ function resolveRef(ref, ctx) {
1571
+ // Check pre-populated definitions first
1572
+ const cached = ctx.definitions.get(ref);
1573
+ if (cached) {
1574
+ return cached;
1575
+ }
1576
+ // Only support internal references (starting with #)
1577
+ if (!ref.startsWith('#')) {
1578
+ return undefined;
1579
+ }
1580
+ // Handle root reference
1581
+ if (ref === '#') {
1582
+ return ctx.rootSchema;
1583
+ }
1584
+ // Parse JSON Pointer path
1585
+ const path = ref.slice(1); // Remove leading #
1586
+ if (!path.startsWith('/')) {
1587
+ return undefined;
1588
+ }
1589
+ const segments = path
1590
+ .split('/')
1591
+ .slice(1) // Remove empty first segment
1592
+ .map((segment) => segment.replace(/~1/g, '/').replace(/~0/g, '~'));
1593
+ // Navigate to the referenced schema
1594
+ let current = ctx.rootSchema;
1595
+ for (const segment of segments) {
1596
+ if (current === null || typeof current !== 'object') {
1597
+ return undefined;
1598
+ }
1599
+ current = current[segment];
1600
+ }
1601
+ // Cache the resolved schema
1602
+ if (current && typeof current === 'object') {
1603
+ const resolved = current;
1604
+ ctx.definitions.set(ref, resolved);
1605
+ return resolved;
1606
+ }
1607
+ return undefined;
1608
+ }
1609
+
1610
+ /**
1611
+ * Validates a value against a JSON Schema.
1612
+ *
1613
+ * @param instance - The value to validate
1614
+ * @param schema - The JSON Schema to validate against
1615
+ * @param options - Validation options
1616
+ * @returns Validation result with valid flag and any errors
1617
+ *
1618
+ * @example
1619
+ * ```typescript
1620
+ * const schema = { type: 'string', minLength: 1 }
1621
+ * const result = validate('hello', schema)
1622
+ * console.log(result.valid) // true
1623
+ * ```
1624
+ */
1625
+ function validate(instance, schema, options) {
1626
+ // Resolve safePatterns option to a checker function
1627
+ let patternSafetyChecker;
1628
+ const ctx = createValidationContext(schema, validateSchema, true, false, patternSafetyChecker);
1629
+ const valid = validateSchema(instance, schema, ctx);
1630
+ return {
1631
+ valid,
1632
+ errors: ctx.errors,
1633
+ };
1634
+ }
1635
+ /**
1636
+ * Internal recursive validation function.
1637
+ *
1638
+ * @param instance - Value being validated
1639
+ * @param schema - Schema to validate against
1640
+ * @param ctx - Validation context
1641
+ * @returns true if validation passes, false otherwise
1642
+ */
1643
+ function validateSchema(instance, schema, ctx) {
1644
+ // Handle $ref
1645
+ if (schema.$ref) {
1646
+ const resolved = resolveRef(schema.$ref, ctx);
1647
+ /* istanbul ignore if -- $ref resolution failures are tested in resolve-ref.spec.ts */
1648
+ if (!resolved) {
1649
+ // Could not resolve reference - treat as valid
1650
+ return true;
1651
+ }
1652
+ return validateSchema(instance, resolved, ctx);
1653
+ }
1654
+ let valid = true;
1655
+ // Type validation
1656
+ if (!validateType(instance, schema, ctx)) {
1657
+ valid = false;
1658
+ if (!shouldContinue(ctx))
1659
+ return false;
1660
+ }
1661
+ // Enum validation
1662
+ if (!validateEnum(instance, schema, ctx)) {
1663
+ valid = false;
1664
+ if (!shouldContinue(ctx))
1665
+ return false;
1666
+ }
1667
+ // String-specific validations
1668
+ if (typeof instance === 'string') {
1669
+ if (!validateStringBounds(instance, schema, ctx)) {
1670
+ valid = false;
1671
+ if (!shouldContinue(ctx))
1672
+ return false;
1673
+ }
1674
+ if (!validateFormat(instance, schema, ctx)) {
1675
+ valid = false;
1676
+ if (!shouldContinue(ctx))
1677
+ return false;
1678
+ }
1679
+ }
1680
+ // Number-specific validations
1681
+ if (typeof instance === 'number') {
1682
+ if (!validateNumberBounds(instance, schema, ctx)) {
1683
+ valid = false;
1684
+ if (!shouldContinue(ctx))
1685
+ return false;
1686
+ }
1687
+ }
1688
+ // Array-specific validations
1689
+ if (isArray(instance)) {
1690
+ if (!validateItems(instance, schema, ctx)) {
1691
+ valid = false;
1692
+ if (!shouldContinue(ctx))
1693
+ return false;
1694
+ }
1695
+ if (!validateArrayBounds(instance, schema, ctx)) {
1696
+ valid = false;
1697
+ if (!shouldContinue(ctx))
1698
+ return false;
1699
+ }
1700
+ }
1701
+ // Object-specific validations
1702
+ if (instance !== null && typeof instance === 'object' && !isArray(instance)) {
1703
+ const obj = instance;
1704
+ if (!validateProperties(obj, schema, ctx)) {
1705
+ valid = false;
1706
+ if (!shouldContinue(ctx))
1707
+ return false;
1708
+ }
1709
+ if (!validateRequired(obj, schema, ctx)) {
1710
+ valid = false;
1711
+ /* istanbul ignore if -- early exit tested elsewhere */
1712
+ if (!shouldContinue(ctx))
1713
+ return false;
1714
+ }
1715
+ /* istanbul ignore next -- patternProperties validation */
1716
+ if (!validatePatternProperties(obj, schema, ctx)) {
1717
+ valid = false;
1718
+ /* istanbul ignore next -- early exit tested elsewhere */
1719
+ if (!shouldContinue(ctx))
1720
+ return false;
1721
+ }
1722
+ /* istanbul ignore next -- additionalProperties validation */
1723
+ if (!validateAdditionalProperties(obj, schema, ctx)) {
1724
+ valid = false;
1725
+ /* istanbul ignore next -- early exit tested elsewhere */
1726
+ if (!shouldContinue(ctx))
1727
+ return false;
1728
+ }
1729
+ /* istanbul ignore next -- objectBounds validation */
1730
+ if (!validateObjectBounds(obj, schema, ctx)) {
1731
+ valid = false;
1732
+ /* istanbul ignore next -- early exit tested elsewhere */
1733
+ if (!shouldContinue(ctx))
1734
+ return false;
1735
+ }
1736
+ /* istanbul ignore next -- dependencies validation */
1737
+ if (!validateDependencies(obj, schema, ctx)) {
1738
+ valid = false;
1739
+ /* istanbul ignore next -- early exit tested elsewhere */
1740
+ if (!shouldContinue(ctx))
1741
+ return false;
1742
+ }
1743
+ }
1744
+ // Composition keywords
1745
+ if (!validateAllOf(instance, schema, ctx)) {
1746
+ valid = false;
1747
+ if (!shouldContinue(ctx))
1748
+ return false;
1749
+ }
1750
+ if (!validateAnyOf(instance, schema, ctx)) {
1751
+ valid = false;
1752
+ if (!shouldContinue(ctx))
1753
+ return false;
1754
+ }
1755
+ if (!validateOneOf(instance, schema, ctx)) {
1756
+ valid = false;
1757
+ if (!shouldContinue(ctx))
1758
+ return false;
1759
+ }
1760
+ if (!validateNot(instance, schema, ctx)) {
1761
+ valid = false;
1762
+ if (!shouldContinue(ctx))
1763
+ return false;
1764
+ }
1765
+ return valid;
1766
+ }
1767
+
1768
+ /**
1769
+ * Changelog JSON Schema
1770
+ *
1771
+ * JSON Schema definitions for changelog validation and schema compatibility checking.
1772
+ * Uses `@hyperfrontend/json-utils` for validation.
1773
+ */
1774
+ /**
1775
+ * JSON Schema for a ChangelogLink.
1776
+ */
1777
+ const changelogLinkSchema = {
1778
+ type: 'object',
1779
+ required: ['label', 'url'],
1780
+ properties: {
1781
+ label: { type: 'string' },
1782
+ url: { type: 'string' },
1783
+ },
1784
+ additionalProperties: false,
1785
+ };
1786
+ /**
1787
+ * JSON Schema for a CommitRef.
1788
+ */
1789
+ const commitRefSchema = {
1790
+ type: 'object',
1791
+ required: ['hash', 'shortHash'],
1792
+ properties: {
1793
+ hash: { type: 'string', minLength: 7, maxLength: 40 },
1794
+ shortHash: { type: 'string', minLength: 7, maxLength: 7 },
1795
+ url: { type: 'string' },
1796
+ },
1797
+ additionalProperties: false,
1798
+ };
1799
+ /**
1800
+ * JSON Schema for an IssueRef.
1801
+ */
1802
+ const issueRefSchema = {
1803
+ type: 'object',
1804
+ required: ['number', 'type'],
1805
+ properties: {
1806
+ number: { type: 'integer', minimum: 1 },
1807
+ type: { type: 'string', enum: ['issue', 'pull-request'] },
1808
+ url: { type: 'string' },
1809
+ },
1810
+ additionalProperties: false,
1811
+ };
1812
+ /**
1813
+ * JSON Schema for a ChangelogItem.
1814
+ */
1815
+ const changelogItemSchema = {
1816
+ type: 'object',
1817
+ required: ['description', 'commits', 'references', 'breaking'],
1818
+ properties: {
1819
+ scope: { type: 'string' },
1820
+ description: { type: 'string' },
1821
+ breaking: { type: 'boolean' },
1822
+ commits: {
1823
+ type: 'array',
1824
+ items: commitRefSchema,
1825
+ },
1826
+ references: {
1827
+ type: 'array',
1828
+ items: issueRefSchema,
1829
+ },
1830
+ },
1831
+ additionalProperties: false,
1832
+ };
1833
+ /**
1834
+ * JSON Schema for a ChangelogSection.
1835
+ */
1836
+ const changelogSectionSchema = {
1837
+ type: 'object',
1838
+ required: ['type', 'heading', 'items'],
1839
+ properties: {
1840
+ type: {
1841
+ type: 'string',
1842
+ enum: [
1843
+ 'breaking',
1844
+ 'features',
1845
+ 'fixes',
1846
+ 'performance',
1847
+ 'documentation',
1848
+ 'deprecations',
1849
+ 'refactoring',
1850
+ 'tests',
1851
+ 'build',
1852
+ 'ci',
1853
+ 'chores',
1854
+ 'other',
1855
+ ],
1856
+ },
1857
+ heading: { type: 'string' },
1858
+ items: {
1859
+ type: 'array',
1860
+ items: changelogItemSchema,
1861
+ },
1862
+ },
1863
+ additionalProperties: false,
1864
+ };
1865
+ /**
1866
+ * JSON Schema for a ChangelogEntry.
1867
+ */
1868
+ const changelogEntrySchema = {
1869
+ type: 'object',
1870
+ required: ['version', 'date', 'unreleased', 'sections'],
1871
+ properties: {
1872
+ version: { type: 'string' },
1873
+ date: { type: ['string', 'null'] },
1874
+ unreleased: { type: 'boolean' },
1875
+ compareUrl: { type: 'string' },
1876
+ sections: {
1877
+ type: 'array',
1878
+ items: changelogSectionSchema,
1879
+ },
1880
+ rawContent: { type: 'string' },
1881
+ },
1882
+ additionalProperties: false,
1883
+ };
1884
+ /**
1885
+ * JSON Schema for ChangelogHeader.
1886
+ */
1887
+ const changelogHeaderSchema = {
1888
+ type: 'object',
1889
+ required: ['title', 'description', 'links'],
1890
+ properties: {
1891
+ title: { type: 'string' },
1892
+ description: {
1893
+ type: 'array',
1894
+ items: { type: 'string' },
1895
+ },
1896
+ links: {
1897
+ type: 'array',
1898
+ items: changelogLinkSchema,
1899
+ },
1900
+ },
1901
+ additionalProperties: false,
1902
+ };
1903
+ /**
1904
+ * JSON Schema for ChangelogMetadata.
1905
+ */
1906
+ const changelogMetadataSchema = {
1907
+ type: 'object',
1908
+ required: ['format', 'isConventional', 'warnings'],
1909
+ properties: {
1910
+ format: {
1911
+ type: 'string',
1912
+ enum: ['keep-a-changelog', 'conventional', 'custom', 'unknown'],
1913
+ },
1914
+ isConventional: { type: 'boolean' },
1915
+ repositoryUrl: { type: 'string' },
1916
+ packageName: { type: 'string' },
1917
+ warnings: {
1918
+ type: 'array',
1919
+ items: { type: 'string' },
1920
+ },
1921
+ },
1922
+ additionalProperties: false,
1923
+ };
1924
+ /**
1925
+ * JSON Schema for a complete Changelog document.
1926
+ * Used for validation and format compatibility checking.
1927
+ */
1928
+ const changelogSchema = {
1929
+ type: 'object',
1930
+ required: ['header', 'entries', 'metadata'],
1931
+ properties: {
1932
+ source: { type: 'string' },
1933
+ header: changelogHeaderSchema,
1934
+ entries: {
1935
+ type: 'array',
1936
+ items: changelogEntrySchema,
1937
+ },
1938
+ metadata: changelogMetadataSchema,
1939
+ },
1940
+ additionalProperties: false,
1941
+ };
1942
+ /**
1943
+ * Validates a changelog object against the schema.
1944
+ *
1945
+ * @param changelog - The changelog object to validate
1946
+ * @returns Validation result with any errors
1947
+ *
1948
+ * @example
1949
+ * ```ts
1950
+ * const result = validateChangelog(myChangelog)
1951
+ * if (!result.valid) {
1952
+ * console.log('Validation errors:', result.errors)
1953
+ * }
1954
+ * ```
1955
+ */
1956
+ function validateChangelog(changelog) {
1957
+ return validate(changelog, changelogSchema);
1958
+ }
1959
+ /**
1960
+ * Checks if two changelogs have compatible schemas.
1961
+ * Used to detect format incompatibilities before merge/compare.
1962
+ *
1963
+ * @param source - The source changelog
1964
+ * @param target - The target changelog
1965
+ * @returns Compatibility result with any differences found
1966
+ *
1967
+ * @example
1968
+ * ```ts
1969
+ * const result = checkSchemaCompatibility(mainChangelog, branchChangelog)
1970
+ * if (!result.compatible) {
1971
+ * console.log('Schema differences:', result.differences)
1972
+ * }
1973
+ * ```
1974
+ */
1975
+ function checkSchemaCompatibility(source, target) {
1976
+ const differences = [];
1977
+ // Check format compatibility
1978
+ if (source.metadata.format !== target.metadata.format) {
1979
+ differences.push({
1980
+ path: 'metadata.format',
1981
+ type: 'type-mismatch',
1982
+ sourceType: source.metadata.format,
1983
+ targetType: target.metadata.format,
1984
+ });
1985
+ }
1986
+ // Check header structure
1987
+ if (source.header.title !== target.header.title) ;
1988
+ // Check section types used
1989
+ const sourceSectionTypes = createSet();
1990
+ const targetSectionTypes = createSet();
1991
+ for (const entry of source.entries) {
1992
+ for (const section of entry.sections) {
1993
+ sourceSectionTypes.add(section.type);
1994
+ }
1995
+ }
1996
+ for (const entry of target.entries) {
1997
+ for (const section of entry.sections) {
1998
+ targetSectionTypes.add(section.type);
1999
+ }
2000
+ }
2001
+ // Find section types in source but not in target
2002
+ for (const type of sourceSectionTypes) {
2003
+ if (!targetSectionTypes.has(type)) {
2004
+ differences.push({
2005
+ path: `sections[type=${type}]`,
2006
+ type: 'missing-property',
2007
+ sourceType: type,
2008
+ });
2009
+ }
2010
+ }
2011
+ // Find section types in target but not in source
2012
+ for (const type of targetSectionTypes) {
2013
+ if (!sourceSectionTypes.has(type)) {
2014
+ differences.push({
2015
+ path: `sections[type=${type}]`,
2016
+ type: 'extra-property',
2017
+ targetType: type,
2018
+ });
2019
+ }
2020
+ }
2021
+ return {
2022
+ compatible: differences.length === 0,
2023
+ differences,
2024
+ };
2025
+ }
2026
+
2027
+ exports.SECTION_HEADINGS = SECTION_HEADINGS;
2028
+ exports.SECTION_TYPE_MAP = SECTION_TYPE_MAP;
2029
+ exports.changelogSchema = changelogSchema;
2030
+ exports.checkSchemaCompatibility = checkSchemaCompatibility;
2031
+ exports.createChangelog = createChangelog;
2032
+ exports.createChangelogEntry = createChangelogEntry;
2033
+ exports.createChangelogItem = createChangelogItem;
2034
+ exports.createChangelogLink = createChangelogLink;
2035
+ exports.createChangelogSection = createChangelogSection;
2036
+ exports.createCommitRef = createCommitRef;
2037
+ exports.createEmptyChangelog = createEmptyChangelog;
2038
+ exports.createIssueRef = createIssueRef;
2039
+ exports.createUnreleasedEntry = createUnreleasedEntry;
2040
+ exports.getSectionType = getSectionType;
2041
+ exports.getShortHash = getShortHash;
2042
+ exports.validateChangelog = validateChangelog;
2043
+ //# sourceMappingURL=index.cjs.js.map