@hyperfrontend/versioning/repositoryrepository/
Repository detection and compare URL generation for changelog entries.
Overview
This module handles repository configuration for generating compare URLs in changelog entries. It supports automatic detection from package.json or git remotes, with built-in formatters for GitHub, GitLab, Bitbucket, and Azure DevOps.
Supported Platforms
| Platform | Compare URL Format |
|---|---|
| GitHub | {baseUrl}/compare/{fromCommit}...{toCommit} |
| GitLab | {baseUrl}/-/compare/{fromCommit}...{toCommit} |
| Bitbucket | {baseUrl}/compare/{toCommit}..{fromCommit} (reversed) |
| Azure DevOps | {baseUrl}?version=GT{toCommit}&compareVersion=GT{from} |
Usage Examples
Parse Repository URL
import { parseRepositoryUrl } from '@hyperfrontend/versioning/repository/parse'
// HTTPS URLs
parseRepositoryUrl('https://github.com/owner/repo')
// → { platform: 'github', baseUrl: 'https://github.com/owner/repo' }
// SSH URLs
parseRepositoryUrl('git@github.com:owner/repo.git')
// → { platform: 'github', baseUrl: 'https://github.com/owner/repo' }
// GitLab with subgroups
parseRepositoryUrl('https://gitlab.com/group/subgroup/project')
// → { platform: 'gitlab', baseUrl: 'https://gitlab.com/group/subgroup/project' }
Generate Compare URL
import { createRepositoryConfig } from '@hyperfrontend/versioning/repository'
import { createCompareUrl } from '@hyperfrontend/versioning/repository/url'
const repo = createRepositoryConfig({
platform: 'github',
baseUrl: 'https://github.com/owner/repo',
})
createCompareUrl({ repository: repo, fromCommit: 'abc1234', toCommit: 'def5678' })
// → 'https://github.com/owner/repo/compare/abc1234...def5678'
Custom Platform Formatter
import { createRepositoryConfig } from '@hyperfrontend/versioning/repository'
const repo = createRepositoryConfig({
platform: 'custom',
baseUrl: 'https://my-git.internal/repo',
formatCompareUrl: (from, to) => `https://my-git.internal/diff/${from}/${to}`,
})
Flow Integration
The repository module integrates with the versioning flow via the repository config option:
import { createVersionFlow } from '@hyperfrontend/versioning/flow'
// Auto-detect from package.json or git remote
const flow = createVersionFlow('conventional', {
repository: 'inferred',
})
// Explicit configuration
const flow2 = createVersionFlow('conventional', {
repository: {
mode: 'explicit',
repository: {
platform: 'github',
baseUrl: 'https://github.com/owner/repo',
},
},
})
// Disable compare URLs
const flow3 = createVersionFlow('conventional', {
repository: 'disabled',
})
Constants
| Export | Value | Description |
|---|---|---|
PLATFORM_HOSTNAMES |
Map of hostnames to platforms | Known platform hostname mapping |
DEFAULT_INFERENCE_ORDER |
['package-json', 'git-remote'] |
Default inference source order |
API Reference
ƒ Functions
Each platform has a different URL format:
- GitHub:
{baseUrl}/compare/{fromCommit}...{toCommit}(three dots) - GitLab:
{baseUrl}/-/compare/{fromCommit}...{toCommit}(three dots,/-/prefix) - Bitbucket:
{baseUrl}/compare/{toCommit}..{fromCommit}(two dots, reversed order) - Azure DevOps:
{baseUrl}/compare?version=GT{toCommit}&compareVersion=GT{fromCommit}(query params)
custom platforms, a formatCompareUrl function must be provided in the repository config. For unknown platforms, returns null.Parameters
| Name | Type | Description |
|---|---|---|
§options | CreateCompareUrlOptions | Compare URL options including repository, fromCommit, and toCommit |
Returns
stringExample
Creating platform-specific compare URLs
// GitHub
createCompareUrl({
repository: { platform: 'github', baseUrl: 'https://github.com/owner/repo' },
fromCommit: 'abc1234',
toCommit: 'def5678'
})
// → 'https://github.com/owner/repo/compare/abc1234...def5678'
// GitLab
createCompareUrl({
repository: { platform: 'gitlab', baseUrl: 'https://gitlab.com/group/project' },
fromCommit: 'abc1234',
toCommit: 'def5678'
})
// → 'https://gitlab.com/group/project/-/compare/abc1234...def5678'
// Bitbucket (reversed order)
createCompareUrl({
repository: { platform: 'bitbucket', baseUrl: 'https://bitbucket.org/owner/repo' },
fromCommit: 'abc1234',
toCommit: 'def5678'
})
// → 'https://bitbucket.org/owner/repo/compare/def5678..abc1234'
// Azure DevOps
createCompareUrl({
repository: { platform: 'azure-devops', baseUrl: 'https://dev.azure.com/org/proj/_git/repo' },
fromCommit: 'abc1234',
toCommit: 'def5678'
})
// → 'https://dev.azure.com/org/proj/_git/repo/compare?version=GTdef5678&compareVersion=GTabc1234'
// Custom formatter
createCompareUrl({
repository: {
platform: 'custom',
baseUrl: 'https://my-git.internal/repo',
formatCompareUrl: (from, to) => `https://my-git.internal/diff/${from}/${to}`
},
fromCommit: 'abc1234',
toCommit: 'def5678'
})
// → 'https://my-git.internal/diff/abc1234/def5678'No compare URLs will be generated.
Returns
RepositoryResolutionExample
Disabling repository resolution
const config = createDisabledResolution()
// { mode: 'disabled' }Parameters
| Name | Type | Description |
|---|---|---|
§repository | RepositoryConfig | The repository config to use |
Returns
RepositoryResolutionExample
Using an explicit repository configuration
const config = createExplicitResolution({
platform: 'github',
baseUrl: 'https://github.com/owner/repo'
})Parameters
| Name | Type | Description |
|---|---|---|
§inferenceOrder | unknown | Order to try inference sources (default: package-json first) (default: ...) |
Returns
RepositoryResolutionExample
Configuring inference order
// Default order: package.json → git remote
const config = createInferredResolution()
// Custom order: git remote → package.json
const customOrder = createInferredResolution(['git-remote', 'package-json'])Normalizes the base URL by stripping trailing slashes and validating that custom platforms have a formatter function.
Parameters
| Name | Type | Description |
|---|---|---|
§options | CreateRepositoryConfigOptions | Repository configuration options |
Returns
RepositoryConfigExample
Creating repository configurations
// GitHub repository
const config = createRepositoryConfig({
platform: 'github',
baseUrl: 'https://github.com/owner/repo'
})
// Custom platform
const customConfig = createRepositoryConfig({
platform: 'custom',
baseUrl: 'https://my-git.internal/repo',
formatCompareUrl: (from, to) => `https://my-git.internal/diff/${from}/${to}`
})This is a convenience function that combines
parseRepositoryUrl with createRepositoryConfig to produce a ready-to-use configuration.Parameters
| Name | Type | Description |
|---|---|---|
§gitUrl | string | Git repository URL in any supported format |
Returns
RepositoryConfigExample
Creating config from git URLs
const config = createRepositoryConfigFromUrl('https://github.com/owner/repo'))
// → { platform: 'github', baseUrl: 'https://github.com/owner/repo' }
const config = createRepositoryConfigFromUrl('git@gitlab.com:group/project.git')
// → { platform: 'gitlab', baseUrl: 'https://gitlab.com/group/project' }First checks for exact match in known platforms, then applies heuristics for self-hosted instances (e.g.,
github.company.com → github).Parameters
| Name | Type | Description |
|---|---|---|
§hostname | string | Hostname to detect platform from (e.g., "github.com") |
Returns
RepositoryPlatformExample
Detecting platform from hostname
detectPlatformFromHostname('github.com') // 'github'
detectPlatformFromHostname('gitlab.mycompany.com') // 'gitlab'
detectPlatformFromHostname('custom-git.internal') // 'unknown'Unlike
inferRepositoryFromPackageJson, this returns just the URL string without creating a RepositoryConfig. Useful when you need the raw URL.Parameters
| Name | Type | Description |
|---|---|---|
§packageJsonContent | string | Raw JSON string content of package.json |
Returns
stringExample
Extracting raw repository URL
extractRepositoryUrl('{"repository": {"url": "https://github.com/owner/repo"}}')
// → 'https://github.com/owner/repo'
extractRepositoryUrl('{"repository": "github:owner/repo"}')
// → null (shorthand is not a URL)Handles multiple formats:
- Shorthand:
"github:owner/repo","gitlab:group/project","bitbucket:team/repo" - Bare shorthand:
"owner/repo"(defaults to GitHub) - URL string:
"https://github.com/owner/repo" - Object with URL:
{ "type": "git", "url": "https://..." }
Parameters
| Name | Type | Description |
|---|---|---|
§packageJsonContent | string | Raw JSON string content of package.json |
Returns
RepositoryConfigExample
Inferring repository from package.json content
// Shorthand format
inferRepositoryFromPackageJson('{"repository": "github:owner/repo"}')
// → { platform: 'github', baseUrl: 'https://github.com/owner/repo' }
// URL string
inferRepositoryFromPackageJson('{"repository": "https://github.com/owner/repo"}')
// → { platform: 'github', baseUrl: 'https://github.com/owner/repo' }
// Object format
inferRepositoryFromPackageJson('{"repository": {"type": "git", "url": "https://github.com/owner/repo"}}')
// → { platform: 'github', baseUrl: 'https://github.com/owner/repo' }
// Bare shorthand (defaults to GitHub)
inferRepositoryFromPackageJson('{"repository": "owner/repo"}')
// → { platform: 'github', baseUrl: 'https://github.com/owner/repo' }inferRepositoryFromPackageJsonObject(packageJson: PackageJsonForRepository): RepositoryConfig
This is useful when you already have the parsed object.
Parameters
| Name | Type | Description |
|---|---|---|
§packageJson | PackageJsonForRepository | Parsed package.json object |
Returns
RepositoryConfigExample
Inferring repository from parsed object
const pkg = { repository: 'github:owner/repo' }
inferRepositoryFromPackageJsonObject(pkg)
// → { platform: 'github', baseUrl: 'https://github.com/owner/repo' }Parameters
| Name | Type | Description |
|---|---|---|
§platform | RepositoryPlatform | Platform identifier to check |
Returns
unknownExample
Checking if platform has built-in support
isKnownPlatform('github') // true
isKnownPlatform('gitlab') // true
isKnownPlatform('custom') // false
isKnownPlatform('unknown') // falseParameters
| Name | Type | Description |
|---|---|---|
§value | unknown | Value to check |
Returns
unknownExample
Type-checking repository config values
const config = { platform: 'github', baseUrl: 'https://...' }
if (isRepositoryConfig(config)) {
// config is typed as RepositoryConfig
}Parameters
| Name | Type | Description |
|---|---|---|
§value | unknown | Value to check |
Returns
unknownExample
Type-checking resolution configurations
import { isRepositoryResolution } from '@hyperfrontend/versioning'
const config = loadConfig()
if (isRepositoryResolution(config.repository)) {
console.log('Repository mode:', config.repository.mode)
}Supports multiple URL formats:
https://github.com/owner/repohttps://github.com/owner/repo.gitgit+https://github.com/owner/repo.gitgit://github.com/owner/repo.gitgit@github.com:owner/repo.git(SSH format)
github.mycompany.com→githubgitlab.internal.com→gitlab
https://dev.azure.com/org/project/_git/repohttps://org.visualstudio.com/project/_git/repo
Parameters
| Name | Type | Description |
|---|---|---|
§gitUrl | string | Git repository URL in any supported format |
Returns
ParsedRepositoryExample
Parsing various git URL formats
// GitHub HTTPS
parseRepositoryUrl('https://github.com/owner/repo')
// → { platform: 'github', baseUrl: 'https://github.com/owner/repo' }
// SSH format
parseRepositoryUrl('git@github.com:owner/repo.git')
// → { platform: 'github', baseUrl: 'https://github.com/owner/repo' }
// Azure DevOps
parseRepositoryUrl('https://dev.azure.com/org/proj/_git/repo')
// → { platform: 'azure-devops', baseUrl: 'https://dev.azure.com/org/proj/_git/repo' }
// Self-hosted GitLab
parseRepositoryUrl('https://gitlab.mycompany.com/team/project')
// → { platform: 'gitlab', baseUrl: 'https://gitlab.mycompany.com/team/project' }◈ Interfaces
Properties
Package.json supports multiple formats for the repository field:
- Shorthand:
"github:owner/repo" - URL string:
"https://github.com/owner/repo" - Object:
{ "type": "git", "url": "..." }
Supports both standard platforms and self-hosted instances. When using a known platform, compare URLs are generated automatically. For custom or unknown platforms, provide a
formatCompareUrl function.Properties
readonly baseUrl:string— This is the URL without any trailing slashes or paths like
/compare.readonly formatCompareUrl?:CompareUrlFormatter— Required when
platform is 'custom'. Optional for known platforms (overrides built-in formatter). Receives the from and to tags, returns the full compare URL.
Provides fine-grained control over repository resolution behavior.
Properties
readonly inferenceOrder?:unknown— mode is 'inferred'. Sources are tried in order until one succeeds. Default:
['package-json', 'git-remote']readonly repository?:RepositoryConfig— Required when
mode is 'explicit'. Ignored when mode is 'inferred' or 'disabled'.◆ Types
type CompareUrlFormatter = (fromCommit: string, toCommit: string) => stringEach platform has a specific URL format for compare links:
github:{baseUrl}/compare/{fromCommit}...{toCommit}gitlab:{baseUrl}/-/compare/{fromCommit}...{toCommit}bitbucket:{baseUrl}/compare/{toCommit}..{fromCommit}(reversed order)azure-devops:{baseUrl}/compare?version=GT{toCommit}&compareVersion=GT{fromCommit}
type KnownPlatform = "github" | "gitlab" | "bitbucket" | "azure-devops"package-json: Read fromrepositoryfield in package.jsongit-remote: Read fromgit remote get-url origin
type RepositoryInferenceSource = "package-json" | "git-remote"- Known platforms have built-in compare URL formatters
customrequires a customformatCompareUrlfunctionunknownindicates platform could not be determined (no URL generation)
type RepositoryPlatform = KnownPlatform | "custom" | "unknown"explicit: Use only the providedRepositoryConfig; error if missinginferred: Auto-detect from package.json repository field or git remotedisabled: Do not generate compare URLs (default for backward compatibility)
type RepositoryResolutionMode = "explicit" | "inferred" | "disabled"