This commit is contained in:
2025-08-18 23:06:34 +08:00
parent 0bc04fb659
commit ed18af0cad
1926 changed files with 275098 additions and 0 deletions

15
package/node_modules/@npmcli/git/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,15 @@
The ISC License
Copyright (c) npm, Inc.
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 NPM DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS. IN NO EVENT SHALL THE NPM 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.

172
package/node_modules/@npmcli/git/lib/clone.js generated vendored Normal file
View File

@@ -0,0 +1,172 @@
// The goal here is to minimize both git workload and
// the number of refs we download over the network.
//
// Every method ends up with the checked out working dir
// at the specified ref, and resolves with the git sha.
// Only certain whitelisted hosts get shallow cloning.
// Many hosts (including GHE) don't always support it.
// A failed shallow fetch takes a LOT longer than a full
// fetch in most cases, so we skip it entirely.
// Set opts.gitShallow = true/false to force this behavior
// one way or the other.
const shallowHosts = new Set([
'github.com',
'gist.github.com',
'gitlab.com',
'bitbucket.com',
'bitbucket.org',
])
// we have to use url.parse until we add the same shim that hosted-git-info has
// to handle scp:// urls
const { parse } = require('url') // eslint-disable-line node/no-deprecated-api
const path = require('path')
const getRevs = require('./revs.js')
const spawn = require('./spawn.js')
const { isWindows } = require('./utils.js')
const pickManifest = require('npm-pick-manifest')
const fs = require('fs/promises')
module.exports = (repo, ref = 'HEAD', target = null, opts = {}) =>
getRevs(repo, opts).then(revs => clone(
repo,
revs,
ref,
resolveRef(revs, ref, opts),
target || defaultTarget(repo, opts.cwd),
opts
))
const maybeShallow = (repo, opts) => {
if (opts.gitShallow === false || opts.gitShallow) {
return opts.gitShallow
}
return shallowHosts.has(parse(repo).host)
}
const defaultTarget = (repo, /* istanbul ignore next */ cwd = process.cwd()) =>
path.resolve(cwd, path.basename(repo.replace(/[/\\]?\.git$/, '')))
const clone = (repo, revs, ref, revDoc, target, opts) => {
if (!revDoc) {
return unresolved(repo, ref, target, opts)
}
if (revDoc.sha === revs.refs.HEAD.sha) {
return plain(repo, revDoc, target, opts)
}
if (revDoc.type === 'tag' || revDoc.type === 'branch') {
return branch(repo, revDoc, target, opts)
}
return other(repo, revDoc, target, opts)
}
const resolveRef = (revs, ref, opts) => {
const { spec = {} } = opts
ref = spec.gitCommittish || ref
/* istanbul ignore next - will fail anyway, can't pull */
if (!revs) {
return null
}
if (spec.gitRange) {
return pickManifest(revs, spec.gitRange, opts)
}
if (!ref) {
return revs.refs.HEAD
}
if (revs.refs[ref]) {
return revs.refs[ref]
}
if (revs.shas[ref]) {
return revs.refs[revs.shas[ref][0]]
}
return null
}
// pull request or some other kind of advertised ref
const other = (repo, revDoc, target, opts) => {
const shallow = maybeShallow(repo, opts)
const fetchOrigin = ['fetch', 'origin', revDoc.rawRef]
.concat(shallow ? ['--depth=1'] : [])
const git = (args) => spawn(args, { ...opts, cwd: target })
return fs.mkdir(target, { recursive: true })
.then(() => git(['init']))
.then(() => isWindows(opts)
? git(['config', '--local', '--add', 'core.longpaths', 'true'])
: null)
.then(() => git(['remote', 'add', 'origin', repo]))
.then(() => git(fetchOrigin))
.then(() => git(['checkout', revDoc.sha]))
.then(() => updateSubmodules(target, opts))
.then(() => revDoc.sha)
}
// tag or branches. use -b
const branch = (repo, revDoc, target, opts) => {
const args = [
'clone',
'-b',
revDoc.ref,
repo,
target,
'--recurse-submodules',
]
if (maybeShallow(repo, opts)) {
args.push('--depth=1')
}
if (isWindows(opts)) {
args.push('--config', 'core.longpaths=true')
}
return spawn(args, opts).then(() => revDoc.sha)
}
// just the head. clone it
const plain = (repo, revDoc, target, opts) => {
const args = [
'clone',
repo,
target,
'--recurse-submodules',
]
if (maybeShallow(repo, opts)) {
args.push('--depth=1')
}
if (isWindows(opts)) {
args.push('--config', 'core.longpaths=true')
}
return spawn(args, opts).then(() => revDoc.sha)
}
const updateSubmodules = async (target, opts) => {
const hasSubmodules = await fs.stat(`${target}/.gitmodules`)
.then(() => true)
.catch(() => false)
if (!hasSubmodules) {
return null
}
return spawn([
'submodule',
'update',
'-q',
'--init',
'--recursive',
], { ...opts, cwd: target })
}
const unresolved = (repo, ref, target, opts) => {
// can't do this one shallowly, because the ref isn't advertised
// but we can avoid checking out the working dir twice, at least
const lp = isWindows(opts) ? ['--config', 'core.longpaths=true'] : []
const cloneArgs = ['clone', '--mirror', '-q', repo, target + '/.git']
const git = (args) => spawn(args, { ...opts, cwd: target })
return fs.mkdir(target, { recursive: true })
.then(() => git(cloneArgs.concat(lp)))
.then(() => git(['init']))
.then(() => git(['checkout', ref]))
.then(() => updateSubmodules(target, opts))
.then(() => git(['rev-parse', '--revs-only', 'HEAD']))
.then(({ stdout }) => stdout.trim())
}

