diff --git a/lib/manager/npm/extract/index.js b/lib/manager/npm/extract/index.js index 4c1f5f6db039ee0a0e360bacbd6a0412ed32bfcc..cc132f9fb2ece356ac8fcb122281ea7010391f4b 100644 --- a/lib/manager/npm/extract/index.js +++ b/lib/manager/npm/extract/index.js @@ -169,6 +169,19 @@ async function extractPackageFile(content, fileName, config) { } return dep; } + if (dep.currentValue.startsWith('npm:')) { + dep.npmPackageAlias = true; + const valSplit = dep.currentValue.replace('npm:', '').split('@'); + if (valSplit.length === 2) { + dep.lookupName = valSplit[0]; + dep.currentValue = valSplit[1]; + } else if (valSplit.length === 3) { + dep.lookupName = valSplit[0] + '@' + valSplit[1]; + dep.currentValue = valSplit[2]; + } else { + logger.info('Invalid npm package alias: ' + dep.currentValue); + } + } if (dep.currentValue.startsWith('file:')) { dep.skipReason = 'file'; hasFileRefs = true; diff --git a/lib/manager/npm/update.js b/lib/manager/npm/update.js index 31f824b100ecd3acd71efc4ccd847cc33ac83d82..bf81a6914bb1d356e0c62d00721b668ce06e53c6 100644 --- a/lib/manager/npm/update.js +++ b/lib/manager/npm/update.js @@ -24,6 +24,9 @@ function updateDependency(fileContent, upgrade) { ); } } + if (upgrade.npmPackageAlias) { + newValue = `npm:${upgrade.lookupName}@${newValue}`; + } logger.debug(`npm.updateDependency(): ${depType}.${depName} = ${newValue}`); try { const parsedContents = JSON.parse(fileContent); diff --git a/test/manager/npm/__snapshots__/update.spec.js.snap b/test/manager/npm/__snapshots__/update.spec.js.snap index 21bae2617951adc179befb7f9884699b6c1d6477..a3b4198523efe405bf2bd8e42bd2b0e2c2583902 100644 --- a/test/manager/npm/__snapshots__/update.spec.js.snap +++ b/test/manager/npm/__snapshots__/update.spec.js.snap @@ -11,3 +11,5 @@ exports[`workers/branch/package-json .updateDependency(fileContent, depType, dep exports[`workers/branch/package-json .updateDependency(fileContent, depType, depName, newValue) replaces a github fully specified version 1`] = `"{\\"dependencies\\":{\\"n\\":\\"git+https://github.com/owner/n#v1.1.0\\"}}"`; exports[`workers/branch/package-json .updateDependency(fileContent, depType, depName, newValue) replaces a github short hash 1`] = `"{\\"dependencies\\":{\\"gulp\\":\\"gulpjs/gulp#0000000\\"}}"`; + +exports[`workers/branch/package-json .updateDependency(fileContent, depType, depName, newValue) replaces a npm package alias 1`] = `"{\\"dependencies\\":{\\"hapi\\":\\"npm:@hapi/hapi@18.3.1\\"}}"`; diff --git a/test/manager/npm/extract/__snapshots__/index.spec.js.snap b/test/manager/npm/extract/__snapshots__/index.spec.js.snap index 4af3f2c25ad41cf718a689dba54548334e6e765c..1161e93147e8aa3a853ebf3d175326c03de61628 100644 --- a/test/manager/npm/extract/__snapshots__/index.spec.js.snap +++ b/test/manager/npm/extract/__snapshots__/index.spec.js.snap @@ -287,6 +287,52 @@ Object { } `; +exports[`manager/npm/extract .extractPackageFile() extracts npm package alias 1`] = ` +Object { + "deps": Array [ + Object { + "currentValue": "1", + "datasource": "npm", + "depName": "a", + "depType": "dependencies", + "lookupName": "foo", + "npmPackageAlias": true, + "prettyDepType": "dependency", + }, + Object { + "currentValue": "1.2.3", + "datasource": "npm", + "depName": "b", + "depType": "dependencies", + "lookupName": "@foo/bar", + "npmPackageAlias": true, + "prettyDepType": "dependency", + }, + Object { + "currentValue": "npm:foo", + "depName": "c", + "depType": "dependencies", + "npmPackageAlias": true, + "prettyDepType": "dependency", + "skipReason": "unknown-version", + }, + ], + "lernaClient": undefined, + "lernaDir": undefined, + "lernaPackages": undefined, + "npmLock": undefined, + "npmrc": undefined, + "packageJsonName": undefined, + "packageJsonType": "app", + "packageJsonVersion": undefined, + "pnpmShrinkwrap": undefined, + "skipInstalls": true, + "yarnLock": undefined, + "yarnWorkspacesPackages": undefined, + "yarnrc": undefined, +} +`; + exports[`manager/npm/extract .extractPackageFile() finds a lock file 1`] = ` Object { "deps": Array [ diff --git a/test/manager/npm/extract/index.spec.js b/test/manager/npm/extract/index.spec.js index a59e8053c546cda6032d533eb5f9f44816ef7fa8..a8f15aa49ac99c400a335038c0a769bd31dac16d 100644 --- a/test/manager/npm/extract/index.spec.js +++ b/test/manager/npm/extract/index.spec.js @@ -202,6 +202,22 @@ describe('manager/npm/extract', () => { ); expect(res).toMatchSnapshot(); }); + it('extracts npm package alias', async () => { + const pJson = { + dependencies: { + a: 'npm:foo@1', + b: 'npm:@foo/bar@1.2.3', + c: 'npm:foo', + }, + }; + const pJsonStr = JSON.stringify(pJson); + const res = await npmExtract.extractPackageFile( + pJsonStr, + 'package.json', + defaultConfig + ); + expect(res).toMatchSnapshot(); + }); }); describe('.postExtract()', () => { it('runs', async () => { diff --git a/test/manager/npm/update.spec.js b/test/manager/npm/update.spec.js index f9a7da5c69f18a872c89377e5528e823d53c287d..5f124f9de2d37ae92f87563f915fdbaa3f3325b4 100644 --- a/test/manager/npm/update.spec.js +++ b/test/manager/npm/update.spec.js @@ -41,6 +41,23 @@ describe('workers/branch/package-json', () => { const res = npmUpdater.updateDependency(input, upgrade); expect(res).toMatchSnapshot(); }); + it('replaces a npm package alias', () => { + const upgrade = { + depType: 'dependencies', + depName: 'hapi', + npmPackageAlias: true, + lookupName: '@hapi/hapi', + currentValue: '18.3.0', + newValue: '18.3.1', + }; + const input = JSON.stringify({ + dependencies: { + hapi: 'npm:@hapi/hapi@18.3.0', + }, + }); + const res = npmUpdater.updateDependency(input, upgrade); + expect(res).toMatchSnapshot(); + }); it('replaces a github short hash', () => { const upgrade = { depType: 'dependencies',