codekingpro/portable-devtools
115k
1/* eslint-disable max-len */
2
3'use strict'
4
5const maybeJoin = (...args) => args.every(arg => arg) ? args.join('') : ''
6const maybeEncode = (arg) => arg ? encodeURIComponent(arg) : ''
7const 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
13const 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
41const hosts = {}
42hosts.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
78hosts.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
106hosts.gitlab = {
107 protocols: ['git+ssh:', 'git+https:', 'ssh:', 'https:'],
108 domain: 'gitlab.com',
109 treepath: 'tree',
110 blobpath: 'tree',
111 editpath: '-/edit',
112 tarballtemplate: ({ domain, user, project, committish }) =>
113 `https://${domain}/${user}/${project}/repository/archive.tar.gz?ref=${maybeEncode(committish || 'HEAD')}`,
114 extract: (url) => {
115 const path = url.pathname.slice(1)
116 if (path.includes('/-/') || path.includes('/archive.tar.gz')) {
117 return
118 }
119
120 const segments = path.split('/')
121 let project = segments.pop()
122 if (project.endsWith('.git')) {
123 project = project.slice(0, -4)
124 }
125
126 const user = segments.join('/')
127 if (!user || !project) {
128 return
129 }
130
131 return { user, project, committish: url.hash.slice(1) }
132 },
133}
134
135hosts.gist = {
136 protocols: ['git:', 'git+ssh:', 'git+https:', 'ssh:', 'https:'],
137 domain: 'gist.github.com',
138 editpath: 'edit',
139 sshtemplate: ({ domain, project, committish }) =>
140 `git@${domain}:${project}.git${maybeJoin('#', committish)}`,
141 sshurltemplate: ({ domain, project, committish }) =>
142 `git+ssh://git@${domain}/${project}.git${maybeJoin('#', committish)}`,
143 edittemplate: ({ domain, user, project, committish, editpath }) =>
144 `https://${domain}/${user}/${project}${maybeJoin('/', maybeEncode(committish))}/${editpath}`,
145 browsetemplate: ({ domain, project, committish }) =>
146 `https://${domain}/${project}${maybeJoin('/', maybeEncode(committish))}`,
147 browsetreetemplate: ({ domain, project, committish, path, hashformat }) =>
148 `https://${domain}/${project}${maybeJoin('/', maybeEncode(committish))}${maybeJoin('#', hashformat(path))}`,
149 browseblobtemplate: ({ domain, project, committish, path, hashformat }) =>
150 `https://${domain}/${project}${maybeJoin('/', maybeEncode(committish))}${maybeJoin('#', hashformat(path))}`,
151 docstemplate: ({ domain, project, committish }) =>
152 `https://${domain}/${project}${maybeJoin('/', maybeEncode(committish))}`,
153 httpstemplate: ({ domain, project, committish }) =>
154 `git+https://${domain}/${project}.git${maybeJoin('#', committish)}`,
155 filetemplate: ({ user, project, committish, path }) =>
156 `https://gist.githubusercontent.com/${user}/${project}/raw${maybeJoin('/', maybeEncode(committish))}/${path}`,
157 shortcuttemplate: ({ type, project, committish }) =>
158 `${type}:${project}${maybeJoin('#', committish)}`,
159 pathtemplate: ({ project, committish }) =>
160 `${project}${maybeJoin('#', committish)}`,
161 bugstemplate: ({ domain, project }) =>
162 `https://${domain}/${project}`,
163 gittemplate: ({ domain, project, committish }) =>
164 `git://${domain}/${project}.git${maybeJoin('#', committish)}`,
165 tarballtemplate: ({ project, committish }) =>
166 `https://codeload.github.com/gist/${project}/tar.gz/${maybeEncode(committish || 'HEAD')}`,
167 extract: (url) => {
168 let [, user, project, aux] = url.pathname.split('/', 4)
169 if (aux === 'raw') {
170 return
171 }
172
173 if (!project) {
174 if (!user) {
175 return
176 }
177
178 project = user
179 user = null
180 }
181
182 if (project.endsWith('.git')) {
183 project = project.slice(0, -4)
184 }
185
186 return { user, project, committish: url.hash.slice(1) }
187 },
188 hashformat: function (fragment) {
189 return fragment && 'file-' + formatHashFragment(fragment)
190 },
191}
192
193hosts.sourcehut = {
194 protocols: ['git+ssh:', 'https:'],
195 domain: 'git.sr.ht',
196 treepath: 'tree',
197 blobpath: 'tree',
198 filetemplate: ({ domain, user, project, committish, path }) =>
199 `https://${domain}/${user}/${project}/blob/${maybeEncode(committish) || 'HEAD'}/${path}`,
200 httpstemplate: ({ domain, user, project, committish }) =>
201 `https://${domain}/${user}/${project}.git${maybeJoin('#', committish)}`,
202 tarballtemplate: ({ domain, user, project, committish }) =>
203 `https://${domain}/${user}/${project}/archive/${maybeEncode(committish) || 'HEAD'}.tar.gz`,
204 bugstemplate: () => null,
205 extract: (url) => {
206 let [, user, project, aux] = url.pathname.split('/', 4)
207
208 // tarball url
209 if (['archive'].includes(aux)) {
210 return
211 }
212
213 if (project && project.endsWith('.git')) {
214 project = project.slice(0, -4)
215 }
216
217 if (!user || !project) {
218 return
219 }
220
221 return { user, project, committish: url.hash.slice(1) }
222 },
223}
224
225for (const [name, host] of Object.entries(hosts)) {
226 hosts[name] = Object.assign({}, defaults, host)
227}
228
229module.exports = hosts
230 