36
package/node_modules/@npmcli/git/lib/errors.js generated vendored Normal file
View File

@@ -0,0 +1,36 @@
const maxRetry = 3
class GitError extends Error {
shouldRetry () {
return false
}
}
class GitConnectionError extends GitError {
constructor () {
super('A git connection error occurred')
}
shouldRetry (number) {
return number < maxRetry
}
}
class GitPathspecError extends GitError {
constructor () {
super('The git reference could not be found')
}
}
class GitUnknownError extends GitError {
constructor () {
super('An unknown git error occurred')
}
}
module.exports = {
GitConnectionError,
GitPathspecError,
GitUnknownError,
}

15
package/node_modules/@npmcli/git/lib/find.js generated vendored Normal file
View File

@@ -0,0 +1,15 @@
const is = require('./is.js')
const { dirname } = require('path')
module.exports = async ({ cwd = process.cwd(), root } = {}) => {
while (true) {
if (await is({ cwd })) {
return cwd
}
const next = dirname(cwd)
if (cwd === root || cwd === next) {
return null
}
cwd = next
}
}

9
package/node_modules/@npmcli/git/lib/index.js generated vendored Normal file
View File

@@ -0,0 +1,9 @@
module.exports = {
clone: require('./clone.js'),
revs: require('./revs.js'),
spawn: require('./spawn.js'),
is: require('./is.js'),
find: require('./find.js'),
isClean: require('./is-clean.js'),
errors: require('./errors.js'),
}

6
package/node_modules/@npmcli/git/lib/is-clean.js generated vendored Normal file
View File

@@ -0,0 +1,6 @@
const spawn = require('./spawn.js')
module.exports = (opts = {}) =>
spawn(['status', '--porcelain=v1', '-uno'], opts)
.then(res => !res.stdout.trim().split(/\r?\n+/)
.map(l => l.trim()).filter(l => l).length)

4
package/node_modules/@npmcli/git/lib/is.js generated vendored Normal file
View File

@@ -0,0 +1,4 @@
// not an airtight indicator, but a good gut-check to even bother trying
const { stat } = require('fs/promises')
module.exports = ({ cwd = process.cwd() } = {}) =>
stat(cwd + '/.git').then(() => true, () => false)

