UNPKG

renovate

Version:

Automated dependency updates. Flexible so you don't need to be.

148 lines (147 loc) • 6.95 kB
import { escapeRegExp, regEx } from "../../../../../util/regex.js"; import { matchAt, replaceAt } from "../../../../../util/string.js"; import { logger } from "../../../../../logger/index.js"; import "../../dep-types.js"; import { getNewGitValue, getNewNpmAliasValue } from "./common.js"; import { updatePnpmWorkspaceDependency } from "./pnpm.js"; import { updateYarnrcCatalogDependency } from "./yarn.js"; import { isArray, isNonEmptyStringAndNotWhitespace } from "@sindresorhus/is"; import { dequal } from "dequal"; //#region lib/modules/manager/npm/update/dependency/index.ts function renameObjKey(oldObj, oldKey, newKey) { return Object.keys(oldObj).reduce((acc, key) => { if (key === oldKey) acc[newKey] = oldObj[oldKey]; else acc[key] = oldObj[key]; return acc; }, {}); } function replaceAsString(parsedContents, fileContent, depType, depName, oldValue, newValue, parents) { if (depType === "packageManager") parsedContents[depType] = newValue; else if (depType === "pnpm.overrides") parsedContents.pnpm.overrides[depName] = newValue; else if (depName === oldValue) delete Object.assign(parsedContents[depType], { [newValue]: parsedContents[depType][oldValue] })[oldValue]; else if (depType === "dependenciesMeta") { // v8 ignore else -- TODO: add test #40625 if (oldValue !== newValue) parsedContents.dependenciesMeta = renameObjKey(parsedContents.dependenciesMeta, oldValue, newValue); } else if (parents && depType === "overrides") { const { depObjectReference, overrideDepName } = overrideDepPosition(parsedContents[depType], parents, depName); // v8 ignore else -- TODO: add test #40625 if (depObjectReference) depObjectReference[overrideDepName] = newValue; } else parsedContents[depType][depName] = newValue; const searchString = `"${oldValue}"`; let newString = `"${newValue}"`; const match = regEx(`^(patch:${escapeRegExp(depName)}@(npm:)?).*#`).exec(oldValue); if (match && depType === "resolutions") { const patch = oldValue.replace(match[0], `${match[1]}${newValue}#`); parsedContents[depType][depName] = patch; newString = `"${patch}"`; } let searchIndex = fileContent.indexOf(`"${depType}"`) + depType.length; logger.trace(`Starting search at index ${searchIndex}`); for (; searchIndex < fileContent.length; searchIndex += 1) if (matchAt(fileContent, searchIndex, searchString)) { logger.trace(`Found match at index ${searchIndex}`); const testContent = replaceAt(fileContent, searchIndex, searchString, newString); if (dequal(parsedContents, JSON.parse(testContent))) return testContent; } // v8 ignore next -- TODO: add test #40625 throw new Error(); } function updateDependency({ fileContent, packageFile: packageFileName, upgrade }) { if (upgrade.depType?.startsWith("pnpm.catalog") || upgrade.depType === "pnpm-workspace.overrides") return updatePnpmWorkspaceDependency({ fileContent, packageFile: packageFileName, upgrade }); if (upgrade.depType?.startsWith("yarn.catalog")) return updateYarnrcCatalogDependency({ fileContent, packageFile: packageFileName, upgrade }); const { depType, managerData } = upgrade; const depName = managerData?.key ?? upgrade.depName; let { newValue } = upgrade; newValue = getNewGitValue(upgrade) ?? newValue; newValue = getNewNpmAliasValue(newValue, upgrade) ?? newValue; logger.debug(`npm.updateDependency(): ${depType}.${depName} = ${newValue}`); try { const parsedContents = JSON.parse(fileContent); let overrideDepParents = void 0; let oldVersion; if (depType === "packageManager") { oldVersion = parsedContents[depType]; newValue = `${depName}@${newValue}`; } else if (isOverrideObject(upgrade)) { overrideDepParents = managerData?.parents; // v8 ignore else -- TODO: add test #40625 if (overrideDepParents) { const { depObjectReference, overrideDepName } = overrideDepPosition(parsedContents.overrides, overrideDepParents, depName); // v8 ignore else -- TODO: add test #40625 if (depObjectReference) oldVersion = depObjectReference[overrideDepName]; } } else if (depType === "pnpm.overrides") oldVersion = parsedContents.pnpm?.overrides?.[depName]; else oldVersion = parsedContents[depType][depName]; if (oldVersion === newValue) { logger.trace("Version is already updated"); return fileContent; } let newFileContent; if (upgrade.newName && upgrade.replacementApproach === "alias") newFileContent = replaceAsString(parsedContents, fileContent, depType, depName, oldVersion, `npm:${upgrade.newName}@${newValue}`, overrideDepParents); else { newFileContent = replaceAsString(parsedContents, fileContent, depType, depName, oldVersion, newValue, overrideDepParents); if (upgrade.newName) newFileContent = replaceAsString(parsedContents, newFileContent, depType, depName, depName, upgrade.newName, overrideDepParents); } /* v8 ignore next -- needs test */ if (!newFileContent) { logger.debug({ fileContent, parsedContents, depType, depName, newValue }, "Warning: updateDependency error"); return fileContent; } if (parsedContents?.resolutions) { let depKey; if (parsedContents.resolutions[depName]) depKey = depName; else if (parsedContents.resolutions[`**/${depName}`]) depKey = `**/${depName}`; if (depKey) { /* v8 ignore next -- needs test */ if (parsedContents.resolutions[depKey] !== oldVersion) logger.debug({ depName, depKey, oldVersion, resolutionsVersion: parsedContents.resolutions[depKey] }, "Upgraded dependency exists in yarn resolutions but is different version"); newFileContent = replaceAsString(parsedContents, newFileContent, "resolutions", depKey, parsedContents.resolutions[depKey], newValue); if (upgrade.newName) { if (depKey === `**/${depName}`) upgrade.newName = `**/${upgrade.newName}`; newFileContent = replaceAsString(parsedContents, newFileContent, "resolutions", depKey, depKey, upgrade.newName); } } } 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"); return null; } } function overrideDepPosition(overrideBlock, parents, depName) { const lastParent = parents[parents.length - 1]; let overrideDep = overrideBlock; for (const parent of parents) // v8 ignore else -- TODO: add test #40625 if (overrideDep) overrideDep = overrideDep[parent]; return { depObjectReference: overrideDep, overrideDepName: depName === lastParent ? "." : depName }; } function isOverrideObject(upgrade) { return isArray(upgrade.managerData?.parents, isNonEmptyStringAndNotWhitespace) && upgrade.depType === "overrides"; } //#endregion export { updateDependency }; //# sourceMappingURL=index.js.map