diff --git a/lib/modules/manager/npm/__fixtures__/inputs/patch1.json b/lib/modules/manager/npm/__fixtures__/inputs/patch1.json index cecd931c74f8bed9e79f624f213b32412fb427bd..ea98fe91e4b767087ecf3d436fa536a22af15cba 100644 --- a/lib/modules/manager/npm/__fixtures__/inputs/patch1.json +++ b/lib/modules/manager/npm/__fixtures__/inputs/patch1.json @@ -1,7 +1,8 @@ { "name": "renovate-repro", "dependencies": { - "lodash": "^4.16.0" + "lodash": "^4.16.0", + "mermaid": "8.8.1" }, "resolutions": { "lodash": "patch:lodash@npm:4.16.0#patches/lodash.patch" @@ -9,6 +10,9 @@ "dependenciesMeta": { "lodash@4.16.0": { "unplugged": true + }, + "mermaid@8.8.1": { + "optional": true } } } diff --git a/lib/modules/manager/npm/__fixtures__/outputs/patch1o.json b/lib/modules/manager/npm/__fixtures__/outputs/patch1o.json index 01c60a6c2dae9dfd034201f485ef55c7fb99db7f..58be7f8b3521d81a7e3e7edfa125544b9465ac52 100644 --- a/lib/modules/manager/npm/__fixtures__/outputs/patch1o.json +++ b/lib/modules/manager/npm/__fixtures__/outputs/patch1o.json @@ -1,14 +1,18 @@ { "name": "renovate-repro", "dependencies": { - "lodash": "4.17.21" + "lodash": "4.17.21", + "mermaid": "8.8.1" }, "resolutions": { "lodash": "patch:lodash@npm:4.17.21#patches/lodash.patch" }, "dependenciesMeta": { - "lodash@4.16.0": { + "lodash@4.17.21": { "unplugged": true + }, + "mermaid@8.8.1": { + "optional": true } } } diff --git a/lib/modules/manager/npm/extract/types.ts b/lib/modules/manager/npm/extract/types.ts index 8f6ebf19ffdf3d1e9089adc9e311a6a7db3d2c03..cbdba5428f5e0dc5413cad892d0bdf229597e78b 100644 --- a/lib/modules/manager/npm/extract/types.ts +++ b/lib/modules/manager/npm/extract/types.ts @@ -1,12 +1,17 @@ import type { PackageJson } from 'type-fest'; export type NpmPackageDependency = PackageJson.Dependency; +export type DependenciesMeta = Record< + string, + { optional: boolean; built: boolean; unplugged: boolean } +>; export interface NpmPackage extends PackageJson { renovate?: unknown; _from?: any; _args?: any; _id?: any; + dependenciesMeta?: DependenciesMeta; } export type LockFileEntry = Record< diff --git a/lib/modules/manager/npm/update/dependency/index.ts b/lib/modules/manager/npm/update/dependency/index.ts index 4b411922005898e39d7150eea4f949debe2c1077..c1a518ef33b2051fcc1e3601a33b32ba7e1d62cc 100644 --- a/lib/modules/manager/npm/update/dependency/index.ts +++ b/lib/modules/manager/npm/update/dependency/index.ts @@ -1,12 +1,28 @@ import { dequal } from 'dequal'; -import type { PackageJson } from 'type-fest'; import { logger } from '../../../../../logger'; import { escapeRegExp, regEx } from '../../../../../util/regex'; import { matchAt, replaceAt } from '../../../../../util/string'; import type { UpdateDependencyConfig } from '../../../types'; +import type { DependenciesMeta, NpmPackage } from '../../extract/types'; + +function renameObjKey( + oldObj: DependenciesMeta, + oldKey: string, + newKey: string +): DependenciesMeta { + const keys = Object.keys(oldObj); + return keys.reduce((acc, key) => { + if (key === oldKey) { + acc[newKey] = oldObj[oldKey]; + } else { + acc[key] = oldObj[key]; + } + return acc; + }, {}); +} function replaceAsString( - parsedContents: PackageJson, + parsedContents: NpmPackage, fileContent: string, depType: string, depName: string, @@ -20,6 +36,14 @@ function replaceAsString( delete Object.assign(parsedContents[depType], { [newValue]: parsedContents[depType][oldValue], })[oldValue]; + } else if (depType === 'dependenciesMeta') { + if (oldValue !== newValue) { + parsedContents.dependenciesMeta = renameObjKey( + parsedContents.dependenciesMeta, + oldValue, + newValue + ); + } } else { // The old value is the version of the dependency parsedContents[depType][depName] = newValue; @@ -89,7 +113,7 @@ export function updateDependency({ } logger.debug(`npm.updateDependency(): ${depType}.${depName} = ${newValue}`); try { - const parsedContents: PackageJson = JSON.parse(fileContent); + const parsedContents: NpmPackage = JSON.parse(fileContent); // Save the old version let oldVersion: string; if (depType === 'packageManager') { @@ -173,6 +197,20 @@ export function updateDependency({ } } } + if (parsedContents?.dependenciesMeta) { + for (const [depKey] of Object.entries(parsedContents.dependenciesMeta)) { + if (depKey.startsWith(depName + '@')) { + newFileContent = replaceAsString( + parsedContents, + newFileContent, + 'dependenciesMeta', + depName, + depKey, + depName + '@' + newValue + ); + } + } + } return newFileContent; } catch (err) { logger.debug({ err }, 'updateDependency error');