147
package/node_modules/@npmcli/git/lib/lines-to-revs.js generated vendored Normal file
View File

@@ -0,0 +1,147 @@
// turn an array of lines from `git ls-remote` into a thing
// vaguely resembling a packument, where docs are a resolved ref
const semver = require('semver')
module.exports = lines => finish(lines.reduce(linesToRevsReducer, {
versions: {},
'dist-tags': {},
refs: {},
shas: {},
}))
const finish = revs => distTags(shaList(peelTags(revs)))
// We can check out shallow clones on specific SHAs if we have a ref
const shaList = revs => {
Object.keys(revs.refs).forEach(ref => {
const doc = revs.refs[ref]
if (!revs.shas[doc.sha]) {
revs.shas[doc.sha] = [ref]
} else {
revs.shas[doc.sha].push(ref)
}
})
return revs
}
// Replace any tags with their ^{} counterparts, if those exist
const peelTags = revs => {
Object.keys(revs.refs).filter(ref => ref.endsWith('^{}')).forEach(ref => {
const peeled = revs.refs[ref]
const unpeeled = revs.refs[ref.replace(/\^\{\}$/, '')]
if (unpeeled) {
unpeeled.sha = peeled.sha
delete revs.refs[ref]
}
})
return revs
}
const distTags = revs => {
// not entirely sure what situations would result in an
// ichabod repo, but best to be careful in Sleepy Hollow anyway
const HEAD = revs.refs.HEAD || /* istanbul ignore next */ {}
const versions = Object.keys(revs.versions)
versions.forEach(v => {
// simulate a dist-tags with latest pointing at the
// 'latest' branch if one exists and is a version,
// or HEAD if not.
const ver = revs.versions[v]
if (revs.refs.latest && ver.sha === revs.refs.latest.sha) {
revs['dist-tags'].latest = v
} else if (ver.sha === HEAD.sha) {
revs['dist-tags'].HEAD = v
if (!revs.refs.latest) {
revs['dist-tags'].latest = v
}
}
})
return revs
}
const refType = ref => {
if (ref.startsWith('refs/tags/')) {
return 'tag'
}
if (ref.startsWith('refs/heads/')) {
return 'branch'
}
if (ref.startsWith('refs/pull/')) {
return 'pull'
}
if (ref === 'HEAD') {
return 'head'
}
// Could be anything, ignore for now
/* istanbul ignore next */
return 'other'
}
// return the doc, or null if we should ignore it.
const lineToRevDoc = line => {
const split = line.trim().split(/\s+/, 2)
if (split.length < 2) {
return null
}
const sha = split[0].trim()
const rawRef = split[1].trim()
const type = refType(rawRef)
if (type === 'tag') {
// refs/tags/foo^{} is the 'peeled tag', ie the commit
// that is tagged by refs/tags/foo they resolve to the same
// content, just different objects in git's data structure.
// But, we care about the thing the tag POINTS to, not the tag
// object itself, so we only look at the peeled tag refs, and
// ignore the pointer.
// For now, though, we have to save both, because some tags
// don't have peels, if they were not annotated.
const ref = rawRef.slice('refs/tags/'.length)
return { sha, ref, rawRef, type }
}
if (type === 'branch') {
const ref = rawRef.slice('refs/heads/'.length)
return { sha, ref, rawRef, type }
}
if (type === 'pull') {
// NB: merged pull requests installable with #pull/123/merge
// for the merged pr, or #pull/123 for the PR head
const ref = rawRef.slice('refs/'.length).replace(/\/head$/, '')
return { sha, ref, rawRef, type }
}
if (type === 'head') {
const ref = 'HEAD'
return { sha, ref, rawRef, type }
}
// at this point, all we can do is leave the ref un-munged
return { sha, ref: rawRef, rawRef, type }
}
const linesToRevsReducer = (revs, line) => {
const doc = lineToRevDoc(line)
if (!doc) {
return revs
}
revs.refs[doc.ref] = doc
revs.refs[doc.rawRef] = doc
if (doc.type === 'tag') {
// try to pull a semver value out of tags like `release-v1.2.3`
// which is a pretty common pattern.
const match = !doc.ref.endsWith('^{}') &&
doc.ref.match(/v?(\d+\.\d+\.\d+(?:[-+].+)?)$/)
if (match && semver.valid(match[1], true)) {
revs.versions[semver.clean(match[1], true)] = doc
}
}
return revs
}

33
package/node_modules/@npmcli/git/lib/make-error.js generated vendored Normal file
View File

@@ -0,0 +1,33 @@
const {
GitConnectionError,
GitPathspecError,
GitUnknownError,
} = require('./errors.js')
const connectionErrorRe = new RegExp([
'remote error: Internal Server Error',
'The remote end hung up unexpectedly',
'Connection timed out',
'Operation timed out',
'Failed to connect to .* Timed out',
'Connection reset by peer',
'SSL_ERROR_SYSCALL',
'The requested URL returned error: 503',
].join('|'))
const missingPathspecRe = /pathspec .* did not match any file\(s\) known to git/
function makeError (er) {
const message = er.stderr
let gitEr
if (connectionErrorRe.test(message)) {
gitEr = new GitConnectionError(message)
} else if (missingPathspecRe.test(message)) {
gitEr = new GitPathspecError(message)
} else {
gitEr = new GitUnknownError(message)
}
return Object.assign(gitEr, er)
}
module.exports = makeError

57
package/node_modules/@npmcli/git/lib/opts.js generated vendored Normal file
View File

@@ -0,0 +1,57 @@
const fs = require('node:fs')
const os = require('node:os')
const path = require('node:path')
const ini = require('ini')
const gitConfigPath = path.join(os.homedir(), '.gitconfig')
let cachedConfig = null
// Function to load and cache the git config
const loadGitConfig = () => {
if (cachedConfig === null) {
try {
cachedConfig = {}
if (fs.existsSync(gitConfigPath)) {
const configContent = fs.readFileSync(gitConfigPath, 'utf-8')
cachedConfig = ini.parse(configContent)
}
} catch (error) {
cachedConfig = {}
}
}
return cachedConfig
}
const checkGitConfigs = () => {
const config = loadGitConfig()
return {
sshCommandSetInConfig: config?.core?.sshCommand !== undefined,
askPassSetInConfig: config?.core?.askpass !== undefined,
}
}
const sshCommandSetInEnv = process.env.GIT_SSH_COMMAND !== undefined
const askPassSetInEnv = process.env.GIT_ASKPASS !== undefined
const { sshCommandSetInConfig, askPassSetInConfig } = checkGitConfigs()
// Values we want to set if they're not already defined by the end user
// This defaults to accepting new ssh host key fingerprints
const finalGitEnv = {
...(askPassSetInEnv || askPassSetInConfig ? {} : {
GIT_ASKPASS: 'echo',
}),
...(sshCommandSetInEnv || sshCommandSetInConfig ? {} : {
GIT_SSH_COMMAND: 'ssh -oStrictHostKeyChecking=accept-new',
}),
}
module.exports = (opts = {}) => ({
stdioString: true,
...opts,
shell: false,
env: opts.env || { ...finalGitEnv, ...process.env },
})
// Export the loadGitConfig function for testing
module.exports.loadGitConfig = loadGitConfig

28
package/node_modules/@npmcli/git/lib/revs.js generated vendored Normal file
View File

@@ -0,0 +1,28 @@
const pinflight = require('promise-inflight')
const spawn = require('./spawn.js')
const { LRUCache } = require('lru-cache')
const revsCache = new LRUCache({
max: 100,
ttl: 5 * 60 * 1000,
})
const linesToRevs = require('./lines-to-revs.js')
module.exports = async (repo, opts = {}) => {
if (!opts.noGitRevCache) {
const cached = revsCache.get(repo)
if (cached) {
return cached
}
}
return pinflight(`ls-remote:${repo}`, () =>
spawn(['ls-remote', repo], opts)
.then(({ stdout }) => linesToRevs(stdout.trim().split('\n')))
.then(revs => {
revsCache.set(repo, revs)
return revs
})
)
}

