Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions scripts/publish.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,22 @@ test('npm view preflight treats E404 as needing publish', (t) => {
);
});

test('npm view preflight treats execFileSync E404 as needing publish', (t) => {
const stderr =
'npm ERR! code E404\nnpm ERR! 404 Not Found - GET https://registry.npmjs.org/@flatbread%2fcore - Not found';
t.is(
classifyNpmViewResult({ error: { status: 1, stderr } }, '1.0.0'),
'publish'
);
t.is(
classifyNpmViewResult(
{ error: { status: 1, stderr: Buffer.from(stderr) } },
'1.0.0'
),
'publish'
);
});

test('npm view preflight aborts on non-not-found failures', (t) => {
t.throws(
() =>
Expand All @@ -93,6 +109,20 @@ test('npm view preflight aborts on non-not-found failures', (t) => {
),
{ message: /npm view failed/ }
);
t.throws(
() =>
classifyNpmViewResult(
{
error: {
status: 1,
stderr:
'npm ERR! code EOTP\nnpm ERR! This operation requires a one-time password',
},
},
'1.0.0'
),
{ message: /npm view failed/ }
);
});

test('npm view preflight aborts on ambiguous not-found text', (t) => {
Expand Down
30 changes: 19 additions & 11 deletions scripts/publish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,27 +42,35 @@ export function classifyNpmViewResult(
error && typeof error === 'object'
? (error as Record<string, unknown>)
: undefined;
if (
errorRecord &&
(errorRecord.code === 'E404' ||
errorRecord.status === 404 ||
errorRecord.statusCode === 404)
) {
return 'publish';
}

const details = errorRecord
? [
errorRecord.code,
errorRecord.status,
errorRecord.stderr,
errorRecord.stdout,
errorRecord.message,
]
.filter(Boolean)
.map(String)
.filter((value) => value != null && value !== '')
.map((value) =>
Buffer.isBuffer(value) ? value.toString('utf8') : String(value)
)
.join(' ')
: String(error ?? '');

// execFileSync throws with status 1 and E404 in stderr; error.code is not
// npm's E404 (that lives in the child stderr). Treat either shape as
// "version not on the registry yet."
if (
errorRecord &&
(errorRecord.code === 'E404' ||
errorRecord.status === 404 ||
errorRecord.statusCode === 404 ||
details.includes('E404') ||
details.includes('404 Not Found'))
) {
return 'publish';
}

if (!error && version === undefined) {
throw new Error('npm view returned an unexpected response');
}
Expand Down
Loading