Skip to content

Commit 636e29e

Browse files
committedMay 22, 2023
fix: move to @npmcli/package-json where possible
Some commands have tests that mock the library that parses package.json and will need to be fixed before we can move them over
1 parent b21e11f commit 636e29e

15 files changed

+58
-66
lines changed
 

‎lib/commands/access.js

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
const path = require('path')
2-
31
const libnpmaccess = require('libnpmaccess')
42
const npa = require('npm-package-arg')
5-
const readPackageJson = require('read-package-json-fast')
3+
const pkgJson = require('@npmcli/package-json')
64
const localeCompare = require('@isaacs/string-locale-compare')('en')
75

86
const otplease = require('../utils/otplease.js')
@@ -178,8 +176,8 @@ class Access extends BaseCommand {
178176
async #getPackage (name, requireScope) {
179177
if (!name) {
180178
try {
181-
const pkg = await readPackageJson(path.resolve(this.npm.prefix, 'package.json'))
182-
name = pkg.name
179+
const { content } = await pkgJson.normalize(this.npm.prefix)
180+
name = content.name
183181
} catch (err) {
184182
if (err.code === 'ENOENT') {
185183
throw Object.assign(new Error('no package name given and no package.json found'), {

‎lib/commands/config.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const { spawn } = require('child_process')
77
const { EOL } = require('os')
88
const ini = require('ini')
99
const localeCompare = require('@isaacs/string-locale-compare')('en')
10-
const rpj = require('read-package-json-fast')
10+
const pkgJson = require('@npmcli/package-json')
1111
const log = require('../utils/log-shim.js')
1212

1313
// These are the configs that we can nerf-dart. Not all of them currently even
@@ -346,15 +346,15 @@ ${defData}
346346
}
347347

348348
if (!this.npm.global) {
349-
const pkgPath = resolve(this.npm.prefix, 'package.json')
350-
const pkg = await rpj(pkgPath).catch(() => ({}))
349+
const { content } = await pkgJson.normalize(this.npm.prefix).catch(() => ({ content: {} }))
351350

352-
if (pkg.publishConfig) {
351+
if (content.publishConfig) {
352+
const pkgPath = resolve(this.npm.prefix, 'package.json')
353353
msg.push(`; "publishConfig" from ${pkgPath}`)
354354
msg.push('; This set of config values will be used at publish-time.', '')
355-
const pkgKeys = Object.keys(pkg.publishConfig).sort(localeCompare)
355+
const pkgKeys = Object.keys(content.publishConfig).sort(localeCompare)
356356
for (const k of pkgKeys) {
357-
const v = publicVar(k) ? JSON.stringify(pkg.publishConfig[k]) : '(protected)'
357+
const v = publicVar(k) ? JSON.stringify(content.publishConfig[k]) : '(protected)'
358358
msg.push(`${k} = ${v}`)
359359
}
360360
msg.push('')

‎lib/commands/diff.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const npa = require('npm-package-arg')
55
const pacote = require('pacote')
66
const pickManifest = require('npm-pick-manifest')
77
const log = require('../utils/log-shim')
8-
const readPackage = require('read-package-json-fast')
8+
const pkgJson = require('@npmcli/package-json')
99
const BaseCommand = require('../base-command.js')
1010

1111
class Diff extends BaseCommand {
@@ -81,7 +81,7 @@ class Diff extends BaseCommand {
8181
async packageName (path) {
8282
let name
8383
try {
84-
const pkg = await readPackage(resolve(this.prefix, 'package.json'))
84+
const { content: pkg } = await pkgJson.normalize(this.prefix)
8585
name = pkg.name
8686
} catch (e) {
8787
log.verbose('diff', 'could not read project dir package.json')
@@ -115,7 +115,7 @@ class Diff extends BaseCommand {
115115
let noPackageJson
116116
let pkgName
117117
try {
118-
const pkg = await readPackage(resolve(this.prefix, 'package.json'))
118+
const { content: pkg } = await pkgJson.normalize(this.prefix)
119119
pkgName = pkg.name
120120
} catch (e) {
121121
log.verbose('diff', 'could not read project dir package.json')
@@ -228,7 +228,7 @@ class Diff extends BaseCommand {
228228
if (semverA && semverB) {
229229
let pkgName
230230
try {
231-
const pkg = await readPackage(resolve(this.prefix, 'package.json'))
231+
const { content: pkg } = await pkgJson.normalize(this.prefix)
232232
pkgName = pkg.name
233233
} catch (e) {
234234
log.verbose('diff', 'could not read project dir package.json')

‎lib/commands/dist-tag.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
const npa = require('npm-package-arg')
2-
const path = require('path')
32
const regFetch = require('npm-registry-fetch')
43
const semver = require('semver')
54
const log = require('../utils/log-shim')
65
const otplease = require('../utils/otplease.js')
7-
const readPackage = require('read-package-json-fast')
6+
const pkgJson = require('@npmcli/package-json')
87
const BaseCommand = require('../base-command.js')
98

109
class DistTag extends BaseCommand {
@@ -152,7 +151,7 @@ class DistTag extends BaseCommand {
152151
if (this.npm.global) {
153152
throw this.usageError()
154153
}
155-
const { name } = await readPackage(path.resolve(this.npm.prefix, 'package.json'))
154+
const { content: { name } } = await pkgJson.normalize(this.npm.prefix)
156155
if (!name) {
157156
throw this.usageError()
158157
}

‎lib/commands/init.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ const { relative, resolve } = require('path')
33
const { mkdir } = require('fs/promises')
44
const initJson = require('init-package-json')
55
const npa = require('npm-package-arg')
6-
const rpj = require('read-package-json-fast')
76
const libexec = require('libnpmexec')
87
const mapWorkspaces = require('@npmcli/map-workspaces')
98
const PackageJson = require('@npmcli/package-json')
@@ -54,7 +53,7 @@ class Init extends BaseCommand {
5453
// reads package.json for the top-level folder first, by doing this we
5554
// ensure the command throw if no package.json is found before trying
5655
// to create a workspace package.json file or its folders
57-
const pkg = await rpj(resolve(this.npm.localPrefix, 'package.json')).catch((err) => {
56+
const { content: pkg } = await PackageJson.normalize(this.npm.localPrefix).catch(err => {
5857
if (err.code === 'ENOENT') {
5958
log.warn('Missing package.json. Try with `--include-workspace-root`.')
6059
}
@@ -217,7 +216,7 @@ class Init extends BaseCommand {
217216
// translate workspaces paths into an array containing workspaces names
218217
const workspaces = []
219218
for (const path of workspacesPaths) {
220-
const { name } = await rpj(resolve(path, 'package.json')).catch(() => ({}))
219+
const { content: { name } } = await PackageJson.normalize(path).catch(() => ({ content: {} }))
221220

222221
if (name) {
223222
workspaces.push(name)

‎lib/commands/link.js

+7-6
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const readdir = util.promisify(fs.readdir)
44
const { resolve } = require('path')
55

66
const npa = require('npm-package-arg')
7-
const rpj = require('read-package-json-fast')
7+
const pkgJson = require('@npmcli/package-json')
88
const semver = require('semver')
99

1010
const reifyFinish = require('../utils/reify-finish.js')
@@ -96,11 +96,12 @@ class Link extends ArboristWorkspaceCmd {
9696
const names = []
9797
for (const a of args) {
9898
const arg = npa(a)
99-
names.push(
100-
arg.type === 'directory'
101-
? (await rpj(resolve(arg.fetchSpec, 'package.json'))).name
102-
: arg.name
103-
)
99+
if (arg.type === 'directory') {
100+
const { content } = await pkgJson.normalize(arg.fetchSpec)
101+
names.push(content.name)
102+
} else {
103+
names.push(arg.name)
104+
}
104105
}
105106

106107
// npm link should not save=true by default unless you're

‎lib/commands/owner.js

+6-7
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,13 @@ const npmFetch = require('npm-registry-fetch')
33
const pacote = require('pacote')
44
const log = require('../utils/log-shim')
55
const otplease = require('../utils/otplease.js')
6-
const readPackageJsonFast = require('read-package-json-fast')
6+
const pkgJson = require('@npmcli/package-json')
77
const BaseCommand = require('../base-command.js')
8-
const { resolve } = require('path')
98

10-
const readJson = async (pkg) => {
9+
const readJson = async (path) => {
1110
try {
12-
const json = await readPackageJsonFast(pkg)
13-
return json
11+
const { content } = await pkgJson.normalize(path)
12+
return content
1413
} catch {
1514
return {}
1615
}
@@ -54,7 +53,7 @@ class Owner extends BaseCommand {
5453
if (this.npm.global) {
5554
return []
5655
}
57-
const { name } = await readJson(resolve(this.npm.prefix, 'package.json'))
56+
const { name } = await readJson(this.npm.prefix)
5857
if (!name) {
5958
return []
6059
}
@@ -130,7 +129,7 @@ class Owner extends BaseCommand {
130129
if (this.npm.global) {
131130
throw this.usageError()
132131
}
133-
const { name } = await readJson(resolve(prefix, 'package.json'))
132+
const { name } = await readJson(prefix)
134133
if (!name) {
135134
throw this.usageError()
136135
}

‎lib/commands/publish.js

+4-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
const util = require('util')
21
const log = require('../utils/log-shim.js')
32
const semver = require('semver')
43
const pack = require('libnpmpack')
@@ -17,11 +16,7 @@ const { getContents, logTar } = require('../utils/tar.js')
1716
// revisit this at some point, and have a minimal set that's a SemVer-major
1817
// change that ought to get a RFC written on it.
1918
const { flatten } = require('../utils/config/index.js')
20-
21-
// this is the only case in the CLI where we want to use the old full slow
22-
// 'read-package-json' module, because we want to pull in all the defaults and
23-
// metadata, like git sha's and default scripts and all that.
24-
const readJson = util.promisify(require('read-package-json'))
19+
const pkgJson = require('@npmcli/package-json')
2520

2621
const BaseCommand = require('../base-command.js')
2722
class Publish extends BaseCommand {
@@ -204,7 +199,9 @@ class Publish extends BaseCommand {
204199
async getManifest (spec, opts) {
205200
let manifest
206201
if (spec.type === 'directory') {
207-
manifest = await readJson(`${spec.fetchSpec}/package.json`)
202+
// Prepare is the special function for publishing, different than normalize
203+
const { content } = await pkgJson.prepare(spec.fetchSpec)
204+
manifest = content
208205
} else {
209206
manifest = await pacote.manifest(spec, {
210207
...opts,

‎lib/commands/run-script.js

+12-11
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
const { resolve } = require('path')
21
const runScript = require('@npmcli/run-script')
32
const { isServerPackage } = runScript
4-
const rpj = require('read-package-json-fast')
3+
const pkgJson = require('@npmcli/package-json')
54
const log = require('../utils/log-shim.js')
65
const didYouMean = require('../utils/did-you-mean.js')
76
const { isWindowsShell } = require('../utils/is-windows.js')
@@ -39,9 +38,8 @@ class RunScript extends BaseCommand {
3938
async completion (opts) {
4039
const argv = opts.conf.argv.remain
4140
if (argv.length === 2) {
42-
// find the script name
43-
const json = resolve(this.npm.localPrefix, 'package.json')
44-
const { scripts = {} } = await rpj(json).catch(er => ({}))
41+
const { content: { scripts = {} } } = await pkgJson.normalize(this.npm.localPrefix)
42+
.catch(er => ({ content: {} }))
4543
if (opts.isFish) {
4644
return Object.keys(scripts).map(s => `${s}\t${scripts[s].slice(0, 30)}`)
4745
}
@@ -70,7 +68,10 @@ class RunScript extends BaseCommand {
7068
// null value
7169
const scriptShell = this.npm.config.get('script-shell') || undefined
7270

73-
pkg = pkg || (await rpj(`${path}/package.json`))
71+
if (!pkg) {
72+
const { content } = await pkgJson.normalize(path)
73+
pkg = content
74+
}
7475
const { scripts = {} } = pkg
7576

7677
if (event === 'restart' && !scripts.restart) {
@@ -126,8 +127,8 @@ class RunScript extends BaseCommand {
126127
}
127128

128129
async list (args, path) {
129-
path = path || this.npm.localPrefix
130-
const { scripts, name, _id } = await rpj(`${path}/package.json`)
130+
/* eslint-disable-next-line max-len */
131+
const { content: { scripts, name, _id } } = await pkgJson.normalize(path || this.npm.localPrefix)
131132
const pkgid = _id || name
132133

133134
if (!scripts) {
@@ -197,7 +198,7 @@ class RunScript extends BaseCommand {
197198
await this.setWorkspaces()
198199

199200
for (const workspacePath of this.workspacePaths) {
200-
const pkg = await rpj(`${workspacePath}/package.json`)
201+
const { content: pkg } = await pkgJson.normalize(workspacePath)
201202
const runResult = await this.run(args, {
202203
path: workspacePath,
203204
pkg,
@@ -236,7 +237,7 @@ class RunScript extends BaseCommand {
236237
if (this.npm.config.get('json')) {
237238
const res = {}
238239
for (const workspacePath of this.workspacePaths) {
239-
const { scripts, name } = await rpj(`${workspacePath}/package.json`)
240+
const { content: { scripts, name } } = await pkgJson.normalize(workspacePath)
240241
res[name] = { ...scripts }
241242
}
242243
this.npm.output(JSON.stringify(res, null, 2))
@@ -245,7 +246,7 @@ class RunScript extends BaseCommand {
245246

246247
if (this.npm.config.get('parseable')) {
247248
for (const workspacePath of this.workspacePaths) {
248-
const { scripts, name } = await rpj(`${workspacePath}/package.json`)
249+
const { content: { scripts, name } } = await pkgJson.normalize(workspacePath)
249250
for (const [script, cmd] of Object.entries(scripts || {})) {
250251
this.npm.output(`${name}:${script}:${cmd}`)
251252
}

‎lib/commands/uninstall.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
const { resolve } = require('path')
2-
const rpj = require('read-package-json-fast')
2+
const pkgJson = require('@npmcli/package-json')
33

44
const reifyFinish = require('../utils/reify-finish.js')
55
const completion = require('../utils/completion/installed-shallow.js')
@@ -24,7 +24,7 @@ class Uninstall extends ArboristWorkspaceCmd {
2424
throw new Error('Must provide a package name to remove')
2525
} else {
2626
try {
27-
const pkg = await rpj(resolve(this.npm.localPrefix, 'package.json'))
27+
const { content: pkg } = await pkgJson.normalize(this.npm.localPrefix)
2828
args.push(pkg.name)
2929
} catch (er) {
3030
if (er.code !== 'ENOENT' && er.code !== 'ENOTDIR') {

‎lib/commands/unpublish.js

+3-5
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ const libaccess = require('libnpmaccess')
22
const libunpub = require('libnpmpublish').unpublish
33
const npa = require('npm-package-arg')
44
const npmFetch = require('npm-registry-fetch')
5-
const path = require('path')
6-
const util = require('util')
7-
const readJson = util.promisify(require('read-package-json'))
5+
const pkgJson = require('@npmcli/package-json')
86

97
const { flatten } = require('../utils/config/index.js')
108
const getIdentity = require('../utils/get-identity.js')
@@ -96,8 +94,8 @@ class Unpublish extends BaseCommand {
9694
let manifest
9795
let manifestErr
9896
try {
99-
const pkgJson = path.join(this.npm.localPrefix, 'package.json')
100-
manifest = await readJson(pkgJson)
97+
const { content } = await pkgJson.prepare(this.npm.localPrefix)
98+
manifest = content
10199
} catch (err) {
102100
manifestErr = err
103101
}

‎lib/utils/did-you-mean.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
const { distance } = require('fastest-levenshtein')
2-
const readJson = require('read-package-json-fast')
2+
const pkgJson = require('@npmcli/package-json')
33
const { commands } = require('./cmd-list.js')
44

55
const didYouMean = async (npm, path, scmd) => {
@@ -13,7 +13,7 @@ const didYouMean = async (npm, path, scmd) => {
1313
// We would already be suggesting this in `npm x` so omit them here
1414
const runScripts = ['stop', 'start', 'test', 'restart']
1515
try {
16-
const { bin, scripts } = await readJson(`${path}/package.json`)
16+
const { content: { scripts, bin } } = await pkgJson.normalize(path)
1717
best = best.concat(
1818
Object.keys(scripts || {})
1919
.filter(cmd => distance(scmd, cmd) < scmd.length * 0.4 && !runScripts.includes(cmd))

‎lib/workspaces/get-workspaces.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
const { resolve, relative } = require('path')
22
const mapWorkspaces = require('@npmcli/map-workspaces')
33
const { minimatch } = require('minimatch')
4-
const rpj = require('read-package-json-fast')
4+
const pkgJson = require('@npmcli/package-json')
55

66
// minimatch wants forward slashes only for glob patterns
77
const globify = pattern => pattern.split('\\').join('/')
88

99
// Returns an Map of paths to workspaces indexed by workspace name
1010
// { foo => '/path/to/foo' }
1111
const getWorkspaces = async (filters, { path, includeWorkspaceRoot, relativeFrom }) => {
12-
// TODO we need a better error to be bubbled up here if this rpj call fails
13-
const pkg = await rpj(resolve(path, 'package.json'))
12+
// TODO we need a better error to be bubbled up here if this call fails
13+
const { content: pkg } = await pkgJson.normalize(path)
1414
const workspaces = await mapWorkspaces({ cwd: path, pkg })
1515
let res = new Map()
1616
if (includeWorkspaceRoot) {

‎test/lib/commands/init.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ t.test('workspaces', async t => {
312312
await t.test('fail parsing top-level package.json to set workspace', async t => {
313313
const { npm } = await mockNpm(t, {
314314
prefixDir: {
315-
'package.json': 'not json['
315+
'package.json': 'not json[',
316316
},
317317
config: { workspace: 'a', yes: true },
318318
noLog: true,

‎test/lib/commands/unpublish.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ t.test('no args --force error reading package.json', async t => {
5858

5959
await t.rejects(
6060
npm.exec('unpublish', []),
61-
/Failed to parse json/,
61+
/Invalid package.json/,
6262
'should throw error from reading package.json'
6363
)
6464
})

0 commit comments

Comments
 (0)
Please sign in to comment.