44
package/node_modules/@npmcli/git/lib/spawn.js generated vendored Normal file
View File

@@ -0,0 +1,44 @@
const spawn = require('@npmcli/promise-spawn')
const promiseRetry = require('promise-retry')
const { log } = require('proc-log')
const makeError = require('./make-error.js')
const makeOpts = require('./opts.js')
module.exports = (gitArgs, opts = {}) => {
const whichGit = require('./which.js')
const gitPath = whichGit(opts)
if (gitPath instanceof Error) {
return Promise.reject(gitPath)
}
// undocumented option, mostly only here for tests
const args = opts.allowReplace || gitArgs[0] === '--no-replace-objects'
? gitArgs
: ['--no-replace-objects', ...gitArgs]
let retryOpts = opts.retry
if (retryOpts === null || retryOpts === undefined) {
retryOpts = {
retries: opts.fetchRetries || 2,
factor: opts.fetchRetryFactor || 10,
maxTimeout: opts.fetchRetryMaxtimeout || 60000,
minTimeout: opts.fetchRetryMintimeout || 1000,
}
}
return promiseRetry((retryFn, number) => {
if (number !== 1) {
log.silly('git', `Retrying git command: ${
args.join(' ')} attempt # ${number}`)
}
return spawn(gitPath, args, makeOpts(opts))
.catch(er => {
const gitError = makeError(er)
if (!gitError.shouldRetry(number)) {
throw gitError
}
retryFn(gitError)
})
}, retryOpts)
}

3
package/node_modules/@npmcli/git/lib/utils.js generated vendored Normal file
View File

@@ -0,0 +1,3 @@
const isWindows = opts => (opts.fakePlatform || process.platform) === 'win32'
exports.isWindows = isWindows

18
package/node_modules/@npmcli/git/lib/which.js generated vendored Normal file
View File

@@ -0,0 +1,18 @@
const which = require('which')
let gitPath
try {
gitPath = which.sync('git')
} catch {
// ignore errors
}
module.exports = (opts = {}) => {
if (opts.git) {
return opts.git
}
if (!gitPath || opts.git === false) {
return Object.assign(new Error('No git binary found in $PATH'), { code: 'ENOGIT' })
}
return gitPath
}

58
package/node_modules/@npmcli/git/package.json generated vendored Normal file
View File

@@ -0,0 +1,58 @@
{
"name": "@npmcli/git",
"version": "5.0.8",
"main": "lib/index.js",
"files": [
"bin/",
"lib/"
],
"description": "a util for spawning git from npm CLI contexts",
"repository": {
"type": "git",
"url": "git+https://github.com/npm/git.git"
},
"author": "GitHub Inc.",
"license": "ISC",
"scripts": {
"lint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"",
"snap": "tap",
"test": "tap",
"posttest": "npm run lint",
"postlint": "template-oss-check",
"lintfix": "npm run lint -- --fix",
"template-oss-apply": "template-oss-apply --force"
},
"tap": {
"timeout": 600,
"nyc-arg": [
"--exclude",
"tap-snapshots/**"
]
},
"devDependencies": {
"@npmcli/eslint-config": "^4.0.0",
"@npmcli/template-oss": "4.22.0",
"npm-package-arg": "^11.0.0",
"slash": "^3.0.0",
"tap": "^16.0.1"
},
"dependencies": {
"@npmcli/promise-spawn": "^7.0.0",
"ini": "^4.1.3",
"lru-cache": "^10.0.1",
"npm-pick-manifest": "^9.0.0",
"proc-log": "^4.0.0",
"promise-inflight": "^1.0.1",
"promise-retry": "^2.0.1",
"semver": "^7.3.5",
"which": "^4.0.0"
},
"engines": {
"node": "^16.14.0 || >=18.0.0"
},
"templateOSS": {
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
"version": "4.22.0",
"publish": true
}
}