@hyperfrontend/versioning 0.1.0 → 0.2.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 (158) hide show
  1. package/ARCHITECTURE.md +50 -1
  2. package/CHANGELOG.md +23 -23
  3. package/README.md +12 -9
  4. package/changelog/index.cjs.js +23 -2
  5. package/changelog/index.cjs.js.map +1 -1
  6. package/changelog/index.esm.js +23 -2
  7. package/changelog/index.esm.js.map +1 -1
  8. package/changelog/models/entry.d.ts +5 -0
  9. package/changelog/models/entry.d.ts.map +1 -1
  10. package/changelog/models/index.cjs.js +2 -0
  11. package/changelog/models/index.cjs.js.map +1 -1
  12. package/changelog/models/index.esm.js +2 -0
  13. package/changelog/models/index.esm.js.map +1 -1
  14. package/changelog/operations/index.cjs.js.map +1 -1
  15. package/changelog/operations/index.esm.js.map +1 -1
  16. package/changelog/parse/index.cjs.js +23 -2
  17. package/changelog/parse/index.cjs.js.map +1 -1
  18. package/changelog/parse/index.esm.js +23 -2
  19. package/changelog/parse/index.esm.js.map +1 -1
  20. package/changelog/parse/line.d.ts.map +1 -1
  21. package/commits/classify/classifier.d.ts +73 -0
  22. package/commits/classify/classifier.d.ts.map +1 -0
  23. package/commits/classify/index.cjs.js +705 -0
  24. package/commits/classify/index.cjs.js.map +1 -0
  25. package/commits/classify/index.d.ts +8 -0
  26. package/commits/classify/index.d.ts.map +1 -0
  27. package/commits/classify/index.esm.js +678 -0
  28. package/commits/classify/index.esm.js.map +1 -0
  29. package/commits/classify/infrastructure.d.ts +205 -0
  30. package/commits/classify/infrastructure.d.ts.map +1 -0
  31. package/commits/classify/models.d.ts +108 -0
  32. package/commits/classify/models.d.ts.map +1 -0
  33. package/commits/classify/project-scopes.d.ts +59 -0
  34. package/commits/classify/project-scopes.d.ts.map +1 -0
  35. package/commits/index.cjs.js +702 -0
  36. package/commits/index.cjs.js.map +1 -1
  37. package/commits/index.d.ts +1 -0
  38. package/commits/index.d.ts.map +1 -1
  39. package/commits/index.esm.js +677 -1
  40. package/commits/index.esm.js.map +1 -1
  41. package/flow/executor/execute.d.ts +6 -0
  42. package/flow/executor/execute.d.ts.map +1 -1
  43. package/flow/executor/index.cjs.js +1604 -42
  44. package/flow/executor/index.cjs.js.map +1 -1
  45. package/flow/executor/index.esm.js +1610 -48
  46. package/flow/executor/index.esm.js.map +1 -1
  47. package/flow/index.cjs.js +6651 -2893
  48. package/flow/index.cjs.js.map +1 -1
  49. package/flow/index.esm.js +6655 -2899
  50. package/flow/index.esm.js.map +1 -1
  51. package/flow/models/index.cjs.js +125 -0
  52. package/flow/models/index.cjs.js.map +1 -1
  53. package/flow/models/index.esm.js +125 -0
  54. package/flow/models/index.esm.js.map +1 -1
  55. package/flow/models/types.d.ts +148 -3
  56. package/flow/models/types.d.ts.map +1 -1
  57. package/flow/presets/conventional.d.ts +9 -8
  58. package/flow/presets/conventional.d.ts.map +1 -1
  59. package/flow/presets/independent.d.ts.map +1 -1
  60. package/flow/presets/index.cjs.js +3588 -298
  61. package/flow/presets/index.cjs.js.map +1 -1
  62. package/flow/presets/index.esm.js +3588 -298
  63. package/flow/presets/index.esm.js.map +1 -1
  64. package/flow/presets/synced.d.ts.map +1 -1
  65. package/flow/steps/analyze-commits.d.ts +9 -6
  66. package/flow/steps/analyze-commits.d.ts.map +1 -1
  67. package/flow/steps/calculate-bump.d.ts.map +1 -1
  68. package/flow/steps/fetch-registry.d.ts.map +1 -1
  69. package/flow/steps/generate-changelog.d.ts.map +1 -1
  70. package/flow/steps/index.cjs.js +3604 -318
  71. package/flow/steps/index.cjs.js.map +1 -1
  72. package/flow/steps/index.d.ts +1 -0
  73. package/flow/steps/index.d.ts.map +1 -1
  74. package/flow/steps/index.esm.js +3603 -319
  75. package/flow/steps/index.esm.js.map +1 -1
  76. package/flow/steps/resolve-repository.d.ts +36 -0
  77. package/flow/steps/resolve-repository.d.ts.map +1 -0
  78. package/flow/steps/update-packages.d.ts.map +1 -1
  79. package/git/factory.d.ts +14 -0
  80. package/git/factory.d.ts.map +1 -1
  81. package/git/index.cjs.js +65 -0
  82. package/git/index.cjs.js.map +1 -1
  83. package/git/index.esm.js +66 -2
  84. package/git/index.esm.js.map +1 -1
  85. package/git/operations/index.cjs.js +40 -0
  86. package/git/operations/index.cjs.js.map +1 -1
  87. package/git/operations/index.d.ts +1 -1
  88. package/git/operations/index.d.ts.map +1 -1
  89. package/git/operations/index.esm.js +41 -2
  90. package/git/operations/index.esm.js.map +1 -1
  91. package/git/operations/log.d.ts +23 -0
  92. package/git/operations/log.d.ts.map +1 -1
  93. package/index.cjs.js +6962 -4413
  94. package/index.cjs.js.map +1 -1
  95. package/index.esm.js +6964 -4415
  96. package/index.esm.js.map +1 -1
  97. package/package.json +26 -1
  98. package/registry/index.cjs.js +3 -3
  99. package/registry/index.cjs.js.map +1 -1
  100. package/registry/index.esm.js +3 -3
  101. package/registry/index.esm.js.map +1 -1
  102. package/registry/models/index.cjs.js +2 -0
  103. package/registry/models/index.cjs.js.map +1 -1
  104. package/registry/models/index.esm.js +2 -0
  105. package/registry/models/index.esm.js.map +1 -1
  106. package/registry/models/version-info.d.ts +10 -0
  107. package/registry/models/version-info.d.ts.map +1 -1
  108. package/registry/npm/client.d.ts.map +1 -1
  109. package/registry/npm/index.cjs.js +1 -3
  110. package/registry/npm/index.cjs.js.map +1 -1
  111. package/registry/npm/index.esm.js +1 -3
  112. package/registry/npm/index.esm.js.map +1 -1
  113. package/repository/index.cjs.js +998 -0
  114. package/repository/index.cjs.js.map +1 -0
  115. package/repository/index.d.ts +4 -0
  116. package/repository/index.d.ts.map +1 -0
  117. package/repository/index.esm.js +981 -0
  118. package/repository/index.esm.js.map +1 -0
  119. package/repository/models/index.cjs.js +301 -0
  120. package/repository/models/index.cjs.js.map +1 -0
  121. package/repository/models/index.d.ts +7 -0
  122. package/repository/models/index.d.ts.map +1 -0
  123. package/repository/models/index.esm.js +290 -0
  124. package/repository/models/index.esm.js.map +1 -0
  125. package/repository/models/platform.d.ts +58 -0
  126. package/repository/models/platform.d.ts.map +1 -0
  127. package/repository/models/repository-config.d.ts +132 -0
  128. package/repository/models/repository-config.d.ts.map +1 -0
  129. package/repository/models/resolution.d.ts +121 -0
  130. package/repository/models/resolution.d.ts.map +1 -0
  131. package/repository/parse/index.cjs.js +755 -0
  132. package/repository/parse/index.cjs.js.map +1 -0
  133. package/repository/parse/index.d.ts +5 -0
  134. package/repository/parse/index.d.ts.map +1 -0
  135. package/repository/parse/index.esm.js +749 -0
  136. package/repository/parse/index.esm.js.map +1 -0
  137. package/repository/parse/package-json.d.ts +100 -0
  138. package/repository/parse/package-json.d.ts.map +1 -0
  139. package/repository/parse/url.d.ts +81 -0
  140. package/repository/parse/url.d.ts.map +1 -0
  141. package/repository/url/compare.d.ts +84 -0
  142. package/repository/url/compare.d.ts.map +1 -0
  143. package/repository/url/index.cjs.js +178 -0
  144. package/repository/url/index.cjs.js.map +1 -0
  145. package/repository/url/index.d.ts +3 -0
  146. package/repository/url/index.d.ts.map +1 -0
  147. package/repository/url/index.esm.js +176 -0
  148. package/repository/url/index.esm.js.map +1 -0
  149. package/workspace/discovery/index.cjs.js +324 -330
  150. package/workspace/discovery/index.cjs.js.map +1 -1
  151. package/workspace/discovery/index.esm.js +324 -330
  152. package/workspace/discovery/index.esm.js.map +1 -1
  153. package/workspace/discovery/packages.d.ts +0 -6
  154. package/workspace/discovery/packages.d.ts.map +1 -1
  155. package/workspace/index.cjs.js +0 -6
  156. package/workspace/index.cjs.js.map +1 -1
  157. package/workspace/index.esm.js +0 -6
  158. package/workspace/index.esm.js.map +1 -1
@@ -0,0 +1,998 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Safe copies of Map built-in via factory function.
5
+ *
6
+ * Since constructors cannot be safely captured via Object.assign, this module
7
+ * provides a factory function that uses Reflect.construct internally.
8
+ *
9
+ * These references are captured at module initialization time to protect against
10
+ * prototype pollution attacks. Import only what you need for tree-shaking.
11
+ *
12
+ * @module @hyperfrontend/immutable-api-utils/built-in-copy/map
13
+ */
14
+ // Capture references at module initialization time
15
+ const _Map = globalThis.Map;
16
+ const _Reflect$2 = globalThis.Reflect;
17
+ /**
18
+ * (Safe copy) Creates a new Map using the captured Map constructor.
19
+ * Use this instead of `new Map()`.
20
+ *
21
+ * @param iterable - Optional iterable of key-value pairs.
22
+ * @returns A new Map instance.
23
+ */
24
+ const createMap = (iterable) => _Reflect$2.construct(_Map, iterable ? [iterable] : []);
25
+
26
+ /**
27
+ * Checks if a platform identifier is a known platform with built-in support.
28
+ *
29
+ * @param platform - Platform identifier to check
30
+ * @returns True if the platform is a known platform
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * isKnownPlatform('github') // true
35
+ * isKnownPlatform('gitlab') // true
36
+ * isKnownPlatform('custom') // false
37
+ * isKnownPlatform('unknown') // false
38
+ * ```
39
+ */
40
+ function isKnownPlatform(platform) {
41
+ return platform === 'github' || platform === 'gitlab' || platform === 'bitbucket' || platform === 'azure-devops';
42
+ }
43
+ /**
44
+ * Known platform hostnames mapped to their platform type.
45
+ * Used for automatic platform detection from repository URLs.
46
+ *
47
+ * Includes both standard SaaS domains and common patterns for self-hosted instances.
48
+ */
49
+ const PLATFORM_HOSTNAMES = createMap([
50
+ // GitHub
51
+ ['github.com', 'github'],
52
+ // GitLab
53
+ ['gitlab.com', 'gitlab'],
54
+ // Bitbucket
55
+ ['bitbucket.org', 'bitbucket'],
56
+ // Azure DevOps
57
+ ['dev.azure.com', 'azure-devops'],
58
+ ['visualstudio.com', 'azure-devops'],
59
+ ]);
60
+ /**
61
+ * Detects platform from a hostname.
62
+ *
63
+ * First checks for exact match in known platforms, then applies heuristics
64
+ * for self-hosted instances (e.g., `github.company.com` → `github`).
65
+ *
66
+ * @param hostname - Hostname to detect platform from (e.g., "github.com")
67
+ * @returns Detected platform or 'unknown' if not recognized
68
+ *
69
+ * @example
70
+ * ```typescript
71
+ * detectPlatformFromHostname('github.com') // 'github'
72
+ * detectPlatformFromHostname('gitlab.mycompany.com') // 'gitlab'
73
+ * detectPlatformFromHostname('custom-git.internal') // 'unknown'
74
+ * ```
75
+ */
76
+ function detectPlatformFromHostname(hostname) {
77
+ const normalized = hostname.toLowerCase();
78
+ // Check exact matches first
79
+ const exactMatch = PLATFORM_HOSTNAMES.get(normalized);
80
+ if (exactMatch) {
81
+ return exactMatch;
82
+ }
83
+ // Check for Azure DevOps legacy domain pattern
84
+ if (normalized.endsWith('.visualstudio.com')) {
85
+ return 'azure-devops';
86
+ }
87
+ // Check for Azure DevOps modern domain pattern (includes ssh.dev.azure.com)
88
+ if (normalized.endsWith('.azure.com')) {
89
+ return 'azure-devops';
90
+ }
91
+ // Heuristics for self-hosted instances
92
+ // GitHub Enterprise typically uses "github" in the hostname
93
+ if (normalized.includes('github')) {
94
+ return 'github';
95
+ }
96
+ // GitLab self-hosted typically uses "gitlab" in the hostname
97
+ if (normalized.includes('gitlab')) {
98
+ return 'gitlab';
99
+ }
100
+ // Bitbucket Data Center/Server might use "bitbucket" in hostname
101
+ if (normalized.includes('bitbucket')) {
102
+ return 'bitbucket';
103
+ }
104
+ return 'unknown';
105
+ }
106
+
107
+ /**
108
+ * Safe copies of Error built-ins via factory functions.
109
+ *
110
+ * Since constructors cannot be safely captured via Object.assign, this module
111
+ * provides factory functions that use Reflect.construct internally.
112
+ *
113
+ * These references are captured at module initialization time to protect against
114
+ * prototype pollution attacks. Import only what you need for tree-shaking.
115
+ *
116
+ * @module @hyperfrontend/immutable-api-utils/built-in-copy/error
117
+ */
118
+ // Capture references at module initialization time
119
+ const _Error = globalThis.Error;
120
+ const _Reflect$1 = globalThis.Reflect;
121
+ /**
122
+ * (Safe copy) Creates a new Error using the captured Error constructor.
123
+ * Use this instead of `new Error()`.
124
+ *
125
+ * @param message - Optional error message.
126
+ * @param options - Optional error options.
127
+ * @returns A new Error instance.
128
+ */
129
+ const createError = (message, options) => _Reflect$1.construct(_Error, [message, options]);
130
+
131
+ /**
132
+ * Creates a new RepositoryConfig.
133
+ *
134
+ * Normalizes the base URL by stripping trailing slashes and validating
135
+ * that custom platforms have a formatter function.
136
+ *
137
+ * @param options - Repository configuration options
138
+ * @returns A new RepositoryConfig object
139
+ * @throws {Error} if platform is 'custom' but no formatCompareUrl is provided
140
+ *
141
+ * @example
142
+ * ```typescript
143
+ * // GitHub repository
144
+ * const config = createRepositoryConfig({
145
+ * platform: 'github',
146
+ * baseUrl: 'https://github.com/owner/repo'
147
+ * })
148
+ *
149
+ * // Custom platform
150
+ * const customConfig = createRepositoryConfig({
151
+ * platform: 'custom',
152
+ * baseUrl: 'https://my-git.internal/repo',
153
+ * formatCompareUrl: (from, to) => `https://my-git.internal/diff/${from}/${to}`
154
+ * })
155
+ * ```
156
+ */
157
+ function createRepositoryConfig(options) {
158
+ const { platform, formatCompareUrl } = options;
159
+ // Validate custom platform has formatter
160
+ if (platform === 'custom' && !formatCompareUrl) {
161
+ throw createError("Repository config with platform 'custom' requires a formatCompareUrl function");
162
+ }
163
+ // Normalize base URL - strip trailing slashes
164
+ const baseUrl = normalizeBaseUrl(options.baseUrl);
165
+ return {
166
+ platform,
167
+ baseUrl,
168
+ formatCompareUrl,
169
+ };
170
+ }
171
+ /**
172
+ * Checks if a value is a RepositoryConfig object.
173
+ *
174
+ * @param value - Value to check
175
+ * @returns True if the value is a RepositoryConfig
176
+ *
177
+ * @example
178
+ * ```typescript
179
+ * const config = { platform: 'github', baseUrl: 'https://...' }
180
+ * if (isRepositoryConfig(config)) {
181
+ * // config is typed as RepositoryConfig
182
+ * }
183
+ * ```
184
+ */
185
+ function isRepositoryConfig(value) {
186
+ if (typeof value !== 'object' || value === null) {
187
+ return false;
188
+ }
189
+ const obj = value;
190
+ return (typeof obj['platform'] === 'string' &&
191
+ typeof obj['baseUrl'] === 'string' &&
192
+ (obj['formatCompareUrl'] === undefined || typeof obj['formatCompareUrl'] === 'function'));
193
+ }
194
+ /**
195
+ * Normalizes a base URL by stripping trailing slashes and .git suffix.
196
+ *
197
+ * @param url - URL to normalize
198
+ * @returns Normalized URL
199
+ *
200
+ * @internal
201
+ */
202
+ function normalizeBaseUrl(url) {
203
+ let normalized = url.trim();
204
+ // Remove trailing slashes
205
+ while (normalized.endsWith('/')) {
206
+ normalized = normalized.slice(0, -1);
207
+ }
208
+ // Remove .git suffix if present
209
+ if (normalized.endsWith('.git')) {
210
+ normalized = normalized.slice(0, -4);
211
+ }
212
+ return normalized;
213
+ }
214
+
215
+ /**
216
+ * Creates a disabled repository resolution configuration.
217
+ *
218
+ * No compare URLs will be generated.
219
+ *
220
+ * @returns A RepositoryResolution with mode 'disabled'
221
+ *
222
+ * @example
223
+ * ```typescript
224
+ * const config = createDisabledResolution()
225
+ * // { mode: 'disabled' }
226
+ * ```
227
+ */
228
+ function createDisabledResolution() {
229
+ return { mode: 'disabled' };
230
+ }
231
+ /**
232
+ * Creates an explicit repository resolution configuration.
233
+ *
234
+ * @param repository - The repository config to use
235
+ * @returns A RepositoryResolution with mode 'explicit'
236
+ *
237
+ * @example
238
+ * ```typescript
239
+ * const config = createExplicitResolution({
240
+ * platform: 'github',
241
+ * baseUrl: 'https://github.com/owner/repo'
242
+ * })
243
+ * ```
244
+ */
245
+ function createExplicitResolution(repository) {
246
+ return {
247
+ mode: 'explicit',
248
+ repository,
249
+ };
250
+ }
251
+ /**
252
+ * Creates an inferred repository resolution configuration.
253
+ *
254
+ * @param inferenceOrder - Order to try inference sources (default: package-json first)
255
+ * @returns A RepositoryResolution with mode 'inferred'
256
+ *
257
+ * @example
258
+ * ```typescript
259
+ * // Default order: package.json → git remote
260
+ * const config = createInferredResolution()
261
+ *
262
+ * // Custom order: git remote → package.json
263
+ * const customOrder = createInferredResolution(['git-remote', 'package-json'])
264
+ * ```
265
+ */
266
+ function createInferredResolution(inferenceOrder = ['package-json', 'git-remote']) {
267
+ return {
268
+ mode: 'inferred',
269
+ inferenceOrder,
270
+ };
271
+ }
272
+ /**
273
+ * Checks if a value is a RepositoryResolution object.
274
+ *
275
+ * @param value - Value to check
276
+ * @returns True if the value is a RepositoryResolution
277
+ */
278
+ function isRepositoryResolution(value) {
279
+ if (typeof value !== 'object' || value === null) {
280
+ return false;
281
+ }
282
+ const obj = value;
283
+ const mode = obj['mode'];
284
+ return mode === 'explicit' || mode === 'inferred' || mode === 'disabled';
285
+ }
286
+ /**
287
+ * Default inference order when mode is 'inferred'.
288
+ */
289
+ const DEFAULT_INFERENCE_ORDER = ['package-json', 'git-remote'];
290
+
291
+ /**
292
+ * Safe copies of Math built-in methods.
293
+ *
294
+ * These references are captured at module initialization time to protect against
295
+ * prototype pollution attacks. Import only what you need for tree-shaking.
296
+ *
297
+ * @module @hyperfrontend/immutable-api-utils/built-in-copy/math
298
+ */
299
+ // Capture references at module initialization time
300
+ const _Math = globalThis.Math;
301
+ /**
302
+ * (Safe copy) Returns the smaller of zero or more numbers.
303
+ */
304
+ const min = _Math.min;
305
+
306
+ /**
307
+ * Safe copies of URL built-ins via factory functions.
308
+ *
309
+ * Provides safe references to URL and URLSearchParams.
310
+ * These references are captured at module initialization time to protect against
311
+ * prototype pollution attacks. Import only what you need for tree-shaking.
312
+ *
313
+ * @module @hyperfrontend/immutable-api-utils/built-in-copy/url
314
+ */
315
+ // Capture references at module initialization time
316
+ const _URL = globalThis.URL;
317
+ const _Reflect = globalThis.Reflect;
318
+ // ============================================================================
319
+ // URL
320
+ // ============================================================================
321
+ /**
322
+ * (Safe copy) Creates a new URL using the captured URL constructor.
323
+ * Use this instead of `new URL()`.
324
+ *
325
+ * @param url - The URL string to parse.
326
+ * @param base - Optional base URL for relative URLs.
327
+ * @returns A new URL instance.
328
+ */
329
+ const createURL = (url, base) => _Reflect.construct(_URL, [url, base]);
330
+ /**
331
+ * (Safe copy) Creates an object URL for the given object.
332
+ * Use this instead of `URL.createObjectURL()`.
333
+ *
334
+ * Note: This is a browser-only API. In Node.js environments, this will throw.
335
+ */
336
+ typeof _URL.createObjectURL === 'function'
337
+ ? _URL.createObjectURL.bind(_URL)
338
+ : () => {
339
+ throw new Error('URL.createObjectURL is not available in this environment');
340
+ };
341
+ /**
342
+ * (Safe copy) Revokes an object URL previously created with createObjectURL.
343
+ * Use this instead of `URL.revokeObjectURL()`.
344
+ *
345
+ * Note: This is a browser-only API. In Node.js environments, this will throw.
346
+ */
347
+ typeof _URL.revokeObjectURL === 'function'
348
+ ? _URL.revokeObjectURL.bind(_URL)
349
+ : () => {
350
+ throw new Error('URL.revokeObjectURL is not available in this environment');
351
+ };
352
+
353
+ /**
354
+ * Parses a git URL and extracts platform and base URL.
355
+ *
356
+ * Supports multiple URL formats:
357
+ * - `https://github.com/owner/repo`
358
+ * - `https://github.com/owner/repo.git`
359
+ * - `git+https://github.com/owner/repo.git`
360
+ * - `git://github.com/owner/repo.git`
361
+ * - `git@github.com:owner/repo.git` (SSH format)
362
+ *
363
+ * Handles self-hosted instances by detecting platform from hostname:
364
+ * - `github.mycompany.com` → `github`
365
+ * - `gitlab.internal.com` → `gitlab`
366
+ *
367
+ * Handles Azure DevOps URL formats:
368
+ * - `https://dev.azure.com/org/project/_git/repo`
369
+ * - `https://org.visualstudio.com/project/_git/repo`
370
+ *
371
+ * @param gitUrl - Git repository URL in any supported format
372
+ * @returns Parsed repository info with platform and base URL, or null if parsing fails
373
+ *
374
+ * @example
375
+ * ```typescript
376
+ * // GitHub HTTPS
377
+ * parseRepositoryUrl('https://github.com/owner/repo')
378
+ * // → { platform: 'github', baseUrl: 'https://github.com/owner/repo' }
379
+ *
380
+ * // SSH format
381
+ * parseRepositoryUrl('git@github.com:owner/repo.git')
382
+ * // → { platform: 'github', baseUrl: 'https://github.com/owner/repo' }
383
+ *
384
+ * // Azure DevOps
385
+ * parseRepositoryUrl('https://dev.azure.com/org/proj/_git/repo')
386
+ * // → { platform: 'azure-devops', baseUrl: 'https://dev.azure.com/org/proj/_git/repo' }
387
+ *
388
+ * // Self-hosted GitLab
389
+ * parseRepositoryUrl('https://gitlab.mycompany.com/team/project')
390
+ * // → { platform: 'gitlab', baseUrl: 'https://gitlab.mycompany.com/team/project' }
391
+ * ```
392
+ */
393
+ function parseRepositoryUrl(gitUrl) {
394
+ if (!gitUrl || typeof gitUrl !== 'string') {
395
+ return null;
396
+ }
397
+ const trimmed = gitUrl.trim();
398
+ if (!trimmed) {
399
+ return null;
400
+ }
401
+ // Try SSH format first: git@hostname:path
402
+ const sshParsed = parseSshUrl(trimmed);
403
+ if (sshParsed) {
404
+ return sshParsed;
405
+ }
406
+ // Try HTTP(S) formats
407
+ const httpParsed = parseHttpUrl(trimmed);
408
+ if (httpParsed) {
409
+ return httpParsed;
410
+ }
411
+ return null;
412
+ }
413
+ /**
414
+ * Parses an SSH-style git URL.
415
+ *
416
+ * @param url - URL to parse (e.g., "git@github.com:owner/repo.git")
417
+ * @returns Parsed repository or null
418
+ *
419
+ * @internal
420
+ */
421
+ function parseSshUrl(url) {
422
+ // Handle optional ssh:// prefix
423
+ let remaining = url;
424
+ if (remaining.startsWith('ssh://')) {
425
+ remaining = remaining.slice(6);
426
+ }
427
+ // Must start with git@
428
+ if (!remaining.startsWith('git@')) {
429
+ return null;
430
+ }
431
+ // Remove git@ prefix
432
+ remaining = remaining.slice(4);
433
+ // Find the separator (: or /)
434
+ const colonIndex = remaining.indexOf(':');
435
+ const slashIndex = remaining.indexOf('/');
436
+ let separatorIndex;
437
+ if (colonIndex === -1 && slashIndex === -1) {
438
+ return null;
439
+ }
440
+ else if (colonIndex === -1) {
441
+ separatorIndex = slashIndex;
442
+ }
443
+ else if (slashIndex === -1) {
444
+ separatorIndex = colonIndex;
445
+ }
446
+ else {
447
+ separatorIndex = min(colonIndex, slashIndex);
448
+ }
449
+ const hostname = remaining.slice(0, separatorIndex);
450
+ const pathPart = normalizePathPart(remaining.slice(separatorIndex + 1));
451
+ if (!hostname || !pathPart) {
452
+ return null;
453
+ }
454
+ const platform = detectPlatformFromHostname(hostname);
455
+ // For Azure DevOps, construct proper base URL
456
+ if (platform === 'azure-devops') {
457
+ const baseUrl = constructAzureDevOpsBaseUrl(hostname, pathPart);
458
+ if (baseUrl) {
459
+ return { platform, baseUrl };
460
+ }
461
+ return null;
462
+ }
463
+ // Standard platforms: https://hostname/path
464
+ const baseUrl = `https://${hostname}/${pathPart}`;
465
+ return { platform, baseUrl };
466
+ }
467
+ /**
468
+ * Parses an HTTP(S)-style git URL.
469
+ *
470
+ * @param url - URL to parse
471
+ * @returns Parsed repository or null
472
+ *
473
+ * @internal
474
+ */
475
+ function parseHttpUrl(url) {
476
+ // Normalize various git URL prefixes to https://
477
+ const normalized = url
478
+ .replace(/^git\+/, '') // git+https:// → https://
479
+ .replace(/^git:\/\//, 'https://'); // git:// → https://
480
+ let parsed;
481
+ try {
482
+ parsed = createURL(normalized);
483
+ }
484
+ catch {
485
+ return null;
486
+ }
487
+ // Only support http and https protocols
488
+ if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
489
+ return null;
490
+ }
491
+ const hostname = parsed.hostname.toLowerCase();
492
+ const platform = detectPlatformFromHostname(hostname);
493
+ const pathPart = normalizePathPart(parsed.pathname);
494
+ if (!pathPart) {
495
+ return null;
496
+ }
497
+ // Handle Azure DevOps special URL structure
498
+ if (platform === 'azure-devops') {
499
+ const baseUrl = constructAzureDevOpsBaseUrl(hostname, pathPart);
500
+ if (baseUrl) {
501
+ return { platform, baseUrl };
502
+ }
503
+ // If Azure DevOps URL cannot be parsed properly, return null
504
+ return null;
505
+ }
506
+ // Standard platforms
507
+ const baseUrl = `${parsed.protocol}//${hostname}/${pathPart}`;
508
+ return { platform, baseUrl };
509
+ }
510
+ /**
511
+ * Normalizes a path part by removing leading slashes and .git suffix.
512
+ *
513
+ * @param path - Path to normalize
514
+ * @returns Normalized path or null if empty
515
+ *
516
+ * @internal
517
+ */
518
+ function normalizePathPart(path) {
519
+ let normalized = path.trim();
520
+ // Remove leading slashes
521
+ while (normalized.startsWith('/')) {
522
+ normalized = normalized.slice(1);
523
+ }
524
+ // Remove trailing slashes
525
+ while (normalized.endsWith('/')) {
526
+ normalized = normalized.slice(0, -1);
527
+ }
528
+ // Remove .git suffix
529
+ if (normalized.endsWith('.git')) {
530
+ normalized = normalized.slice(0, -4);
531
+ }
532
+ // Validate we have something
533
+ if (!normalized) {
534
+ return null;
535
+ }
536
+ return normalized;
537
+ }
538
+ /**
539
+ * Constructs the base URL for Azure DevOps repositories.
540
+ *
541
+ * Azure DevOps has special URL structures:
542
+ * - Modern: `https://dev.azure.com/{org}/{project}/_git/{repo}`
543
+ * - Legacy: `https://{org}.visualstudio.com/{project}/_git/{repo}`
544
+ * - SSH: `git@ssh.dev.azure.com:v3/{org}/{project}/{repo}`
545
+ *
546
+ * @param hostname - Hostname from the URL
547
+ * @param pathPart - Path portion after hostname
548
+ * @returns Constructed base URL or null if invalid
549
+ *
550
+ * @internal
551
+ */
552
+ function constructAzureDevOpsBaseUrl(hostname, pathPart) {
553
+ const pathParts = pathPart.split('/');
554
+ // dev.azure.com format: org/project/_git/repo
555
+ if (hostname === 'dev.azure.com' || hostname.endsWith('.azure.com')) {
556
+ // Need at least: org/project/_git/repo (4 parts)
557
+ // Or for SSH v3: v3/org/project/repo (4 parts)
558
+ if (pathParts.length >= 4) {
559
+ // Check for v3 SSH format
560
+ if (pathParts[0] === 'v3') {
561
+ // v3/org/project/repo → https://dev.azure.com/org/project/_git/repo
562
+ const org = pathParts[1];
563
+ const project = pathParts[2];
564
+ const repo = pathParts[3];
565
+ if (org && project && repo) {
566
+ return `https://dev.azure.com/${org}/${project}/_git/${repo}`;
567
+ }
568
+ }
569
+ // Standard format: org/project/_git/repo
570
+ const gitIndex = pathParts.indexOf('_git');
571
+ if (gitIndex >= 2 && pathParts[gitIndex + 1]) {
572
+ const org = pathParts.slice(0, gitIndex - 1).join('/');
573
+ const project = pathParts[gitIndex - 1];
574
+ const repo = pathParts[gitIndex + 1];
575
+ if (org && project && repo) {
576
+ return `https://dev.azure.com/${org}/${project}/_git/${repo}`;
577
+ }
578
+ }
579
+ }
580
+ return null;
581
+ }
582
+ // visualstudio.com format: {org}.visualstudio.com/project/_git/repo
583
+ if (hostname.endsWith('.visualstudio.com')) {
584
+ const org = hostname.replace('.visualstudio.com', '');
585
+ const gitIndex = pathParts.indexOf('_git');
586
+ if (gitIndex >= 1 && pathParts[gitIndex + 1]) {
587
+ const project = pathParts.slice(0, gitIndex).join('/');
588
+ const repo = pathParts[gitIndex + 1];
589
+ if (project && repo) {
590
+ // Normalize to dev.azure.com format
591
+ return `https://dev.azure.com/${org}/${project}/_git/${repo}`;
592
+ }
593
+ }
594
+ return null;
595
+ }
596
+ return null;
597
+ }
598
+ /**
599
+ * Creates a RepositoryConfig from a git URL.
600
+ *
601
+ * This is a convenience function that combines `parseRepositoryUrl` with
602
+ * `createRepositoryConfig` to produce a ready-to-use configuration.
603
+ *
604
+ * @param gitUrl - Git repository URL in any supported format
605
+ * @returns RepositoryConfig or null if URL cannot be parsed
606
+ *
607
+ * @example
608
+ * ```typescript
609
+ * const config = createRepositoryConfigFromUrl('https://github.com/owner/repo')
610
+ * // → { platform: 'github', baseUrl: 'https://github.com/owner/repo' }
611
+ *
612
+ * const config = createRepositoryConfigFromUrl('git@gitlab.com:group/project.git')
613
+ * // → { platform: 'gitlab', baseUrl: 'https://gitlab.com/group/project' }
614
+ * ```
615
+ */
616
+ function createRepositoryConfigFromUrl(gitUrl) {
617
+ const parsed = parseRepositoryUrl(gitUrl);
618
+ if (!parsed) {
619
+ return null;
620
+ }
621
+ // Don't create configs for unknown platforms as they can't generate URLs
622
+ if (parsed.platform === 'unknown') {
623
+ return null;
624
+ }
625
+ return createRepositoryConfig({
626
+ platform: parsed.platform,
627
+ baseUrl: parsed.baseUrl,
628
+ });
629
+ }
630
+
631
+ /**
632
+ * Safe copies of JSON built-in methods.
633
+ *
634
+ * These references are captured at module initialization time to protect against
635
+ * prototype pollution attacks. Import only what you need for tree-shaking.
636
+ *
637
+ * @module @hyperfrontend/immutable-api-utils/built-in-copy/json
638
+ */
639
+ // Capture references at module initialization time
640
+ const _JSON = globalThis.JSON;
641
+ /**
642
+ * (Safe copy) Converts a JavaScript Object Notation (JSON) string into an object.
643
+ */
644
+ const parse = _JSON.parse;
645
+
646
+ /**
647
+ * Shorthand platform prefixes supported in package.json repository field.
648
+ *
649
+ * Format: `"platform:owner/repo"` or `"owner/repo"` (defaults to GitHub)
650
+ *
651
+ * @see https://docs.npmjs.com/cli/v9/configuring-npm/package-json#repository
652
+ */
653
+ const SHORTHAND_PLATFORMS = createMap([
654
+ ['github', 'https://github.com'],
655
+ ['gitlab', 'https://gitlab.com'],
656
+ ['bitbucket', 'https://bitbucket.org'],
657
+ ['gist', 'https://gist.github.com'],
658
+ ]);
659
+ /**
660
+ * Infers repository configuration from package.json content.
661
+ *
662
+ * Handles multiple formats:
663
+ * - Shorthand: `"github:owner/repo"`, `"gitlab:group/project"`, `"bitbucket:team/repo"`
664
+ * - Bare shorthand: `"owner/repo"` (defaults to GitHub)
665
+ * - URL string: `"https://github.com/owner/repo"`
666
+ * - Object with URL: `{ "type": "git", "url": "https://..." }`
667
+ *
668
+ * @param packageJsonContent - Raw JSON string content of package.json
669
+ * @returns RepositoryConfig or null if repository cannot be inferred
670
+ *
671
+ * @example
672
+ * ```typescript
673
+ * // Shorthand format
674
+ * inferRepositoryFromPackageJson('{"repository": "github:owner/repo"}')
675
+ * // → { platform: 'github', baseUrl: 'https://github.com/owner/repo' }
676
+ *
677
+ * // URL string
678
+ * inferRepositoryFromPackageJson('{"repository": "https://github.com/owner/repo"}')
679
+ * // → { platform: 'github', baseUrl: 'https://github.com/owner/repo' }
680
+ *
681
+ * // Object format
682
+ * inferRepositoryFromPackageJson('{"repository": {"type": "git", "url": "https://github.com/owner/repo"}}')
683
+ * // → { platform: 'github', baseUrl: 'https://github.com/owner/repo' }
684
+ *
685
+ * // Bare shorthand (defaults to GitHub)
686
+ * inferRepositoryFromPackageJson('{"repository": "owner/repo"}')
687
+ * // → { platform: 'github', baseUrl: 'https://github.com/owner/repo' }
688
+ * ```
689
+ */
690
+ function inferRepositoryFromPackageJson(packageJsonContent) {
691
+ if (!packageJsonContent || typeof packageJsonContent !== 'string') {
692
+ return null;
693
+ }
694
+ let packageJson;
695
+ try {
696
+ packageJson = parse(packageJsonContent);
697
+ }
698
+ catch {
699
+ return null;
700
+ }
701
+ return inferRepositoryFromPackageJsonObject(packageJson);
702
+ }
703
+ /**
704
+ * Infers repository configuration from a parsed package.json object.
705
+ *
706
+ * This is useful when you already have the parsed object.
707
+ *
708
+ * @param packageJson - Parsed package.json object
709
+ * @returns RepositoryConfig or null if repository cannot be inferred
710
+ *
711
+ * @example
712
+ * ```typescript
713
+ * const pkg = { repository: 'github:owner/repo' }
714
+ * inferRepositoryFromPackageJsonObject(pkg)
715
+ * // → { platform: 'github', baseUrl: 'https://github.com/owner/repo' }
716
+ * ```
717
+ */
718
+ function inferRepositoryFromPackageJsonObject(packageJson) {
719
+ const { repository } = packageJson;
720
+ if (!repository) {
721
+ return null;
722
+ }
723
+ // Handle string format
724
+ if (typeof repository === 'string') {
725
+ return parseRepositoryString(repository);
726
+ }
727
+ // Handle object format
728
+ if (typeof repository === 'object' && repository.url) {
729
+ return createRepositoryConfigFromUrl(repository.url);
730
+ }
731
+ return null;
732
+ }
733
+ /**
734
+ * Parses a repository string (shorthand or URL).
735
+ *
736
+ * @param repoString - Repository string from package.json
737
+ * @returns RepositoryConfig or null
738
+ *
739
+ * @internal
740
+ */
741
+ function parseRepositoryString(repoString) {
742
+ const trimmed = repoString.trim();
743
+ if (!trimmed) {
744
+ return null;
745
+ }
746
+ // Check for shorthand format: platform:owner/repo
747
+ const colonIndex = trimmed.indexOf(':');
748
+ if (colonIndex > 0) {
749
+ const potentialPlatform = trimmed.slice(0, colonIndex);
750
+ // Platform must be only letters (a-z, case insensitive)
751
+ if (isOnlyLetters(potentialPlatform)) {
752
+ const platform = potentialPlatform.toLowerCase();
753
+ const path = trimmed.slice(colonIndex + 1);
754
+ if (path) {
755
+ const baseUrl = SHORTHAND_PLATFORMS.get(platform);
756
+ if (baseUrl) {
757
+ // Construct full URL and parse it
758
+ const fullUrl = `${baseUrl}/${path}`;
759
+ return createRepositoryConfigFromUrl(fullUrl);
760
+ }
761
+ // Unknown shorthand platform - try as URL
762
+ return createRepositoryConfigFromUrl(trimmed);
763
+ }
764
+ }
765
+ }
766
+ // Check for bare shorthand: owner/repo (no protocol, no platform prefix)
767
+ // Must match pattern like "owner/repo" but not "https://..." or "git@..."
768
+ if (!trimmed.includes('://') && !trimmed.startsWith('git@')) {
769
+ if (isBareShorthand(trimmed)) {
770
+ // Bare shorthand defaults to GitHub
771
+ const fullUrl = `https://github.com/${trimmed}`;
772
+ return createRepositoryConfigFromUrl(fullUrl);
773
+ }
774
+ }
775
+ // Try as a full URL
776
+ return createRepositoryConfigFromUrl(trimmed);
777
+ }
778
+ /**
779
+ * Checks if a string contains only ASCII letters (a-z, A-Z).
780
+ *
781
+ * @param str - String to check
782
+ * @returns True if string contains only letters
783
+ *
784
+ * @internal
785
+ */
786
+ function isOnlyLetters(str) {
787
+ for (let i = 0; i < str.length; i++) {
788
+ const char = str.charCodeAt(i);
789
+ const isLowercase = char >= 97 && char <= 122; // a-z
790
+ const isUppercase = char >= 65 && char <= 90; // A-Z
791
+ if (!isLowercase && !isUppercase) {
792
+ return false;
793
+ }
794
+ }
795
+ return str.length > 0;
796
+ }
797
+ /**
798
+ * Checks if a string is a bare shorthand format (owner/repo).
799
+ * Must have exactly one forward slash with content on both sides.
800
+ *
801
+ * @param str - String to check
802
+ * @returns True if string matches owner/repo format
803
+ *
804
+ * @internal
805
+ */
806
+ function isBareShorthand(str) {
807
+ const slashIndex = str.indexOf('/');
808
+ if (slashIndex <= 0 || slashIndex === str.length - 1) {
809
+ return false;
810
+ }
811
+ // Must not have another slash
812
+ return str.indexOf('/', slashIndex + 1) === -1;
813
+ }
814
+ /**
815
+ * Extracts the repository URL from package.json content.
816
+ *
817
+ * Unlike `inferRepositoryFromPackageJson`, this returns just the URL string
818
+ * without creating a RepositoryConfig. Useful when you need the raw URL.
819
+ *
820
+ * @param packageJsonContent - Raw JSON string content of package.json
821
+ * @returns Repository URL string or null if not found
822
+ *
823
+ * @example
824
+ * ```typescript
825
+ * extractRepositoryUrl('{"repository": {"url": "https://github.com/owner/repo"}}')
826
+ * // → 'https://github.com/owner/repo'
827
+ *
828
+ * extractRepositoryUrl('{"repository": "github:owner/repo"}')
829
+ * // → null (shorthand is not a URL)
830
+ * ```
831
+ */
832
+ function extractRepositoryUrl(packageJsonContent) {
833
+ if (!packageJsonContent || typeof packageJsonContent !== 'string') {
834
+ return null;
835
+ }
836
+ let packageJson;
837
+ try {
838
+ packageJson = parse(packageJsonContent);
839
+ }
840
+ catch {
841
+ return null;
842
+ }
843
+ const { repository } = packageJson;
844
+ if (!repository) {
845
+ return null;
846
+ }
847
+ // String URL format
848
+ if (typeof repository === 'string') {
849
+ // Check if it's a URL (has protocol)
850
+ if (repository.includes('://') || repository.startsWith('git@')) {
851
+ const parsed = parseRepositoryUrl(repository);
852
+ return parsed && parsed.platform !== 'unknown' ? parsed.baseUrl : null;
853
+ }
854
+ // Shorthand - need to expand
855
+ const config = parseRepositoryString(repository);
856
+ return config ? config.baseUrl : null;
857
+ }
858
+ // Object format
859
+ if (typeof repository === 'object' && repository.url) {
860
+ const parsed = parseRepositoryUrl(repository.url);
861
+ return parsed && parsed.platform !== 'unknown' ? parsed.baseUrl : null;
862
+ }
863
+ return null;
864
+ }
865
+
866
+ /**
867
+ * Creates a platform-specific compare URL for viewing changes between two commits.
868
+ *
869
+ * Each platform has a different URL format:
870
+ * - **GitHub**: `{baseUrl}/compare/{fromCommit}...{toCommit}` (three dots)
871
+ * - **GitLab**: `{baseUrl}/-/compare/{fromCommit}...{toCommit}` (three dots, `/-/` prefix)
872
+ * - **Bitbucket**: `{baseUrl}/compare/{toCommit}..{fromCommit}` (two dots, reversed order)
873
+ * - **Azure DevOps**: `{baseUrl}/compare?version=GT{toCommit}&compareVersion=GT{fromCommit}` (query params)
874
+ *
875
+ * For `custom` platforms, a `formatCompareUrl` function must be provided in the repository config.
876
+ * For `unknown` platforms, returns `null`.
877
+ *
878
+ * @param options - Compare URL options including repository, fromCommit, and toCommit
879
+ * @returns The compare URL string, or null if URL cannot be generated
880
+ *
881
+ * @example
882
+ * ```typescript
883
+ * // GitHub
884
+ * createCompareUrl({
885
+ * repository: { platform: 'github', baseUrl: 'https://github.com/owner/repo' },
886
+ * fromCommit: 'abc1234',
887
+ * toCommit: 'def5678'
888
+ * })
889
+ * // → 'https://github.com/owner/repo/compare/abc1234...def5678'
890
+ *
891
+ * // GitLab
892
+ * createCompareUrl({
893
+ * repository: { platform: 'gitlab', baseUrl: 'https://gitlab.com/group/project' },
894
+ * fromCommit: 'abc1234',
895
+ * toCommit: 'def5678'
896
+ * })
897
+ * // → 'https://gitlab.com/group/project/-/compare/abc1234...def5678'
898
+ *
899
+ * // Bitbucket (reversed order)
900
+ * createCompareUrl({
901
+ * repository: { platform: 'bitbucket', baseUrl: 'https://bitbucket.org/owner/repo' },
902
+ * fromCommit: 'abc1234',
903
+ * toCommit: 'def5678'
904
+ * })
905
+ * // → 'https://bitbucket.org/owner/repo/compare/def5678..abc1234'
906
+ *
907
+ * // Azure DevOps
908
+ * createCompareUrl({
909
+ * repository: { platform: 'azure-devops', baseUrl: 'https://dev.azure.com/org/proj/_git/repo' },
910
+ * fromCommit: 'abc1234',
911
+ * toCommit: 'def5678'
912
+ * })
913
+ * // → 'https://dev.azure.com/org/proj/_git/repo/compare?version=GTdef5678&compareVersion=GTabc1234'
914
+ *
915
+ * // Custom formatter
916
+ * createCompareUrl({
917
+ * repository: {
918
+ * platform: 'custom',
919
+ * baseUrl: 'https://my-git.internal/repo',
920
+ * formatCompareUrl: (from, to) => `https://my-git.internal/diff/${from}/${to}`
921
+ * },
922
+ * fromCommit: 'abc1234',
923
+ * toCommit: 'def5678'
924
+ * })
925
+ * // → 'https://my-git.internal/diff/abc1234/def5678'
926
+ * ```
927
+ */
928
+ function createCompareUrl(options) {
929
+ const { repository, fromCommit, toCommit } = options;
930
+ // Validate inputs
931
+ if (!repository || !fromCommit || !toCommit) {
932
+ return null;
933
+ }
934
+ // If custom formatter is provided, use it (works for any platform including overrides)
935
+ if (repository.formatCompareUrl) {
936
+ return repository.formatCompareUrl(fromCommit, toCommit);
937
+ }
938
+ const { platform, baseUrl } = repository;
939
+ // Cannot generate URL for unknown platforms without a formatter
940
+ if (platform === 'unknown') {
941
+ return null;
942
+ }
943
+ // Custom platform requires a formatter
944
+ if (platform === 'custom') {
945
+ return null;
946
+ }
947
+ // Generate URL for known platforms
948
+ if (isKnownPlatform(platform)) {
949
+ return formatKnownPlatformCompareUrl(platform, baseUrl, fromCommit, toCommit);
950
+ }
951
+ return null;
952
+ }
953
+ /**
954
+ * Formats a compare URL for known platforms.
955
+ *
956
+ * @param platform - Known platform type
957
+ * @param baseUrl - Repository base URL
958
+ * @param fromCommit - Source commit hash (older version)
959
+ * @param toCommit - Target commit hash (newer version)
960
+ * @returns Formatted compare URL
961
+ *
962
+ * @internal
963
+ */
964
+ function formatKnownPlatformCompareUrl(platform, baseUrl, fromCommit, toCommit) {
965
+ switch (platform) {
966
+ case 'github':
967
+ // GitHub: {baseUrl}/compare/{fromCommit}...{toCommit}
968
+ return `${baseUrl}/compare/${fromCommit}...${toCommit}`;
969
+ case 'gitlab':
970
+ // GitLab: {baseUrl}/-/compare/{fromCommit}...{toCommit}
971
+ return `${baseUrl}/-/compare/${fromCommit}...${toCommit}`;
972
+ case 'bitbucket':
973
+ // Bitbucket: {baseUrl}/compare/{toCommit}..{fromCommit} (reversed order, two dots)
974
+ return `${baseUrl}/compare/${toCommit}..${fromCommit}`;
975
+ case 'azure-devops':
976
+ // Azure DevOps: {baseUrl}/compare?version=GT{toCommit}&compareVersion=GT{fromCommit}
977
+ // Use encodeURIComponent for query parameter values
978
+ return `${baseUrl}/compare?version=GT${encodeURIComponent(toCommit)}&compareVersion=GT${encodeURIComponent(fromCommit)}`;
979
+ }
980
+ }
981
+
982
+ exports.DEFAULT_INFERENCE_ORDER = DEFAULT_INFERENCE_ORDER;
983
+ exports.PLATFORM_HOSTNAMES = PLATFORM_HOSTNAMES;
984
+ exports.createCompareUrl = createCompareUrl;
985
+ exports.createDisabledResolution = createDisabledResolution;
986
+ exports.createExplicitResolution = createExplicitResolution;
987
+ exports.createInferredResolution = createInferredResolution;
988
+ exports.createRepositoryConfig = createRepositoryConfig;
989
+ exports.createRepositoryConfigFromUrl = createRepositoryConfigFromUrl;
990
+ exports.detectPlatformFromHostname = detectPlatformFromHostname;
991
+ exports.extractRepositoryUrl = extractRepositoryUrl;
992
+ exports.inferRepositoryFromPackageJson = inferRepositoryFromPackageJson;
993
+ exports.inferRepositoryFromPackageJsonObject = inferRepositoryFromPackageJsonObject;
994
+ exports.isKnownPlatform = isKnownPlatform;
995
+ exports.isRepositoryConfig = isRepositoryConfig;
996
+ exports.isRepositoryResolution = isRepositoryResolution;
997
+ exports.parseRepositoryUrl = parseRepositoryUrl;
998
+ //# sourceMappingURL=index.cjs.js.map