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/libnpmdiff/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,15 @@
The ISC License
Copyright (c) GitHub 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 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.

96
package/node_modules/libnpmdiff/README.md generated vendored Normal file
View File

@@ -0,0 +1,96 @@
# libnpmdiff
[![npm version](https://img.shields.io/npm/v/libnpmdiff.svg)](https://npm.im/libnpmdiff)
[![license](https://img.shields.io/npm/l/libnpmdiff.svg)](https://npm.im/libnpmdiff)
[![CI - libnpmdiff](https://github.com/npm/cli/actions/workflows/ci-libnpmdiff.yml/badge.svg)](https://github.com/npm/cli/actions/workflows/ci-libnpmdiff.yml)
The registry diff lib.
## Table of Contents
* [Example](#example)
* [Install](#install)
* [Contributing](#contributing)
* [API](#api)
* [LICENSE](#license)
## Example
```js
const libdiff = require('libnpmdiff')
const patch = await libdiff([
'abbrev@1.1.0',
'abbrev@1.1.1'
])
console.log(
patch
)
```
Returns:
```patch
diff --git a/package.json b/package.json
index v1.1.0..v1.1.1 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "abbrev",
- "version": "1.1.0",
+ "version": "1.1.1",
"description": "Like ruby's abbrev module, but in js",
"author": "Isaac Z. Schlueter <i@izs.me>",
"main": "abbrev.js",
```
## Install
`$ npm install libnpmdiff`
### Contributing
The npm team enthusiastically welcomes contributions and project participation!
There's a bunch of things you can do if you want to contribute! The
[Contributor Guide](https://github.com/npm/cli/blob/latest/CONTRIBUTING.md)
outlines the process for community interaction and contribution. Please don't
hesitate to jump in if you'd like to, or even ask us questions if something
isn't clear.
All participants and maintainers in this project are expected to follow the
[npm Code of Conduct](https://docs.npmjs.com/policies/conduct), and just
generally be excellent to each other.
Please refer to the [Changelog](CHANGELOG.md) for project history details, too.
Happy hacking!
### API
#### `> libnpmdif([ a, b ], [opts]) -> Promise<String>`
Fetches the registry tarballs and compare files between a spec `a` and spec `b`. **npm** spec types are usually described in `<pkg-name>@<version>` form but multiple other types are alsos supported, for more info on valid specs take a look at [`npm-package-arg`](https://github.com/npm/npm-package-arg).
**Options**:
- `color <Boolean>`: Should add ANSI colors to string output? Defaults to `false`.
- `tagVersionPrefix <Sring>`: What prefix should be used to define version numbers. Defaults to `v`
- `diffUnified <Number>`: How many lines of code to print before/after each diff. Defaults to `3`.
- `diffFiles <Array<String>>`: If set only prints patches for the files listed in this array (also accepts globs). Defaults to `undefined`.
- `diffIgnoreAllSpace <Boolean>`: Whether or not should ignore changes in whitespace (very useful to avoid indentation changes extra diff lines). Defaults to `false`.
- `diffNameOnly <Boolean>`: Prints only file names and no patch diffs. Defaults to `false`.
- `diffNoPrefix <Boolean>`: If true then skips printing any prefixes in filenames. Defaults to `false`.
- `diffSrcPrefix <String>`: Prefix to be used in the filenames from `a`. Defaults to `a/`.
- `diffDstPrefix <String>`: Prefix to be used in the filenames from `b`. Defaults to `b/`.
- `diffText <Boolean>`: Should treat all files as text and try to print diff for binary files. Defaults to `false`.
- ...`cache`, `registry`, `where` and other common options accepted by [pacote](https://github.com/npm/pacote#options)
Returns a `Promise` that fullfils with a `String` containing the resulting patch diffs.
Throws an error if either `a` or `b` are missing or if trying to diff more than two specs.
## LICENSE
[ISC](./LICENSE)

118
package/node_modules/libnpmdiff/lib/format-diff.js generated vendored Normal file
View File

@@ -0,0 +1,118 @@
const jsDiff = require('diff')
const shouldPrintPatch = require('./should-print-patch.js')
const colors = {
// red
removed: { open: '\x1B[31m', close: '\x1B[39m' },
// green
added: { open: '\x1B[32m', close: '\x1B[39m' },
// blue
header: { open: '\x1B[34m', close: '\x1B[39m' },
// cyan
section: { open: '\x1B[36m', close: '\x1B[39m' },
}
const color = (colorStr, colorId) => {
const { open, close } = colors[colorId]
// avoid highlighting the "\n" (would highlight till the end of the line)
return colorStr.replace(/[^\n\r]+/g, open + '$&' + close)
}
const formatDiff = ({ files, opts = {}, refs, versions }) => {
let res = ''
const srcPrefix = opts.diffNoPrefix ? '' : opts.diffSrcPrefix || 'a/'
const dstPrefix = opts.diffNoPrefix ? '' : opts.diffDstPrefix || 'b/'
for (const filename of files.values()) {
const names = {
a: `${srcPrefix}${filename}`,
b: `${dstPrefix}${filename}`,
}
let fileMode = ''
const filenames = {
a: refs.get(`a/${filename}`),
b: refs.get(`b/${filename}`),
}
const contents = {
a: filenames.a && filenames.a.content,
b: filenames.b && filenames.b.content,
}
const modes = {
a: filenames.a && filenames.a.mode,
b: filenames.b && filenames.b.mode,
}
if (contents.a === contents.b && modes.a === modes.b) {
continue
}
if (opts.diffNameOnly) {
res += `${filename}\n`
continue
}
let patch = ''
let headerLength = 0
const header = str => {
headerLength++
patch += `${str}\n`
}
// manually build a git diff-compatible header
header(`diff --git ${names.a} ${names.b}`)
if (modes.a === modes.b) {
fileMode = filenames.a.mode
} else {
if (modes.a && !modes.b) {
header(`deleted file mode ${modes.a}`)
} else if (!modes.a && modes.b) {
header(`new file mode ${modes.b}`)
} else {
header(`old mode ${modes.a}`)
header(`new mode ${modes.b}`)
}
}
/* eslint-disable-next-line max-len */
header(`index ${opts.tagVersionPrefix || 'v'}${versions.a}..${opts.tagVersionPrefix || 'v'}${versions.b} ${fileMode}`)
if (shouldPrintPatch(filename)) {
patch += jsDiff.createTwoFilesPatch(
names.a,
names.b,
contents.a || '',
contents.b || '',
'',
'',
{
context: opts.diffUnified === 0 ? 0 : opts.diffUnified || 3,
ignoreWhitespace: opts.diffIgnoreAllSpace,
}
).replace(
'===================================================================\n',
''
).replace(/\t\n/g, '\n') // strip trailing tabs
headerLength += 2
} else {
header(`--- ${names.a}`)
header(`+++ ${names.b}`)
}
if (opts.color) {
// this RegExp will include all the `\n` chars into the lines, easier to join
const lines = patch.split(/^/m)
res += color(lines.slice(0, headerLength).join(''), 'header')
res += lines.slice(headerLength).join('')
.replace(/^-.*/gm, color('$&', 'removed'))
.replace(/^\+.*/gm, color('$&', 'added'))
.replace(/^@@.+@@/gm, color('$&', 'section'))
} else {
res += patch
}
}
return res.trim()
}
module.exports = formatDiff

62
package/node_modules/libnpmdiff/lib/index.js generated vendored Normal file
View File

@@ -0,0 +1,62 @@
const pacote = require('pacote')
const formatDiff = require('./format-diff.js')
const getTarball = require('./tarball.js')
const untar = require('./untar.js')
// TODO: we test this condition in the diff command
// so this error probably doesnt need to be here. Or
// if it does we should figure out a standard code
// so we can catch it in the cli and display it consistently
const argsError = () =>
Object.assign(
new TypeError('libnpmdiff needs two arguments to compare'),
{ code: 'EDIFFARGS' }
)
const diff = async (specs, opts = {}) => {
if (specs.length !== 2) {
throw argsError()
}
const [
aManifest,
bManifest,
] =
await Promise.all(specs.map(spec => pacote.manifest(spec, opts)))
const versions = {
a: aManifest.version,
b: bManifest.version,
}
// fetches tarball using pacote
const [a, b] = await Promise.all([
getTarball(aManifest, opts),
getTarball(bManifest, opts),
])
// read all files
// populates `files` and `refs`
const {
files,
refs,
} = await untar([
{
prefix: 'a/',
item: a,
},
{
prefix: 'b/',
item: b,
},
], opts)
return formatDiff({
files,
opts,
refs,
versions,
})
}
module.exports = diff

View File

@@ -0,0 +1,22 @@
const { basename, extname } = require('node:path')
const binaryExtensions = require('binary-extensions')
// we should try to print patches as long as the
// extension is not identified as binary files
const shouldPrintPatch = (path, opts = {}) => {
if (opts.diffText) {
return true
}
const filename = basename(path)
const extension = (
filename.startsWith('.')
? filename
: extname(filename)
).slice(1)
return !binaryExtensions.includes(extension)
}
module.exports = shouldPrintPatch

38
package/node_modules/libnpmdiff/lib/tarball.js generated vendored Normal file
View File

@@ -0,0 +1,38 @@
const { relative } = require('node:path')
const Arborist = require('@npmcli/arborist')
const npa = require('npm-package-arg')
const pkgContents = require('@npmcli/installed-package-contents')
const pacote = require('pacote')
const { tarCreateOptions } = pacote.DirFetcher
const tar = require('tar')
// returns a simplified tarball when reading files from node_modules folder,
// thus avoiding running the prepare scripts and the extra logic from packlist
const nodeModulesTarball = (manifest) =>
pkgContents({ path: manifest._resolved, depth: 1 })
.then(files =>
files.map(file => relative(manifest._resolved, file))
)
.then(files =>
tar.c(tarCreateOptions(manifest), files).concat()
)
const tarball = (manifest, opts) => {
const resolved = manifest._resolved
const where = opts.where || process.cwd()
const fromNodeModules = npa(resolved).type === 'directory'
&& /node_modules[\\/](@[^\\/]+\/)?[^\\/]+[\\/]?$/.test(relative(where, resolved))
if (fromNodeModules) {
return nodeModulesTarball(manifest, opts)
}
return pacote.tarball(manifest._resolved, {
...opts,
Arborist,
})
}
module.exports = tarball

96
package/node_modules/libnpmdiff/lib/untar.js generated vendored Normal file
View File

@@ -0,0 +1,96 @@
const tar = require('tar')
const { minimatch } = require('minimatch')
const normalizeMatch = str => str
.replace(/\\+/g, '/')
.replace(/^\.\/|^\./, '')
// files and refs are mutating params
// filterFiles, item, prefix and opts are read-only options
const untar = ({ files, refs }, { filterFiles, item, prefix }) => {
tar.list({
filter: (path, entry) => {
const fileMatch = () =>
(!filterFiles.length ||
filterFiles.some(f => {
const pattern = normalizeMatch(f)
return minimatch(
normalizeMatch(path),
`{package/,}${pattern}`,
{ matchBase: pattern.startsWith('*') }
)
}))
// expands usage of simple path filters, e.g: lib or src/
const folderMatch = () =>
filterFiles.some(f =>
normalizeMatch(path).startsWith(normalizeMatch(f)) ||
normalizeMatch(path).startsWith(`package/${normalizeMatch(f)}`))
if (
entry.type === 'File' &&
(fileMatch() || folderMatch())
) {
const key = path.replace(/^[^/]+\/?/, '')
files.add(key)
// should skip reading file when using --name-only option
let content
try {
entry.setEncoding('utf8')
content = entry.concat()
} catch (e) {
/* istanbul ignore next */
throw Object.assign(
new Error('failed to read files'),
{ code: 'EDIFFUNTAR' }
)
}
refs.set(`${prefix}${key}`, {
content,
mode: `100${entry.mode.toString(8)}`,
})
return true
}
},
})
.on('error', /* istanbul ignore next */ e => {
throw e
})
.end(item)
}
const readTarballs = async (tarballs, opts = {}) => {
const files = new Set()
const refs = new Map()
const arr = [].concat(tarballs)
const filterFiles = opts.diffFiles || []
for (const i of arr) {
untar({
files,
refs,
}, {
item: i.item,
prefix: i.prefix,
filterFiles,
})
}
// await to read all content from included files
const allRefs = [...refs.values()]
const contents = await Promise.all(allRefs.map(async ref => ref.content))
contents.forEach((content, index) => {
allRefs[index].content = content
})
return {
files,
refs,
}
}
module.exports = readTarballs

69
package/node_modules/libnpmdiff/package.json generated vendored Normal file
View File

@@ -0,0 +1,69 @@
{
"name": "libnpmdiff",
"version": "6.1.4",
"description": "The registry diff",
"repository": {
"type": "git",
"url": "git+https://github.com/npm/cli.git",
"directory": "workspaces/libnpmdiff"
},
"main": "lib/index.js",
"files": [
"bin/",
"lib/"
],
"engines": {
"node": "^16.14.0 || >=18.0.0"
},
"keywords": [
"npm",
"npmcli",
"libnpm",
"cli",
"diff"
],
"author": "GitHub Inc.",
"contributors": [
{
"name": "Ruy Adorno",
"url": "https://ruyadorno.com",
"twitter": "ruyadorno"
}
],
"license": "ISC",
"scripts": {
"lint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"",
"lintfix": "npm run lint -- --fix",
"test": "tap",
"posttest": "npm run lint",
"snap": "tap",
"postlint": "template-oss-check",
"template-oss-apply": "template-oss-apply --force"
},
"devDependencies": {
"@npmcli/eslint-config": "^4.0.0",
"@npmcli/template-oss": "4.22.0",
"tap": "^16.3.8"
},
"dependencies": {
"@npmcli/arborist": "^7.5.4",
"@npmcli/installed-package-contents": "^2.1.0",
"binary-extensions": "^2.3.0",
"diff": "^5.1.0",
"minimatch": "^9.0.4",
"npm-package-arg": "^11.0.2",
"pacote": "^18.0.6",
"tar": "^6.2.1"
},
"templateOSS": {
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
"version": "4.22.0",
"content": "../../scripts/template-oss/index.js"
},
"tap": {
"nyc-arg": [
"--exclude",
"tap-snapshots/**"
]
}
}