From eab092d721f70605d2aa412e96d8c1edb8deeefc Mon Sep 17 00:00:00 2001
From: StinkyLord <42116482+PhilipAbed@users.noreply.github.com>
Date: Tue, 5 Apr 2022 13:41:13 +0300
Subject: [PATCH] feat(manager/npm): update yarn metadata versions (#14933)

Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
---
 .../npm/__fixtures__/inputs/patch1.json       |  6 ++-
 .../npm/__fixtures__/outputs/patch1o.json     |  8 +++-
 lib/modules/manager/npm/extract/types.ts      |  5 +++
 .../manager/npm/update/dependency/index.ts    | 44 +++++++++++++++++--
 4 files changed, 57 insertions(+), 6 deletions(-)

diff --git a/lib/modules/manager/npm/__fixtures__/inputs/patch1.json b/lib/modules/manager/npm/__fixtures__/inputs/patch1.json
index cecd931c74..ea98fe91e4 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 01c60a6c2d..58be7f8b35 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 8f6ebf19ff..cbdba5428f 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 4b41192200..c1a518ef33 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');
-- 
GitLab