UNPKG

renovate

Version:

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

150 lines (149 loc) • 7.99 kB
import { matchAt, replaceAt } from "../../../util/string.js"; import { logger } from "../../../logger/index.js"; import { parseJsonc } from "../../../util/common.js"; import { updateDependency as updateDependency$1 } from "../npm/update/dependency/index.js"; import "../npm/index.js"; import { UpdateDenoJsonFile, UpdateImportMapJsonFile } from "./schema.js"; import { isNonEmptyArray, isObject, isString } from "@sindresorhus/is"; import { dequal } from "dequal"; import upath from "upath"; //#region lib/modules/manager/deno/update.ts function getValueByDatasource(datasource, depName, currentValue) { if (datasource === "deno") return currentValue ? `${depName}@${currentValue}` : depName; if (datasource === "jsr" || datasource === "npm") return currentValue ? `${datasource}:${depName}@${currentValue}` : `${datasource}:${depName}`; return null; } function replaceAsString(parsedContents, fileContent, depType, searchString, newString) { 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, parseJsonc(testContent))) return testContent; } throw new Error(); } function updateImportMapLikeDepTypes(parsedContents, fileContent, depType, searchString, newString) { let newFileContent = null; if (depType === "imports" && parsedContents.imports) { const matches = Object.entries(parsedContents.imports).filter(([, value]) => value.includes(searchString)); for (const [key] of matches) { parsedContents.imports[key] = parsedContents.imports[key].replace(searchString, newString); newFileContent = replaceAsString(parsedContents, fileContent, depType, searchString, newString); } } if (depType === "scopes" && parsedContents.scopes) for (const scopeName of Object.keys(parsedContents.scopes)) { const scope = parsedContents.scopes[scopeName]; const matches = Object.entries(scope).filter(([, value]) => value.includes(searchString)); for (const [key] of matches) { parsedContents.scopes[scopeName][key] = parsedContents.scopes[scopeName][key].replace(searchString, newString); newFileContent = replaceAsString(parsedContents, newFileContent ?? fileContent, depType, searchString, newString); } } return newFileContent; } function updateDependency(config) { const { fileContent, packageFile, upgrade } = config; const { depName, currentValue, newValue, datasource, managerData } = upgrade; if (!packageFile) { logger.debug("deno.updateDependency(): No package file found"); return null; } if (managerData?.importMapReferrer) { if (!depName || !newValue || !datasource || !upgrade.depType) { logger.debug({ depName, currentValue, newValue }, "Unknown value"); return null; } const depType = upgrade.depType; logger.debug(`deno.updateDependency(): ${packageFile}:${depType}.${depName} = ${newValue}`); const parsedResult = UpdateImportMapJsonFile.safeParse(fileContent); if (!parsedResult.success) { logger.debug({ err: parsedResult.error }, `Invalid packageFile: ${packageFile} detected`); return null; } const parsedContents = parsedResult.data; const searchCurrentValue = getValueByDatasource(datasource, depName, currentValue); const newString = getValueByDatasource(datasource, depName, newValue); if (!searchCurrentValue || !newString) { logger.debug(`deno.updateDependency(): "${datasource}" is not supported datasource`); return null; } return updateImportMapLikeDepTypes(parsedContents, fileContent, depType, searchCurrentValue, newString); } if (upath.basename(packageFile).startsWith("deno.json")) { if (!depName || !newValue || !datasource || !upgrade.depType) { logger.debug({ depName, currentValue, newValue }, "Unknown value"); return null; } const depType = upgrade.depType; logger.debug(`deno.updateDependency(): ${packageFile}:${depType}.${depName} = ${newValue}`); const parsedResult = UpdateDenoJsonFile.safeParse(fileContent); if (!parsedResult.success) { logger.debug({ err: parsedResult.error }, `Invalid packageFile: ${packageFile} detected`); return null; } const parsedContents = parsedResult.data; let newFileContent = null; const searchCurrentValue = getValueByDatasource(datasource, depName, currentValue); const newString = getValueByDatasource(datasource, depName, newValue); if (!searchCurrentValue || !newString) { logger.debug(`deno.updateDependency(): "${datasource}" is not supported datasource`); return null; } newFileContent = updateImportMapLikeDepTypes(parsedContents, fileContent, depType, searchCurrentValue, newString); if (depType === "tasks" && parsedContents.tasks) { const matches = Object.entries(parsedContents.tasks).flatMap(([key, value]) => isString(value) && value.includes(searchCurrentValue) ? [[key, value]] : []); for (const [key, value] of matches) { parsedContents.tasks[key] = value.replace(searchCurrentValue, newString); newFileContent = replaceAsString(parsedContents, newFileContent ?? fileContent, depType, searchCurrentValue, newString); } } if (depType === "tasks.command" && parsedContents.tasks) { const hasCommandMatch = (value) => isObject(value) && "command" in value && isString(value.command) && value.command.includes(searchCurrentValue); const matches = Object.entries(parsedContents.tasks).filter((entry) => hasCommandMatch(entry[1])); for (const [key, task] of matches) { task.command = task.command.replace(searchCurrentValue, newString); parsedContents.tasks[key] = task; newFileContent = replaceAsString(parsedContents, newFileContent ?? fileContent, depType, searchCurrentValue, newString); } } if (depType === "compilerOptions.types" && isNonEmptyArray(parsedContents.compilerOptions?.types)) { const index = parsedContents.compilerOptions.types.findIndex((value) => value === searchCurrentValue); if (index !== -1) { parsedContents.compilerOptions.types[index] = parsedContents.compilerOptions.types[index].replace(searchCurrentValue, newString); newFileContent = replaceAsString(parsedContents, newFileContent ?? fileContent, depType, searchCurrentValue, newString); } } if (depType === "compilerOptions.jsxImportSource" && parsedContents.compilerOptions?.jsxImportSource) { parsedContents.compilerOptions.jsxImportSource = parsedContents.compilerOptions.jsxImportSource.replace(searchCurrentValue, newString); newFileContent = replaceAsString(parsedContents, newFileContent ?? fileContent, depType, searchCurrentValue, newString); } if (depType === "compilerOptions.jsxImportSourceTypes" && parsedContents.compilerOptions?.jsxImportSourceTypes) { parsedContents.compilerOptions.jsxImportSourceTypes = parsedContents.compilerOptions.jsxImportSourceTypes.replace(searchCurrentValue, newString); newFileContent = replaceAsString(parsedContents, newFileContent ?? fileContent, depType, searchCurrentValue, newString); } if (depType === "lint.plugins" && isNonEmptyArray(parsedContents.lint?.plugins)) { const index = parsedContents.lint.plugins.findIndex((value) => value === searchCurrentValue); if (index !== -1) { parsedContents.lint.plugins[index] = parsedContents.lint.plugins[index].replace(searchCurrentValue, newString); newFileContent = replaceAsString(parsedContents, newFileContent ?? fileContent, depType, searchCurrentValue, newString); } } if (newFileContent === fileContent) return fileContent; return newFileContent; } if (upath.basename(packageFile) === "package.json") return updateDependency$1(config); logger.debug(`${packageFile} is not supported`); return null; } //#endregion export { updateDependency }; //# sourceMappingURL=update.js.map