diff --git a/docs/lib/index.js b/docs/lib/index.js index d7a5e83ccf506..9779d54657293 100644 --- a/docs/lib/index.js +++ b/docs/lib/index.js @@ -151,10 +151,12 @@ const generateFlagsTable = (definitionPool) => { if (!defaultVal) { defaultVal = String(def.default) } + defaultVal = defaultVal.replace(/\n/g, ' ').trim() let typeVal = def.typeDescription || String(def.type) if (def.required) { typeVal = `${typeVal} (required)` } + typeVal = typeVal.replace(/\n/g, ' ').trim() const desc = (def.description || '').replace(/\n/g, ' ').trim() return `| ${flagsStr} | ${defaultVal} | ${typeVal} | ${desc} |` }) diff --git a/lib/commands/publish.js b/lib/commands/publish.js index 25dda0c156918..bc243dbea68f1 100644 --- a/lib/commands/publish.js +++ b/lib/commands/publish.js @@ -287,7 +287,7 @@ class Publish extends BaseCommand { } else { manifest = await pacote.manifest(spec, { ...opts, - fullmetadata: true, + fullMetadata: true, fullReadJson: true, }) } diff --git a/workspaces/libnpmexec/lib/index.js b/workspaces/libnpmexec/lib/index.js index 3681653d8217d..3add22cd2edca 100644 --- a/workspaces/libnpmexec/lib/index.js +++ b/workspaces/libnpmexec/lib/index.js @@ -87,8 +87,10 @@ const missingFromTree = async ({ spec, tree, flatOptions, isNpxTree, shallow }) } // see if the package.json at `path` has an entry that matches `cmd` +// the path is a known-local directory, not a user-supplied dep, so +// allow-directory must not gate this introspection const hasPkgBin = (path, cmd, flatOptions) => - pacote.manifest(path, flatOptions) + pacote.manifest(path, { ...flatOptions, allowDirectory: 'all' }) .then(manifest => manifest?.bin?.[cmd]).catch(() => null) const exec = async (opts) => { @@ -147,6 +149,8 @@ const exec = async (opts) => { // we have to install the local package into the npx cache so that its // bin links get set up flatOptions.installLinks = false + // self-execution of a local bin, not a directory dep install + flatOptions.allowDirectory = 'all' // args[0] will exist when the package is installed packages.push(p) yes = true diff --git a/workspaces/libnpmexec/test/local.js b/workspaces/libnpmexec/test/local.js index 23035b01769e3..2423440c9d82c 100644 --- a/workspaces/libnpmexec/test/local.js +++ b/workspaces/libnpmexec/test/local.js @@ -423,3 +423,49 @@ t.test('global scoped pkg', async t => { created: 'global/node_modules/@npmcli/create-test/bin-file.js', }) }) + +// Regression: local bin lookup must not be gated by allow-directory, +// even when the policy is `none` or `root`. +for (const allowDirectory of ['none', 'root']) { + t.test(`local bin still resolves with allow-directory=${allowDirectory}`, async t => { + const { pkg, fixtures } = createPkg({ + version: '1.0.0', + name: '@npmcli/local-pkg-allow-directory-test', + bin: { + a: 'local-bin-test.js', + }, + files: { + 'local-bin-test.js': { key: 'local-bin', value: 'LOCAL PKG' }, + }, + }) + + const { exec, chmod, readOutput, path } = setup(t, { + pkg, + testdir: merge( + fixtures.packages[`@npmcli-local-pkg-allow-directory-test-1.0.0`], + { + node_modules: { + '@npmcli': { + 'some-other-pkg-with-same-scope': {}, + }, + }, + } + ), + }) + + const localBin = resolve(path, 'node_modules', '.bin') + + await chmod('local-bin-test.js') + + await exec({ + localBin, + args: ['a', 'argument-a'], + allowDirectory, + }) + + t.match(await readOutput('local-bin'), { + value: 'LOCAL PKG', + args: ['argument-a'], + }) + }) +}