Skip to content

Commit 7ddfbad

Browse files
committed
deps: @npmcli/package-json@6.1.1
1 parent 18e0449 commit 7ddfbad

File tree

9 files changed

+283
-47
lines changed

9 files changed

+283
-47
lines changed

DEPENDENCIES.json

Lines changed: 2 additions & 2 deletions
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

Lines changed: 2 additions & 3 deletions
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

Lines changed: 3 additions & 1 deletion
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

Lines changed: 257 additions & 0 deletions
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

Lines changed: 3 additions & 25 deletions
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

Lines changed: 6 additions & 6 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy