diff options
author | 2020-05-28 19:00:10 +0200 | |
---|---|---|
committer | 2020-05-28 19:00:10 +0200 | |
commit | 7589633720493550e359468ffdb4294858b74646 (patch) | |
tree | 9574de3d8a560ff0726fdb1070d561bc7e5d867a /source/github-helpers/github-url.ts | |
parent | 2235c23dedef9f5ef91cc07c53175e28e5f64b6d (diff) | |
download | refined-github-7589633720493550e359468ffdb4294858b74646.tar.gz refined-github-7589633720493550e359468ffdb4294858b74646.tar.zst refined-github-7589633720493550e359468ffdb4294858b74646.zip |
Meta: improve GitHub URL parser (#3138)
Diffstat (limited to 'source/github-helpers/github-url.ts')
-rw-r--r-- | source/github-helpers/github-url.ts | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/source/github-helpers/github-url.ts b/source/github-helpers/github-url.ts new file mode 100644 index 00000000..395723d4 --- /dev/null +++ b/source/github-helpers/github-url.ts @@ -0,0 +1,71 @@ +import {getCurrentBranch} from '.'; + +function disambiguateReference(ambiguousReference: string[]): {branch: string; filePath: string} { + const branch = ambiguousReference[0]; + const filePath = ambiguousReference.slice(1).join('/'); + + const currentBranch = getCurrentBranch(); + const currentBranchSections = currentBranch.split('/'); + if ( + ambiguousReference.length === 1 || // Ref has no slashes + currentBranchSections.length === 1 || // Current branch has no slashes + /\^|~|@{/.test(branch) // Ref is an extended revision #3137 https://git-scm.com/docs/git-rev-parse#_specifying_revisions + ) { + // Then the reference is not ambiguous + return {branch, filePath}; + } + + for (const [i, section] of currentBranchSections.entries()) { + if (ambiguousReference[i] !== section) { + console.warn(`The supplied path (${ambiguousReference.join('/')}) is ambiguous (current reference is \`${currentBranch}\`)`); + return {branch, filePath}; + } + } + + return { + branch: currentBranch, + filePath: ambiguousReference.slice(currentBranchSections.length).join('/') + }; +} + +export default class GitHubURL extends URL { + // @ts-ignore https://github.com/microsoft/TypeScript/issues/26792 + user: string; + // @ts-ignore + repository: string; + // @ts-ignore + route: string; + // @ts-ignore + branch: string; + // @ts-ignore + filePath: string; + constructor(url: string) { + super(url); + this.pathname = super.pathname; + } + + assign(replacements: Partial<GitHubURL>): this { + Object.assign(this, replacements); + return this; + } + + get pathname() { + return `/${this.user}/${this.repository}/${this.route}/${this.branch}/${this.filePath}`.replace(/\/+$/, ''); + } + + set pathname(pathname) { + const [user, repository, route, ...ambiguousReference] = pathname.replace(/^\/|\/$/g, '').split('/'); + const {branch, filePath} = disambiguateReference(ambiguousReference); + this.assign({user, repository, route, branch, filePath}); + } + + get href() { + // Update the actual underlying URL + super.pathname = this.pathname; + return super.href; + } + + toString() { + return this.href; + } +} |