Skip to content

Commit

Permalink
fix yarn npm publish for scoped packages
Browse files Browse the repository at this point in the history
this will make yarn berry `yarn npm publish` behave like `npm publish`:
`npm publish` on an already public scoped package will publish it gladly
however for `yarn npm publish`, even if the scoped package is already published publicly
we need to specify the `--access public` argument, or it will fail with 402 (Payment Required)
here I add a check (currently only for yarn berry) for whether the published version of the package is public,
and if so, set publishScoped to true (and don't ask for it)
  • Loading branch information
mifi authored and sindresorhus committed Dec 9, 2023
1 parent 7c00edc commit 6c2c930
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 3 deletions.
8 changes: 5 additions & 3 deletions source/ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ const checkNewFilesAndDependencies = async (pkg, rootDir) => {
};

// eslint-disable-next-line complexity
const ui = async (options, {pkg, rootDir, isYarnBerry}) => {
const ui = async (options, {pkg, rootDir, isYarnBerry = false}) => {
const oldVersion = pkg.version;
const extraBaseUrls = ['gitlab.com'];
const repoUrl = pkg.repository && githubUrlFromGit(pkg.repository.url, {extraBaseUrls});
Expand Down Expand Up @@ -241,12 +241,14 @@ const ui = async (options, {pkg, rootDir, isYarnBerry}) => {
&& !options.tag
);

const alreadyPublicScoped = isYarnBerry && options.runPublish && await util.getNpmPackageAccess(pkg.name) === 'public';

// Note that inquirer question.when is a bit confusing. Only `false` will cause the question to be skipped.
// Any other value like `true` and `undefined` means ask the question.
// so we make sure to always return an explicit boolean here to make it less confusing
// see https://github.com/SBoudrias/Inquirer.js/pull/1340
const needToAskForPublish = (() => {
if (!isScoped(pkg.name) || !options.availability.isAvailable || options.availability.isUnknown || !options.runPublish) {
if (alreadyPublicScoped || !isScoped(pkg.name) || !options.availability.isAvailable || options.availability.isUnknown || !options.runPublish) {
return false;
}

Expand Down Expand Up @@ -347,7 +349,7 @@ const ui = async (options, {pkg, rootDir, isYarnBerry}) => {
...options,
version: answers.version || answers.customVersion || options.version,
tag: answers.tag || answers.customTag || options.tag,
publishScoped: answers.publishScoped,
publishScoped: alreadyPublicScoped || answers.publishScoped,
confirm: true,
repoUrl,
releaseNotes,
Expand Down
5 changes: 5 additions & 0 deletions source/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,8 @@ export const validateEngineVersionSatisfies = (engine, version) => {
throw new Error(`\`np\` requires ${engine} ${engineRange}`);
}
};

export async function getNpmPackageAccess(name) {
const {stdout} = await execa('npm', ['access', 'get', 'status', name, '--json']);
return JSON.parse(stdout)[name]; // Note: returns "private" for non-existent packages
}

0 comments on commit 6c2c930

Please sign in to comment.