diff --git a/node_modules/.gitignore b/node_modules/.gitignore index 6b6963e6939f7..76cfc9b818e9f 100644 --- a/node_modules/.gitignore +++ b/node_modules/.gitignore @@ -36,8 +36,6 @@ !/@npmcli/package-json !/@npmcli/package-json/node_modules/ /@npmcli/package-json/node_modules/* -!/@npmcli/package-json/node_modules/hosted-git-info -!/@npmcli/package-json/node_modules/lru-cache !/@npmcli/package-json/node_modules/normalize-package-data !/@npmcli/promise-spawn !/@npmcli/query @@ -124,6 +122,9 @@ !/has-unicode !/has !/hosted-git-info +!/hosted-git-info/node_modules/ +/hosted-git-info/node_modules/* +!/hosted-git-info/node_modules/lru-cache !/http-cache-semantics !/http-proxy-agent !/https-proxy-agent @@ -211,11 +212,17 @@ !/node-gyp/node_modules/which !/nopt !/normalize-package-data +!/normalize-package-data/node_modules/ +/normalize-package-data/node_modules/* +!/normalize-package-data/node_modules/hosted-git-info !/npm-audit-report !/npm-bundled !/npm-install-checks !/npm-normalize-package-bin !/npm-package-arg +!/npm-package-arg/node_modules/ +/npm-package-arg/node_modules/* +!/npm-package-arg/node_modules/hosted-git-info !/npm-packlist !/npm-pick-manifest !/npm-profile diff --git a/node_modules/hosted-git-info/lib/index.js b/node_modules/hosted-git-info/lib/index.js index a7339c217e9a3..0c9d0b08c866b 100644 --- a/node_modules/hosted-git-info/lib/index.js +++ b/node_modules/hosted-git-info/lib/index.js @@ -1,11 +1,11 @@ 'use strict' -const LRU = require('lru-cache') +const { LRUCache } = require('lru-cache') const hosts = require('./hosts.js') const fromUrl = require('./from-url.js') const parseUrl = require('./parse-url.js') -const cache = new LRU({ max: 1000 }) +const cache = new LRUCache({ max: 1000 }) class GitHost { constructor (type, user, auth, project, committish, defaultRepresentation, opts = {}) { diff --git a/node_modules/@npmcli/package-json/node_modules/lru-cache/LICENSE b/node_modules/hosted-git-info/node_modules/lru-cache/LICENSE similarity index 100% rename from node_modules/@npmcli/package-json/node_modules/lru-cache/LICENSE rename to node_modules/hosted-git-info/node_modules/lru-cache/LICENSE diff --git a/node_modules/@npmcli/package-json/node_modules/lru-cache/dist/cjs/index.js b/node_modules/hosted-git-info/node_modules/lru-cache/dist/cjs/index.js similarity index 100% rename from node_modules/@npmcli/package-json/node_modules/lru-cache/dist/cjs/index.js rename to node_modules/hosted-git-info/node_modules/lru-cache/dist/cjs/index.js diff --git a/node_modules/@npmcli/package-json/node_modules/lru-cache/dist/cjs/index.min.js b/node_modules/hosted-git-info/node_modules/lru-cache/dist/cjs/index.min.js similarity index 100% rename from node_modules/@npmcli/package-json/node_modules/lru-cache/dist/cjs/index.min.js rename to node_modules/hosted-git-info/node_modules/lru-cache/dist/cjs/index.min.js diff --git a/node_modules/@npmcli/package-json/node_modules/lru-cache/dist/cjs/package.json b/node_modules/hosted-git-info/node_modules/lru-cache/dist/cjs/package.json similarity index 100% rename from node_modules/@npmcli/package-json/node_modules/lru-cache/dist/cjs/package.json rename to node_modules/hosted-git-info/node_modules/lru-cache/dist/cjs/package.json diff --git a/node_modules/@npmcli/package-json/node_modules/lru-cache/dist/mjs/index.js b/node_modules/hosted-git-info/node_modules/lru-cache/dist/mjs/index.js similarity index 100% rename from node_modules/@npmcli/package-json/node_modules/lru-cache/dist/mjs/index.js rename to node_modules/hosted-git-info/node_modules/lru-cache/dist/mjs/index.js diff --git a/node_modules/@npmcli/package-json/node_modules/lru-cache/dist/mjs/index.min.js b/node_modules/hosted-git-info/node_modules/lru-cache/dist/mjs/index.min.js similarity index 100% rename from node_modules/@npmcli/package-json/node_modules/lru-cache/dist/mjs/index.min.js rename to node_modules/hosted-git-info/node_modules/lru-cache/dist/mjs/index.min.js diff --git a/node_modules/@npmcli/package-json/node_modules/lru-cache/dist/mjs/package.json b/node_modules/hosted-git-info/node_modules/lru-cache/dist/mjs/package.json similarity index 100% rename from node_modules/@npmcli/package-json/node_modules/lru-cache/dist/mjs/package.json rename to node_modules/hosted-git-info/node_modules/lru-cache/dist/mjs/package.json diff --git a/node_modules/@npmcli/package-json/node_modules/lru-cache/package.json b/node_modules/hosted-git-info/node_modules/lru-cache/package.json similarity index 100% rename from node_modules/@npmcli/package-json/node_modules/lru-cache/package.json rename to node_modules/hosted-git-info/node_modules/lru-cache/package.json diff --git a/node_modules/hosted-git-info/package.json b/node_modules/hosted-git-info/package.json index 612259948afe7..262a6c20fcf00 100644 --- a/node_modules/hosted-git-info/package.json +++ b/node_modules/hosted-git-info/package.json @@ -1,6 +1,6 @@ { "name": "hosted-git-info", - "version": "6.1.1", + "version": "7.0.0", "description": "Provides metadata and conversions from repository urls for GitHub, Bitbucket and GitLab", "main": "./lib/index.js", "repository": { @@ -30,11 +30,11 @@ "template-oss-apply": "template-oss-apply --force" }, "dependencies": { - "lru-cache": "^7.5.1" + "lru-cache": "^10.0.1" }, "devDependencies": { "@npmcli/eslint-config": "^4.0.0", - "@npmcli/template-oss": "4.7.1", + "@npmcli/template-oss": "4.18.0", "tap": "^16.0.1" }, "files": [ @@ -42,7 +42,7 @@ "lib/" ], "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^16.14.0 || >=18.0.0" }, "tap": { "color": 1, @@ -54,6 +54,13 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "4.7.1" + "version": "4.18.0", + "publish": "true", + "ciVersions": [ + "16.14.0", + "16.x", + "18.0.0", + "18.x" + ] } } diff --git a/node_modules/@npmcli/package-json/node_modules/hosted-git-info/LICENSE b/node_modules/normalize-package-data/node_modules/hosted-git-info/LICENSE similarity index 100% rename from node_modules/@npmcli/package-json/node_modules/hosted-git-info/LICENSE rename to node_modules/normalize-package-data/node_modules/hosted-git-info/LICENSE diff --git a/node_modules/@npmcli/package-json/node_modules/hosted-git-info/lib/from-url.js b/node_modules/normalize-package-data/node_modules/hosted-git-info/lib/from-url.js similarity index 100% rename from node_modules/@npmcli/package-json/node_modules/hosted-git-info/lib/from-url.js rename to node_modules/normalize-package-data/node_modules/hosted-git-info/lib/from-url.js diff --git a/node_modules/@npmcli/package-json/node_modules/hosted-git-info/lib/hosts.js b/node_modules/normalize-package-data/node_modules/hosted-git-info/lib/hosts.js similarity index 100% rename from node_modules/@npmcli/package-json/node_modules/hosted-git-info/lib/hosts.js rename to node_modules/normalize-package-data/node_modules/hosted-git-info/lib/hosts.js diff --git a/node_modules/@npmcli/package-json/node_modules/hosted-git-info/lib/index.js b/node_modules/normalize-package-data/node_modules/hosted-git-info/lib/index.js similarity index 98% rename from node_modules/@npmcli/package-json/node_modules/hosted-git-info/lib/index.js rename to node_modules/normalize-package-data/node_modules/hosted-git-info/lib/index.js index 0c9d0b08c866b..a7339c217e9a3 100644 --- a/node_modules/@npmcli/package-json/node_modules/hosted-git-info/lib/index.js +++ b/node_modules/normalize-package-data/node_modules/hosted-git-info/lib/index.js @@ -1,11 +1,11 @@ 'use strict' -const { LRUCache } = require('lru-cache') +const LRU = require('lru-cache') const hosts = require('./hosts.js') const fromUrl = require('./from-url.js') const parseUrl = require('./parse-url.js') -const cache = new LRUCache({ max: 1000 }) +const cache = new LRU({ max: 1000 }) class GitHost { constructor (type, user, auth, project, committish, defaultRepresentation, opts = {}) { diff --git a/node_modules/@npmcli/package-json/node_modules/hosted-git-info/lib/parse-url.js b/node_modules/normalize-package-data/node_modules/hosted-git-info/lib/parse-url.js similarity index 100% rename from node_modules/@npmcli/package-json/node_modules/hosted-git-info/lib/parse-url.js rename to node_modules/normalize-package-data/node_modules/hosted-git-info/lib/parse-url.js diff --git a/node_modules/@npmcli/package-json/node_modules/hosted-git-info/package.json b/node_modules/normalize-package-data/node_modules/hosted-git-info/package.json similarity index 83% rename from node_modules/@npmcli/package-json/node_modules/hosted-git-info/package.json rename to node_modules/normalize-package-data/node_modules/hosted-git-info/package.json index 262a6c20fcf00..612259948afe7 100644 --- a/node_modules/@npmcli/package-json/node_modules/hosted-git-info/package.json +++ b/node_modules/normalize-package-data/node_modules/hosted-git-info/package.json @@ -1,6 +1,6 @@ { "name": "hosted-git-info", - "version": "7.0.0", + "version": "6.1.1", "description": "Provides metadata and conversions from repository urls for GitHub, Bitbucket and GitLab", "main": "./lib/index.js", "repository": { @@ -30,11 +30,11 @@ "template-oss-apply": "template-oss-apply --force" }, "dependencies": { - "lru-cache": "^10.0.1" + "lru-cache": "^7.5.1" }, "devDependencies": { "@npmcli/eslint-config": "^4.0.0", - "@npmcli/template-oss": "4.18.0", + "@npmcli/template-oss": "4.7.1", "tap": "^16.0.1" }, "files": [ @@ -42,7 +42,7 @@ "lib/" ], "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" }, "tap": { "color": 1, @@ -54,13 +54,6 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "4.18.0", - "publish": "true", - "ciVersions": [ - "16.14.0", - "16.x", - "18.0.0", - "18.x" - ] + "version": "4.7.1" } } diff --git a/node_modules/npm-package-arg/node_modules/hosted-git-info/LICENSE b/node_modules/npm-package-arg/node_modules/hosted-git-info/LICENSE new file mode 100644 index 0000000000000..45055763dc838 --- /dev/null +++ b/node_modules/npm-package-arg/node_modules/hosted-git-info/LICENSE @@ -0,0 +1,13 @@ +Copyright (c) 2015, Rebecca Turner + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/npm-package-arg/node_modules/hosted-git-info/lib/from-url.js b/node_modules/npm-package-arg/node_modules/hosted-git-info/lib/from-url.js new file mode 100644 index 0000000000000..efc1247d59d12 --- /dev/null +++ b/node_modules/npm-package-arg/node_modules/hosted-git-info/lib/from-url.js @@ -0,0 +1,122 @@ +'use strict' + +const parseUrl = require('./parse-url') + +// look for github shorthand inputs, such as npm/cli +const isGitHubShorthand = (arg) => { + // it cannot contain whitespace before the first # + // it cannot start with a / because that's probably an absolute file path + // but it must include a slash since repos are username/repository + // it cannot start with a . because that's probably a relative file path + // it cannot start with an @ because that's a scoped package if it passes the other tests + // it cannot contain a : before a # because that tells us that there's a protocol + // a second / may not exist before a # + const firstHash = arg.indexOf('#') + const firstSlash = arg.indexOf('/') + const secondSlash = arg.indexOf('/', firstSlash + 1) + const firstColon = arg.indexOf(':') + const firstSpace = /\s/.exec(arg) + const firstAt = arg.indexOf('@') + + const spaceOnlyAfterHash = !firstSpace || (firstHash > -1 && firstSpace.index > firstHash) + const atOnlyAfterHash = firstAt === -1 || (firstHash > -1 && firstAt > firstHash) + const colonOnlyAfterHash = firstColon === -1 || (firstHash > -1 && firstColon > firstHash) + const secondSlashOnlyAfterHash = secondSlash === -1 || (firstHash > -1 && secondSlash > firstHash) + const hasSlash = firstSlash > 0 + // if a # is found, what we really want to know is that the character + // immediately before # is not a / + const doesNotEndWithSlash = firstHash > -1 ? arg[firstHash - 1] !== '/' : !arg.endsWith('/') + const doesNotStartWithDot = !arg.startsWith('.') + + return spaceOnlyAfterHash && hasSlash && doesNotEndWithSlash && + doesNotStartWithDot && atOnlyAfterHash && colonOnlyAfterHash && + secondSlashOnlyAfterHash +} + +module.exports = (giturl, opts, { gitHosts, protocols }) => { + if (!giturl) { + return + } + + const correctedUrl = isGitHubShorthand(giturl) ? `github:${giturl}` : giturl + const parsed = parseUrl(correctedUrl, protocols) + if (!parsed) { + return + } + + const gitHostShortcut = gitHosts.byShortcut[parsed.protocol] + const gitHostDomain = gitHosts.byDomain[parsed.hostname.startsWith('www.') + ? parsed.hostname.slice(4) + : parsed.hostname] + const gitHostName = gitHostShortcut || gitHostDomain + if (!gitHostName) { + return + } + + const gitHostInfo = gitHosts[gitHostShortcut || gitHostDomain] + let auth = null + if (protocols[parsed.protocol]?.auth && (parsed.username || parsed.password)) { + auth = `${parsed.username}${parsed.password ? ':' + parsed.password : ''}` + } + + let committish = null + let user = null + let project = null + let defaultRepresentation = null + + try { + if (gitHostShortcut) { + let pathname = parsed.pathname.startsWith('/') ? parsed.pathname.slice(1) : parsed.pathname + const firstAt = pathname.indexOf('@') + // we ignore auth for shortcuts, so just trim it out + if (firstAt > -1) { + pathname = pathname.slice(firstAt + 1) + } + + const lastSlash = pathname.lastIndexOf('/') + if (lastSlash > -1) { + user = decodeURIComponent(pathname.slice(0, lastSlash)) + // we want nulls only, never empty strings + if (!user) { + user = null + } + project = decodeURIComponent(pathname.slice(lastSlash + 1)) + } else { + project = decodeURIComponent(pathname) + } + + if (project.endsWith('.git')) { + project = project.slice(0, -4) + } + + if (parsed.hash) { + committish = decodeURIComponent(parsed.hash.slice(1)) + } + + defaultRepresentation = 'shortcut' + } else { + if (!gitHostInfo.protocols.includes(parsed.protocol)) { + return + } + + const segments = gitHostInfo.extract(parsed) + if (!segments) { + return + } + + user = segments.user && decodeURIComponent(segments.user) + project = decodeURIComponent(segments.project) + committish = decodeURIComponent(segments.committish) + defaultRepresentation = protocols[parsed.protocol]?.name || parsed.protocol.slice(0, -1) + } + } catch (err) { + /* istanbul ignore else */ + if (err instanceof URIError) { + return + } else { + throw err + } + } + + return [gitHostName, user, auth, project, committish, defaultRepresentation, opts] +} diff --git a/node_modules/npm-package-arg/node_modules/hosted-git-info/lib/hosts.js b/node_modules/npm-package-arg/node_modules/hosted-git-info/lib/hosts.js new file mode 100644 index 0000000000000..013712b7842c8 --- /dev/null +++ b/node_modules/npm-package-arg/node_modules/hosted-git-info/lib/hosts.js @@ -0,0 +1,228 @@ +/* eslint-disable max-len */ + +'use strict' + +const maybeJoin = (...args) => args.every(arg => arg) ? args.join('') : '' +const maybeEncode = (arg) => arg ? encodeURIComponent(arg) : '' +const formatHashFragment = (f) => f.toLowerCase().replace(/^\W+|\/|\W+$/g, '').replace(/\W+/g, '-') + +const defaults = { + sshtemplate: ({ domain, user, project, committish }) => + `git@${domain}:${user}/${project}.git${maybeJoin('#', committish)}`, + sshurltemplate: ({ domain, user, project, committish }) => + `git+ssh://git@${domain}/${user}/${project}.git${maybeJoin('#', committish)}`, + edittemplate: ({ domain, user, project, committish, editpath, path }) => + `https://${domain}/${user}/${project}${maybeJoin('/', editpath, '/', maybeEncode(committish || 'HEAD'), '/', path)}`, + browsetemplate: ({ domain, user, project, committish, treepath }) => + `https://${domain}/${user}/${project}${maybeJoin('/', treepath, '/', maybeEncode(committish))}`, + browsetreetemplate: ({ domain, user, project, committish, treepath, path, fragment, hashformat }) => + `https://${domain}/${user}/${project}/${treepath}/${maybeEncode(committish || 'HEAD')}/${path}${maybeJoin('#', hashformat(fragment || ''))}`, + browseblobtemplate: ({ domain, user, project, committish, blobpath, path, fragment, hashformat }) => + `https://${domain}/${user}/${project}/${blobpath}/${maybeEncode(committish || 'HEAD')}/${path}${maybeJoin('#', hashformat(fragment || ''))}`, + docstemplate: ({ domain, user, project, treepath, committish }) => + `https://${domain}/${user}/${project}${maybeJoin('/', treepath, '/', maybeEncode(committish))}#readme`, + httpstemplate: ({ auth, domain, user, project, committish }) => + `git+https://${maybeJoin(auth, '@')}${domain}/${user}/${project}.git${maybeJoin('#', committish)}`, + filetemplate: ({ domain, user, project, committish, path }) => + `https://${domain}/${user}/${project}/raw/${maybeEncode(committish || 'HEAD')}/${path}`, + shortcuttemplate: ({ type, user, project, committish }) => + `${type}:${user}/${project}${maybeJoin('#', committish)}`, + pathtemplate: ({ user, project, committish }) => + `${user}/${project}${maybeJoin('#', committish)}`, + bugstemplate: ({ domain, user, project }) => + `https://${domain}/${user}/${project}/issues`, + hashformat: formatHashFragment, +} + +const hosts = {} +hosts.github = { + // First two are insecure and generally shouldn't be used any more, but + // they are still supported. + protocols: ['git:', 'http:', 'git+ssh:', 'git+https:', 'ssh:', 'https:'], + domain: 'github.com', + treepath: 'tree', + blobpath: 'blob', + editpath: 'edit', + filetemplate: ({ auth, user, project, committish, path }) => + `https://${maybeJoin(auth, '@')}raw.githubusercontent.com/${user}/${project}/${maybeEncode(committish || 'HEAD')}/${path}`, + gittemplate: ({ auth, domain, user, project, committish }) => + `git://${maybeJoin(auth, '@')}${domain}/${user}/${project}.git${maybeJoin('#', committish)}`, + tarballtemplate: ({ domain, user, project, committish }) => + `https://codeload.${domain}/${user}/${project}/tar.gz/${maybeEncode(committish || 'HEAD')}`, + extract: (url) => { + let [, user, project, type, committish] = url.pathname.split('/', 5) + if (type && type !== 'tree') { + return + } + + if (!type) { + committish = url.hash.slice(1) + } + + if (project && project.endsWith('.git')) { + project = project.slice(0, -4) + } + + if (!user || !project) { + return + } + + return { user, project, committish } + }, +} + +hosts.bitbucket = { + protocols: ['git+ssh:', 'git+https:', 'ssh:', 'https:'], + domain: 'bitbucket.org', + treepath: 'src', + blobpath: 'src', + editpath: '?mode=edit', + edittemplate: ({ domain, user, project, committish, treepath, path, editpath }) => + `https://${domain}/${user}/${project}${maybeJoin('/', treepath, '/', maybeEncode(committish || 'HEAD'), '/', path, editpath)}`, + tarballtemplate: ({ domain, user, project, committish }) => + `https://${domain}/${user}/${project}/get/${maybeEncode(committish || 'HEAD')}.tar.gz`, + extract: (url) => { + let [, user, project, aux] = url.pathname.split('/', 4) + if (['get'].includes(aux)) { + return + } + + if (project && project.endsWith('.git')) { + project = project.slice(0, -4) + } + + if (!user || !project) { + return + } + + return { user, project, committish: url.hash.slice(1) } + }, +} + +hosts.gitlab = { + protocols: ['git+ssh:', 'git+https:', 'ssh:', 'https:'], + domain: 'gitlab.com', + treepath: 'tree', + blobpath: 'tree', + editpath: '-/edit', + httpstemplate: ({ auth, domain, user, project, committish }) => + `git+https://${maybeJoin(auth, '@')}${domain}/${user}/${project}.git${maybeJoin('#', committish)}`, + tarballtemplate: ({ domain, user, project, committish }) => + `https://${domain}/${user}/${project}/repository/archive.tar.gz?ref=${maybeEncode(committish || 'HEAD')}`, + extract: (url) => { + const path = url.pathname.slice(1) + if (path.includes('/-/') || path.includes('/archive.tar.gz')) { + return + } + + const segments = path.split('/') + let project = segments.pop() + if (project.endsWith('.git')) { + project = project.slice(0, -4) + } + + const user = segments.join('/') + if (!user || !project) { + return + } + + return { user, project, committish: url.hash.slice(1) } + }, +} + +hosts.gist = { + protocols: ['git:', 'git+ssh:', 'git+https:', 'ssh:', 'https:'], + domain: 'gist.github.com', + editpath: 'edit', + sshtemplate: ({ domain, project, committish }) => + `git@${domain}:${project}.git${maybeJoin('#', committish)}`, + sshurltemplate: ({ domain, project, committish }) => + `git+ssh://git@${domain}/${project}.git${maybeJoin('#', committish)}`, + edittemplate: ({ domain, user, project, committish, editpath }) => + `https://${domain}/${user}/${project}${maybeJoin('/', maybeEncode(committish))}/${editpath}`, + browsetemplate: ({ domain, project, committish }) => + `https://${domain}/${project}${maybeJoin('/', maybeEncode(committish))}`, + browsetreetemplate: ({ domain, project, committish, path, hashformat }) => + `https://${domain}/${project}${maybeJoin('/', maybeEncode(committish))}${maybeJoin('#', hashformat(path))}`, + browseblobtemplate: ({ domain, project, committish, path, hashformat }) => + `https://${domain}/${project}${maybeJoin('/', maybeEncode(committish))}${maybeJoin('#', hashformat(path))}`, + docstemplate: ({ domain, project, committish }) => + `https://${domain}/${project}${maybeJoin('/', maybeEncode(committish))}`, + httpstemplate: ({ domain, project, committish }) => + `git+https://${domain}/${project}.git${maybeJoin('#', committish)}`, + filetemplate: ({ user, project, committish, path }) => + `https://gist.githubusercontent.com/${user}/${project}/raw${maybeJoin('/', maybeEncode(committish))}/${path}`, + shortcuttemplate: ({ type, project, committish }) => + `${type}:${project}${maybeJoin('#', committish)}`, + pathtemplate: ({ project, committish }) => + `${project}${maybeJoin('#', committish)}`, + bugstemplate: ({ domain, project }) => + `https://${domain}/${project}`, + gittemplate: ({ domain, project, committish }) => + `git://${domain}/${project}.git${maybeJoin('#', committish)}`, + tarballtemplate: ({ project, committish }) => + `https://codeload.github.com/gist/${project}/tar.gz/${maybeEncode(committish || 'HEAD')}`, + extract: (url) => { + let [, user, project, aux] = url.pathname.split('/', 4) + if (aux === 'raw') { + return + } + + if (!project) { + if (!user) { + return + } + + project = user + user = null + } + + if (project.endsWith('.git')) { + project = project.slice(0, -4) + } + + return { user, project, committish: url.hash.slice(1) } + }, + hashformat: function (fragment) { + return fragment && 'file-' + formatHashFragment(fragment) + }, +} + +hosts.sourcehut = { + protocols: ['git+ssh:', 'https:'], + domain: 'git.sr.ht', + treepath: 'tree', + blobpath: 'tree', + filetemplate: ({ domain, user, project, committish, path }) => + `https://${domain}/${user}/${project}/blob/${maybeEncode(committish) || 'HEAD'}/${path}`, + httpstemplate: ({ domain, user, project, committish }) => + `https://${domain}/${user}/${project}.git${maybeJoin('#', committish)}`, + tarballtemplate: ({ domain, user, project, committish }) => + `https://${domain}/${user}/${project}/archive/${maybeEncode(committish) || 'HEAD'}.tar.gz`, + bugstemplate: ({ user, project }) => + `https://todo.sr.ht/${user}/${project}`, + extract: (url) => { + let [, user, project, aux] = url.pathname.split('/', 4) + + // tarball url + if (['archive'].includes(aux)) { + return + } + + if (project && project.endsWith('.git')) { + project = project.slice(0, -4) + } + + if (!user || !project) { + return + } + + return { user, project, committish: url.hash.slice(1) } + }, +} + +for (const [name, host] of Object.entries(hosts)) { + hosts[name] = Object.assign({}, defaults, host) +} + +module.exports = hosts diff --git a/node_modules/npm-package-arg/node_modules/hosted-git-info/lib/index.js b/node_modules/npm-package-arg/node_modules/hosted-git-info/lib/index.js new file mode 100644 index 0000000000000..a7339c217e9a3 --- /dev/null +++ b/node_modules/npm-package-arg/node_modules/hosted-git-info/lib/index.js @@ -0,0 +1,179 @@ +'use strict' + +const LRU = require('lru-cache') +const hosts = require('./hosts.js') +const fromUrl = require('./from-url.js') +const parseUrl = require('./parse-url.js') + +const cache = new LRU({ max: 1000 }) + +class GitHost { + constructor (type, user, auth, project, committish, defaultRepresentation, opts = {}) { + Object.assign(this, GitHost.#gitHosts[type], { + type, + user, + auth, + project, + committish, + default: defaultRepresentation, + opts, + }) + } + + static #gitHosts = { byShortcut: {}, byDomain: {} } + static #protocols = { + 'git+ssh:': { name: 'sshurl' }, + 'ssh:': { name: 'sshurl' }, + 'git+https:': { name: 'https', auth: true }, + 'git:': { auth: true }, + 'http:': { auth: true }, + 'https:': { auth: true }, + 'git+http:': { auth: true }, + } + + static addHost (name, host) { + GitHost.#gitHosts[name] = host + GitHost.#gitHosts.byDomain[host.domain] = name + GitHost.#gitHosts.byShortcut[`${name}:`] = name + GitHost.#protocols[`${name}:`] = { name } + } + + static fromUrl (giturl, opts) { + if (typeof giturl !== 'string') { + return + } + + const key = giturl + JSON.stringify(opts || {}) + + if (!cache.has(key)) { + const hostArgs = fromUrl(giturl, opts, { + gitHosts: GitHost.#gitHosts, + protocols: GitHost.#protocols, + }) + cache.set(key, hostArgs ? new GitHost(...hostArgs) : undefined) + } + + return cache.get(key) + } + + static parseUrl (url) { + return parseUrl(url) + } + + #fill (template, opts) { + if (typeof template !== 'function') { + return null + } + + const options = { ...this, ...this.opts, ...opts } + + // the path should always be set so we don't end up with 'undefined' in urls + if (!options.path) { + options.path = '' + } + + // template functions will insert the leading slash themselves + if (options.path.startsWith('/')) { + options.path = options.path.slice(1) + } + + if (options.noCommittish) { + options.committish = null + } + + const result = template(options) + return options.noGitPlus && result.startsWith('git+') ? result.slice(4) : result + } + + hash () { + return this.committish ? `#${this.committish}` : '' + } + + ssh (opts) { + return this.#fill(this.sshtemplate, opts) + } + + sshurl (opts) { + return this.#fill(this.sshurltemplate, opts) + } + + browse (path, ...args) { + // not a string, treat path as opts + if (typeof path !== 'string') { + return this.#fill(this.browsetemplate, path) + } + + if (typeof args[0] !== 'string') { + return this.#fill(this.browsetreetemplate, { ...args[0], path }) + } + + return this.#fill(this.browsetreetemplate, { ...args[1], fragment: args[0], path }) + } + + // If the path is known to be a file, then browseFile should be used. For some hosts + // the url is the same as browse, but for others like GitHub a file can use both `/tree/` + // and `/blob/` in the path. When using a default committish of `HEAD` then the `/tree/` + // path will redirect to a specific commit. Using the `/blob/` path avoids this and + // does not redirect to a different commit. + browseFile (path, ...args) { + if (typeof args[0] !== 'string') { + return this.#fill(this.browseblobtemplate, { ...args[0], path }) + } + + return this.#fill(this.browseblobtemplate, { ...args[1], fragment: args[0], path }) + } + + docs (opts) { + return this.#fill(this.docstemplate, opts) + } + + bugs (opts) { + return this.#fill(this.bugstemplate, opts) + } + + https (opts) { + return this.#fill(this.httpstemplate, opts) + } + + git (opts) { + return this.#fill(this.gittemplate, opts) + } + + shortcut (opts) { + return this.#fill(this.shortcuttemplate, opts) + } + + path (opts) { + return this.#fill(this.pathtemplate, opts) + } + + tarball (opts) { + return this.#fill(this.tarballtemplate, { ...opts, noCommittish: false }) + } + + file (path, opts) { + return this.#fill(this.filetemplate, { ...opts, path }) + } + + edit (path, opts) { + return this.#fill(this.edittemplate, { ...opts, path }) + } + + getDefaultRepresentation () { + return this.default + } + + toString (opts) { + if (this.default && typeof this[this.default] === 'function') { + return this[this.default](opts) + } + + return this.sshurl(opts) + } +} + +for (const [name, host] of Object.entries(hosts)) { + GitHost.addHost(name, host) +} + +module.exports = GitHost diff --git a/node_modules/npm-package-arg/node_modules/hosted-git-info/lib/parse-url.js b/node_modules/npm-package-arg/node_modules/hosted-git-info/lib/parse-url.js new file mode 100644 index 0000000000000..7d5489c008ab4 --- /dev/null +++ b/node_modules/npm-package-arg/node_modules/hosted-git-info/lib/parse-url.js @@ -0,0 +1,78 @@ +const url = require('url') + +const lastIndexOfBefore = (str, char, beforeChar) => { + const startPosition = str.indexOf(beforeChar) + return str.lastIndexOf(char, startPosition > -1 ? startPosition : Infinity) +} + +const safeUrl = (u) => { + try { + return new url.URL(u) + } catch { + // this fn should never throw + } +} + +// accepts input like git:github.com:user/repo and inserts the // after the first : +const correctProtocol = (arg, protocols) => { + const firstColon = arg.indexOf(':') + const proto = arg.slice(0, firstColon + 1) + if (Object.prototype.hasOwnProperty.call(protocols, proto)) { + return arg + } + + const firstAt = arg.indexOf('@') + if (firstAt > -1) { + if (firstAt > firstColon) { + return `git+ssh://${arg}` + } else { + return arg + } + } + + const doubleSlash = arg.indexOf('//') + if (doubleSlash === firstColon + 1) { + return arg + } + + return `${arg.slice(0, firstColon + 1)}//${arg.slice(firstColon + 1)}` +} + +// attempt to correct an scp style url so that it will parse with `new URL()` +const correctUrl = (giturl) => { + // ignore @ that come after the first hash since the denotes the start + // of a committish which can contain @ characters + const firstAt = lastIndexOfBefore(giturl, '@', '#') + // ignore colons that come after the hash since that could include colons such as: + // git@github.com:user/package-2#semver:^1.0.0 + const lastColonBeforeHash = lastIndexOfBefore(giturl, ':', '#') + + if (lastColonBeforeHash > firstAt) { + // the last : comes after the first @ (or there is no @) + // like it would in: + // proto://hostname.com:user/repo + // username@hostname.com:user/repo + // :password@hostname.com:user/repo + // username:password@hostname.com:user/repo + // proto://username@hostname.com:user/repo + // proto://:password@hostname.com:user/repo + // proto://username:password@hostname.com:user/repo + // then we replace the last : with a / to create a valid path + giturl = giturl.slice(0, lastColonBeforeHash) + '/' + giturl.slice(lastColonBeforeHash + 1) + } + + if (lastIndexOfBefore(giturl, ':', '#') === -1 && giturl.indexOf('//') === -1) { + // we have no : at all + // as it would be in: + // username@hostname.com/user/repo + // then we prepend a protocol + giturl = `git+ssh://${giturl}` + } + + return giturl +} + +module.exports = (giturl, protocols) => { + const withProtocol = protocols ? correctProtocol(giturl, protocols) : giturl + return safeUrl(withProtocol) || safeUrl(correctUrl(withProtocol)) +} diff --git a/node_modules/npm-package-arg/node_modules/hosted-git-info/package.json b/node_modules/npm-package-arg/node_modules/hosted-git-info/package.json new file mode 100644 index 0000000000000..612259948afe7 --- /dev/null +++ b/node_modules/npm-package-arg/node_modules/hosted-git-info/package.json @@ -0,0 +1,59 @@ +{ + "name": "hosted-git-info", + "version": "6.1.1", + "description": "Provides metadata and conversions from repository urls for GitHub, Bitbucket and GitLab", + "main": "./lib/index.js", + "repository": { + "type": "git", + "url": "https://github.com/npm/hosted-git-info.git" + }, + "keywords": [ + "git", + "github", + "bitbucket", + "gitlab" + ], + "author": "GitHub Inc.", + "license": "ISC", + "bugs": { + "url": "https://github.com/npm/hosted-git-info/issues" + }, + "homepage": "https://github.com/npm/hosted-git-info", + "scripts": { + "posttest": "npm run lint", + "snap": "tap", + "test": "tap", + "test:coverage": "tap --coverage-report=html", + "lint": "eslint \"**/*.js\"", + "postlint": "template-oss-check", + "lintfix": "npm run lint -- --fix", + "template-oss-apply": "template-oss-apply --force" + }, + "dependencies": { + "lru-cache": "^7.5.1" + }, + "devDependencies": { + "@npmcli/eslint-config": "^4.0.0", + "@npmcli/template-oss": "4.7.1", + "tap": "^16.0.1" + }, + "files": [ + "bin/", + "lib/" + ], + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "tap": { + "color": 1, + "coverage": true, + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] + }, + "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "4.7.1" + } +} diff --git a/package-lock.json b/package-lock.json index 11c73d2843e2f..46ba9a0e343cf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -106,7 +106,7 @@ "fs-minipass": "^3.0.3", "glob": "^10.3.3", "graceful-fs": "^4.2.11", - "hosted-git-info": "^6.1.1", + "hosted-git-info": "^7.0.0", "ini": "^4.1.1", "init-package-json": "^5.0.0", "is-cidr": "^4.0.2", @@ -2548,27 +2548,6 @@ "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@npmcli/package-json/node_modules/hosted-git-info": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.0.tgz", - "integrity": "sha512-ICclEpTLhHj+zCuSb2/usoNXSVkxUSIopre+b1w8NDY9Dntp9LO4vLdHYI336TH8sAqwrRgnSfdkBG2/YpisHA==", - "inBundle": true, - "dependencies": { - "lru-cache": "^10.0.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/package-json/node_modules/lru-cache": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", - "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", - "inBundle": true, - "engines": { - "node": "14 || >=16.14" - } - }, "node_modules/@npmcli/package-json/node_modules/normalize-package-data": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.0.tgz", @@ -2706,6 +2685,18 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/@npmcli/template-oss/node_modules/hosted-git-info": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz", + "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==", + "dev": true, + "dependencies": { + "lru-cache": "^7.5.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/@octokit/auth-token": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.3.tgz", @@ -6510,15 +6501,24 @@ } }, "node_modules/hosted-git-info": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz", - "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.0.tgz", + "integrity": "sha512-ICclEpTLhHj+zCuSb2/usoNXSVkxUSIopre+b1w8NDY9Dntp9LO4vLdHYI336TH8sAqwrRgnSfdkBG2/YpisHA==", "inBundle": true, "dependencies": { - "lru-cache": "^7.5.1" + "lru-cache": "^10.0.1" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", + "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", + "inBundle": true, + "engines": { + "node": "14 || >=16.14" } }, "node_modules/html-encoding-sniffer": { @@ -9740,6 +9740,18 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/normalize-package-data/node_modules/hosted-git-info": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz", + "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==", + "inBundle": true, + "dependencies": { + "lru-cache": "^7.5.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -9812,6 +9824,18 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/npm-package-arg/node_modules/hosted-git-info": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz", + "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==", + "inBundle": true, + "dependencies": { + "lru-cache": "^7.5.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/npm-packlist": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-7.0.4.tgz", @@ -16054,7 +16078,7 @@ "bin-links": "^4.0.1", "cacache": "^18.0.0", "common-ancestor-path": "^1.0.1", - "hosted-git-info": "^6.1.1", + "hosted-git-info": "^7.0.0", "json-parse-even-better-errors": "^3.0.0", "json-stringify-nice": "^1.1.4", "minimatch": "^9.0.0", diff --git a/package.json b/package.json index e74281c6f093f..c405b20e7b246 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "fs-minipass": "^3.0.3", "glob": "^10.3.3", "graceful-fs": "^4.2.11", - "hosted-git-info": "^6.1.1", + "hosted-git-info": "^7.0.0", "ini": "^4.1.1", "init-package-json": "^5.0.0", "is-cidr": "^4.0.2", diff --git a/workspaces/arborist/package.json b/workspaces/arborist/package.json index 6ff0119d21f20..a8948c001e389 100644 --- a/workspaces/arborist/package.json +++ b/workspaces/arborist/package.json @@ -16,7 +16,7 @@ "bin-links": "^4.0.1", "cacache": "^18.0.0", "common-ancestor-path": "^1.0.1", - "hosted-git-info": "^6.1.1", + "hosted-git-info": "^7.0.0", "json-parse-even-better-errors": "^3.0.0", "json-stringify-nice": "^1.1.4", "minimatch": "^9.0.0",