Skip to content

Commit 7ddfbad

Browse files
committed
deps: @npmcli/[email protected]
1 parent 18e0449 commit 7ddfbad

File tree

9 files changed

+283
-47
lines changed

9 files changed

+283
-47
lines changed

DEPENDENCIES.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@
5252
"@npmcli/promise-spawn",
5353
"npm-install-checks",
5454
"npm-bundled",
55-
"normalize-package-data",
5655
"@npmcli/fs",
5756
"unique-filename",
5857
"npm-packlist",
@@ -61,7 +60,8 @@
6160
"nopt",
6261
"parse-conflict-json",
6362
"read-package-json-fast",
64-
"read"
63+
"read",
64+
"normalize-package-data"
6565
],
6666
[
6767
"@npmcli/eslint-config",

DEPENDENCIES.md

+2-3
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,6 @@ graph LR;
218218
npmcli-mock-registry-->pacote;
219219
npmcli-package-json-->hosted-git-info;
220220
npmcli-package-json-->json-parse-even-better-errors;
221-
npmcli-package-json-->normalize-package-data;
222221
npmcli-package-json-->npmcli-git["@npmcli/git"];
223222
npmcli-package-json-->proc-log;
224223
npmcli-package-json-->semver;
@@ -660,10 +659,10 @@ graph LR;
660659
npmcli-package-json-->glob;
661660
npmcli-package-json-->hosted-git-info;
662661
npmcli-package-json-->json-parse-even-better-errors;
663-
npmcli-package-json-->normalize-package-data;
664662
npmcli-package-json-->npmcli-git["@npmcli/git"];
665663
npmcli-package-json-->proc-log;
666664
npmcli-package-json-->semver;
665+
npmcli-package-json-->validate-npm-package-license;
667666
npmcli-promise-spawn-->which;
668667
npmcli-query-->postcss-selector-parser;
669668
npmcli-run-script-->node-gyp;
@@ -783,5 +782,5 @@ packages higher up the chain.
783782
- @npmcli/package-json, npm-registry-fetch
784783
- @npmcli/git, make-fetch-happen
785784
- @npmcli/smoke-tests, npm-pick-manifest, @npmcli/installed-package-contents, cacache, promzard
786-
- @npmcli/docs, npm-package-arg, @npmcli/promise-spawn, npm-install-checks, npm-bundled, normalize-package-data, @npmcli/fs, unique-filename, npm-packlist, @npmcli/mock-globals, bin-links, nopt, parse-conflict-json, read-package-json-fast, read
785+
- @npmcli/docs, npm-package-arg, @npmcli/promise-spawn, npm-install-checks, npm-bundled, @npmcli/fs, unique-filename, npm-packlist, @npmcli/mock-globals, bin-links, nopt, parse-conflict-json, read-package-json-fast, read, normalize-package-data
787786
- @npmcli/eslint-config, @npmcli/template-oss, ignore-walk, semver, hosted-git-info, proc-log, validate-npm-package-name, which, ini, npm-normalize-package-bin, json-parse-even-better-errors, @npmcli/node-gyp, ssri, unique-slug, @npmcli/redact, @npmcli/agent, minipass-fetch, @npmcli/name-from-folder, @npmcli/query, cmd-shim, read-cmd-shim, write-file-atomic, abbrev, proggy, minify-registry-metadata, mute-stream, npm-audit-report, npm-user-validate

node_modules/@npmcli/package-json/lib/index.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,9 @@ class PackageJson {
252252
.replace(/\n/g, eol)
253253

254254
if (fileContent.trim() !== this.#readFileContent.trim()) {
255-
return await writeFile(this.filename, fileContent)
255+
const written = await writeFile(this.filename, fileContent)
256+
this.#readFileContent = fileContent
257+
return written
256258
}
257259
}
258260

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
// Originally normalize-package-data
2+
3+
const url = require('node:url')
4+
const hostedGitInfo = require('hosted-git-info')
5+
const validateLicense = require('validate-npm-package-license')
6+
7+
const typos = {
8+
dependancies: 'dependencies',
9+
dependecies: 'dependencies',
10+
depdenencies: 'dependencies',
11+
devEependencies: 'devDependencies',
12+
depends: 'dependencies',
13+
'dev-dependencies': 'devDependencies',
14+
devDependences: 'devDependencies',
15+
devDepenencies: 'devDependencies',
16+
devdependencies: 'devDependencies',
17+
repostitory: 'repository',
18+
repo: 'repository',
19+
prefereGlobal: 'preferGlobal',
20+
hompage: 'homepage',
21+
hampage: 'homepage',
22+
autohr: 'author',
23+
autor: 'author',
24+
contributers: 'contributors',
25+
publicationConfig: 'publishConfig',
26+
script: 'scripts',
27+
}
28+
29+
const isEmail = str => str.includes('@') && (str.indexOf('@') < str.lastIndexOf('.'))
30+
31+
// Extracts description from contents of a readme file in markdown format
32+
function extractDescription (description) {
33+
// the first block of text before the first heading that isn't the first line heading
34+
const lines = description.trim().split('\n')
35+
let start = 0
36+
// skip initial empty lines and lines that start with #
37+
while (lines[start]?.trim().match(/^(#|$)/)) {
38+
start++
39+
}
40+
let end = start + 1
41+
// keep going till we get to the end or an empty line
42+
while (end < lines.length && lines[end].trim()) {
43+
end++
44+
}
45+
return lines.slice(start, end).join(' ').trim()
46+
}
47+
48+
function stringifyPerson (person) {
49+
if (typeof person !== 'string') {
50+
const name = person.name || ''
51+
const u = person.url || person.web
52+
const wrappedUrl = u ? (' (' + u + ')') : ''
53+
const e = person.email || person.mail
54+
const wrappedEmail = e ? (' <' + e + '>') : ''
55+
person = name + wrappedEmail + wrappedUrl
56+
}
57+
const matchedName = person.match(/^([^(<]+)/)
58+
const matchedUrl = person.match(/\(([^()]+)\)/)
59+
const matchedEmail = person.match(/<([^<>]+)>/)
60+
const parsed = {}
61+
if (matchedName?.[0].trim()) {
62+
parsed.name = matchedName[0].trim()
63+
}
64+
if (matchedEmail) {
65+
parsed.email = matchedEmail[1]
66+
}
67+
if (matchedUrl) {
68+
parsed.url = matchedUrl[1]
69+
}
70+
return parsed
71+
}
72+
73+
function normalizeData (data, changes) {
74+
// fixDescriptionField
75+
if (data.description && typeof data.description !== 'string') {
76+
changes?.push(`'description' field should be a string`)
77+
delete data.description
78+
}
79+
if (data.readme && !data.description && data.readme !== 'ERROR: No README data found!') {
80+
data.description = extractDescription(data.readme)
81+
}
82+
if (data.description === undefined) {
83+
delete data.description
84+
}
85+
if (!data.description) {
86+
changes?.push('No description')
87+
}
88+
89+
// fixModulesField
90+
if (data.modules) {
91+
changes?.push(`modules field is deprecated`)
92+
delete data.modules
93+
}
94+
95+
// fixFilesField
96+
const files = data.files
97+
if (files && !Array.isArray(files)) {
98+
changes?.push(`Invalid 'files' member`)
99+
delete data.files
100+
} else if (data.files) {
101+
data.files = data.files.filter(function (file) {
102+
if (!file || typeof file !== 'string') {
103+
changes?.push(`Invalid filename in 'files' list: ${file}`)
104+
return false
105+
} else {
106+
return true
107+
}
108+
})
109+
}
110+
111+
// fixManField
112+
if (data.man && typeof data.man === 'string') {
113+
data.man = [data.man]
114+
}
115+
116+
// fixBugsField
117+
if (!data.bugs && data.repository?.url) {
118+
const hosted = hostedGitInfo.fromUrl(data.repository.url)
119+
if (hosted && hosted.bugs()) {
120+
data.bugs = { url: hosted.bugs() }
121+
}
122+
} else if (data.bugs) {
123+
if (typeof data.bugs === 'string') {
124+
if (isEmail(data.bugs)) {
125+
data.bugs = { email: data.bugs }
126+
/* eslint-disable-next-line node/no-deprecated-api */
127+
} else if (url.parse(data.bugs).protocol) {
128+
data.bugs = { url: data.bugs }
129+
} else {
130+
changes?.push(`Bug string field must be url, email, or {email,url}`)
131+
}
132+
} else {
133+
for (const k in data.bugs) {
134+
if (['web', 'name'].includes(k)) {
135+
changes?.push(`bugs['${k}'] should probably be bugs['url'].`)
136+
data.bugs.url = data.bugs[k]
137+
delete data.bugs[k]
138+
}
139+
}
140+
const oldBugs = data.bugs
141+
data.bugs = {}
142+
if (oldBugs.url) {
143+
/* eslint-disable-next-line node/no-deprecated-api */
144+
if (typeof (oldBugs.url) === 'string' && url.parse(oldBugs.url).protocol) {
145+
data.bugs.url = oldBugs.url
146+
} else {
147+
changes?.push('bugs.url field must be a string url. Deleted.')
148+
}
149+
}
150+
if (oldBugs.email) {
151+
if (typeof (oldBugs.email) === 'string' && isEmail(oldBugs.email)) {
152+
data.bugs.email = oldBugs.email
153+
} else {
154+
changes?.push('bugs.email field must be a string email. Deleted.')
155+
}
156+
}
157+
}
158+
if (!data.bugs.email && !data.bugs.url) {
159+
delete data.bugs
160+
changes?.push('Normalized value of bugs field is an empty object. Deleted.')
161+
}
162+
}
163+
// fixKeywordsField
164+
if (typeof data.keywords === 'string') {
165+
data.keywords = data.keywords.split(/,\s+/)
166+
}
167+
if (data.keywords && !Array.isArray(data.keywords)) {
168+
delete data.keywords
169+
changes?.push(`keywords should be an array of strings`)
170+
} else if (data.keywords) {
171+
data.keywords = data.keywords.filter(function (kw) {
172+
if (typeof kw !== 'string' || !kw) {
173+
changes?.push(`keywords should be an array of strings`)
174+
return false
175+
} else {
176+
return true
177+
}
178+
})
179+
}
180+
// fixBundleDependenciesField
181+
const bdd = 'bundledDependencies'
182+
const bd = 'bundleDependencies'
183+
if (data[bdd] && !data[bd]) {
184+
data[bd] = data[bdd]
185+
delete data[bdd]
186+
}
187+
if (data[bd] && !Array.isArray(data[bd])) {
188+
changes?.push(`Invalid 'bundleDependencies' list. Must be array of package names`)
189+
delete data[bd]
190+
} else if (data[bd]) {
191+
data[bd] = data[bd].filter(function (filtered) {
192+
if (!filtered || typeof filtered !== 'string') {
193+
changes?.push(`Invalid bundleDependencies member: ${filtered}`)
194+
return false
195+
} else {
196+
if (!data.dependencies) {
197+
data.dependencies = {}
198+
}
199+
if (!Object.prototype.hasOwnProperty.call(data.dependencies, filtered)) {
200+
changes?.push(`Non-dependency in bundleDependencies: ${filtered}`)
201+
data.dependencies[filtered] = '*'
202+
}
203+
return true
204+
}
205+
})
206+
}
207+
// fixHomepageField
208+
if (!data.homepage && data.repository && data.repository.url) {
209+
const hosted = hostedGitInfo.fromUrl(data.repository.url)
210+
if (hosted) {
211+
data.homepage = hosted.docs()
212+
}
213+
}
214+
if (data.homepage) {
215+
if (typeof data.homepage !== 'string') {
216+
changes?.push('homepage field must be a string url. Deleted.')
217+
delete data.homepage
218+
} else {
219+
/* eslint-disable-next-line node/no-deprecated-api */
220+
if (!url.parse(data.homepage).protocol) {
221+
data.homepage = 'http://' + data.homepage
222+
}
223+
}
224+
}
225+
// fixReadmeField
226+
if (!data.readme) {
227+
changes?.push('No README data')
228+
data.readme = 'ERROR: No README data found!'
229+
}
230+
// fixLicenseField
231+
const license = data.license || data.licence
232+
if (!license) {
233+
changes?.push('No license field.')
234+
} else if (typeof (license) !== 'string' || license.length < 1 || license.trim() === '') {
235+
changes?.push('license should be a valid SPDX license expression')
236+
} else if (!validateLicense(license).validForNewPackages) {
237+
changes?.push('license should be a valid SPDX license expression')
238+
}
239+
// fixPeople
240+
if (data.author) {
241+
data.author = stringifyPerson(data.author)
242+
}
243+
['maintainers', 'contributors'].forEach(function (set) {
244+
if (!Array.isArray(data[set])) {
245+
return
246+
}
247+
data[set] = data[set].map(stringifyPerson)
248+
})
249+
// fixTypos
250+
for (const d in typos) {
251+
if (Object.prototype.hasOwnProperty.call(data, d)) {
252+
changes?.push(`${d} should probably be ${typos[d]}.`)
253+
}
254+
}
255+
}
256+
257+
module.exports = { normalizeData }

node_modules/@npmcli/package-json/lib/normalize.js

+3-25
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,6 @@ const normalize = async (pkg, { strict, steps, root, changes, allowLegacyCase })
348348
changes?.push(`"readmeFilename" was set to ${readmeFile}`)
349349
}
350350
if (!data.readme) {
351-
// this.warn('missingReadme')
352351
data.readme = 'ERROR: No README data found!'
353352
}
354353
}
@@ -488,7 +487,6 @@ const normalize = async (pkg, { strict, steps, root, changes, allowLegacyCase })
488487
// Some steps are isolated so we can do a limited subset of these in `fix`
489488
if (steps.includes('fixRepositoryField') || steps.includes('normalizeData')) {
490489
if (data.repositories) {
491-
/* eslint-disable-next-line max-len */
492490
changes?.push(`"repository" was set to the first entry in "repositories" (${data.repository})`)
493491
data.repository = data.repositories[0]
494492
}
@@ -572,30 +570,10 @@ const normalize = async (pkg, { strict, steps, root, changes, allowLegacyCase })
572570
}
573571
}
574572

573+
// TODO some of this is duplicated in other steps here, a future breaking change may be able to remove the duplicates involved in this step
575574
if (steps.includes('normalizeData')) {
576-
const legacyFixer = require('normalize-package-data/lib/fixer.js')
577-
const legacyMakeWarning = require('normalize-package-data/lib/make_warning.js')
578-
legacyFixer.warn = function () {
579-
changes?.push(legacyMakeWarning.apply(null, arguments))
580-
}
581-
582-
const legacySteps = [
583-
'fixDescriptionField',
584-
'fixModulesField',
585-
'fixFilesField',
586-
'fixManField',
587-
'fixBugsField',
588-
'fixKeywordsField',
589-
'fixBundleDependenciesField',
590-
'fixHomepageField',
591-
'fixReadmeField',
592-
'fixLicenseField',
593-
'fixPeople',
594-
'fixTypos',
595-
]
596-
for (const legacyStep of legacySteps) {
597-
legacyFixer[legacyStep](data)
598-
}
575+
const { normalizeData } = require('./normalize-data.js')
576+
normalizeData(data, changes)
599577
}
600578

601579
// Warn if the bin references don't point to anything. This might be better

node_modules/@npmcli/package-json/package.json

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@npmcli/package-json",
3-
"version": "6.1.0",
3+
"version": "6.1.1",
44
"description": "Programmatic API to update package.json",
55
"keywords": [
66
"npm",
@@ -33,13 +33,13 @@
3333
"glob": "^10.2.2",
3434
"hosted-git-info": "^8.0.0",
3535
"json-parse-even-better-errors": "^4.0.0",
36-
"normalize-package-data": "^7.0.0",
3736
"proc-log": "^5.0.0",
38-
"semver": "^7.5.3"
37+
"semver": "^7.5.3",
38+
"validate-npm-package-license": "^3.0.4"
3939
},
4040
"devDependencies": {
41-
"@npmcli/eslint-config": "^5.0.0",
42-
"@npmcli/template-oss": "4.23.5",
41+
"@npmcli/eslint-config": "^5.1.0",
42+
"@npmcli/template-oss": "4.23.6",
4343
"read-package-json": "^7.0.0",
4444
"read-package-json-fast": "^4.0.0",
4545
"tap": "^16.0.1"
@@ -49,7 +49,7 @@
4949
},
5050
"templateOSS": {
5151
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
52-
"version": "4.23.5",
52+
"version": "4.23.6",
5353
"publish": "true"
5454
},
5555
"tap": {

0 commit comments

Comments
 (0)