diff --git a/lib/modules/manager/npm/detect.spec.ts b/lib/modules/manager/npm/detect.spec.ts index f6bf78700cc3691c086f043acfd9aea79e25552b..c38cbcb4f5e9d1d166ee3a7af474ca1fa4296c48 100644 --- a/lib/modules/manager/npm/detect.spec.ts +++ b/lib/modules/manager/npm/detect.spec.ts @@ -1,5 +1,5 @@ import { fs } from '../../../../test/util'; -import { detectGlobalConfig } from './detect'; +import { detectGlobalConfig } from '.'; jest.mock('../../../util/fs'); diff --git a/lib/modules/manager/npm/extract/index.spec.ts b/lib/modules/manager/npm/extract/index.spec.ts index 016f8cdc7274e029953d66dfbe1d26e6971d88f2..2f5e4d73342417ea8799213cdce35f99684cf96a 100644 --- a/lib/modules/manager/npm/extract/index.spec.ts +++ b/lib/modules/manager/npm/extract/index.spec.ts @@ -165,7 +165,7 @@ describe('modules/manager/npm/extract/index', () => { 'package.json', {} ); - expect(res.npmrc).toBeDefined(); + expect(res?.npmrc).toBeDefined(); }); it('ignores .npmrc when config.npmrc is defined and npmrcMerge=false', async () => { @@ -180,7 +180,7 @@ describe('modules/manager/npm/extract/index', () => { 'package.json', { npmrc: 'some-configured-npmrc' } ); - expect(res.npmrc).toBeUndefined(); + expect(res?.npmrc).toBeUndefined(); }); it('reads .npmrc when config.npmrc is merged', async () => { @@ -195,7 +195,7 @@ describe('modules/manager/npm/extract/index', () => { 'package.json', { npmrc: 'config-npmrc', npmrcMerge: true } ); - expect(res.npmrc).toBe(`config-npmrc\nrepo-npmrc\n`); + expect(res?.npmrc).toBe(`config-npmrc\nrepo-npmrc\n`); }); it('finds and filters .npmrc with variables', async () => { @@ -210,7 +210,7 @@ describe('modules/manager/npm/extract/index', () => { 'package.json', {} ); - expect(res.npmrc).toBe('registry=https://registry.npmjs.org\n'); + expect(res?.npmrc).toBe('registry=https://registry.npmjs.org\n'); }); it('finds lerna', async () => { diff --git a/lib/modules/manager/npm/post-update/node-version.spec.ts b/lib/modules/manager/npm/post-update/node-version.spec.ts index 55bba94a62c2acf6b754fdca9992bf9eb9ad4691..fc222af12a04847a00e62572b909e3543fe7a110 100644 --- a/lib/modules/manager/npm/post-update/node-version.spec.ts +++ b/lib/modules/manager/npm/post-update/node-version.spec.ts @@ -1,5 +1,5 @@ import { fs } from '../../../../../test/util'; -import { getNodeConstraint } from './node-version'; +import { getNodeConstraint, getNodeUpdate } from './node-version'; jest.mock('../../../../util/fs'); @@ -9,42 +9,51 @@ describe('modules/manager/npm/post-update/node-version', () => { constraints: { node: '^12.16.0' }, }; - it('returns package.json range', async () => { - fs.readLocalFile = jest.fn(); - fs.readLocalFile.mockResolvedValueOnce(null); - fs.readLocalFile.mockResolvedValueOnce(null); - const res = await getNodeConstraint(config); - expect(res).toBe('^12.16.0'); - }); + describe('getNodeConstraint()', () => { + it('returns package.json range', async () => { + fs.readLocalFile.mockResolvedValueOnce(null as never); + fs.readLocalFile.mockResolvedValueOnce(null as never); + const res = await getNodeConstraint(config); + expect(res).toBe('^12.16.0'); + }); - it('returns .node-version value', async () => { - fs.readLocalFile = jest.fn(); - fs.readLocalFile.mockResolvedValueOnce(null); - fs.readLocalFile.mockResolvedValueOnce('12.16.1\n'); - const res = await getNodeConstraint(config); - expect(res).toBe('12.16.1'); - }); + it('returns .node-version value', async () => { + fs.readLocalFile.mockResolvedValueOnce(null as never); + fs.readLocalFile.mockResolvedValueOnce('12.16.1\n'); + const res = await getNodeConstraint(config); + expect(res).toBe('12.16.1'); + }); - it('returns .nvmrc value', async () => { - fs.readLocalFile = jest.fn(); - fs.readLocalFile.mockResolvedValueOnce('12.16.2\n'); - const res = await getNodeConstraint(config); - expect(res).toBe('12.16.2'); - }); + it('returns .nvmrc value', async () => { + fs.readLocalFile.mockResolvedValueOnce('12.16.2\n'); + const res = await getNodeConstraint(config); + expect(res).toBe('12.16.2'); + }); - it('ignores unusable ranges in dotfiles', async () => { - fs.readLocalFile = jest.fn(); - fs.readLocalFile.mockResolvedValueOnce('latest'); - fs.readLocalFile.mockResolvedValueOnce('lts'); - const res = await getNodeConstraint(config); - expect(res).toBe('^12.16.0'); + it('ignores unusable ranges in dotfiles', async () => { + fs.readLocalFile.mockResolvedValueOnce('latest'); + fs.readLocalFile.mockResolvedValueOnce('lts'); + const res = await getNodeConstraint(config); + expect(res).toBe('^12.16.0'); + }); + + it('returns no constraint', async () => { + fs.readLocalFile.mockResolvedValueOnce(null as never); + fs.readLocalFile.mockResolvedValueOnce(null as never); + const res = await getNodeConstraint({ ...config, constraints: null }); + expect(res).toBeNull(); + }); }); - it('returns no constraint', async () => { - fs.readLocalFile = jest.fn(); - fs.readLocalFile.mockResolvedValueOnce(null); - fs.readLocalFile.mockResolvedValueOnce(null); - const res = await getNodeConstraint({ ...config, constraints: null }); - expect(res).toBeNull(); + describe('getNodeUpdate()', () => { + it('returns version', () => { + expect(getNodeUpdate([{ depName: 'node', newValue: '16.15.0' }])).toBe( + '16.15.0' + ); + }); + + it('returns undefined', () => { + expect(getNodeUpdate([])).toBeUndefined(); + }); }); }); diff --git a/lib/modules/manager/npm/post-update/node-version.ts b/lib/modules/manager/npm/post-update/node-version.ts index ad4f4b168182ff91fb9bdc80f19d065b08bf00e3..f35cbaab40721a315fb942b8bf1c8143f8422319 100644 --- a/lib/modules/manager/npm/post-update/node-version.ts +++ b/lib/modules/manager/npm/post-update/node-version.ts @@ -2,7 +2,7 @@ import semver from 'semver'; import { logger } from '../../../../logger'; import { getSiblingFileName, readLocalFile } from '../../../../util/fs'; import { newlineRegex, regEx } from '../../../../util/regex'; -import type { PostUpdateConfig } from '../../types'; +import type { PostUpdateConfig, Upgrade } from '../../types'; async function getNodeFile(filename: string): Promise<string | null> { try { @@ -43,3 +43,7 @@ export async function getNodeConstraint( } return constraint; } + +export function getNodeUpdate(upgrades: Upgrade[]): string | undefined { + return upgrades.find((u) => u.depName === 'node')?.newValue; +} diff --git a/lib/modules/manager/npm/post-update/npm.ts b/lib/modules/manager/npm/post-update/npm.ts index ca4ea0ad5a725bb659074ee9712d0250dd624dcb..6bc9e8bdf8592caff39eb076ceaaecdc5994a0ad 100644 --- a/lib/modules/manager/npm/post-update/npm.ts +++ b/lib/modules/manager/npm/post-update/npm.ts @@ -19,7 +19,7 @@ import { } from '../../../../util/fs'; import type { PostUpdateConfig, Upgrade } from '../../types'; import { composeLockFile, parseLockFile } from '../utils'; -import { getNodeConstraint } from './node-version'; +import { getNodeConstraint, getNodeUpdate } from './node-version'; import type { GenerateLockFileResult } from './types'; export async function generateLockFile( @@ -55,7 +55,8 @@ export async function generateLockFile( cmdOptions += ' --ignore-scripts'; } - const tagConstraint = await getNodeConstraint(config); + const tagConstraint = + getNodeUpdate(upgrades) ?? (await getNodeConstraint(config)); const extraEnv: ExtraEnv = { NPM_CONFIG_CACHE: env.NPM_CONFIG_CACHE, npm_config_store: env.npm_config_store, diff --git a/lib/modules/manager/npm/post-update/pnpm.ts b/lib/modules/manager/npm/post-update/pnpm.ts index 4b61b802448da9c24d934cabaa24db4288566ab5..3dc3c808586dc7b4719184bbc36680366b24b36d 100644 --- a/lib/modules/manager/npm/post-update/pnpm.ts +++ b/lib/modules/manager/npm/post-update/pnpm.ts @@ -13,7 +13,7 @@ import type { import { deleteLocalFile, readLocalFile } from '../../../../util/fs'; import type { PostUpdateConfig, Upgrade } from '../../types'; import type { NpmPackage } from '../extract/types'; -import { getNodeConstraint } from './node-version'; +import { getNodeConstraint, getNodeUpdate } from './node-version'; import type { GenerateLockFileResult, PnpmLockFile } from './types'; export async function generateLockFile( @@ -34,7 +34,8 @@ export async function generateLockFile( constraint: config.constraints?.pnpm ?? (await getPnpmContraint(lockFileDir)), }; - const tagConstraint = await getNodeConstraint(config); + const tagConstraint = + getNodeUpdate(upgrades) ?? (await getNodeConstraint(config)); const extraEnv: ExtraEnv = { NPM_CONFIG_CACHE: env.NPM_CONFIG_CACHE, npm_config_store: env.npm_config_store, diff --git a/lib/modules/manager/npm/post-update/yarn.ts b/lib/modules/manager/npm/post-update/yarn.ts index 5a2bbffb03c9025dc84b78fca7481af00808b9cd..173c1ece1a90cda84095010b43cadd3dcb6a00a4 100644 --- a/lib/modules/manager/npm/post-update/yarn.ts +++ b/lib/modules/manager/npm/post-update/yarn.ts @@ -26,7 +26,7 @@ import { uniqueStrings } from '../../../../util/string'; import { NpmDatasource } from '../../../datasource/npm'; import type { PostUpdateConfig, Upgrade } from '../../types'; import type { NpmManagerData } from '../types'; -import { getNodeConstraint } from './node-version'; +import { getNodeConstraint, getNodeUpdate } from './node-version'; import type { GenerateLockFileResult } from './types'; export async function checkYarnrc( @@ -175,7 +175,8 @@ export async function generateLockFile( extraEnv.YARN_ENABLE_SCRIPTS = '0'; } } - const tagConstraint = await getNodeConstraint(config); + const tagConstraint = + getNodeUpdate(upgrades) ?? (await getNodeConstraint(config)); const execOptions: ExecOptions = { cwdFile: lockFileName, extraEnv, diff --git a/lib/modules/manager/npm/update/dependency/index.spec.ts b/lib/modules/manager/npm/update/dependency/index.spec.ts index c5a5187886110a58099843500462823009c49c43..fd1223261fece0351a8d92a590edf1cbe46956e4 100644 --- a/lib/modules/manager/npm/update/dependency/index.spec.ts +++ b/lib/modules/manager/npm/update/dependency/index.spec.ts @@ -1,5 +1,6 @@ +/* eslint-disable @typescript-eslint/no-unnecessary-type-assertion */ +import * as npmUpdater from '../..'; import { Fixtures } from '../../../../../../test/fixtures'; -import * as npmUpdater from '.'; const readFixture = (x: string): string => Fixtures.get(x, '../..'); @@ -41,7 +42,7 @@ describe('modules/manager/npm/update/dependency/index', () => { upgrade, }); expect(res).toBeJsonString(); - expect(JSON.parse(res)).toEqual({ + expect(JSON.parse(res!)).toEqual({ dependencies: { gulp: 'gulpjs/gulp#v4.0.0' }, }); }); @@ -65,7 +66,7 @@ describe('modules/manager/npm/update/dependency/index', () => { upgrade, }); expect(res).toBeJsonString(); - expect(JSON.parse(res)).toEqual({ + expect(JSON.parse(res!)).toEqual({ dependencies: { hapi: 'npm:@hapi/hapi@18.3.1' }, }); }); @@ -88,7 +89,7 @@ describe('modules/manager/npm/update/dependency/index', () => { upgrade, }); expect(res).toBeJsonString(); - expect(JSON.parse(res)).toEqual({ + expect(JSON.parse(res!)).toEqual({ dependencies: { gulp: 'gulpjs/gulp#0000000' }, }); }); @@ -124,8 +125,8 @@ describe('modules/manager/npm/update/dependency/index', () => { fileContent: input01Content, upgrade, }); - expect(JSON.parse(testContent).dependencies.config).toBe('1.22.0'); - expect(JSON.parse(testContent).resolutions.config).toBe('1.22.0'); + expect(JSON.parse(testContent!).dependencies.config).toBe('1.22.0'); + expect(JSON.parse(testContent!).resolutions.config).toBe('1.22.0'); }); it('updates glob resolutions', () => { @@ -138,8 +139,8 @@ describe('modules/manager/npm/update/dependency/index', () => { fileContent: input01GlobContent, upgrade, }); - expect(JSON.parse(testContent).dependencies.config).toBe('1.22.0'); - expect(JSON.parse(testContent).resolutions['**/config']).toBe('1.22.0'); + expect(JSON.parse(testContent!).dependencies.config).toBe('1.22.0'); + expect(JSON.parse(testContent!).resolutions['**/config']).toBe('1.22.0'); }); it('updates glob resolutions without dep', () => { @@ -153,7 +154,7 @@ describe('modules/manager/npm/update/dependency/index', () => { fileContent: input01Content, upgrade, }); - expect(JSON.parse(testContent).resolutions['**/@angular/cli']).toBe( + expect(JSON.parse(testContent!).resolutions['**/@angular/cli']).toBe( '8.1.0' ); }); @@ -233,7 +234,7 @@ describe('modules/manager/npm/update/dependency/index', () => { newValue: '1.5.8', }; const testContent = npmUpdater.updateDependency({ - fileContent: null, + fileContent: null as never, upgrade, }); expect(testContent).toBeNull(); @@ -250,8 +251,8 @@ describe('modules/manager/npm/update/dependency/index', () => { fileContent: input01Content, upgrade, }); - expect(JSON.parse(testContent).dependencies.config).toBeUndefined(); - expect(JSON.parse(testContent).dependencies.abc).toBe('2.0.0'); + expect(JSON.parse(testContent!).dependencies.config).toBeUndefined(); + expect(JSON.parse(testContent!).dependencies.abc).toBe('2.0.0'); }); it('replaces glob package resolutions', () => { @@ -265,8 +266,8 @@ describe('modules/manager/npm/update/dependency/index', () => { fileContent: input01GlobContent, upgrade, }); - expect(JSON.parse(testContent).resolutions.config).toBeUndefined(); - expect(JSON.parse(testContent).resolutions['**/abc']).toBe('2.0.0'); + expect(JSON.parse(testContent!).resolutions.config).toBeUndefined(); + expect(JSON.parse(testContent!).resolutions['**/abc']).toBe('2.0.0'); }); it('pins also the version in patch with npm protocol in resolutions', () => { diff --git a/lib/modules/manager/npm/update/locked-dependency/index.spec.ts b/lib/modules/manager/npm/update/locked-dependency/index.spec.ts index 114183121949c82eb55c5d028377cb28628c384e..08f8f76b25996438903b61bb3fc02c873fe1a466 100644 --- a/lib/modules/manager/npm/update/locked-dependency/index.spec.ts +++ b/lib/modules/manager/npm/update/locked-dependency/index.spec.ts @@ -1,8 +1,9 @@ +/* eslint-disable @typescript-eslint/no-unnecessary-type-assertion */ +import { updateLockedDependency } from '../..'; import * as httpMock from '../../../../../../test/http-mock'; import { loadFixture } from '../../../../../../test/util'; import { clone } from '../../../../../util/clone'; import type { UpdateLockedConfig } from '../../../types'; -import { updateLockedDependency } from '.'; const packageFileContent = loadFixture('package.json', './package-lock'); const lockFileContent = loadFixture('package-lock.json', './package-lock'); @@ -97,7 +98,7 @@ describe('modules/manager/npm/update/locked-dependency/index', () => { newVersion: '1.2.12', }); expect( - JSON.parse(res.files['package-lock.json']).dependencies.mime.version + JSON.parse(res.files!['package-lock.json']).dependencies.mime.version ).toBe('1.2.12'); }); @@ -137,8 +138,8 @@ describe('modules/manager/npm/update/locked-dependency/index', () => { config.currentVersion = '4.0.0'; config.newVersion = '4.1.0'; const res = await updateLockedDependency(config); - expect(res.files['package.json']).toContain('"express": "4.1.0"'); - const packageLock = JSON.parse(res.files['package-lock.json']); + expect(res.files!['package.json']).toContain('"express": "4.1.0"'); + const packageLock = JSON.parse(res.files!['package-lock.json']); expect(packageLock.dependencies.express.version).toBe('4.1.0'); }); @@ -148,8 +149,8 @@ describe('modules/manager/npm/update/locked-dependency/index', () => { config.newVersion = '4.1.0'; config.lockFileContent = lockFileV2Content; const res = await updateLockedDependency(config); - expect(res.files['package.json']).toContain('"express": "4.1.0"'); - const packageLock = JSON.parse(res.files['package-lock.json']); + expect(res.files!['package.json']).toContain('"express": "4.1.0"'); + const packageLock = JSON.parse(res.files!['package-lock.json']); expect(packageLock.dependencies.express.version).toBe('4.1.0'); }); @@ -218,7 +219,7 @@ describe('modules/manager/npm/update/locked-dependency/index', () => { .get('/type-is') .reply(200, typeIsJson); const res = await updateLockedDependency(config); - const packageLock = JSON.parse(res.files['package-lock.json']); + const packageLock = JSON.parse(res.files!['package-lock.json']); expect(packageLock.dependencies.mime.version).toBe('1.4.1'); expect(packageLock.dependencies.express.version).toBe('4.16.0'); }); diff --git a/lib/modules/manager/npm/update/package-version/index.spec.ts b/lib/modules/manager/npm/update/package-version/index.spec.ts index 4de57ba062687c9446d224a361f9d68f8582d9fc..53829adc47b389075aad45d63040f05d49f42291 100644 --- a/lib/modules/manager/npm/update/package-version/index.spec.ts +++ b/lib/modules/manager/npm/update/package-version/index.spec.ts @@ -1,4 +1,4 @@ -import * as npmUpdater from '.'; +import * as npmUpdater from '../..'; describe('modules/manager/npm/update/package-version/index', () => { describe('.bumpPackageVersion()', () => {