From 9529b8f6e633bb1f98cbc10f881b475ff21cd522 Mon Sep 17 00:00:00 2001 From: Gar Date: Fri, 31 Jan 2025 07:30:12 -0800 Subject: [PATCH] fix: warn on invalid publishConfig --- lib/commands/config.js | 3 +++ lib/commands/publish.js | 5 +++++ lib/commands/unpublish.js | 3 +++ tap-snapshots/test/lib/commands/config.js.test.cjs | 9 ++++++++- tap-snapshots/test/lib/commands/publish.js.test.cjs | 9 +++++++++ test/lib/commands/config.js | 6 ++++-- test/lib/commands/publish.js | 10 +++++++--- test/lib/commands/unpublish.js | 7 ++++++- workspaces/config/lib/index.js | 4 ++-- 9 files changed, 47 insertions(+), 9 deletions(-) diff --git a/lib/commands/config.js b/lib/commands/config.js index d9b593064b001..31dbc074a8372 100644 --- a/lib/commands/config.js +++ b/lib/commands/config.js @@ -366,6 +366,9 @@ ${defData} const { content } = await pkgJson.normalize(this.npm.prefix).catch(() => ({ content: {} })) if (content.publishConfig) { + for (const key in content.publishConfig) { + this.npm.config.checkUnknown('publishConfig', key) + } const pkgPath = resolve(this.npm.prefix, 'package.json') msg.push(`; "publishConfig" from ${pkgPath}`) msg.push('; This set of config values will be used at publish-time.', '') diff --git a/lib/commands/publish.js b/lib/commands/publish.js index 1967e05a23534..cc15087f0b368 100644 --- a/lib/commands/publish.js +++ b/lib/commands/publish.js @@ -266,6 +266,11 @@ class Publish extends BaseCommand { // corresponding `publishConfig` settings const filteredPublishConfig = Object.fromEntries( Object.entries(manifest.publishConfig).filter(([key]) => !(key in cliFlags))) + if (logWarnings) { + for (const key in filteredPublishConfig) { + this.npm.config.checkUnknown('publishConfig', key) + } + } flatten(filteredPublishConfig, opts) } return manifest diff --git a/lib/commands/unpublish.js b/lib/commands/unpublish.js index 4944888fe5aca..e1c06d3184057 100644 --- a/lib/commands/unpublish.js +++ b/lib/commands/unpublish.js @@ -145,6 +145,9 @@ class Unpublish extends BaseCommand { // corresponding `publishConfig` settings const filteredPublishConfig = Object.fromEntries( Object.entries(manifest.publishConfig).filter(([key]) => !(key in cliFlags))) + for (const key in filteredPublishConfig) { + this.npm.config.checkUnknown('publishConfig', key) + } flatten(filteredPublishConfig, opts) } diff --git a/tap-snapshots/test/lib/commands/config.js.test.cjs b/tap-snapshots/test/lib/commands/config.js.test.cjs index 0d62bacd45fa1..df1505cea26a3 100644 --- a/tap-snapshots/test/lib/commands/config.js.test.cjs +++ b/tap-snapshots/test/lib/commands/config.js.test.cjs @@ -413,6 +413,13 @@ color = {COLOR} ; "publishConfig" from {CWD}/prefix/package.json ; This set of config values will be used at publish-time. -_authToken = (protected) +//some.registry:_authToken = (protected) +other = "not defined" registry = "https://some.registry" ` + +exports[`test/lib/commands/config.js TAP config list with publishConfig local > warns about unknown config 1`] = ` +Array [ + "Unknown publishConfig config /"other/". This will stop working in the next major version of npm.", +] +` diff --git a/tap-snapshots/test/lib/commands/publish.js.test.cjs b/tap-snapshots/test/lib/commands/publish.js.test.cjs index 81c7dbe908d24..4d3606b93bfa6 100644 --- a/tap-snapshots/test/lib/commands/publish.js.test.cjs +++ b/tap-snapshots/test/lib/commands/publish.js.test.cjs @@ -290,6 +290,15 @@ exports[`test/lib/commands/publish.js TAP re-loads publishConfig.registry if add exports[`test/lib/commands/publish.js TAP respects publishConfig.registry, runs appropriate scripts > new package version 1`] = ` +> @npmcli/test-package@1.0.0 prepublishOnly +> touch scripts-prepublishonly + +> @npmcli/test-package@1.0.0 publish +> touch scripts-publish + +> @npmcli/test-package@1.0.0 postpublish +> touch scripts-postpublish ++ @npmcli/test-package@1.0.0 ` exports[`test/lib/commands/publish.js TAP restricted access > must match snapshot 1`] = ` diff --git a/test/lib/commands/config.js b/test/lib/commands/config.js index 849f832554aab..bcd88915dc97a 100644 --- a/test/lib/commands/config.js +++ b/test/lib/commands/config.js @@ -164,8 +164,9 @@ t.test('config list with publishConfig', async t => { prefixDir: { 'package.json': JSON.stringify({ publishConfig: { + other: 'not defined', registry: 'https://some.registry', - _authToken: 'mytoken', + '//some.registry:_authToken': 'mytoken', }, }), }, @@ -173,7 +174,7 @@ t.test('config list with publishConfig', async t => { }) t.test('local', async t => { - const { npm, joinedOutput } = await loadMockNpmWithPublishConfig(t) + const { npm, logs, joinedOutput } = await loadMockNpmWithPublishConfig(t) await npm.exec('config', ['list']) @@ -182,6 +183,7 @@ t.test('config list with publishConfig', async t => { t.match(output, 'registry = "https://some.registry"') t.matchSnapshot(output, 'output matches snapshot') + t.matchSnapshot(logs.warn, 'warns about unknown config') }) t.test('global', async t => { diff --git a/test/lib/commands/publish.js b/test/lib/commands/publish.js index f310587418b1f..3d1d629e31ba4 100644 --- a/test/lib/commands/publish.js +++ b/test/lib/commands/publish.js @@ -29,11 +29,14 @@ t.test('respects publishConfig.registry, runs appropriate scripts', async t => { publish: 'touch scripts-publish', postpublish: 'touch scripts-postpublish', }, - publishConfig: { registry: alternateRegistry }, + publishConfig: { + other: 'not defined', + registry: alternateRegistry, + }, } - const { npm, joinedOutput, prefix, registry } = await loadNpmWithRegistry(t, { + const { npm, joinedOutput, logs, prefix, registry } = await loadNpmWithRegistry(t, { config: { - loglevel: 'silent', + loglevel: 'warn', [`${alternateRegistry.slice(6)}/:_authToken`]: 'test-other-token', }, prefixDir: { @@ -49,6 +52,7 @@ t.test('respects publishConfig.registry, runs appropriate scripts', async t => { t.equal(fs.existsSync(path.join(prefix, 'scripts-prepublish')), false, 'did not run prepublish') t.equal(fs.existsSync(path.join(prefix, 'scripts-publish')), true, 'ran publish') t.equal(fs.existsSync(path.join(prefix, 'scripts-postpublish')), true, 'ran postpublish') + t.same(logs.warn, ['Unknown publishConfig config "other". This will stop working in the next major version of npm.']) }) t.test('re-loads publishConfig.registry if added during script process', async t => { diff --git a/test/lib/commands/unpublish.js b/test/lib/commands/unpublish.js index 31dc77ea46cd0..996edf2b881fc 100644 --- a/test/lib/commands/unpublish.js +++ b/test/lib/commands/unpublish.js @@ -380,7 +380,7 @@ t.test('dryRun with no args', async t => { t.test('publishConfig no spec', async t => { const alternateRegistry = 'https://other.registry.npmjs.org' - const { joinedOutput, npm } = await loadMockNpm(t, { + const { logs, joinedOutput, npm } = await loadMockNpm(t, { config: { force: true, '//other.registry.npmjs.org/:_authToken': 'test-other-token', @@ -390,6 +390,7 @@ t.test('publishConfig no spec', async t => { name: pkg, version: '1.0.0', publishConfig: { + other: 'not defined', registry: alternateRegistry, }, }, null, 2), @@ -406,6 +407,10 @@ t.test('publishConfig no spec', async t => { registry.unpublish({ manifest }) await npm.exec('unpublish', []) t.equal(joinedOutput(), '- test-package') + t.same(logs.warn, [ + 'using --force Recommended protections disabled.', + 'Unknown publishConfig config "other". This will stop working in the next major version of npm.', + ]) }) t.test('prioritize CLI flags over publishConfig no spec', async t => { diff --git a/workspaces/config/lib/index.js b/workspaces/config/lib/index.js index fbc8c2365ac0d..cba2ebd3621c5 100644 --- a/workspaces/config/lib/index.js +++ b/workspaces/config/lib/index.js @@ -584,14 +584,14 @@ class Config { } // Some defaults like npm-version are not user-definable and thus don't have definitions if (where !== 'default') { - this.#checkUnknown(where, key) + this.checkUnknown(where, key) } conf.data[k] = v } } } - #checkUnknown (where, key) { + checkUnknown (where, key) { if (!this.definitions[key]) { if (internalEnv.includes(key)) { return 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