Skip to content

Commit b5bd5e3

Browse files
committed
1 parent 6221e27 commit b5bd5e3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+9009
-13
lines changed

node_modules/.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,15 @@
195195
!/npm-packlist/node_modules/minimatch
196196
!/npm-pick-manifest
197197
!/npm-profile
198+
!/npm-profile/node_modules/
199+
/npm-profile/node_modules/*
200+
!/npm-profile/node_modules/hosted-git-info
201+
!/npm-profile/node_modules/lru-cache
202+
!/npm-profile/node_modules/make-fetch-happen
203+
!/npm-profile/node_modules/minizlib
204+
!/npm-profile/node_modules/negotiator
205+
!/npm-profile/node_modules/npm-package-arg
206+
!/npm-profile/node_modules/npm-registry-fetch
198207
!/npm-registry-fetch
199208
!/npm-registry-fetch/node_modules/
200209
/npm-registry-fetch/node_modules/*
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Copyright (c) 2015, Rebecca Turner
2+
3+
Permission to use, copy, modify, and/or distribute this software for any
4+
purpose with or without fee is hereby granted, provided that the above
5+
copyright notice and this permission notice appear in all copies.
6+
7+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
8+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
9+
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
10+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
11+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
12+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
13+
PERFORMANCE OF THIS SOFTWARE.
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
'use strict'
2+
3+
const parseUrl = require('./parse-url')
4+
5+
// look for github shorthand inputs, such as npm/cli
6+
const isGitHubShorthand = (arg) => {
7+
// it cannot contain whitespace before the first #
8+
// it cannot start with a / because that's probably an absolute file path
9+
// but it must include a slash since repos are username/repository
10+
// it cannot start with a . because that's probably a relative file path
11+
// it cannot start with an @ because that's a scoped package if it passes the other tests
12+
// it cannot contain a : before a # because that tells us that there's a protocol
13+
// a second / may not exist before a #
14+
const firstHash = arg.indexOf('#')
15+
const firstSlash = arg.indexOf('/')
16+
const secondSlash = arg.indexOf('/', firstSlash + 1)
17+
const firstColon = arg.indexOf(':')
18+
const firstSpace = /\s/.exec(arg)
19+
const firstAt = arg.indexOf('@')
20+
21+
const spaceOnlyAfterHash = !firstSpace || (firstHash > -1 && firstSpace.index > firstHash)
22+
const atOnlyAfterHash = firstAt === -1 || (firstHash > -1 && firstAt > firstHash)
23+
const colonOnlyAfterHash = firstColon === -1 || (firstHash > -1 && firstColon > firstHash)
24+
const secondSlashOnlyAfterHash = secondSlash === -1 || (firstHash > -1 && secondSlash > firstHash)
25+
const hasSlash = firstSlash > 0
26+
// if a # is found, what we really want to know is that the character
27+
// immediately before # is not a /
28+
const doesNotEndWithSlash = firstHash > -1 ? arg[firstHash - 1] !== '/' : !arg.endsWith('/')
29+
const doesNotStartWithDot = !arg.startsWith('.')
30+
31+
return spaceOnlyAfterHash && hasSlash && doesNotEndWithSlash &&
32+
doesNotStartWithDot && atOnlyAfterHash && colonOnlyAfterHash &&
33+
secondSlashOnlyAfterHash
34+
}
35+
36+
module.exports = (giturl, opts, { gitHosts, protocols }) => {
37+
if (!giturl) {
38+
return
39+
}
40+
41+
const correctedUrl = isGitHubShorthand(giturl) ? `github:${giturl}` : giturl
42+
const parsed = parseUrl(correctedUrl, protocols)
43+
if (!parsed) {
44+
return
45+
}
46+
47+
const gitHostShortcut = gitHosts.byShortcut[parsed.protocol]
48+
const gitHostDomain = gitHosts.byDomain[parsed.hostname.startsWith('www.')
49+
? parsed.hostname.slice(4)
50+
: parsed.hostname]
51+
const gitHostName = gitHostShortcut || gitHostDomain
52+
if (!gitHostName) {
53+
return
54+
}
55+
56+
const gitHostInfo = gitHosts[gitHostShortcut || gitHostDomain]
57+
let auth = null
58+
if (protocols[parsed.protocol]?.auth && (parsed.username || parsed.password)) {
59+
auth = `${parsed.username}${parsed.password ? ':' + parsed.password : ''}`
60+
}
61+
62+
let committish = null
63+
let user = null
64+
let project = null
65+
let defaultRepresentation = null
66+
67+
try {
68+
if (gitHostShortcut) {
69+
let pathname = parsed.pathname.startsWith('/') ? parsed.pathname.slice(1) : parsed.pathname
70+
const firstAt = pathname.indexOf('@')
71+
// we ignore auth for shortcuts, so just trim it out
72+
if (firstAt > -1) {
73+
pathname = pathname.slice(firstAt + 1)
74+
}
75+
76+
const lastSlash = pathname.lastIndexOf('/')
77+
if (lastSlash > -1) {
78+
user = decodeURIComponent(pathname.slice(0, lastSlash))
79+
// we want nulls only, never empty strings
80+
if (!user) {
81+
user = null
82+
}
83+
project = decodeURIComponent(pathname.slice(lastSlash + 1))
84+
} else {
85+
project = decodeURIComponent(pathname)
86+
}
87+
88+
if (project.endsWith('.git')) {
89+
project = project.slice(0, -4)
90+
}
91+
92+
if (parsed.hash) {
93+
committish = decodeURIComponent(parsed.hash.slice(1))
94+
}
95+
96+
defaultRepresentation = 'shortcut'
97+
} else {
98+
if (!gitHostInfo.protocols.includes(parsed.protocol)) {
99+
return
100+
}
101+
102+
const segments = gitHostInfo.extract(parsed)
103+
if (!segments) {
104+
return
105+
}
106+
107+
user = segments.user && decodeURIComponent(segments.user)
108+
project = decodeURIComponent(segments.project)
109+
committish = decodeURIComponent(segments.committish)
110+
defaultRepresentation = protocols[parsed.protocol]?.name || parsed.protocol.slice(0, -1)
111+
}
112+
} catch (err) {
113+
/* istanbul ignore else */
114+
if (err instanceof URIError) {
115+
return
116+
} else {
117+
throw err
118+
}
119+
}
120+
121+
return [gitHostName, user, auth, project, committish, defaultRepresentation, opts]
122+
}
Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
/* eslint-disable max-len */
2+
3+
'use strict'
4+
5+
const maybeJoin = (...args) => args.every(arg => arg) ? args.join('') : ''
6+
const maybeEncode = (arg) => arg ? encodeURIComponent(arg) : ''
7+
const formatHashFragment = (f) => f.toLowerCase()
8+
.replace(/^\W+/g, '') // strip leading non-characters
9+
.replace(/(?<!\W)\W+$/, '') // strip trailing non-characters
10+
.replace(/\//g, '') // strip all slashes
11+
.replace(/\W+/g, '-') // replace remaining non-characters with '-'
12+
13+
const defaults = {
14+
sshtemplate: ({ domain, user, project, committish }) =>
15+
`git@${domain}:${user}/${project}.git${maybeJoin('#', committish)}`,
16+
sshurltemplate: ({ domain, user, project, committish }) =>
17+
`git+ssh://git@${domain}/${user}/${project}.git${maybeJoin('#', committish)}`,
18+
edittemplate: ({ domain, user, project, committish, editpath, path }) =>
19+
`https://${domain}/${user}/${project}${maybeJoin('/', editpath, '/', maybeEncode(committish || 'HEAD'), '/', path)}`,
20+
browsetemplate: ({ domain, user, project, committish, treepath }) =>
21+
`https://${domain}/${user}/${project}${maybeJoin('/', treepath, '/', maybeEncode(committish))}`,
22+
browsetreetemplate: ({ domain, user, project, committish, treepath, path, fragment, hashformat }) =>
23+
`https://${domain}/${user}/${project}/${treepath}/${maybeEncode(committish || 'HEAD')}/${path}${maybeJoin('#', hashformat(fragment || ''))}`,
24+
browseblobtemplate: ({ domain, user, project, committish, blobpath, path, fragment, hashformat }) =>
25+
`https://${domain}/${user}/${project}/${blobpath}/${maybeEncode(committish || 'HEAD')}/${path}${maybeJoin('#', hashformat(fragment || ''))}`,
26+
docstemplate: ({ domain, user, project, treepath, committish }) =>
27+
`https://${domain}/${user}/${project}${maybeJoin('/', treepath, '/', maybeEncode(committish))}#readme`,
28+
httpstemplate: ({ auth, domain, user, project, committish }) =>
29+
`git+https://${maybeJoin(auth, '@')}${domain}/${user}/${project}.git${maybeJoin('#', committish)}`,
30+
filetemplate: ({ domain, user, project, committish, path }) =>
31+
`https://${domain}/${user}/${project}/raw/${maybeEncode(committish || 'HEAD')}/${path}`,
32+
shortcuttemplate: ({ type, user, project, committish }) =>
33+
`${type}:${user}/${project}${maybeJoin('#', committish)}`,
34+
pathtemplate: ({ user, project, committish }) =>
35+
`${user}/${project}${maybeJoin('#', committish)}`,
36+
bugstemplate: ({ domain, user, project }) =>
37+
`https://${domain}/${user}/${project}/issues`,
38+
hashformat: formatHashFragment,
39+
}
40+
41+
const hosts = {}
42+
hosts.github = {
43+
// First two are insecure and generally shouldn't be used any more, but
44+
// they are still supported.
45+
protocols: ['git:', 'http:', 'git+ssh:', 'git+https:', 'ssh:', 'https:'],
46+
domain: 'github.com',
47+
treepath: 'tree',
48+
blobpath: 'blob',
49+
editpath: 'edit',
50+
filetemplate: ({ auth, user, project, committish, path }) =>
51+
`https://${maybeJoin(auth, '@')}raw.githubusercontent.com/${user}/${project}/${maybeEncode(committish || 'HEAD')}/${path}`,
52+
gittemplate: ({ auth, domain, user, project, committish }) =>
53+
`git://${maybeJoin(auth, '@')}${domain}/${user}/${project}.git${maybeJoin('#', committish)}`,
54+
tarballtemplate: ({ domain, user, project, committish }) =>
55+
`https://codeload.${domain}/${user}/${project}/tar.gz/${maybeEncode(committish || 'HEAD')}`,
56+
extract: (url) => {
57+
let [, user, project, type, committish] = url.pathname.split('/', 5)
58+
if (type && type !== 'tree') {
59+
return
60+
}
61+
62+
if (!type) {
63+
committish = url.hash.slice(1)
64+
}
65+
66+
if (project && project.endsWith('.git')) {
67+
project = project.slice(0, -4)
68+
}
69+
70+
if (!user || !project) {
71+
return
72+
}
73+
74+
return { user, project, committish }
75+
},
76+
}
77+
78+
hosts.bitbucket = {
79+
protocols: ['git+ssh:', 'git+https:', 'ssh:', 'https:'],
80+
domain: 'bitbucket.org',
81+
treepath: 'src',
82+
blobpath: 'src',
83+
editpath: '?mode=edit',
84+
edittemplate: ({ domain, user, project, committish, treepath, path, editpath }) =>
85+
`https://${domain}/${user}/${project}${maybeJoin('/', treepath, '/', maybeEncode(committish || 'HEAD'), '/', path, editpath)}`,
86+
tarballtemplate: ({ domain, user, project, committish }) =>
87+
`https://${domain}/${user}/${project}/get/${maybeEncode(committish || 'HEAD')}.tar.gz`,
88+
extract: (url) => {
89+
let [, user, project, aux] = url.pathname.split('/', 4)
90+
if (['get'].includes(aux)) {
91+
return
92+
}
93+
94+
if (project && project.endsWith('.git')) {
95+
project = project.slice(0, -4)
96+
}
97+
98+
if (!user || !project) {
99+
return
100+
}
101+
102+
return { user, project, committish: url.hash.slice(1) }
103+
},
104+
}
105+
106+
hosts.gitlab = {
107+
protocols: ['git+ssh:', 'git+https:', 'ssh:', 'https:'],
108+
domain: 'gitlab.com',
109+
treepath: 'tree',
110+
blobpath: 'tree',
111+
editpath: '-/edit',
112+
httpstemplate: ({ auth, domain, user, project, committish }) =>
113+
`git+https://${maybeJoin(auth, '@')}${domain}/${user}/${project}.git${maybeJoin('#', committish)}`,
114+
tarballtemplate: ({ domain, user, project, committish }) =>
115+
`https://${domain}/${user}/${project}/repository/archive.tar.gz?ref=${maybeEncode(committish || 'HEAD')}`,
116+
extract: (url) => {
117+
const path = url.pathname.slice(1)
118+
if (path.includes('/-/') || path.includes('/archive.tar.gz')) {
119+
return
120+
}
121+
122+
const segments = path.split('/')
123+
let project = segments.pop()
124+
if (project.endsWith('.git')) {
125+
project = project.slice(0, -4)
126+
}
127+
128+
const user = segments.join('/')
129+
if (!user || !project) {
130+
return
131+
}
132+
133+
return { user, project, committish: url.hash.slice(1) }
134+
},
135+
}
136+
137+
hosts.gist = {
138+
protocols: ['git:', 'git+ssh:', 'git+https:', 'ssh:', 'https:'],
139+
domain: 'gist.github.com',
140+
editpath: 'edit',
141+
sshtemplate: ({ domain, project, committish }) =>
142+
`git@${domain}:${project}.git${maybeJoin('#', committish)}`,
143+
sshurltemplate: ({ domain, project, committish }) =>
144+
`git+ssh://git@${domain}/${project}.git${maybeJoin('#', committish)}`,
145+
edittemplate: ({ domain, user, project, committish, editpath }) =>
146+
`https://${domain}/${user}/${project}${maybeJoin('/', maybeEncode(committish))}/${editpath}`,
147+
browsetemplate: ({ domain, project, committish }) =>
148+
`https://${domain}/${project}${maybeJoin('/', maybeEncode(committish))}`,
149+
browsetreetemplate: ({ domain, project, committish, path, hashformat }) =>
150+
`https://${domain}/${project}${maybeJoin('/', maybeEncode(committish))}${maybeJoin('#', hashformat(path))}`,
151+
browseblobtemplate: ({ domain, project, committish, path, hashformat }) =>
152+
`https://${domain}/${project}${maybeJoin('/', maybeEncode(committish))}${maybeJoin('#', hashformat(path))}`,
153+
docstemplate: ({ domain, project, committish }) =>
154+
`https://${domain}/${project}${maybeJoin('/', maybeEncode(committish))}`,
155+
httpstemplate: ({ domain, project, committish }) =>
156+
`git+https://${domain}/${project}.git${maybeJoin('#', committish)}`,
157+
filetemplate: ({ user, project, committish, path }) =>
158+
`https://gist.githubusercontent.com/${user}/${project}/raw${maybeJoin('/', maybeEncode(committish))}/${path}`,
159+
shortcuttemplate: ({ type, project, committish }) =>
160+
`${type}:${project}${maybeJoin('#', committish)}`,
161+
pathtemplate: ({ project, committish }) =>
162+
`${project}${maybeJoin('#', committish)}`,
163+
bugstemplate: ({ domain, project }) =>
164+
`https://${domain}/${project}`,
165+
gittemplate: ({ domain, project, committish }) =>
166+
`git://${domain}/${project}.git${maybeJoin('#', committish)}`,
167+
tarballtemplate: ({ project, committish }) =>
168+
`https://codeload.github.com/gist/${project}/tar.gz/${maybeEncode(committish || 'HEAD')}`,
169+
extract: (url) => {
170+
let [, user, project, aux] = url.pathname.split('/', 4)
171+
if (aux === 'raw') {
172+
return
173+
}
174+
175+
if (!project) {
176+
if (!user) {
177+
return
178+
}
179+
180+
project = user
181+
user = null
182+
}
183+
184+
if (project.endsWith('.git')) {
185+
project = project.slice(0, -4)
186+
}
187+
188+
return { user, project, committish: url.hash.slice(1) }
189+
},
190+
hashformat: function (fragment) {
191+
return fragment && 'file-' + formatHashFragment(fragment)
192+
},
193+
}
194+
195+
hosts.sourcehut = {
196+
protocols: ['git+ssh:', 'https:'],
197+
domain: 'git.sr.ht',
198+
treepath: 'tree',
199+
blobpath: 'tree',
200+
filetemplate: ({ domain, user, project, committish, path }) =>
201+
`https://${domain}/${user}/${project}/blob/${maybeEncode(committish) || 'HEAD'}/${path}`,
202+
httpstemplate: ({ domain, user, project, committish }) =>
203+
`https://${domain}/${user}/${project}.git${maybeJoin('#', committish)}`,
204+
tarballtemplate: ({ domain, user, project, committish }) =>
205+
`https://${domain}/${user}/${project}/archive/${maybeEncode(committish) || 'HEAD'}.tar.gz`,
206+
bugstemplate: () => null,
207+
extract: (url) => {
208+
let [, user, project, aux] = url.pathname.split('/', 4)
209+
210+
// tarball url
211+
if (['archive'].includes(aux)) {
212+
return
213+
}
214+
215+
if (project && project.endsWith('.git')) {
216+
project = project.slice(0, -4)
217+
}
218+
219+
if (!user || !project) {
220+
return
221+
}
222+
223+
return { user, project, committish: url.hash.slice(1) }
224+
},
225+
}
226+
227+
for (const [name, host] of Object.entries(hosts)) {
228+
hosts[name] = Object.assign({}, defaults, host)
229+
}
230+
231+
module.exports = hosts

0 commit comments

Comments
 (0)