diff --git a/lib/modules/manager/npm/post-update/rules.spec.ts b/lib/modules/manager/npm/post-update/rules.spec.ts index ea17d6025b02e537f6168f8ee99caee0218b59a2..3d1ad4988ddef82d01824a92abd0a51ccc48e024 100644 --- a/lib/modules/manager/npm/post-update/rules.spec.ts +++ b/lib/modules/manager/npm/post-update/rules.spec.ts @@ -91,6 +91,12 @@ describe('modules/manager/npm/post-update/rules', () => { additionalYarnRcYml: { npmRegistries: { + '//https://registry.npmjs.org/': { + npmAuthToken: 'token123', + }, + '//https://registry.other.org/': { + npmAuthIdent: 'basictoken123', + }, '//registry.company.com/': { npmAuthIdent: 'user123:pass123', }, @@ -115,6 +121,12 @@ describe('modules/manager/npm/post-update/rules', () => { ], "additionalYarnRcYml": { "npmRegistries": { + "//https://registry.npmjs.org/": { + "npmAuthToken": "token123", + }, + "//https://registry.other.org/": { + "npmAuthIdent": "basictoken123", + }, "//registry.company.com/": { "npmAuthIdent": "user123:pass123", }, diff --git a/lib/modules/manager/npm/post-update/rules.ts b/lib/modules/manager/npm/post-update/rules.ts index 59380f7a616a968bd9164ff26ea1a979a07b5adb..2da03556713fb2771a368daf917425ac9a0dae27 100644 --- a/lib/modules/manager/npm/post-update/rules.ts +++ b/lib/modules/manager/npm/post-update/rules.ts @@ -3,6 +3,7 @@ import * as hostRules from '../../../../util/host-rules'; import { regEx } from '../../../../util/regex'; import { toBase64 } from '../../../../util/string'; import { isHttpUrl } from '../../../../util/url'; +import type { YarnRcYmlFile } from './types'; export interface HostRulesResult { additionalNpmrcContent: string[]; @@ -10,7 +11,7 @@ export interface HostRulesResult { } export function processHostRules(): HostRulesResult { - let additionalYarnRcYml: any; + const additionalYarnRcYml: YarnRcYmlFile = { npmRegistries: {} }; // Determine the additional npmrc content to add based on host rules const additionalNpmrcContent = []; @@ -18,36 +19,67 @@ export function processHostRules(): HostRulesResult { hostType: 'npm', }); for (const hostRule of npmHostRules) { - if (hostRule.resolvedHost) { - let uri = hostRule.matchHost; - uri = - is.string(uri) && isHttpUrl(uri) - ? uri.replace(regEx(/^https?:/), '') - : // TODO: types (#22198) - `//${uri}/`; - if (hostRule.token) { - const key = hostRule.authType === 'Basic' ? '_auth' : '_authToken'; - additionalNpmrcContent.push(`${uri}:${key}=${hostRule.token}`); - additionalYarnRcYml ||= { npmRegistries: {} }; - if (hostRule.authType === 'Basic') { - additionalYarnRcYml.npmRegistries[uri] = { - npmAuthIdent: hostRule.token, - }; - } else { - additionalYarnRcYml.npmRegistries[uri] = { - npmAuthToken: hostRule.token, - }; - } - } else if (is.string(hostRule.username) && is.string(hostRule.password)) { - const password = toBase64(hostRule.password); - additionalNpmrcContent.push(`${uri}:username=${hostRule.username}`); - additionalNpmrcContent.push(`${uri}:_password=${password}`); - additionalYarnRcYml ||= { npmRegistries: {} }; - additionalYarnRcYml.npmRegistries[uri] = { - npmAuthIdent: `${hostRule.username}:${hostRule.password}`, + if (!hostRule.resolvedHost) { + continue; + } + + const matchedHost = hostRule.matchHost; + // Should never be necessary as if we have a resolvedHost, there has to be a matchHost + // istanbul ignore next + if (!matchedHost) { + continue; + } + + const uri = `//${matchedHost}/`; + let cleanedUri = uri; + if (isHttpUrl(matchedHost)) { + cleanedUri = matchedHost.replace(regEx(/^https?:/), ''); + } + + if (hostRule.token) { + const key = hostRule.authType === 'Basic' ? '_auth' : '_authToken'; + additionalNpmrcContent.push(`${cleanedUri}:${key}=${hostRule.token}`); + + if (hostRule.authType === 'Basic') { + const registry = { + npmAuthIdent: hostRule.token, }; + additionalYarnRcYml.npmRegistries[cleanedUri] = registry; + additionalYarnRcYml.npmRegistries[uri] = registry; + + continue; } + + const registry = { + npmAuthToken: hostRule.token, + }; + additionalYarnRcYml.npmRegistries[cleanedUri] = registry; + additionalYarnRcYml.npmRegistries[uri] = registry; + + continue; + } + + if (is.string(hostRule.username) && is.string(hostRule.password)) { + const password = toBase64(hostRule.password); + additionalNpmrcContent.push( + `${cleanedUri}:username=${hostRule.username}`, + ); + additionalNpmrcContent.push(`${cleanedUri}:_password=${password}`); + + const registries = { + npmAuthIdent: `${hostRule.username}:${hostRule.password}`, + }; + additionalYarnRcYml.npmRegistries[cleanedUri] = registries; + additionalYarnRcYml.npmRegistries[uri] = registries; } } - return { additionalNpmrcContent, additionalYarnRcYml }; + + const hasYarnRcNpmRegistries = + Object.keys(additionalYarnRcYml.npmRegistries).length > 0; + return { + additionalNpmrcContent, + additionalYarnRcYml: hasYarnRcNpmRegistries + ? additionalYarnRcYml + : undefined, + }; } diff --git a/lib/modules/manager/npm/post-update/types.ts b/lib/modules/manager/npm/post-update/types.ts index ed00f0967ffcd75a6fea489a2f47375822e4df84..35efbdd2f790e40f3b96a71849bd61f866feab89 100644 --- a/lib/modules/manager/npm/post-update/types.ts +++ b/lib/modules/manager/npm/post-update/types.ts @@ -41,6 +41,13 @@ export interface PnpmLockFile { optionalDependencies: PnpmDependencySchema; } +export interface YarnRcNpmRegistry { + npmAlwaysAuth?: boolean; + npmAuthIdent?: string; + npmAuthToken?: string; +} + export interface YarnRcYmlFile { yarnPath?: string | null; + npmRegistries: Record<string, YarnRcNpmRegistry>; }