|
4 | 4 |
|
5 | 5 | // eslint-disable-next-line max-statements
|
6 | 6 | (function () {
|
| 7 | + /** |
| 8 | + * Given a set of variant values, creates an enum. |
| 9 | + * @param {string[]} variants - |
| 10 | + * A list of unique strings, representing the enum variants. |
| 11 | + * @return {object} an enum-like, immutable dictionary |
| 12 | + */ |
| 13 | + const createEnum = function (variants) { |
| 14 | + const enumObject = {}; |
| 15 | + for (const vari of variants) { |
| 16 | + enumObject[vari] = Symbol(vari); |
| 17 | + } |
| 18 | + return Object.freeze(enumObject); |
| 19 | + }; |
| 20 | + |
| 21 | + const FORGE_SOFTWARES = createEnum([ |
| 22 | + 'GitHub', |
| 23 | + 'BitBucket', |
| 24 | + 'GitLab', |
| 25 | + 'ForgeJo', |
| 26 | + 'SourceHut' |
| 27 | + ]); |
| 28 | + |
| 29 | + const FORGE_HOSTS = createEnum([ |
| 30 | + 'GitHub_com', |
| 31 | + 'BitBucket_org', |
| 32 | + 'GitLab_com', |
| 33 | + 'Allmende_io', |
| 34 | + 'CodeBerg_org', |
| 35 | + 'Git_Sr_Ht' |
| 36 | + ]); |
7 | 37 |
|
8 | 38 | /**
|
9 | 39 | * If the first parameter is a URL to a file on a known git forge,
|
|
20 | 50 | .replace(/\/blob\//, '/').replace(/\/raw\//, '/');
|
21 | 51 | };
|
22 | 52 |
|
| 53 | + /** |
| 54 | + * Extracts the forge software and host, |
| 55 | + * the given a URL that points to a file on a known git forge. |
| 56 | + * @param {URL} url - Any URL, |
| 57 | + * potentially pointing to a git hosted raw (plain-text) file |
| 58 | + * @returns {{ software: Symbol, host: Symbol}} `(software, host)`, |
| 59 | + * or `(null, null)` if unsupported/unidentified/ |
| 60 | + * not a git hosted raw file. |
| 61 | + * |
| 62 | + * NOTE: This is function 2 of 2 that is git-forge specific. |
| 63 | + */ |
| 64 | + // eslint-disable-next-line max-statements |
| 65 | + const extractForge = function (url) { |
| 66 | + let software = null; |
| 67 | + let host = null; |
| 68 | + if (url.host == 'raw.githubusercontent.com') { |
| 69 | + software = FORGE_SOFTWARES.GitHub; |
| 70 | + host = FORGE_HOSTS.GitHub_com; |
| 71 | + } else if (url.host == 'bitbucket.org' |
| 72 | + && (/\/[^/]+\/[^/]+\/raw\/[^/]+/).test(url.pathname)) { |
| 73 | + software = FORGE_SOFTWARES.BitBucket; |
| 74 | + host = FORGE_HOSTS.BitBucket_org; |
| 75 | + } else if (url.host == 'gitlab.com' |
| 76 | + && (/\/[^/]+\/.+\/(-\/)?raw\/[^/]+/).test(url.pathname)) { |
| 77 | + software = FORGE_SOFTWARES.GitLab; |
| 78 | + host = FORGE_HOSTS.GitLab_com; |
| 79 | + } else if (url.host == 'lab.allmende.io' |
| 80 | + && (/\/[^/]+\/.+\/(-\/)?raw\/[^/]+/).test(url.pathname)) { |
| 81 | + software = FORGE_SOFTWARES.GitLab; |
| 82 | + host = FORGE_HOSTS.Lab_Allmende_io; |
| 83 | + } else if (url.host == 'codeberg.org' |
| 84 | + && (/\/[^/]+\/[^/]+\/raw\/[^/]+/).test(url.pathname)) { |
| 85 | + software = FORGE_SOFTWARES.ForgeJo; |
| 86 | + host = FORGE_HOSTS.CodeBerg_org; |
| 87 | + } else if (url.host == 'git.sr.ht' |
| 88 | + && (/\/~[^/]+\/[^/]+\/blob\/[^/]+/).test(url.pathname)) { |
| 89 | + software = FORGE_SOFTWARES.SourceHut; |
| 90 | + host = FORGE_HOSTS.Git_Sr_Ht; |
| 91 | + } |
| 92 | + return [software, host]; |
| 93 | + }; |
| 94 | + |
| 95 | + /** |
| 96 | + * Indicates whether the given URL points to a file on a known git forge. |
| 97 | + * @param {URL} url - Any URL, |
| 98 | + * potentially pointing to a git hosted raw (plain-text) file |
| 99 | + * @returns {boolean} `true` if the given URL indeed does point |
| 100 | + * to a git hosted raw file |
| 101 | + */ |
| 102 | + const isGitForgeFileUrlParsed = function (url) { |
| 103 | + return extractForge(url)[0] !== null; |
| 104 | + }; |
| 105 | + |
23 | 106 | /**
|
24 | 107 | * Indicates whether the given URL points to a file on a known git forge.
|
25 | 108 | * @param {string} url - Any URL,
|
26 | 109 | * potentially pointing to a git hosted raw (plain-text) file
|
27 | 110 | * @returns {boolean} `true` if the given URL indeed does point
|
28 | 111 | * to a git hosted raw file
|
29 |
| - * |
30 |
| - * NOTE: This is function 2 of 2 that is git-forge specific. |
31 | 112 | */
|
32 | 113 | const isGitForgeFileUrl = function (url) {
|
33 |
| - return (url.indexOf('//raw.githubusercontent.com') > 0 |
34 |
| - || url.indexOf('//bitbucket.org') > 0); |
| 114 | + try { |
| 115 | + return isGitForgeFileUrlParsed(new URL(url)); |
| 116 | + } catch (err) { |
| 117 | + if (err instanceof RangeError) { |
| 118 | + return false; |
| 119 | + } |
| 120 | + throw err; |
| 121 | + } |
35 | 122 | };
|
36 | 123 |
|
37 | 124 | /**
|
|
0 commit comments