renovate 43.111.3 → 43.112.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/modules/datasource/maven/schema.js +128 -0
- package/dist/modules/datasource/maven/schema.js.map +1 -0
- package/dist/modules/datasource/maven/util.js +3 -1
- package/dist/modules/datasource/maven/util.js.map +1 -1
- package/dist/modules/platform/github/schema.d.ts +2 -2
- package/dist/util/cache/package/impl/sqlite.js +45 -20
- package/dist/util/cache/package/impl/sqlite.js.map +1 -1
- package/dist/workers/repository/dependency-dashboard.js +6 -5
- package/dist/workers/repository/dependency-dashboard.js.map +1 -1
- package/package.json +2 -2
- package/renovate-schema.json +2 -2
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { z } from "zod/v3";
|
|
2
|
+
import { XmlDocument } from "xmldoc";
|
|
3
|
+
//#region lib/modules/datasource/maven/schema.ts
|
|
4
|
+
const xmlHeader = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
|
|
5
|
+
function escapeXml(value) {
|
|
6
|
+
return value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">");
|
|
7
|
+
}
|
|
8
|
+
var XmlWriter = class {
|
|
9
|
+
lines = [];
|
|
10
|
+
level;
|
|
11
|
+
constructor(level = 0) {
|
|
12
|
+
this.level = level;
|
|
13
|
+
}
|
|
14
|
+
value(name, value) {
|
|
15
|
+
if (value === void 0) return;
|
|
16
|
+
this.lines.push(`${this.indent()}<${name}>${escapeXml(value)}</${name}>`);
|
|
17
|
+
}
|
|
18
|
+
node(name, renderChildren) {
|
|
19
|
+
this.renderNode(name, renderChildren, false);
|
|
20
|
+
}
|
|
21
|
+
nodeOrEmpty(name, renderChildren) {
|
|
22
|
+
this.renderNode(name, renderChildren, true);
|
|
23
|
+
}
|
|
24
|
+
hasContent() {
|
|
25
|
+
return this.lines.length > 0;
|
|
26
|
+
}
|
|
27
|
+
toString() {
|
|
28
|
+
return this.lines.join("\n");
|
|
29
|
+
}
|
|
30
|
+
renderNode(name, renderChildren, preserveEmpty) {
|
|
31
|
+
const contentStart = this.lines.length;
|
|
32
|
+
this.level += 1;
|
|
33
|
+
renderChildren(this);
|
|
34
|
+
this.level -= 1;
|
|
35
|
+
const content = this.lines.splice(contentStart);
|
|
36
|
+
if (!content.length) {
|
|
37
|
+
if (preserveEmpty) this.lines.push(`${this.indent()}<${name} />`);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
this.lines.push(`${this.indent()}<${name}>`, ...content, `${this.indent()}</${name}>`);
|
|
41
|
+
}
|
|
42
|
+
indent() {
|
|
43
|
+
return " ".repeat(this.level);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
function shrinkToUsefulSize(original, trimmed) {
|
|
47
|
+
if (trimmed.length >= original.length) return original;
|
|
48
|
+
return trimmed;
|
|
49
|
+
}
|
|
50
|
+
function renderRelocationNode(xml, relocation) {
|
|
51
|
+
if (!relocation) return;
|
|
52
|
+
xml.nodeOrEmpty("relocation", () => {
|
|
53
|
+
xml.value("groupId", relocation.valueWithPath("groupId"));
|
|
54
|
+
xml.value("artifactId", relocation.valueWithPath("artifactId"));
|
|
55
|
+
xml.value("version", relocation.valueWithPath("version"));
|
|
56
|
+
xml.value("message", relocation.valueWithPath("message"));
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
function trimMetadataXml(metadata, input) {
|
|
60
|
+
const version = metadata.descendantWithPath("version")?.val;
|
|
61
|
+
const latest = metadata.descendantWithPath("versioning.latest")?.val;
|
|
62
|
+
const release = metadata.descendantWithPath("versioning.release")?.val;
|
|
63
|
+
const versions = metadata.descendantWithPath("versioning.versions")?.childrenNamed("version").map((child) => child.val) ?? [];
|
|
64
|
+
const snapshot = metadata.descendantWithPath("versioning.snapshot");
|
|
65
|
+
const timestamp = snapshot?.childNamed("timestamp")?.val;
|
|
66
|
+
const buildNumber = snapshot?.childNamed("buildNumber")?.val;
|
|
67
|
+
const xml = new XmlWriter();
|
|
68
|
+
xml.node("metadata", () => {
|
|
69
|
+
xml.value("version", version);
|
|
70
|
+
xml.node("versioning", () => {
|
|
71
|
+
xml.value("latest", latest);
|
|
72
|
+
xml.value("release", release);
|
|
73
|
+
xml.node("versions", () => {
|
|
74
|
+
for (const trimmedVersion of versions) xml.value("version", trimmedVersion);
|
|
75
|
+
});
|
|
76
|
+
xml.node("snapshot", () => {
|
|
77
|
+
xml.value("timestamp", timestamp);
|
|
78
|
+
xml.value("buildNumber", buildNumber);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
if (!xml.hasContent()) return input;
|
|
83
|
+
return shrinkToUsefulSize(input, [xmlHeader, xml.toString()].join("\n"));
|
|
84
|
+
}
|
|
85
|
+
function trimPomXml(project, input) {
|
|
86
|
+
const homepage = project.valueWithPath("url");
|
|
87
|
+
const sourceUrl = project.valueWithPath("scm.url");
|
|
88
|
+
const groupId = project.valueWithPath("groupId");
|
|
89
|
+
const relocation = project.descendantWithPath("distributionManagement.relocation");
|
|
90
|
+
const parent = project.childNamed("parent");
|
|
91
|
+
const xml = new XmlWriter();
|
|
92
|
+
xml.node("project", () => {
|
|
93
|
+
xml.value("groupId", groupId);
|
|
94
|
+
xml.value("url", homepage);
|
|
95
|
+
xml.node("scm", () => {
|
|
96
|
+
xml.value("url", sourceUrl);
|
|
97
|
+
});
|
|
98
|
+
xml.node("distributionManagement", () => {
|
|
99
|
+
renderRelocationNode(xml, relocation);
|
|
100
|
+
});
|
|
101
|
+
xml.node("parent", () => {
|
|
102
|
+
xml.value("groupId", parent?.valueWithPath("groupId"));
|
|
103
|
+
xml.value("artifactId", parent?.valueWithPath("artifactId"));
|
|
104
|
+
xml.value("version", parent?.valueWithPath("version"));
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
if (!xml.hasContent()) return input;
|
|
108
|
+
return shrinkToUsefulSize(input, [xmlHeader, xml.toString()].join("\n"));
|
|
109
|
+
}
|
|
110
|
+
function trimMavenXml(input) {
|
|
111
|
+
let parsed;
|
|
112
|
+
try {
|
|
113
|
+
parsed = new XmlDocument(input);
|
|
114
|
+
} catch {
|
|
115
|
+
return input;
|
|
116
|
+
}
|
|
117
|
+
if (parsed.name.includes(":")) return input;
|
|
118
|
+
switch (parsed.name) {
|
|
119
|
+
case "metadata": return trimMetadataXml(parsed, input);
|
|
120
|
+
case "project": return trimPomXml(parsed, input);
|
|
121
|
+
default: return input;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
const CachedMavenXml = z.string().transform(trimMavenXml);
|
|
125
|
+
//#endregion
|
|
126
|
+
export { CachedMavenXml };
|
|
127
|
+
|
|
128
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","names":[],"sources":["../../../../lib/modules/datasource/maven/schema.ts"],"sourcesContent":["import { XmlDocument, type XmlElement } from 'xmldoc';\nimport { z } from 'zod/v3';\n\nconst xmlHeader = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>';\n\nfunction escapeXml(value: string): string {\n return value\n .replaceAll('&', '&')\n .replaceAll('<', '<')\n .replaceAll('>', '>');\n}\n\nclass XmlWriter {\n private lines: string[] = [];\n private level: number;\n\n constructor(level = 0) {\n this.level = level;\n }\n\n value(name: string, value: string | undefined): void {\n if (value === undefined) {\n return;\n }\n\n this.lines.push(`${this.indent()}<${name}>${escapeXml(value)}</${name}>`);\n }\n\n node(name: string, renderChildren: (xml: XmlWriter) => void): void {\n this.renderNode(name, renderChildren, false);\n }\n\n nodeOrEmpty(name: string, renderChildren: (xml: XmlWriter) => void): void {\n this.renderNode(name, renderChildren, true);\n }\n\n hasContent(): boolean {\n return this.lines.length > 0;\n }\n\n toString(): string {\n return this.lines.join('\\n');\n }\n\n private renderNode(\n name: string,\n renderChildren: (xml: XmlWriter) => void,\n preserveEmpty: boolean,\n ): void {\n const contentStart = this.lines.length;\n this.level += 1;\n renderChildren(this);\n this.level -= 1;\n\n const content = this.lines.splice(contentStart);\n\n if (!content.length) {\n if (preserveEmpty) {\n this.lines.push(`${this.indent()}<${name} />`);\n }\n\n return;\n }\n\n this.lines.push(\n `${this.indent()}<${name}>`,\n ...content,\n `${this.indent()}</${name}>`,\n );\n }\n\n private indent(): string {\n return ' '.repeat(this.level);\n }\n}\n\nfunction shrinkToUsefulSize(original: string, trimmed: string): string {\n if (trimmed.length >= original.length) {\n return original;\n }\n\n return trimmed;\n}\n\nfunction renderRelocationNode(\n xml: XmlWriter,\n relocation: XmlElement | undefined,\n): void {\n if (!relocation) {\n return;\n }\n\n xml.nodeOrEmpty('relocation', () => {\n xml.value('groupId', relocation.valueWithPath('groupId'));\n xml.value('artifactId', relocation.valueWithPath('artifactId'));\n xml.value('version', relocation.valueWithPath('version'));\n xml.value('message', relocation.valueWithPath('message'));\n });\n}\n\nfunction trimMetadataXml(metadata: XmlDocument, input: string): string {\n const version = metadata.descendantWithPath('version')?.val;\n const latest = metadata.descendantWithPath('versioning.latest')?.val;\n const release = metadata.descendantWithPath('versioning.release')?.val;\n const versions =\n metadata\n .descendantWithPath('versioning.versions')\n ?.childrenNamed('version')\n .map((child) => child.val) ?? [];\n const snapshot = metadata.descendantWithPath('versioning.snapshot');\n const timestamp = snapshot?.childNamed('timestamp')?.val;\n const buildNumber = snapshot?.childNamed('buildNumber')?.val;\n\n const xml = new XmlWriter();\n xml.node('metadata', () => {\n xml.value('version', version);\n xml.node('versioning', () => {\n xml.value('latest', latest);\n xml.value('release', release);\n xml.node('versions', () => {\n for (const trimmedVersion of versions) {\n xml.value('version', trimmedVersion);\n }\n });\n xml.node('snapshot', () => {\n xml.value('timestamp', timestamp);\n xml.value('buildNumber', buildNumber);\n });\n });\n });\n\n if (!xml.hasContent()) {\n return input;\n }\n\n return shrinkToUsefulSize(input, [xmlHeader, xml.toString()].join('\\n'));\n}\n\nfunction trimPomXml(project: XmlDocument, input: string): string {\n const homepage = project.valueWithPath('url');\n const sourceUrl = project.valueWithPath('scm.url');\n const groupId = project.valueWithPath('groupId');\n const relocation = project.descendantWithPath(\n 'distributionManagement.relocation',\n );\n const parent = project.childNamed('parent');\n\n const xml = new XmlWriter();\n xml.node('project', () => {\n xml.value('groupId', groupId);\n xml.value('url', homepage);\n xml.node('scm', () => {\n xml.value('url', sourceUrl);\n });\n xml.node('distributionManagement', () => {\n renderRelocationNode(xml, relocation);\n });\n xml.node('parent', () => {\n xml.value('groupId', parent?.valueWithPath('groupId'));\n xml.value('artifactId', parent?.valueWithPath('artifactId'));\n xml.value('version', parent?.valueWithPath('version'));\n });\n });\n\n if (!xml.hasContent()) {\n return input;\n }\n\n return shrinkToUsefulSize(input, [xmlHeader, xml.toString()].join('\\n'));\n}\n\nexport function trimMavenXml(input: string): string {\n let parsed: XmlDocument;\n try {\n parsed = new XmlDocument(input);\n } catch {\n return input;\n }\n\n if (parsed.name.includes(':')) {\n return input;\n }\n\n switch (parsed.name) {\n case 'metadata':\n return trimMetadataXml(parsed, input);\n case 'project':\n return trimPomXml(parsed, input);\n default:\n return input;\n }\n}\n\nexport const CachedMavenXml = z.string().transform(trimMavenXml);\n"],"mappings":"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"}
|
|
@@ -13,6 +13,7 @@ import "./common.js";
|
|
|
13
13
|
import { PackageHttpCacheProvider } from "../../../util/http/cache/package-http-cache-provider.js";
|
|
14
14
|
import { getS3Client, parseS3Url } from "../../../util/s3.js";
|
|
15
15
|
import { streamToString } from "../../../util/streams.js";
|
|
16
|
+
import { CachedMavenXml } from "./schema.js";
|
|
16
17
|
import { Readable } from "node:stream";
|
|
17
18
|
import { GetObjectCommand } from "@aws-sdk/client-s3";
|
|
18
19
|
import { XmlDocument } from "xmldoc";
|
|
@@ -48,7 +49,8 @@ const cacheProvider = new PackageHttpCacheProvider({
|
|
|
48
49
|
namespace: "datasource-maven:cache-provider",
|
|
49
50
|
softTtlMinutes: 15,
|
|
50
51
|
checkAuthorizationHeader: true,
|
|
51
|
-
checkCacheControlHeader: false
|
|
52
|
+
checkCacheControlHeader: false,
|
|
53
|
+
writeSchema: CachedMavenXml
|
|
52
54
|
});
|
|
53
55
|
async function downloadHttpProtocol(http, pkgUrl, opts = {}) {
|
|
54
56
|
const url = pkgUrl.toString();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","names":["HttpError"],"sources":["../../../../lib/modules/datasource/maven/util.ts"],"sourcesContent":["import { Readable } from 'node:stream';\nimport { GetObjectCommand } from '@aws-sdk/client-s3';\nimport { XmlDocument } from 'xmldoc';\nimport { HOST_DISABLED } from '../../../constants/error-messages.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { ExternalHostError } from '../../../types/errors/external-host-error.ts';\nimport { getCacheType } from '../../../util/cache/package/index.ts';\nimport { PackageHttpCacheProvider } from '../../../util/http/cache/package-http-cache-provider.ts';\nimport { type Http, HttpError } from '../../../util/http/index.ts';\nimport type { HttpOptions, HttpResponse } from '../../../util/http/types.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { Result } from '../../../util/result.ts';\nimport { getS3Client, parseS3Url } from '../../../util/s3.ts';\nimport { streamToString } from '../../../util/streams.ts';\nimport { asTimestamp } from '../../../util/timestamp.ts';\nimport { ensureTrailingSlash, isHttpUrl, parseUrl } from '../../../util/url.ts';\nimport { getGoogleAuthToken } from '../util.ts';\nimport { MAVEN_REPO } from './common.ts';\nimport type {\n DependencyInfo,\n MavenDependency,\n MavenFetchResult,\n MavenFetchSuccess,\n} from './types.ts';\n\nfunction getHost(url: string): string | undefined {\n return parseUrl(url)?.host;\n}\n\nfunction isTemporaryError(err: HttpError): boolean {\n if (err.code === 'ECONNRESET') {\n return true;\n }\n\n if (err.response) {\n const status = err.response.statusCode;\n return status === 429 || (status >= 500 && status < 600);\n }\n\n return false;\n}\n\nfunction isHostError(err: HttpError): boolean {\n return err.code === 'ETIMEDOUT';\n}\n\nfunction isNotFoundError(err: HttpError): boolean {\n return err.code === 'ENOTFOUND' || err.response?.statusCode === 404;\n}\n\nfunction isPermissionsIssue(err: HttpError): boolean {\n const status = err.response?.statusCode;\n return status === 401 || status === 403;\n}\n\nfunction isConnectionError(err: HttpError): boolean {\n return (\n err.code === 'EAI_AGAIN' ||\n err.code === 'ERR_TLS_CERT_ALTNAME_INVALID' ||\n err.code === 'ECONNREFUSED'\n );\n}\n\nfunction isUnsupportedHostError(err: HttpError): boolean {\n return err.name === 'UnsupportedProtocolError';\n}\n\nconst cacheProvider = new PackageHttpCacheProvider({\n namespace: 'datasource-maven:cache-provider',\n softTtlMinutes: 15,\n checkAuthorizationHeader: true,\n checkCacheControlHeader: false, // Maven doesn't respond with `cache-control` headers\n});\n\nexport async function downloadHttpProtocol(\n http: Http,\n pkgUrl: URL | string,\n opts: HttpOptions = {},\n): Promise<MavenFetchResult> {\n const url = pkgUrl.toString();\n const fetchResult = await Result.wrap<HttpResponse, Error>(\n http.getText(url, { ...opts, cacheProvider }),\n )\n .transform((res): MavenFetchSuccess => {\n const result: MavenFetchSuccess = { data: res.body };\n\n if (!res.authorization) {\n result.isCacheable = true;\n }\n\n const lastModified = asTimestamp(res?.headers?.['last-modified']);\n if (lastModified) {\n result.lastModified = lastModified;\n }\n\n return result;\n })\n .catch((err): MavenFetchResult => {\n /* v8 ignore next: never happens, needs for type narrowing */\n if (!(err instanceof HttpError)) {\n return Result.err({ type: 'unknown', err });\n }\n\n const failedUrl = url;\n if (err.message === HOST_DISABLED) {\n logger.trace({ failedUrl }, 'Host disabled');\n return Result.err({ type: 'host-disabled' });\n }\n\n if (isNotFoundError(err)) {\n logger.trace({ failedUrl }, `Url not found`);\n return Result.err({ type: 'not-found' });\n }\n\n if (isHostError(err)) {\n logger.debug(`Cannot connect to host ${failedUrl}`);\n return Result.err({ type: 'host-error' });\n }\n\n if (isPermissionsIssue(err)) {\n logger.debug(\n `Dependency lookup unauthorized. Please add authentication with a hostRule for ${failedUrl}`,\n );\n return Result.err({ type: 'permission-issue' });\n }\n\n if (isTemporaryError(err)) {\n logger.debug({ failedUrl, err }, 'Temporary error');\n if (getHost(url) === getHost(MAVEN_REPO)) {\n const statusCode = err?.response?.statusCode;\n if (statusCode === 429) {\n if (getCacheType() === 'redis') {\n logger.once.warn(\n { failedUrl },\n 'Maven Central rate limiting detected despite Redis caching.',\n );\n } else {\n logger.once.warn(\n { failedUrl },\n 'Maven Central rate limiting detected. Persistent caching required.',\n );\n }\n }\n return Result.err({ type: 'maven-central-temporary-error', err });\n } else {\n return Result.err({ type: 'temporary-error' });\n }\n }\n\n if (isConnectionError(err)) {\n logger.debug(`Connection refused to maven registry ${failedUrl}`);\n return Result.err({ type: 'connection-error' });\n }\n\n if (isUnsupportedHostError(err)) {\n logger.debug(`Unsupported host ${failedUrl}`);\n return Result.err({ type: 'unsupported-host' });\n }\n\n logger.info({ failedUrl, err }, 'Unknown HTTP download error');\n return Result.err({ type: 'unknown', err });\n });\n\n const { err } = fetchResult.unwrap();\n if (err?.type === 'maven-central-temporary-error') {\n throw new ExternalHostError(err.err);\n }\n\n return fetchResult;\n}\n\nexport async function downloadHttpContent(\n http: Http,\n pkgUrl: URL | string,\n opts: HttpOptions = {},\n): Promise<string | null> {\n const fetchResult = await downloadHttpProtocol(http, pkgUrl, opts);\n return fetchResult.transform(({ data }) => data).unwrapOrNull();\n}\n\nfunction isS3NotFound(err: Error): boolean {\n return err.message === 'NotFound' || err.message === 'NoSuchKey';\n}\n\nexport async function downloadS3Protocol(\n pkgUrl: URL,\n): Promise<MavenFetchResult> {\n logger.trace({ url: pkgUrl.toString() }, `Attempting to load S3 dependency`);\n\n const s3Url = parseS3Url(pkgUrl);\n if (!s3Url) {\n return Result.err({ type: 'invalid-url' });\n }\n\n return await Result.wrap(() => {\n const command = new GetObjectCommand(s3Url);\n const client = getS3Client();\n return client.send(command);\n })\n .transform(\n async ({\n Body,\n LastModified,\n DeleteMarker,\n }): Promise<MavenFetchResult> => {\n if (DeleteMarker) {\n logger.trace(\n { failedUrl: pkgUrl.toString() },\n 'Maven S3 lookup error: DeleteMarker encountered',\n );\n return Result.err({ type: 'not-found' });\n }\n\n if (!(Body instanceof Readable)) {\n logger.debug(\n { failedUrl: pkgUrl.toString() },\n 'Maven S3 lookup error: unsupported Body type',\n );\n return Result.err({ type: 'unsupported-format' });\n }\n\n const data = await streamToString(Body);\n const result: MavenFetchSuccess = { data };\n\n const lastModified = asTimestamp(LastModified);\n if (lastModified) {\n result.lastModified = lastModified;\n }\n\n return Result.ok(result);\n },\n )\n .catch((err): MavenFetchResult => {\n if (!(err instanceof Error)) {\n return Result.err(err);\n }\n\n const failedUrl = pkgUrl.toString();\n\n if (err.name === 'CredentialsProviderError') {\n logger.debug(\n { failedUrl },\n 'Maven S3 lookup error: credentials provider error, check \"AWS_ACCESS_KEY_ID\" and \"AWS_SECRET_ACCESS_KEY\" variables',\n );\n return Result.err({ type: 'credentials-error' });\n }\n\n if (err.message === 'Region is missing') {\n logger.debug(\n { failedUrl },\n 'Maven S3 lookup error: missing region, check \"AWS_REGION\" variable',\n );\n return Result.err({ type: 'missing-aws-region' });\n }\n\n if (isS3NotFound(err)) {\n logger.trace({ failedUrl }, 'Maven S3 lookup error: object not found');\n return Result.err({ type: 'not-found' });\n }\n\n logger.debug({ failedUrl, err }, 'Maven S3 lookup error: unknown error');\n return Result.err({ type: 'unknown', err });\n });\n}\n\nexport async function downloadArtifactRegistryProtocol(\n http: Http,\n pkgUrl: URL,\n): Promise<MavenFetchResult> {\n const opts: HttpOptions = {};\n const host = pkgUrl.host;\n const path = pkgUrl.pathname;\n\n logger.trace({ host, path }, `Using google auth for Maven repository`);\n const auth = await getGoogleAuthToken();\n if (auth) {\n opts.headers = { authorization: `Basic ${auth}` };\n } else {\n logger.once.debug(\n { host, path },\n 'Could not get Google access token, using no auth',\n );\n }\n\n const url = pkgUrl.toString().replace('artifactregistry:', 'https:');\n\n return downloadHttpProtocol(http, url, opts);\n}\n\nfunction containsPlaceholder(str: string): boolean {\n return regEx(/\\${.*?}/g).test(str);\n}\n\nfunction removeKnownPlaceholders(str: string): string {\n return str.replace(regEx(/\\/tree\\/\\${[^}]+}/), '');\n}\n\nexport function getMavenUrl(\n dependency: MavenDependency,\n repoUrl: string,\n path: string,\n): URL {\n return new URL(\n `${dependency.dependencyUrl}/${path}`,\n ensureTrailingSlash(repoUrl),\n );\n}\n\nexport async function downloadMaven(\n http: Http,\n url: URL,\n): Promise<MavenFetchResult> {\n const protocol = url.protocol;\n\n let result: MavenFetchResult = Result.err({ type: 'unsupported-protocol' });\n\n if (isHttpUrl(url)) {\n result = await downloadHttpProtocol(http, url);\n }\n\n if (protocol === 'artifactregistry:') {\n result = await downloadArtifactRegistryProtocol(http, url);\n }\n\n if (protocol === 's3:') {\n result = await downloadS3Protocol(url);\n }\n\n return result.onError((err) => {\n if (err.type === 'unsupported-protocol') {\n logger.debug(\n { url: url.toString() },\n `Maven lookup error: unsupported protocol (${protocol})`,\n );\n }\n });\n}\n\nexport async function downloadMavenXml(\n http: Http,\n url: URL,\n): Promise<MavenFetchResult<XmlDocument>> {\n const rawResult = await downloadMaven(http, url);\n return rawResult.transform((result): MavenFetchResult<XmlDocument> => {\n try {\n return Result.ok({\n ...result,\n data: new XmlDocument(result.data),\n });\n } catch (err) {\n return Result.err({ type: 'xml-parse-error', err });\n }\n });\n}\n\nexport function getDependencyParts(packageName: string): MavenDependency {\n const [group, name] = packageName.split(':');\n const dependencyUrl = `${group.replace(regEx(/\\./g), '/')}/${name}`;\n return {\n display: packageName,\n group,\n name,\n dependencyUrl,\n };\n}\n\nfunction extractSnapshotVersion(metadata: XmlDocument): string | null {\n // Parse the maven-metadata.xml for the snapshot version and determine\n // the fixed version of the latest deployed snapshot.\n // The metadata descriptor can be found at\n // https://maven.apache.org/ref/3.3.3/maven-repository-metadata/repository-metadata.html\n //\n // Basically, we need to replace -SNAPSHOT with the artifact timestanp & build number,\n // so for example 1.0.0-SNAPSHOT will become 1.0.0-<timestamp>-<buildNumber>\n const version = metadata\n .descendantWithPath('version')\n ?.val?.replace('-SNAPSHOT', '');\n\n const snapshot = metadata.descendantWithPath('versioning.snapshot');\n const timestamp = snapshot?.childNamed('timestamp')?.val;\n const build = snapshot?.childNamed('buildNumber')?.val;\n\n // If we weren't able to parse out the required 3 version elements,\n // return null because we can't determine the fixed version of the latest snapshot.\n if (!version || !timestamp || !build) {\n return null;\n }\n return `${version}-${timestamp}-${build}`;\n}\n\nasync function getSnapshotFullVersion(\n http: Http,\n version: string,\n dependency: MavenDependency,\n repoUrl: string,\n): Promise<string | null> {\n // To determine what actual files are available for the snapshot, first we have to fetch and parse\n // the metadata located at http://<repo>/<group>/<artifact>/<version-SNAPSHOT>/maven-metadata.xml\n const metadataUrl = getMavenUrl(\n dependency,\n repoUrl,\n `${version}/maven-metadata.xml`,\n );\n\n const metadataXmlResult = await downloadMavenXml(http, metadataUrl);\n\n return metadataXmlResult\n .transform(({ data }) =>\n Result.wrapNullable(extractSnapshotVersion(data), {\n type: 'snapshot-extract-error',\n }),\n )\n .unwrapOrNull();\n}\n\nfunction isSnapshotVersion(version: string): boolean {\n if (version.endsWith('-SNAPSHOT')) {\n return true;\n }\n return false;\n}\n\nexport async function createUrlForDependencyPom(\n http: Http,\n version: string,\n dependency: MavenDependency,\n repoUrl: string,\n): Promise<string> {\n if (isSnapshotVersion(version)) {\n // By default, Maven snapshots are deployed to the repository with fixed file names.\n // Resolve the full, actual pom file name for the version.\n const fullVersion = await getSnapshotFullVersion(\n http,\n version,\n dependency,\n repoUrl,\n );\n\n // If we were able to resolve the version, use that, otherwise fall back to using -SNAPSHOT\n if (fullVersion !== null) {\n // TODO: types (#22198)\n return `${version}/${dependency.name}-${fullVersion}.pom`;\n }\n }\n\n // TODO: types (#22198)\n return `${version}/${dependency.name}-${version}.pom`;\n}\n\nexport async function getDependencyInfo(\n http: Http,\n dependency: MavenDependency,\n repoUrl: string,\n version: string,\n recursionLimit = 5,\n): Promise<DependencyInfo> {\n const path = await createUrlForDependencyPom(\n http,\n version,\n dependency,\n repoUrl,\n );\n\n const pomUrl = getMavenUrl(dependency, repoUrl, path);\n const pomXmlResult = await downloadMavenXml(http, pomUrl);\n const dependencyInfoResult = await pomXmlResult.transform(\n async ({ data: pomContent }) => {\n const result: DependencyInfo = {};\n\n const homepage = pomContent.valueWithPath('url');\n if (homepage && !containsPlaceholder(homepage)) {\n result.homepage = homepage;\n }\n\n const sourceUrl = pomContent.valueWithPath('scm.url');\n if (\n sourceUrl &&\n !containsPlaceholder(removeKnownPlaceholders(sourceUrl))\n ) {\n result.sourceUrl = sourceUrl\n .replace(regEx(/^scm:/), '')\n .replace(regEx(/^git:/), '')\n .replace(regEx(/^git@github.com:/), 'https://github.com/')\n .replace(regEx(/^git@github.com\\//), 'https://github.com/');\n\n if (result.sourceUrl.startsWith('//')) {\n // most likely the result of us stripping scm:, git: etc\n // going with prepending https: here which should result in potential information retrival\n result.sourceUrl = `https:${result.sourceUrl}`;\n }\n }\n\n const relocation = pomContent.descendantWithPath(\n 'distributionManagement.relocation',\n );\n if (relocation) {\n const relocationGroup =\n relocation.valueWithPath('groupId') ?? dependency.group;\n const relocationName =\n relocation.valueWithPath('artifactId') ?? dependency.name;\n result.replacementName = `${relocationGroup}:${relocationName}`;\n const relocationVersion = relocation.valueWithPath('version');\n result.replacementVersion = relocationVersion ?? version;\n const relocationMessage = relocation.valueWithPath('message');\n if (relocationMessage) {\n result.deprecationMessage = relocationMessage;\n }\n }\n\n const groupId = pomContent.valueWithPath('groupId');\n if (groupId) {\n result.packageScope = groupId;\n }\n\n const parent = pomContent.childNamed('parent');\n if (\n recursionLimit > 0 &&\n parent &&\n (!result.sourceUrl || !result.homepage)\n ) {\n // if we found a parent and are missing some information\n // trying to get the scm/homepage information from it\n const [parentGroupId, parentArtifactId, parentVersion] = [\n 'groupId',\n 'artifactId',\n 'version',\n ].map((k) => parent.valueWithPath(k)?.replace(/\\s+/g, ''));\n if (parentGroupId && parentArtifactId && parentVersion) {\n const parentDisplayId = `${parentGroupId}:${parentArtifactId}`;\n const parentDependency = getDependencyParts(parentDisplayId);\n const parentInformation = await getDependencyInfo(\n http,\n parentDependency,\n repoUrl,\n parentVersion,\n recursionLimit - 1,\n );\n if (!result.sourceUrl && parentInformation.sourceUrl) {\n result.sourceUrl = parentInformation.sourceUrl;\n }\n if (!result.homepage && parentInformation.homepage) {\n result.homepage = parentInformation.homepage;\n }\n }\n }\n\n return result;\n },\n );\n\n return dependencyInfoResult.unwrapOr({});\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"util.js","names":["HttpError"],"sources":["../../../../lib/modules/datasource/maven/util.ts"],"sourcesContent":["import { Readable } from 'node:stream';\nimport { GetObjectCommand } from '@aws-sdk/client-s3';\nimport { XmlDocument } from 'xmldoc';\nimport { HOST_DISABLED } from '../../../constants/error-messages.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { ExternalHostError } from '../../../types/errors/external-host-error.ts';\nimport { getCacheType } from '../../../util/cache/package/index.ts';\nimport { PackageHttpCacheProvider } from '../../../util/http/cache/package-http-cache-provider.ts';\nimport { type Http, HttpError } from '../../../util/http/index.ts';\nimport type { HttpOptions, HttpResponse } from '../../../util/http/types.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { Result } from '../../../util/result.ts';\nimport { getS3Client, parseS3Url } from '../../../util/s3.ts';\nimport { streamToString } from '../../../util/streams.ts';\nimport { asTimestamp } from '../../../util/timestamp.ts';\nimport { ensureTrailingSlash, isHttpUrl, parseUrl } from '../../../util/url.ts';\nimport { getGoogleAuthToken } from '../util.ts';\nimport { MAVEN_REPO } from './common.ts';\nimport { CachedMavenXml } from './schema.ts';\nimport type {\n DependencyInfo,\n MavenDependency,\n MavenFetchResult,\n MavenFetchSuccess,\n} from './types.ts';\n\nfunction getHost(url: string): string | undefined {\n return parseUrl(url)?.host;\n}\n\nfunction isTemporaryError(err: HttpError): boolean {\n if (err.code === 'ECONNRESET') {\n return true;\n }\n\n if (err.response) {\n const status = err.response.statusCode;\n return status === 429 || (status >= 500 && status < 600);\n }\n\n return false;\n}\n\nfunction isHostError(err: HttpError): boolean {\n return err.code === 'ETIMEDOUT';\n}\n\nfunction isNotFoundError(err: HttpError): boolean {\n return err.code === 'ENOTFOUND' || err.response?.statusCode === 404;\n}\n\nfunction isPermissionsIssue(err: HttpError): boolean {\n const status = err.response?.statusCode;\n return status === 401 || status === 403;\n}\n\nfunction isConnectionError(err: HttpError): boolean {\n return (\n err.code === 'EAI_AGAIN' ||\n err.code === 'ERR_TLS_CERT_ALTNAME_INVALID' ||\n err.code === 'ECONNREFUSED'\n );\n}\n\nfunction isUnsupportedHostError(err: HttpError): boolean {\n return err.name === 'UnsupportedProtocolError';\n}\n\nconst cacheProvider = new PackageHttpCacheProvider({\n namespace: 'datasource-maven:cache-provider',\n softTtlMinutes: 15,\n checkAuthorizationHeader: true,\n checkCacheControlHeader: false, // Maven doesn't respond with `cache-control` headers\n writeSchema: CachedMavenXml,\n});\n\nexport async function downloadHttpProtocol(\n http: Http,\n pkgUrl: URL | string,\n opts: HttpOptions = {},\n): Promise<MavenFetchResult> {\n const url = pkgUrl.toString();\n const fetchResult = await Result.wrap<HttpResponse, Error>(\n http.getText(url, { ...opts, cacheProvider }),\n )\n .transform((res): MavenFetchSuccess => {\n const result: MavenFetchSuccess = { data: res.body };\n\n if (!res.authorization) {\n result.isCacheable = true;\n }\n\n const lastModified = asTimestamp(res?.headers?.['last-modified']);\n if (lastModified) {\n result.lastModified = lastModified;\n }\n\n return result;\n })\n .catch((err): MavenFetchResult => {\n /* v8 ignore next: never happens, needs for type narrowing */\n if (!(err instanceof HttpError)) {\n return Result.err({ type: 'unknown', err });\n }\n\n const failedUrl = url;\n if (err.message === HOST_DISABLED) {\n logger.trace({ failedUrl }, 'Host disabled');\n return Result.err({ type: 'host-disabled' });\n }\n\n if (isNotFoundError(err)) {\n logger.trace({ failedUrl }, `Url not found`);\n return Result.err({ type: 'not-found' });\n }\n\n if (isHostError(err)) {\n logger.debug(`Cannot connect to host ${failedUrl}`);\n return Result.err({ type: 'host-error' });\n }\n\n if (isPermissionsIssue(err)) {\n logger.debug(\n `Dependency lookup unauthorized. Please add authentication with a hostRule for ${failedUrl}`,\n );\n return Result.err({ type: 'permission-issue' });\n }\n\n if (isTemporaryError(err)) {\n logger.debug({ failedUrl, err }, 'Temporary error');\n if (getHost(url) === getHost(MAVEN_REPO)) {\n const statusCode = err?.response?.statusCode;\n if (statusCode === 429) {\n if (getCacheType() === 'redis') {\n logger.once.warn(\n { failedUrl },\n 'Maven Central rate limiting detected despite Redis caching.',\n );\n } else {\n logger.once.warn(\n { failedUrl },\n 'Maven Central rate limiting detected. Persistent caching required.',\n );\n }\n }\n return Result.err({ type: 'maven-central-temporary-error', err });\n } else {\n return Result.err({ type: 'temporary-error' });\n }\n }\n\n if (isConnectionError(err)) {\n logger.debug(`Connection refused to maven registry ${failedUrl}`);\n return Result.err({ type: 'connection-error' });\n }\n\n if (isUnsupportedHostError(err)) {\n logger.debug(`Unsupported host ${failedUrl}`);\n return Result.err({ type: 'unsupported-host' });\n }\n\n logger.info({ failedUrl, err }, 'Unknown HTTP download error');\n return Result.err({ type: 'unknown', err });\n });\n\n const { err } = fetchResult.unwrap();\n if (err?.type === 'maven-central-temporary-error') {\n throw new ExternalHostError(err.err);\n }\n\n return fetchResult;\n}\n\nexport async function downloadHttpContent(\n http: Http,\n pkgUrl: URL | string,\n opts: HttpOptions = {},\n): Promise<string | null> {\n const fetchResult = await downloadHttpProtocol(http, pkgUrl, opts);\n return fetchResult.transform(({ data }) => data).unwrapOrNull();\n}\n\nfunction isS3NotFound(err: Error): boolean {\n return err.message === 'NotFound' || err.message === 'NoSuchKey';\n}\n\nexport async function downloadS3Protocol(\n pkgUrl: URL,\n): Promise<MavenFetchResult> {\n logger.trace({ url: pkgUrl.toString() }, `Attempting to load S3 dependency`);\n\n const s3Url = parseS3Url(pkgUrl);\n if (!s3Url) {\n return Result.err({ type: 'invalid-url' });\n }\n\n return await Result.wrap(() => {\n const command = new GetObjectCommand(s3Url);\n const client = getS3Client();\n return client.send(command);\n })\n .transform(\n async ({\n Body,\n LastModified,\n DeleteMarker,\n }): Promise<MavenFetchResult> => {\n if (DeleteMarker) {\n logger.trace(\n { failedUrl: pkgUrl.toString() },\n 'Maven S3 lookup error: DeleteMarker encountered',\n );\n return Result.err({ type: 'not-found' });\n }\n\n if (!(Body instanceof Readable)) {\n logger.debug(\n { failedUrl: pkgUrl.toString() },\n 'Maven S3 lookup error: unsupported Body type',\n );\n return Result.err({ type: 'unsupported-format' });\n }\n\n const data = await streamToString(Body);\n const result: MavenFetchSuccess = { data };\n\n const lastModified = asTimestamp(LastModified);\n if (lastModified) {\n result.lastModified = lastModified;\n }\n\n return Result.ok(result);\n },\n )\n .catch((err): MavenFetchResult => {\n if (!(err instanceof Error)) {\n return Result.err(err);\n }\n\n const failedUrl = pkgUrl.toString();\n\n if (err.name === 'CredentialsProviderError') {\n logger.debug(\n { failedUrl },\n 'Maven S3 lookup error: credentials provider error, check \"AWS_ACCESS_KEY_ID\" and \"AWS_SECRET_ACCESS_KEY\" variables',\n );\n return Result.err({ type: 'credentials-error' });\n }\n\n if (err.message === 'Region is missing') {\n logger.debug(\n { failedUrl },\n 'Maven S3 lookup error: missing region, check \"AWS_REGION\" variable',\n );\n return Result.err({ type: 'missing-aws-region' });\n }\n\n if (isS3NotFound(err)) {\n logger.trace({ failedUrl }, 'Maven S3 lookup error: object not found');\n return Result.err({ type: 'not-found' });\n }\n\n logger.debug({ failedUrl, err }, 'Maven S3 lookup error: unknown error');\n return Result.err({ type: 'unknown', err });\n });\n}\n\nexport async function downloadArtifactRegistryProtocol(\n http: Http,\n pkgUrl: URL,\n): Promise<MavenFetchResult> {\n const opts: HttpOptions = {};\n const host = pkgUrl.host;\n const path = pkgUrl.pathname;\n\n logger.trace({ host, path }, `Using google auth for Maven repository`);\n const auth = await getGoogleAuthToken();\n if (auth) {\n opts.headers = { authorization: `Basic ${auth}` };\n } else {\n logger.once.debug(\n { host, path },\n 'Could not get Google access token, using no auth',\n );\n }\n\n const url = pkgUrl.toString().replace('artifactregistry:', 'https:');\n\n return downloadHttpProtocol(http, url, opts);\n}\n\nfunction containsPlaceholder(str: string): boolean {\n return regEx(/\\${.*?}/g).test(str);\n}\n\nfunction removeKnownPlaceholders(str: string): string {\n return str.replace(regEx(/\\/tree\\/\\${[^}]+}/), '');\n}\n\nexport function getMavenUrl(\n dependency: MavenDependency,\n repoUrl: string,\n path: string,\n): URL {\n return new URL(\n `${dependency.dependencyUrl}/${path}`,\n ensureTrailingSlash(repoUrl),\n );\n}\n\nexport async function downloadMaven(\n http: Http,\n url: URL,\n): Promise<MavenFetchResult> {\n const protocol = url.protocol;\n\n let result: MavenFetchResult = Result.err({ type: 'unsupported-protocol' });\n\n if (isHttpUrl(url)) {\n result = await downloadHttpProtocol(http, url);\n }\n\n if (protocol === 'artifactregistry:') {\n result = await downloadArtifactRegistryProtocol(http, url);\n }\n\n if (protocol === 's3:') {\n result = await downloadS3Protocol(url);\n }\n\n return result.onError((err) => {\n if (err.type === 'unsupported-protocol') {\n logger.debug(\n { url: url.toString() },\n `Maven lookup error: unsupported protocol (${protocol})`,\n );\n }\n });\n}\n\nexport async function downloadMavenXml(\n http: Http,\n url: URL,\n): Promise<MavenFetchResult<XmlDocument>> {\n const rawResult = await downloadMaven(http, url);\n return rawResult.transform((result): MavenFetchResult<XmlDocument> => {\n try {\n return Result.ok({\n ...result,\n data: new XmlDocument(result.data),\n });\n } catch (err) {\n return Result.err({ type: 'xml-parse-error', err });\n }\n });\n}\n\nexport function getDependencyParts(packageName: string): MavenDependency {\n const [group, name] = packageName.split(':');\n const dependencyUrl = `${group.replace(regEx(/\\./g), '/')}/${name}`;\n return {\n display: packageName,\n group,\n name,\n dependencyUrl,\n };\n}\n\nfunction extractSnapshotVersion(metadata: XmlDocument): string | null {\n // Parse the maven-metadata.xml for the snapshot version and determine\n // the fixed version of the latest deployed snapshot.\n // The metadata descriptor can be found at\n // https://maven.apache.org/ref/3.3.3/maven-repository-metadata/repository-metadata.html\n //\n // Basically, we need to replace -SNAPSHOT with the artifact timestanp & build number,\n // so for example 1.0.0-SNAPSHOT will become 1.0.0-<timestamp>-<buildNumber>\n const version = metadata\n .descendantWithPath('version')\n ?.val?.replace('-SNAPSHOT', '');\n\n const snapshot = metadata.descendantWithPath('versioning.snapshot');\n const timestamp = snapshot?.childNamed('timestamp')?.val;\n const build = snapshot?.childNamed('buildNumber')?.val;\n\n // If we weren't able to parse out the required 3 version elements,\n // return null because we can't determine the fixed version of the latest snapshot.\n if (!version || !timestamp || !build) {\n return null;\n }\n return `${version}-${timestamp}-${build}`;\n}\n\nasync function getSnapshotFullVersion(\n http: Http,\n version: string,\n dependency: MavenDependency,\n repoUrl: string,\n): Promise<string | null> {\n // To determine what actual files are available for the snapshot, first we have to fetch and parse\n // the metadata located at http://<repo>/<group>/<artifact>/<version-SNAPSHOT>/maven-metadata.xml\n const metadataUrl = getMavenUrl(\n dependency,\n repoUrl,\n `${version}/maven-metadata.xml`,\n );\n\n const metadataXmlResult = await downloadMavenXml(http, metadataUrl);\n\n return metadataXmlResult\n .transform(({ data }) =>\n Result.wrapNullable(extractSnapshotVersion(data), {\n type: 'snapshot-extract-error',\n }),\n )\n .unwrapOrNull();\n}\n\nfunction isSnapshotVersion(version: string): boolean {\n if (version.endsWith('-SNAPSHOT')) {\n return true;\n }\n return false;\n}\n\nexport async function createUrlForDependencyPom(\n http: Http,\n version: string,\n dependency: MavenDependency,\n repoUrl: string,\n): Promise<string> {\n if (isSnapshotVersion(version)) {\n // By default, Maven snapshots are deployed to the repository with fixed file names.\n // Resolve the full, actual pom file name for the version.\n const fullVersion = await getSnapshotFullVersion(\n http,\n version,\n dependency,\n repoUrl,\n );\n\n // If we were able to resolve the version, use that, otherwise fall back to using -SNAPSHOT\n if (fullVersion !== null) {\n // TODO: types (#22198)\n return `${version}/${dependency.name}-${fullVersion}.pom`;\n }\n }\n\n // TODO: types (#22198)\n return `${version}/${dependency.name}-${version}.pom`;\n}\n\nexport async function getDependencyInfo(\n http: Http,\n dependency: MavenDependency,\n repoUrl: string,\n version: string,\n recursionLimit = 5,\n): Promise<DependencyInfo> {\n const path = await createUrlForDependencyPom(\n http,\n version,\n dependency,\n repoUrl,\n );\n\n const pomUrl = getMavenUrl(dependency, repoUrl, path);\n const pomXmlResult = await downloadMavenXml(http, pomUrl);\n const dependencyInfoResult = await pomXmlResult.transform(\n async ({ data: pomContent }) => {\n const result: DependencyInfo = {};\n\n const homepage = pomContent.valueWithPath('url');\n if (homepage && !containsPlaceholder(homepage)) {\n result.homepage = homepage;\n }\n\n const sourceUrl = pomContent.valueWithPath('scm.url');\n if (\n sourceUrl &&\n !containsPlaceholder(removeKnownPlaceholders(sourceUrl))\n ) {\n result.sourceUrl = sourceUrl\n .replace(regEx(/^scm:/), '')\n .replace(regEx(/^git:/), '')\n .replace(regEx(/^git@github.com:/), 'https://github.com/')\n .replace(regEx(/^git@github.com\\//), 'https://github.com/');\n\n if (result.sourceUrl.startsWith('//')) {\n // most likely the result of us stripping scm:, git: etc\n // going with prepending https: here which should result in potential information retrival\n result.sourceUrl = `https:${result.sourceUrl}`;\n }\n }\n\n const relocation = pomContent.descendantWithPath(\n 'distributionManagement.relocation',\n );\n if (relocation) {\n const relocationGroup =\n relocation.valueWithPath('groupId') ?? dependency.group;\n const relocationName =\n relocation.valueWithPath('artifactId') ?? dependency.name;\n result.replacementName = `${relocationGroup}:${relocationName}`;\n const relocationVersion = relocation.valueWithPath('version');\n result.replacementVersion = relocationVersion ?? version;\n const relocationMessage = relocation.valueWithPath('message');\n if (relocationMessage) {\n result.deprecationMessage = relocationMessage;\n }\n }\n\n const groupId = pomContent.valueWithPath('groupId');\n if (groupId) {\n result.packageScope = groupId;\n }\n\n const parent = pomContent.childNamed('parent');\n if (\n recursionLimit > 0 &&\n parent &&\n (!result.sourceUrl || !result.homepage)\n ) {\n // if we found a parent and are missing some information\n // trying to get the scm/homepage information from it\n const [parentGroupId, parentArtifactId, parentVersion] = [\n 'groupId',\n 'artifactId',\n 'version',\n ].map((k) => parent.valueWithPath(k)?.replace(/\\s+/g, ''));\n if (parentGroupId && parentArtifactId && parentVersion) {\n const parentDisplayId = `${parentGroupId}:${parentArtifactId}`;\n const parentDependency = getDependencyParts(parentDisplayId);\n const parentInformation = await getDependencyInfo(\n http,\n parentDependency,\n repoUrl,\n parentVersion,\n recursionLimit - 1,\n );\n if (!result.sourceUrl && parentInformation.sourceUrl) {\n result.sourceUrl = parentInformation.sourceUrl;\n }\n if (!result.homepage && parentInformation.homepage) {\n result.homepage = parentInformation.homepage;\n }\n }\n }\n\n return result;\n },\n );\n\n return dependencyInfoResult.unwrapOr({});\n}\n"],"mappings":"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"}
|
|
@@ -14,7 +14,7 @@ declare const GithubVulnerabilityAlerts: z.ZodEffects<z.ZodEffects<z.ZodArray<z.
|
|
|
14
14
|
};
|
|
15
15
|
security_vulnerability: {
|
|
16
16
|
package: {
|
|
17
|
-
ecosystem: "
|
|
17
|
+
ecosystem: "composer" | "maven" | "npm" | "nuget" | "actions" | "go" | "pip" | "rubygems" | "rust";
|
|
18
18
|
name: string;
|
|
19
19
|
};
|
|
20
20
|
vulnerable_version_range: string;
|
|
@@ -39,7 +39,7 @@ declare const GithubVulnerabilityAlerts: z.ZodEffects<z.ZodEffects<z.ZodArray<z.
|
|
|
39
39
|
};
|
|
40
40
|
security_vulnerability: {
|
|
41
41
|
package: {
|
|
42
|
-
ecosystem: "
|
|
42
|
+
ecosystem: "composer" | "maven" | "npm" | "nuget" | "actions" | "go" | "pip" | "rubygems" | "rust";
|
|
43
43
|
name: string;
|
|
44
44
|
};
|
|
45
45
|
vulnerable_version_range: string;
|
|
@@ -21,6 +21,7 @@ async function decompress(input) {
|
|
|
21
21
|
return JSON.parse(jsonStr);
|
|
22
22
|
}
|
|
23
23
|
var PackageCacheSqlite = class PackageCacheSqlite extends PackageCacheBase {
|
|
24
|
+
static busyTimeoutMs = 100;
|
|
24
25
|
static async create(cacheDir) {
|
|
25
26
|
const Sqlite = await sqlite();
|
|
26
27
|
const sqliteDir = upath.join(cacheDir, "renovate/renovate-cache-sqlite");
|
|
@@ -40,6 +41,7 @@ var PackageCacheSqlite = class PackageCacheSqlite extends PackageCacheBase {
|
|
|
40
41
|
this.client = client;
|
|
41
42
|
client.pragma("journal_mode = WAL");
|
|
42
43
|
client.pragma("encoding = 'UTF-8'");
|
|
44
|
+
client.pragma(`busy_timeout = ${PackageCacheSqlite.busyTimeoutMs}`);
|
|
43
45
|
client.prepare(`
|
|
44
46
|
CREATE TABLE IF NOT EXISTS package_cache (
|
|
45
47
|
namespace TEXT NOT NULL,
|
|
@@ -69,30 +71,53 @@ var PackageCacheSqlite = class PackageCacheSqlite extends PackageCacheBase {
|
|
|
69
71
|
this.countStatement = client.prepare("SELECT COUNT(*) FROM package_cache").pluck(true);
|
|
70
72
|
}
|
|
71
73
|
async set(namespace, key, value, hardTtlMinutes) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
74
|
+
try {
|
|
75
|
+
const compressedData = await compress(value);
|
|
76
|
+
const ttlSeconds = hardTtlMinutes * 60;
|
|
77
|
+
this.upsertStatement.run({
|
|
78
|
+
namespace,
|
|
79
|
+
key,
|
|
80
|
+
data: compressedData,
|
|
81
|
+
ttlSeconds
|
|
82
|
+
});
|
|
83
|
+
} catch (err) {
|
|
84
|
+
logger.once.warn({ err }, "Error while setting SQLite cache value");
|
|
85
|
+
}
|
|
80
86
|
}
|
|
81
87
|
async get(namespace, key) {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
+
try {
|
|
89
|
+
const data = this.getStatement.get({
|
|
90
|
+
namespace,
|
|
91
|
+
key
|
|
92
|
+
});
|
|
93
|
+
if (!data) {
|
|
94
|
+
logger.trace({
|
|
95
|
+
namespace,
|
|
96
|
+
key
|
|
97
|
+
}, "Cache miss");
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
return await decompress(data);
|
|
101
|
+
} catch (err) {
|
|
102
|
+
logger.once.warn({ err }, "Error while reading SQLite cache value");
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
88
105
|
}
|
|
89
106
|
destroy() {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
107
|
+
try {
|
|
108
|
+
const startTime = Date.now();
|
|
109
|
+
const totalCount = this.countStatement.get();
|
|
110
|
+
const { changes: deletedCount } = this.deleteExpiredRows.run();
|
|
111
|
+
const durationMs = Date.now() - startTime;
|
|
112
|
+
logger.debug(`SQLite package cache: deleted ${deletedCount} of ${totalCount} entries in ${durationMs}ms`);
|
|
113
|
+
} catch (err) {
|
|
114
|
+
logger.warn({ err }, "SQLite package cache cleanup failed");
|
|
115
|
+
}
|
|
116
|
+
try {
|
|
117
|
+
this.client.close();
|
|
118
|
+
} catch (err) {
|
|
119
|
+
logger.warn({ err }, "SQLite package cache close failed");
|
|
120
|
+
}
|
|
96
121
|
return Promise.resolve();
|
|
97
122
|
}
|
|
98
123
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite.js","names":[],"sources":["../../../../../lib/util/cache/package/impl/sqlite.ts"],"sourcesContent":["import { promisify } from 'node:util';\nimport zlib, { constants } from 'node:zlib';\nimport type { Database, Statement } from 'better-sqlite3';\nimport fs from 'fs-extra';\nimport upath from 'upath';\nimport { sqlite } from '../../../../expose.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport { ensureDir } from '../../../fs/index.ts';\nimport type { PackageCacheNamespace } from '../types.ts';\nimport { PackageCacheBase } from './base.ts';\n\nconst { exists } = fs;\nconst brotliCompress = promisify(zlib.brotliCompress);\nconst brotliDecompress = promisify(zlib.brotliDecompress);\n\nfunction compress(input: unknown): Promise<Buffer> {\n const jsonStr = JSON.stringify(input);\n return brotliCompress(jsonStr, {\n params: {\n [constants.BROTLI_PARAM_MODE]: constants.BROTLI_MODE_TEXT,\n [constants.BROTLI_PARAM_QUALITY]: 3,\n },\n });\n}\n\nasync function decompress<T>(input: Buffer): Promise<T> {\n const buf = await brotliDecompress(input);\n const jsonStr = buf.toString('utf8');\n return JSON.parse(jsonStr) as T;\n}\n\nexport class PackageCacheSqlite extends PackageCacheBase {\n static async create(cacheDir: string): Promise<PackageCacheSqlite> {\n const Sqlite = await sqlite();\n const sqliteDir = upath.join(cacheDir, 'renovate/renovate-cache-sqlite');\n await ensureDir(sqliteDir);\n const sqliteFile = upath.join(sqliteDir, 'db.sqlite');\n\n if (await exists(sqliteFile)) {\n logger.debug(`Using SQLite package cache: ${sqliteFile}`);\n } else {\n logger.debug(`Creating SQLite package cache: ${sqliteFile}`);\n }\n\n const client = new Sqlite(sqliteFile);\n return new PackageCacheSqlite(client);\n }\n\n private readonly upsertStatement: Statement<unknown[]>;\n private readonly getStatement: Statement<unknown[]>;\n private readonly deleteExpiredRows: Statement<unknown[]>;\n private readonly countStatement: Statement<unknown[]>;\n\n
|
|
1
|
+
{"version":3,"file":"sqlite.js","names":[],"sources":["../../../../../lib/util/cache/package/impl/sqlite.ts"],"sourcesContent":["import { promisify } from 'node:util';\nimport zlib, { constants } from 'node:zlib';\nimport type { Database, Statement } from 'better-sqlite3';\nimport fs from 'fs-extra';\nimport upath from 'upath';\nimport { sqlite } from '../../../../expose.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport { ensureDir } from '../../../fs/index.ts';\nimport type { PackageCacheNamespace } from '../types.ts';\nimport { PackageCacheBase } from './base.ts';\n\nconst { exists } = fs;\nconst brotliCompress = promisify(zlib.brotliCompress);\nconst brotliDecompress = promisify(zlib.brotliDecompress);\n\nfunction compress(input: unknown): Promise<Buffer> {\n const jsonStr = JSON.stringify(input);\n return brotliCompress(jsonStr, {\n params: {\n [constants.BROTLI_PARAM_MODE]: constants.BROTLI_MODE_TEXT,\n [constants.BROTLI_PARAM_QUALITY]: 3,\n },\n });\n}\n\nasync function decompress<T>(input: Buffer): Promise<T> {\n const buf = await brotliDecompress(input);\n const jsonStr = buf.toString('utf8');\n return JSON.parse(jsonStr) as T;\n}\n\nexport class PackageCacheSqlite extends PackageCacheBase {\n private static readonly busyTimeoutMs = 100;\n\n static async create(cacheDir: string): Promise<PackageCacheSqlite> {\n const Sqlite = await sqlite();\n const sqliteDir = upath.join(cacheDir, 'renovate/renovate-cache-sqlite');\n await ensureDir(sqliteDir);\n const sqliteFile = upath.join(sqliteDir, 'db.sqlite');\n\n if (await exists(sqliteFile)) {\n logger.debug(`Using SQLite package cache: ${sqliteFile}`);\n } else {\n logger.debug(`Creating SQLite package cache: ${sqliteFile}`);\n }\n\n const client = new Sqlite(sqliteFile);\n return new PackageCacheSqlite(client);\n }\n\n private readonly upsertStatement: Statement<unknown[]>;\n private readonly getStatement: Statement<unknown[]>;\n private readonly deleteExpiredRows: Statement<unknown[]>;\n private readonly countStatement: Statement<unknown[]>;\n\n readonly client: Database;\n\n private constructor(client: Database) {\n super();\n this.client = client;\n\n client.pragma('journal_mode = WAL');\n client.pragma(\"encoding = 'UTF-8'\");\n client.pragma(`busy_timeout = ${PackageCacheSqlite.busyTimeoutMs}`);\n\n client\n .prepare(\n `\n CREATE TABLE IF NOT EXISTS package_cache (\n namespace TEXT NOT NULL,\n key TEXT NOT NULL,\n expiry INTEGER NOT NULL,\n data BLOB NOT NULL,\n PRIMARY KEY (namespace, key)\n )\n `,\n )\n .run();\n client\n .prepare('CREATE INDEX IF NOT EXISTS expiry ON package_cache (expiry)')\n .run();\n\n this.upsertStatement = client.prepare(`\n INSERT INTO package_cache (namespace, key, data, expiry)\n VALUES (@namespace, @key, @data, unixepoch() + @ttlSeconds)\n ON CONFLICT (namespace, key) DO UPDATE SET\n data = @data,\n expiry = unixepoch() + @ttlSeconds\n `);\n\n this.getStatement = client\n .prepare(\n `\n SELECT data FROM package_cache\n WHERE\n namespace = @namespace AND key = @key AND expiry > unixepoch()\n `,\n )\n .pluck(true);\n\n this.deleteExpiredRows = client.prepare(`\n DELETE FROM package_cache\n WHERE expiry <= unixepoch()\n `);\n\n this.countStatement = client\n .prepare('SELECT COUNT(*) FROM package_cache')\n .pluck(true);\n }\n\n override async set(\n namespace: PackageCacheNamespace,\n key: string,\n value: unknown,\n hardTtlMinutes: number,\n ): Promise<void> {\n try {\n const compressedData = await compress(value);\n const ttlSeconds = hardTtlMinutes * 60;\n this.upsertStatement.run({\n namespace,\n key,\n data: compressedData,\n ttlSeconds,\n });\n } catch (err) {\n logger.once.warn({ err }, 'Error while setting SQLite cache value');\n }\n }\n\n override async get<T = unknown>(\n namespace: PackageCacheNamespace,\n key: string,\n ): Promise<T | undefined> {\n try {\n const data = this.getStatement.get({ namespace, key }) as\n | Buffer\n | undefined;\n\n if (!data) {\n logger.trace({ namespace, key }, 'Cache miss');\n return undefined;\n }\n\n return await decompress<T>(data);\n } catch (err) {\n logger.once.warn({ err }, 'Error while reading SQLite cache value');\n return undefined;\n }\n }\n\n override destroy(): Promise<void> {\n try {\n const startTime = Date.now();\n const totalCount = this.countStatement.get() as number;\n const { changes: deletedCount } = this.deleteExpiredRows.run();\n const durationMs = Date.now() - startTime;\n logger.debug(\n `SQLite package cache: deleted ${deletedCount} of ${totalCount} entries in ${durationMs}ms`,\n );\n } catch (err) {\n logger.warn({ err }, 'SQLite package cache cleanup failed');\n }\n\n try {\n this.client.close();\n } catch (err) {\n logger.warn({ err }, 'SQLite package cache close failed');\n }\n\n return Promise.resolve();\n }\n}\n"],"mappings":";;;;;;;;;AAWA,MAAM,EAAE,WAAW;AACnB,MAAM,iBAAiB,UAAU,KAAK,eAAe;AACrD,MAAM,mBAAmB,UAAU,KAAK,iBAAiB;AAEzD,SAAS,SAAS,OAAiC;AAEjD,QAAO,eADS,KAAK,UAAU,MAAM,EACN,EAC7B,QAAQ;GACL,UAAU,oBAAoB,UAAU;GACxC,UAAU,uBAAuB;EACnC,EACF,CAAC;;AAGJ,eAAe,WAAc,OAA2B;CAEtD,MAAM,WADM,MAAM,iBAAiB,MAAM,EACrB,SAAS,OAAO;AACpC,QAAO,KAAK,MAAM,QAAQ;;AAG5B,IAAa,qBAAb,MAAa,2BAA2B,iBAAiB;CACvD,OAAwB,gBAAgB;CAExC,aAAa,OAAO,UAA+C;EACjE,MAAM,SAAS,MAAM,QAAQ;EAC7B,MAAM,YAAY,MAAM,KAAK,UAAU,iCAAiC;AACxE,QAAM,UAAU,UAAU;EAC1B,MAAM,aAAa,MAAM,KAAK,WAAW,YAAY;AAErD,MAAI,MAAM,OAAO,WAAW,CAC1B,QAAO,MAAM,+BAA+B,aAAa;MAEzD,QAAO,MAAM,kCAAkC,aAAa;AAI9D,SAAO,IAAI,mBADI,IAAI,OAAO,WAAW,CACA;;CAGvC;CACA;CACA;CACA;CAEA;CAEA,YAAoB,QAAkB;AACpC,SAAO;AACP,OAAK,SAAS;AAEd,SAAO,OAAO,qBAAqB;AACnC,SAAO,OAAO,qBAAqB;AACnC,SAAO,OAAO,kBAAkB,mBAAmB,gBAAgB;AAEnE,SACG,QACC;;;;;;;;UASD,CACA,KAAK;AACR,SACG,QAAQ,8DAA8D,CACtE,KAAK;AAER,OAAK,kBAAkB,OAAO,QAAQ;;;;;;MAMpC;AAEF,OAAK,eAAe,OACjB,QACC;;;;UAKD,CACA,MAAM,KAAK;AAEd,OAAK,oBAAoB,OAAO,QAAQ;;;MAGtC;AAEF,OAAK,iBAAiB,OACnB,QAAQ,qCAAqC,CAC7C,MAAM,KAAK;;CAGhB,MAAe,IACb,WACA,KACA,OACA,gBACe;AACf,MAAI;GACF,MAAM,iBAAiB,MAAM,SAAS,MAAM;GAC5C,MAAM,aAAa,iBAAiB;AACpC,QAAK,gBAAgB,IAAI;IACvB;IACA;IACA,MAAM;IACN;IACD,CAAC;WACK,KAAK;AACZ,UAAO,KAAK,KAAK,EAAE,KAAK,EAAE,yCAAyC;;;CAIvE,MAAe,IACb,WACA,KACwB;AACxB,MAAI;GACF,MAAM,OAAO,KAAK,aAAa,IAAI;IAAE;IAAW;IAAK,CAAC;AAItD,OAAI,CAAC,MAAM;AACT,WAAO,MAAM;KAAE;KAAW;KAAK,EAAE,aAAa;AAC9C;;AAGF,UAAO,MAAM,WAAc,KAAK;WACzB,KAAK;AACZ,UAAO,KAAK,KAAK,EAAE,KAAK,EAAE,yCAAyC;AACnE;;;CAIJ,UAAkC;AAChC,MAAI;GACF,MAAM,YAAY,KAAK,KAAK;GAC5B,MAAM,aAAa,KAAK,eAAe,KAAK;GAC5C,MAAM,EAAE,SAAS,iBAAiB,KAAK,kBAAkB,KAAK;GAC9D,MAAM,aAAa,KAAK,KAAK,GAAG;AAChC,UAAO,MACL,iCAAiC,aAAa,MAAM,WAAW,cAAc,WAAW,IACzF;WACM,KAAK;AACZ,UAAO,KAAK,EAAE,KAAK,EAAE,sCAAsC;;AAG7D,MAAI;AACF,QAAK,OAAO,OAAO;WACZ,KAAK;AACZ,UAAO,KAAK,EAAE,KAAK,EAAE,oCAAoC;;AAG3D,SAAO,QAAQ,SAAS"}
|
|
@@ -247,7 +247,7 @@ async function ensureDependencyDashboard(config, allBranches, packageFiles = {},
|
|
|
247
247
|
if (hasDeprecationsOrReplacements) {
|
|
248
248
|
issueBody += "## Deprecations / Replacements\n";
|
|
249
249
|
issueBody += emojify("> :warning: **Warning**\n> \n");
|
|
250
|
-
issueBody += "
|
|
250
|
+
issueBody += "The following dependencies are either deprecated or have replacements available.\n\n";
|
|
251
251
|
issueBody += "| Datasource | Package | Replacement PR? |\n";
|
|
252
252
|
issueBody += "|------------|------|--------------|\n";
|
|
253
253
|
for (const manager of Object.keys(deprecatedPackages).sort()) {
|
|
@@ -335,12 +335,13 @@ function getAbandonedPackagesMd(packageFiles) {
|
|
|
335
335
|
};
|
|
336
336
|
}
|
|
337
337
|
if (abandonedCount === 0) return "";
|
|
338
|
-
let abandonedMd =
|
|
339
|
-
abandonedMd += "
|
|
340
|
-
abandonedMd += "Unlike deprecated packages with official notices, abandonment is detected by release inactivity.\n> \n";
|
|
341
|
-
abandonedMd += "> These dependencies have not received updates for an extended period and may be unmaintained:\n\n";
|
|
338
|
+
let abandonedMd = "## Abandoned Dependencies\n\n";
|
|
339
|
+
abandonedMd += "The following dependencies have not received updates for an extended period and may be unmaintained.\n\n";
|
|
342
340
|
abandonedMd += "<details>\n";
|
|
343
341
|
abandonedMd += `<summary>View abandoned dependencies (${abandonedCount})</summary>\n\n`;
|
|
342
|
+
abandonedMd += emojify("> :information_source: **Note**\n> \n");
|
|
343
|
+
abandonedMd += "Packages are marked as abandoned when they exceed the [`abandonmentThreshold`](https://docs.renovatebot.com/configuration-options/#abandonmentthreshold) since their last release. ";
|
|
344
|
+
abandonedMd += "Unlike deprecated packages with official notices, abandonment is detected by release inactivity.\n> \n";
|
|
344
345
|
abandonedMd += "| Datasource | Package | Last Updated |\n";
|
|
345
346
|
abandonedMd += "|------------|------|-------------|\n";
|
|
346
347
|
for (const manager of Object.keys(abandonedPackages).sort()) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dependency-dashboard.js","names":["template.compile"],"sources":["../../../lib/workers/repository/dependency-dashboard.ts"],"sourcesContent":["import {\n isNonEmptyArray,\n isNonEmptyObject,\n isNonEmptyString,\n isNullOrUndefined,\n isTruthy,\n} from '@sindresorhus/is';\nimport { DateTime } from 'luxon';\nimport { GlobalConfig } from '../../config/global.ts';\nimport type { RenovateConfig } from '../../config/types.ts';\nimport { logger } from '../../logger/index.ts';\nimport type { PackageFile } from '../../modules/manager/types.ts';\nimport { platform } from '../../modules/platform/index.ts';\nimport { coerceArray } from '../../util/array.ts';\nimport { emojify } from '../../util/emoji.ts';\nimport { regEx } from '../../util/regex.ts';\nimport { coerceString } from '../../util/string.ts';\nimport * as template from '../../util/template/index.ts';\nimport type { BranchConfig, SelectAllConfig } from '../types.ts';\nimport { extractRepoProblems } from './common.ts';\nimport type { ConfigMigrationResult } from './config-migration/index.ts';\nimport { getDepWarningsDashboard } from './errors-warnings.ts';\nimport { PackageFiles } from './package-files.ts';\nimport type { Vulnerability } from './process/types.ts';\nimport { Vulnerabilities } from './process/vulnerabilities.ts';\n\ninterface DependencyDashboard {\n dependencyDashboardChecks: Record<string, string>;\n dependencyDashboardRebaseAllOpen: boolean;\n dependencyDashboardAllPending: boolean;\n dependencyDashboardAllRateLimited: boolean;\n dependencyDashboardAllAwaitingSchedule: boolean;\n}\n\nconst rateLimitedRe = regEx(\n ` - \\\\[ \\\\] ${getMarkdownComment('unlimit-branch=([^\\\\s]+)')}`,\n 'g',\n);\nconst pendingApprovalRe = regEx(\n ` - \\\\[ \\\\] ${getMarkdownComment('approve-branch=([^\\\\s]+)')}`,\n 'g',\n);\nconst awaitingScheduleRe = regEx(\n ` - \\\\[ \\\\] ${getMarkdownComment('unschedule-branch=([^\\\\s]+)')}`,\n 'g',\n);\nconst generalBranchRe = regEx(\n ` ${getMarkdownComment('([a-zA-Z]+)-branch=([^\\\\s]+)')}`,\n);\nconst markedBranchesRe = regEx(\n ` - \\\\[x\\\\] ${getMarkdownComment('([a-zA-Z]+)-branch=([^\\\\s]+)')}`,\n 'g',\n);\n\nconst approveAllPendingPrs = 'approve-all-pending-prs';\nconst createAllRateLimitedPrs = 'create-all-rate-limited-prs';\nconst createAllAwaitingSchedulePrs = 'create-all-awaiting-schedule-prs';\nconst createConfigMigrationPr = 'create-config-migration-pr';\nconst configMigrationPrInfo = 'config-migration-pr-info';\nconst rebaseAllOpenPrs = 'rebase-all-open-prs';\n\nfunction getMarkdownComment(comment: string): string {\n return `<!-- ${comment} -->`;\n}\n\nfunction isBoxChecked(issueBody: string, type: string): boolean {\n return issueBody.includes(getCheckbox(type, true));\n}\n\nfunction isBoxUnchecked(issueBody: string, type: string): boolean {\n return issueBody.includes(getCheckbox(type));\n}\n\nfunction getCheckbox(type: string, checked = false): string {\n return ` - [${checked ? 'x' : ' '}] ${getMarkdownComment(type)}`;\n}\n\nfunction checkOpenAllRateLimitedPR(issueBody: string): boolean {\n return isBoxChecked(issueBody, createAllRateLimitedPrs);\n}\n\nfunction checkOpenAllAwaitingSchedulePR(issueBody: string): boolean {\n return isBoxChecked(issueBody, createAllAwaitingSchedulePrs);\n}\n\nfunction checkApproveAllPendingPR(issueBody: string): boolean {\n return isBoxChecked(issueBody, approveAllPendingPrs);\n}\n\nfunction checkRebaseAll(issueBody: string): boolean {\n return isBoxChecked(issueBody, rebaseAllOpenPrs);\n}\n\nfunction getConfigMigrationCheckboxState(\n issueBody: string,\n): 'no-checkbox' | 'checked' | 'unchecked' | 'migration-pr-exists' {\n if (issueBody.includes(getMarkdownComment(configMigrationPrInfo))) {\n return 'migration-pr-exists';\n }\n\n if (isBoxChecked(issueBody, createConfigMigrationPr)) {\n return 'checked';\n }\n\n if (isBoxUnchecked(issueBody, createConfigMigrationPr)) {\n return 'unchecked';\n }\n\n return 'no-checkbox';\n}\n\nfunction selectAllRelevantBranches(issueBody: string): string[] {\n const checkedBranches = [];\n if (checkOpenAllRateLimitedPR(issueBody)) {\n for (const match of issueBody.matchAll(rateLimitedRe)) {\n checkedBranches.push(match[0]);\n }\n }\n if (checkOpenAllAwaitingSchedulePR(issueBody)) {\n for (const match of issueBody.matchAll(awaitingScheduleRe)) {\n checkedBranches.push(match[0]);\n }\n }\n if (checkApproveAllPendingPR(issueBody)) {\n for (const match of issueBody.matchAll(pendingApprovalRe)) {\n checkedBranches.push(match[0]);\n }\n }\n return checkedBranches;\n}\n\nfunction getAllSelectedBranches(\n issueBody: string,\n dependencyDashboardChecks: Record<string, string>,\n): Record<string, string> {\n const allRelevantBranches = selectAllRelevantBranches(issueBody);\n for (const branch of allRelevantBranches) {\n const [, type, branchName] = generalBranchRe.exec(branch)!;\n dependencyDashboardChecks[branchName] = type;\n }\n return dependencyDashboardChecks;\n}\n\nfunction getCheckedBranches(issueBody: string): Record<string, string> {\n let dependencyDashboardChecks: Record<string, string> = {};\n for (const [, type, branchName] of issueBody.matchAll(markedBranchesRe)) {\n dependencyDashboardChecks[branchName] = type;\n }\n dependencyDashboardChecks = getAllSelectedBranches(\n issueBody,\n dependencyDashboardChecks,\n );\n return dependencyDashboardChecks;\n}\n\nfunction parseDashboardIssue(issueBody: string): DependencyDashboard {\n const dependencyDashboardChecks = getCheckedBranches(issueBody);\n const dependencyDashboardRebaseAllOpen = checkRebaseAll(issueBody);\n const dependencyDashboardAllAwaitingSchedule =\n checkOpenAllAwaitingSchedulePR(issueBody);\n const dependencyDashboardAllPending = checkApproveAllPendingPR(issueBody);\n const dependencyDashboardAllRateLimited =\n checkOpenAllRateLimitedPR(issueBody);\n dependencyDashboardChecks.configMigrationCheckboxState =\n getConfigMigrationCheckboxState(issueBody);\n return {\n dependencyDashboardChecks,\n dependencyDashboardRebaseAllOpen,\n dependencyDashboardAllAwaitingSchedule,\n dependencyDashboardAllPending,\n dependencyDashboardAllRateLimited,\n };\n}\n\nexport async function readDashboardBody(\n config: SelectAllConfig,\n): Promise<void> {\n let dashboardChecks: DependencyDashboard = {\n dependencyDashboardChecks: {},\n dependencyDashboardRebaseAllOpen: false,\n dependencyDashboardAllAwaitingSchedule: false,\n dependencyDashboardAllPending: false,\n dependencyDashboardAllRateLimited: false,\n };\n const stringifiedConfig = JSON.stringify(config);\n if (\n config.dependencyDashboard === true ||\n stringifiedConfig.includes('\"dependencyDashboardApproval\":true') ||\n stringifiedConfig.includes('\"prCreation\":\"approval\"')\n ) {\n config.dependencyDashboardTitle =\n config.dependencyDashboardTitle ?? `Dependency Dashboard`;\n const issue = await platform.findIssue(config.dependencyDashboardTitle);\n if (issue) {\n config.dependencyDashboardIssue = issue.number;\n dashboardChecks = parseDashboardIssue(issue.body ?? '');\n }\n }\n\n if (config.checkedBranches) {\n const checkedBranchesRec: Record<string, string> = Object.fromEntries(\n config.checkedBranches.map((branchName) => [branchName, 'global-config']),\n );\n dashboardChecks.dependencyDashboardChecks = {\n ...dashboardChecks.dependencyDashboardChecks,\n ...checkedBranchesRec,\n };\n }\n\n Object.assign(config, dashboardChecks);\n}\n\nfunction formatAsMarkdownLink(name: string, url?: string | null): string {\n return url ? `[${name}](${url})` : `\\`${name}\\``;\n}\n\nfunction getListItem(branch: BranchConfig, type: string): string {\n let item = getCheckbox(`${type}-branch=${branch.branchName}`);\n if (branch.prNo) {\n // TODO: types (#22198)\n item += `[${branch.prTitle!}](../pull/${branch.prNo})`;\n } else {\n item += branch.prTitle;\n }\n const uniquePackages = [\n // TODO: types (#22198)\n ...new Set(branch.upgrades.map((upgrade) => `\\`${upgrade.depName!}\\``)),\n ];\n if (uniquePackages.length < 2) {\n return item + '\\n';\n }\n return item + ' (' + uniquePackages.join(', ') + ')\\n';\n}\n\nfunction splitBranchesByCategory(filteredBranches: BranchConfig[]): {\n categories: Record<string, BranchConfig[]>;\n uncategorized: BranchConfig[];\n hasCategorized: boolean;\n hasUncategorized: boolean;\n} {\n const categories: Record<string, BranchConfig[]> = {};\n const uncategorized: BranchConfig[] = [];\n let hasCategorized = false;\n let hasUncategorized = false;\n for (const branch of filteredBranches) {\n if (branch.dependencyDashboardCategory) {\n categories[branch.dependencyDashboardCategory] ??= [];\n categories[branch.dependencyDashboardCategory].push(branch);\n hasCategorized = true;\n continue;\n }\n uncategorized.push(branch);\n hasUncategorized = true;\n }\n return { categories, uncategorized, hasCategorized, hasUncategorized };\n}\n\nfunction getBranchList(branches: BranchConfig[], listItemType: string): string {\n return branches\n .map((branch: BranchConfig): string => getListItem(branch, listItemType))\n .join('');\n}\n\nfunction getBranchesListMd(\n branches: BranchConfig[],\n predicate: (\n value: BranchConfig,\n index: number,\n array: BranchConfig[],\n ) => unknown,\n title: string,\n description: string,\n listItemType = 'approvePr',\n bulkComment?: string,\n bulkMessage?: string,\n bulkIcon?: '🔐',\n): string {\n const filteredBranches = branches.filter(predicate);\n if (filteredBranches.length === 0) {\n return '';\n }\n let result = `## ${title}\\n\\n${description}\\n\\n`;\n const { categories, uncategorized, hasCategorized, hasUncategorized } =\n splitBranchesByCategory(filteredBranches);\n if (hasCategorized) {\n for (const [category, branches] of Object.entries(categories).sort(\n ([keyA], [keyB]) =>\n keyA.localeCompare(keyB, undefined, { numeric: true }),\n )) {\n result = result.trimEnd() + '\\n\\n';\n result += `### ${category}\\n\\n`;\n result += getBranchList(branches, listItemType);\n }\n if (hasUncategorized) {\n result = result.trimEnd() + '\\n\\n';\n result += `### Others`;\n }\n }\n result = result.trimEnd() + '\\n\\n';\n result += getBranchList(uncategorized, listItemType);\n\n if (bulkComment && bulkMessage && filteredBranches.length > 1) {\n if (hasCategorized) {\n result = result.trimEnd() + '\\n\\n';\n result += '### All\\n\\n';\n }\n result += getCheckbox(bulkComment);\n result += `${bulkIcon ? bulkIcon + ' ' : ''}**${bulkMessage}**${bulkIcon ? ' ' + bulkIcon : ''}`;\n }\n return result.trimEnd() + '\\n\\n';\n}\n\nfunction appendRepoProblems(config: RenovateConfig, issueBody: string): string {\n let newIssueBody = issueBody;\n const repoProblems = extractRepoProblems(config.repository);\n if (repoProblems.size) {\n newIssueBody += '## Repository Problems\\n\\n';\n const repoProblemsHeader =\n config.customizeDashboard?.repoProblemsHeader ??\n 'Renovate tried to run on this repository, but found these problems.';\n newIssueBody += template.compile(repoProblemsHeader, config) + '\\n\\n';\n\n for (const repoProblem of repoProblems) {\n newIssueBody += ` - ${repoProblem}\\n`;\n }\n newIssueBody += '\\n';\n }\n return newIssueBody;\n}\n\nexport async function ensureDependencyDashboard(\n config: SelectAllConfig,\n allBranches: BranchConfig[],\n packageFiles: Record<string, PackageFile[]> = {},\n configMigrationRes: ConfigMigrationResult,\n): Promise<void> {\n logger.debug('ensureDependencyDashboard()');\n if (config.mode === 'silent') {\n logger.debug(\n 'Dependency Dashboard issue is not created, updated or closed when mode=silent',\n );\n return;\n }\n // legacy/migrated issue\n const reuseTitle = 'Update Dependencies (Renovate Bot)';\n const branches = allBranches.filter(\n (branch) =>\n branch.result !== 'automerged' &&\n !branch.upgrades?.every((upgrade) => upgrade.remediationNotPossible),\n );\n if (\n !(\n config.dependencyDashboard === true ||\n config.dependencyDashboardApproval === true ||\n config.packageRules?.some((rule) => rule.dependencyDashboardApproval) ===\n true ||\n branches.some(\n (branch) =>\n !!branch.dependencyDashboardApproval ||\n !!branch.dependencyDashboardPrApproval,\n )\n )\n ) {\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n { title: config.dependencyDashboardTitle },\n 'DRY-RUN: Would close Dependency Dashboard',\n );\n } else {\n logger.debug('Closing Dependency Dashboard');\n await platform.ensureIssueClosing(config.dependencyDashboardTitle!);\n }\n return;\n }\n // istanbul ignore if\n if (config.repoIsOnboarded === false) {\n logger.debug('Repo is onboarding - skipping dependency dashboard');\n return;\n }\n logger.debug('Ensuring Dependency Dashboard');\n\n // Check packageFiles for any deprecations or replacements\n let hasDeprecationsOrReplacements = false;\n const deprecatedPackages: Record<\n string,\n Record<string, { hasReplacement: boolean; sourceUrl?: string | null }>\n > = {};\n logger.debug('Checking packageFiles for deprecated or replacement packages');\n if (isNonEmptyObject(packageFiles)) {\n for (const [manager, fileNames] of Object.entries(packageFiles)) {\n for (const fileName of fileNames) {\n for (const dep of fileName.deps) {\n const name = dep.packageName ?? dep.depName;\n const hasReplacement = !!dep.updates?.find(\n (updates) => updates.updateType === 'replacement',\n );\n if (name && (dep.deprecationMessage ?? hasReplacement)) {\n hasDeprecationsOrReplacements = true;\n deprecatedPackages[manager] ??= {};\n deprecatedPackages[manager][name] ??= {\n hasReplacement,\n sourceUrl: dep.sourceUrl,\n };\n }\n }\n }\n }\n }\n\n const hasBranches = isNonEmptyArray(branches);\n if (\n config.dependencyDashboardAutoclose &&\n !hasBranches &&\n !hasDeprecationsOrReplacements\n ) {\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n { title: config.dependencyDashboardTitle },\n 'DRY-RUN: Would close Dependency Dashboard',\n );\n } else {\n logger.debug('Closing Dependency Dashboard');\n await platform.ensureIssueClosing(config.dependencyDashboardTitle!);\n }\n return;\n }\n let issueBody = '';\n\n if (config.dependencyDashboardHeader?.length) {\n issueBody +=\n template.compile(config.dependencyDashboardHeader, config) + '\\n\\n';\n }\n\n if (configMigrationRes.result === 'pr-exists') {\n issueBody +=\n '## Config Migration Needed\\n\\n' +\n getMarkdownComment(configMigrationPrInfo) +\n ` See Config Migration PR: #${configMigrationRes.prNumber}.\\n\\n`;\n } else if (configMigrationRes?.result === 'pr-modified') {\n issueBody +=\n '## Config Migration Needed (Blocked)\\n\\n' +\n getMarkdownComment(configMigrationPrInfo) +\n ` The Config Migration branch exists but has been modified by another user. Renovate will not push to this branch unless it is first deleted. \\n\\n See Config Migration PR: #${configMigrationRes.prNumber}.\\n\\n`;\n } else if (configMigrationRes?.result === 'add-checkbox') {\n issueBody +=\n '## Config Migration Needed\\n\\n' +\n getCheckbox(createConfigMigrationPr) +\n ' Select this checkbox to let Renovate create an automated Config Migration PR.' +\n '\\n\\n';\n }\n\n issueBody = appendRepoProblems(config, issueBody);\n\n if (hasDeprecationsOrReplacements) {\n issueBody += '## Deprecations / Replacements\\n';\n issueBody += emojify('> :warning: **Warning**\\n> \\n');\n issueBody +=\n 'These dependencies are either deprecated or have replacements available:\\n\\n';\n issueBody += '| Datasource | Package | Replacement PR? |\\n';\n issueBody += '|------------|------|--------------|\\n';\n for (const manager of Object.keys(deprecatedPackages).sort()) {\n const deps = deprecatedPackages[manager];\n for (const depName of Object.keys(deps).sort()) {\n const { hasReplacement, sourceUrl } = deps[depName];\n const packageName = formatAsMarkdownLink(depName, sourceUrl);\n\n issueBody += `| ${manager} | ${packageName} | ${\n hasReplacement\n ? ''\n : ''\n } |\\n`;\n }\n }\n issueBody += '\\n';\n }\n\n if (config.dependencyDashboardReportAbandonment) {\n issueBody += getAbandonedPackagesMd(packageFiles);\n }\n\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'needs-approval',\n 'Pending Approval',\n 'The following branches are pending approval. To create them, click on a checkbox below.',\n 'approve',\n approveAllPendingPrs,\n 'Create all pending approval PRs at once',\n '🔐',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'minimum-group-size-not-met',\n 'Group Size Not Met',\n 'The following branches have not met their minimum group size. To create them, click on a checkbox below.',\n 'approveGroup',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'not-scheduled',\n 'Awaiting Schedule',\n 'The following updates are awaiting their schedule. To get an update now, click on a checkbox below.',\n 'unschedule',\n createAllAwaitingSchedulePrs,\n 'Create all awaiting schedule PRs at once',\n '🔐',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) =>\n branch.result === 'branch-limit-reached' ||\n branch.result === 'pr-limit-reached' ||\n branch.result === 'commit-per-run-limit-reached' ||\n branch.result === 'commit-hourly-limit-reached',\n 'Rate-Limited',\n 'The following updates are currently rate-limited. To force their creation now, click on a checkbox below.',\n 'unlimit',\n createAllRateLimitedPrs,\n 'Create all rate-limited PRs at once',\n '🔐',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'error',\n 'Errored',\n 'The following updates encountered an error and will be retried. To force a retry now, click on a checkbox below.',\n 'retry',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'needs-pr-approval',\n 'PR Creation Approval Required',\n 'The following branches exist but PR creation requires approval. To approve PR creation, click on a checkbox below.',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'pr-edited',\n 'PR Edited (Blocked)',\n 'The following updates have been manually edited so Renovate will no longer make changes. To discard all commits and start over, click on a checkbox below.',\n 'rebase',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'pending',\n 'Pending Status Checks',\n 'The following updates await pending status checks. To force their creation now, click on a checkbox below.',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.prBlockedBy === 'BranchAutomerge',\n 'Pending Branch Automerge',\n 'The following updates await pending status checks before automerging. To abort the branch automerge and create a PR instead, click on a checkbox below.',\n );\n\n const warn = getDepWarningsDashboard(packageFiles, config);\n if (warn) {\n issueBody += warn;\n issueBody += '\\n';\n }\n\n const otherRes = [\n 'pending',\n 'needs-approval',\n 'needs-pr-approval',\n 'not-scheduled',\n 'pr-limit-reached',\n 'commit-per-run-limit-reached',\n 'commit-hourly-limit-reached',\n 'branch-limit-reached',\n 'already-existed',\n 'error',\n 'automerged',\n 'pr-edited',\n 'minimum-group-size-not-met',\n ];\n const inProgress = branches.filter(\n (branch) =>\n !otherRes.includes(branch.result!) &&\n branch.prBlockedBy !== 'BranchAutomerge',\n );\n issueBody += getBranchesListMd(\n inProgress,\n (branch) => !!branch.prBlockedBy || !branch.prNo,\n 'Other Branches',\n 'The following updates are pending. To force the creation of a PR, click on a checkbox below.',\n 'other',\n );\n issueBody += getBranchesListMd(\n inProgress,\n (branch) => branch.prNo && !branch.prBlockedBy,\n 'Open',\n 'The following updates have all been created. To force a retry/rebase of any, click on a checkbox below.',\n 'rebase',\n rebaseAllOpenPrs,\n 'Click on this checkbox to rebase all open PRs at once',\n );\n\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'already-existed',\n 'PR Closed (Blocked)',\n 'The following updates are blocked by an existing closed PR. To recreate the PR, click on a checkbox below.',\n 'recreate',\n );\n\n if (!hasBranches) {\n issueBody +=\n 'This repository currently has no open or pending branches.\\n\\n';\n }\n\n // add CVE section\n issueBody += await getDashboardMarkdownVulnerabilities(config, packageFiles);\n\n // fit the detected dependencies section\n const footer = getFooter(config);\n issueBody += PackageFiles.getDashboardMarkdown(\n platform.maxBodyLength() - issueBody.length - footer.length,\n );\n\n issueBody += footer;\n\n if (config.dependencyDashboardIssue) {\n // If we're not changing the dashboard issue, then we can skip checking if the user changed it.\n // The cached issue we get back here will reflect its state at the _start_ of our run\n const cachedIssue = await platform.getIssue?.(\n config.dependencyDashboardIssue,\n );\n if (cachedIssue?.body === issueBody) {\n logger.debug('No changes to dependency dashboard issue needed');\n return;\n }\n\n // Skip cache when getting the issue to ensure we get the latest body,\n // including any updates the user made after we started the run\n const updatedIssue = await platform.getIssue?.(\n config.dependencyDashboardIssue,\n false,\n );\n if (updatedIssue) {\n const { dependencyDashboardChecks } = parseDashboardIssue(\n coerceString(updatedIssue.body),\n );\n for (const branchName of Object.keys(config.dependencyDashboardChecks!)) {\n delete dependencyDashboardChecks[branchName];\n }\n for (const branchName of Object.keys(dependencyDashboardChecks)) {\n const checkText = getCheckbox(\n `${dependencyDashboardChecks[branchName]}-branch=${branchName}`,\n );\n issueBody = issueBody.replace(\n checkText,\n checkText.replace('[ ]', '[x]'),\n );\n }\n }\n }\n\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n { title: config.dependencyDashboardTitle },\n 'DRY-RUN: Would ensure Dependency Dashboard',\n );\n } else {\n await platform.ensureIssue({\n title: config.dependencyDashboardTitle!,\n reuseTitle,\n body: platform.massageMarkdown(issueBody, config.rebaseLabel),\n labels: config.dependencyDashboardLabels,\n confidential: config.confidential,\n });\n }\n}\n\nexport function getAbandonedPackagesMd(\n packageFiles: Record<string, PackageFile[]>,\n): string {\n const abandonedPackages: Record<\n string,\n Record<\n string,\n { mostRecentTimestamp?: string | null; sourceUrl?: string | null }\n >\n > = {};\n let abandonedCount = 0;\n\n for (const [manager, managerPackageFiles] of Object.entries(packageFiles)) {\n for (const packageFile of managerPackageFiles) {\n for (const dep of coerceArray(packageFile.deps)) {\n if (dep.depName && dep.isAbandoned) {\n abandonedCount++;\n abandonedPackages[manager] = abandonedPackages[manager] || {};\n abandonedPackages[manager][dep.depName] = {\n mostRecentTimestamp: dep.mostRecentTimestamp,\n sourceUrl: dep.sourceUrl,\n };\n }\n }\n }\n }\n\n if (abandonedCount === 0) {\n return '';\n }\n\n let abandonedMd = emojify(\n '## Abandoned Dependencies\\n\\n> :information_source: **Note**\\n> \\n',\n );\n\n abandonedMd +=\n 'Packages are marked as abandoned when they exceed the [`abandonmentThreshold`](https://docs.renovatebot.com/configuration-options/#abandonmentthreshold) since their last release. ';\n abandonedMd +=\n 'Unlike deprecated packages with official notices, abandonment is detected by release inactivity.\\n> \\n';\n\n abandonedMd +=\n '> These dependencies have not received updates for an extended period and may be unmaintained:\\n\\n';\n\n abandonedMd += '<details>\\n';\n abandonedMd += `<summary>View abandoned dependencies (${abandonedCount})</summary>\\n\\n`;\n abandonedMd += '| Datasource | Package | Last Updated |\\n';\n abandonedMd += '|------------|------|-------------|\\n';\n\n for (const manager of Object.keys(abandonedPackages).sort()) {\n const deps = abandonedPackages[manager];\n for (const depName of Object.keys(deps).sort()) {\n const { mostRecentTimestamp, sourceUrl } = deps[depName];\n const formattedDate = mostRecentTimestamp\n ? DateTime.fromISO(mostRecentTimestamp).toFormat('yyyy-MM-dd')\n : 'unknown';\n const packageName = formatAsMarkdownLink(depName, sourceUrl);\n abandonedMd += `| ${manager} | ${packageName} | \\`${formattedDate}\\` |\\n`;\n }\n }\n\n abandonedMd += '\\n</details>\\n\\n\\n';\n\n return abandonedMd;\n}\n\nfunction getFooter(config: RenovateConfig): string {\n let footer = '';\n if (config.dependencyDashboardFooter?.length) {\n footer +=\n '---\\n' +\n template.compile(config.dependencyDashboardFooter, config) +\n '\\n';\n }\n\n return footer;\n}\n\nexport async function getDashboardMarkdownVulnerabilities(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n): Promise<string> {\n let result = '';\n\n if (\n isNullOrUndefined(config.dependencyDashboardOSVVulnerabilitySummary) ||\n config.dependencyDashboardOSVVulnerabilitySummary === 'none'\n ) {\n return result;\n }\n\n result += '## Vulnerabilities\\n\\n';\n\n const vulnerabilityFetcher = await Vulnerabilities.create();\n const vulnerabilities = await vulnerabilityFetcher.fetchVulnerabilities(\n config,\n packageFiles,\n );\n\n if (vulnerabilities.length === 0) {\n result +=\n 'Renovate has not found any CVEs on [osv.dev](https://osv.dev).\\n\\n';\n return result;\n }\n\n const unresolvedVulnerabilities = vulnerabilities.filter((value) =>\n isNullOrUndefined(value.fixedVersion),\n );\n const resolvedVulnerabilitiesLength =\n vulnerabilities.length - unresolvedVulnerabilities.length;\n\n result += emojify('> :exclamation: **Important**\\n> \\n');\n result += `> \\`${resolvedVulnerabilitiesLength}\\`/\\`${vulnerabilities.length}\\``;\n if (isTruthy(config.osvVulnerabilityAlerts)) {\n result += ' CVEs have Renovate fixes.\\n\\n';\n } else {\n result +=\n ' CVEs have possible Renovate fixes.\\n> See [`osvVulnerabilityAlerts`](https://docs.renovatebot.com/configuration-options/#osvvulnerabilityalerts) to allow Renovate to supply fixes.\\n\\n';\n }\n\n let renderedVulnerabilities: Vulnerability[];\n switch (config.dependencyDashboardOSVVulnerabilitySummary) {\n // filter vulnerabilities to display based on configuration\n case 'unresolved':\n renderedVulnerabilities = unresolvedVulnerabilities;\n break;\n default:\n renderedVulnerabilities = vulnerabilities;\n }\n\n const managerRecords: Record<\n string,\n Record<string, Record<string, Vulnerability[]>>\n > = {};\n for (const vulnerability of renderedVulnerabilities) {\n const { manager, packageFile } = vulnerability.packageFileConfig;\n if (isNullOrUndefined(managerRecords[manager!])) {\n managerRecords[manager!] = {};\n }\n if (isNullOrUndefined(managerRecords[manager!][packageFile])) {\n managerRecords[manager!][packageFile] = {};\n }\n if (\n isNullOrUndefined(\n managerRecords[manager!][packageFile][vulnerability.packageName],\n )\n ) {\n managerRecords[manager!][packageFile][vulnerability.packageName] = [];\n }\n managerRecords[manager!][packageFile][vulnerability.packageName].push(\n vulnerability,\n );\n }\n\n for (const [manager, packageFileRecords] of Object.entries(managerRecords)) {\n result += `<details><summary>${manager}</summary>\\n<blockquote>\\n\\n`;\n for (const [packageFile, packageNameRecords] of Object.entries(\n packageFileRecords,\n )) {\n result += `<details><summary>${packageFile}</summary>\\n<blockquote>\\n\\n`;\n for (const [packageName, cves] of Object.entries(packageNameRecords)) {\n result += `<details><summary>${packageName}</summary>\\n<blockquote>\\n\\n`;\n for (const vul of cves) {\n const id = vul.vulnerability.id;\n const suffix = isNonEmptyString(vul.fixedVersion)\n ? ` (fixed in ${vul.fixedVersion})`\n : '';\n result += `- [${id}](https://osv.dev/vulnerability/${id})${suffix}\\n`;\n }\n result += `</blockquote>\\n</details>\\n\\n`;\n }\n result += `</blockquote>\\n</details>\\n\\n`;\n }\n result += `</blockquote>\\n</details>\\n\\n`;\n }\n\n return result;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dependency-dashboard.js","names":["template.compile"],"sources":["../../../lib/workers/repository/dependency-dashboard.ts"],"sourcesContent":["import {\n isNonEmptyArray,\n isNonEmptyObject,\n isNonEmptyString,\n isNullOrUndefined,\n isTruthy,\n} from '@sindresorhus/is';\nimport { DateTime } from 'luxon';\nimport { GlobalConfig } from '../../config/global.ts';\nimport type { RenovateConfig } from '../../config/types.ts';\nimport { logger } from '../../logger/index.ts';\nimport type { PackageFile } from '../../modules/manager/types.ts';\nimport { platform } from '../../modules/platform/index.ts';\nimport { coerceArray } from '../../util/array.ts';\nimport { emojify } from '../../util/emoji.ts';\nimport { regEx } from '../../util/regex.ts';\nimport { coerceString } from '../../util/string.ts';\nimport * as template from '../../util/template/index.ts';\nimport type { BranchConfig, SelectAllConfig } from '../types.ts';\nimport { extractRepoProblems } from './common.ts';\nimport type { ConfigMigrationResult } from './config-migration/index.ts';\nimport { getDepWarningsDashboard } from './errors-warnings.ts';\nimport { PackageFiles } from './package-files.ts';\nimport type { Vulnerability } from './process/types.ts';\nimport { Vulnerabilities } from './process/vulnerabilities.ts';\n\ninterface DependencyDashboard {\n dependencyDashboardChecks: Record<string, string>;\n dependencyDashboardRebaseAllOpen: boolean;\n dependencyDashboardAllPending: boolean;\n dependencyDashboardAllRateLimited: boolean;\n dependencyDashboardAllAwaitingSchedule: boolean;\n}\n\nconst rateLimitedRe = regEx(\n ` - \\\\[ \\\\] ${getMarkdownComment('unlimit-branch=([^\\\\s]+)')}`,\n 'g',\n);\nconst pendingApprovalRe = regEx(\n ` - \\\\[ \\\\] ${getMarkdownComment('approve-branch=([^\\\\s]+)')}`,\n 'g',\n);\nconst awaitingScheduleRe = regEx(\n ` - \\\\[ \\\\] ${getMarkdownComment('unschedule-branch=([^\\\\s]+)')}`,\n 'g',\n);\nconst generalBranchRe = regEx(\n ` ${getMarkdownComment('([a-zA-Z]+)-branch=([^\\\\s]+)')}`,\n);\nconst markedBranchesRe = regEx(\n ` - \\\\[x\\\\] ${getMarkdownComment('([a-zA-Z]+)-branch=([^\\\\s]+)')}`,\n 'g',\n);\n\nconst approveAllPendingPrs = 'approve-all-pending-prs';\nconst createAllRateLimitedPrs = 'create-all-rate-limited-prs';\nconst createAllAwaitingSchedulePrs = 'create-all-awaiting-schedule-prs';\nconst createConfigMigrationPr = 'create-config-migration-pr';\nconst configMigrationPrInfo = 'config-migration-pr-info';\nconst rebaseAllOpenPrs = 'rebase-all-open-prs';\n\nfunction getMarkdownComment(comment: string): string {\n return `<!-- ${comment} -->`;\n}\n\nfunction isBoxChecked(issueBody: string, type: string): boolean {\n return issueBody.includes(getCheckbox(type, true));\n}\n\nfunction isBoxUnchecked(issueBody: string, type: string): boolean {\n return issueBody.includes(getCheckbox(type));\n}\n\nfunction getCheckbox(type: string, checked = false): string {\n return ` - [${checked ? 'x' : ' '}] ${getMarkdownComment(type)}`;\n}\n\nfunction checkOpenAllRateLimitedPR(issueBody: string): boolean {\n return isBoxChecked(issueBody, createAllRateLimitedPrs);\n}\n\nfunction checkOpenAllAwaitingSchedulePR(issueBody: string): boolean {\n return isBoxChecked(issueBody, createAllAwaitingSchedulePrs);\n}\n\nfunction checkApproveAllPendingPR(issueBody: string): boolean {\n return isBoxChecked(issueBody, approveAllPendingPrs);\n}\n\nfunction checkRebaseAll(issueBody: string): boolean {\n return isBoxChecked(issueBody, rebaseAllOpenPrs);\n}\n\nfunction getConfigMigrationCheckboxState(\n issueBody: string,\n): 'no-checkbox' | 'checked' | 'unchecked' | 'migration-pr-exists' {\n if (issueBody.includes(getMarkdownComment(configMigrationPrInfo))) {\n return 'migration-pr-exists';\n }\n\n if (isBoxChecked(issueBody, createConfigMigrationPr)) {\n return 'checked';\n }\n\n if (isBoxUnchecked(issueBody, createConfigMigrationPr)) {\n return 'unchecked';\n }\n\n return 'no-checkbox';\n}\n\nfunction selectAllRelevantBranches(issueBody: string): string[] {\n const checkedBranches = [];\n if (checkOpenAllRateLimitedPR(issueBody)) {\n for (const match of issueBody.matchAll(rateLimitedRe)) {\n checkedBranches.push(match[0]);\n }\n }\n if (checkOpenAllAwaitingSchedulePR(issueBody)) {\n for (const match of issueBody.matchAll(awaitingScheduleRe)) {\n checkedBranches.push(match[0]);\n }\n }\n if (checkApproveAllPendingPR(issueBody)) {\n for (const match of issueBody.matchAll(pendingApprovalRe)) {\n checkedBranches.push(match[0]);\n }\n }\n return checkedBranches;\n}\n\nfunction getAllSelectedBranches(\n issueBody: string,\n dependencyDashboardChecks: Record<string, string>,\n): Record<string, string> {\n const allRelevantBranches = selectAllRelevantBranches(issueBody);\n for (const branch of allRelevantBranches) {\n const [, type, branchName] = generalBranchRe.exec(branch)!;\n dependencyDashboardChecks[branchName] = type;\n }\n return dependencyDashboardChecks;\n}\n\nfunction getCheckedBranches(issueBody: string): Record<string, string> {\n let dependencyDashboardChecks: Record<string, string> = {};\n for (const [, type, branchName] of issueBody.matchAll(markedBranchesRe)) {\n dependencyDashboardChecks[branchName] = type;\n }\n dependencyDashboardChecks = getAllSelectedBranches(\n issueBody,\n dependencyDashboardChecks,\n );\n return dependencyDashboardChecks;\n}\n\nfunction parseDashboardIssue(issueBody: string): DependencyDashboard {\n const dependencyDashboardChecks = getCheckedBranches(issueBody);\n const dependencyDashboardRebaseAllOpen = checkRebaseAll(issueBody);\n const dependencyDashboardAllAwaitingSchedule =\n checkOpenAllAwaitingSchedulePR(issueBody);\n const dependencyDashboardAllPending = checkApproveAllPendingPR(issueBody);\n const dependencyDashboardAllRateLimited =\n checkOpenAllRateLimitedPR(issueBody);\n dependencyDashboardChecks.configMigrationCheckboxState =\n getConfigMigrationCheckboxState(issueBody);\n return {\n dependencyDashboardChecks,\n dependencyDashboardRebaseAllOpen,\n dependencyDashboardAllAwaitingSchedule,\n dependencyDashboardAllPending,\n dependencyDashboardAllRateLimited,\n };\n}\n\nexport async function readDashboardBody(\n config: SelectAllConfig,\n): Promise<void> {\n let dashboardChecks: DependencyDashboard = {\n dependencyDashboardChecks: {},\n dependencyDashboardRebaseAllOpen: false,\n dependencyDashboardAllAwaitingSchedule: false,\n dependencyDashboardAllPending: false,\n dependencyDashboardAllRateLimited: false,\n };\n const stringifiedConfig = JSON.stringify(config);\n if (\n config.dependencyDashboard === true ||\n stringifiedConfig.includes('\"dependencyDashboardApproval\":true') ||\n stringifiedConfig.includes('\"prCreation\":\"approval\"')\n ) {\n config.dependencyDashboardTitle =\n config.dependencyDashboardTitle ?? `Dependency Dashboard`;\n const issue = await platform.findIssue(config.dependencyDashboardTitle);\n if (issue) {\n config.dependencyDashboardIssue = issue.number;\n dashboardChecks = parseDashboardIssue(issue.body ?? '');\n }\n }\n\n if (config.checkedBranches) {\n const checkedBranchesRec: Record<string, string> = Object.fromEntries(\n config.checkedBranches.map((branchName) => [branchName, 'global-config']),\n );\n dashboardChecks.dependencyDashboardChecks = {\n ...dashboardChecks.dependencyDashboardChecks,\n ...checkedBranchesRec,\n };\n }\n\n Object.assign(config, dashboardChecks);\n}\n\nfunction formatAsMarkdownLink(name: string, url?: string | null): string {\n return url ? `[${name}](${url})` : `\\`${name}\\``;\n}\n\nfunction getListItem(branch: BranchConfig, type: string): string {\n let item = getCheckbox(`${type}-branch=${branch.branchName}`);\n if (branch.prNo) {\n // TODO: types (#22198)\n item += `[${branch.prTitle!}](../pull/${branch.prNo})`;\n } else {\n item += branch.prTitle;\n }\n const uniquePackages = [\n // TODO: types (#22198)\n ...new Set(branch.upgrades.map((upgrade) => `\\`${upgrade.depName!}\\``)),\n ];\n if (uniquePackages.length < 2) {\n return item + '\\n';\n }\n return item + ' (' + uniquePackages.join(', ') + ')\\n';\n}\n\nfunction splitBranchesByCategory(filteredBranches: BranchConfig[]): {\n categories: Record<string, BranchConfig[]>;\n uncategorized: BranchConfig[];\n hasCategorized: boolean;\n hasUncategorized: boolean;\n} {\n const categories: Record<string, BranchConfig[]> = {};\n const uncategorized: BranchConfig[] = [];\n let hasCategorized = false;\n let hasUncategorized = false;\n for (const branch of filteredBranches) {\n if (branch.dependencyDashboardCategory) {\n categories[branch.dependencyDashboardCategory] ??= [];\n categories[branch.dependencyDashboardCategory].push(branch);\n hasCategorized = true;\n continue;\n }\n uncategorized.push(branch);\n hasUncategorized = true;\n }\n return { categories, uncategorized, hasCategorized, hasUncategorized };\n}\n\nfunction getBranchList(branches: BranchConfig[], listItemType: string): string {\n return branches\n .map((branch: BranchConfig): string => getListItem(branch, listItemType))\n .join('');\n}\n\nfunction getBranchesListMd(\n branches: BranchConfig[],\n predicate: (\n value: BranchConfig,\n index: number,\n array: BranchConfig[],\n ) => unknown,\n title: string,\n description: string,\n listItemType = 'approvePr',\n bulkComment?: string,\n bulkMessage?: string,\n bulkIcon?: '🔐',\n): string {\n const filteredBranches = branches.filter(predicate);\n if (filteredBranches.length === 0) {\n return '';\n }\n let result = `## ${title}\\n\\n${description}\\n\\n`;\n const { categories, uncategorized, hasCategorized, hasUncategorized } =\n splitBranchesByCategory(filteredBranches);\n if (hasCategorized) {\n for (const [category, branches] of Object.entries(categories).sort(\n ([keyA], [keyB]) =>\n keyA.localeCompare(keyB, undefined, { numeric: true }),\n )) {\n result = result.trimEnd() + '\\n\\n';\n result += `### ${category}\\n\\n`;\n result += getBranchList(branches, listItemType);\n }\n if (hasUncategorized) {\n result = result.trimEnd() + '\\n\\n';\n result += `### Others`;\n }\n }\n result = result.trimEnd() + '\\n\\n';\n result += getBranchList(uncategorized, listItemType);\n\n if (bulkComment && bulkMessage && filteredBranches.length > 1) {\n if (hasCategorized) {\n result = result.trimEnd() + '\\n\\n';\n result += '### All\\n\\n';\n }\n result += getCheckbox(bulkComment);\n result += `${bulkIcon ? bulkIcon + ' ' : ''}**${bulkMessage}**${bulkIcon ? ' ' + bulkIcon : ''}`;\n }\n return result.trimEnd() + '\\n\\n';\n}\n\nfunction appendRepoProblems(config: RenovateConfig, issueBody: string): string {\n let newIssueBody = issueBody;\n const repoProblems = extractRepoProblems(config.repository);\n if (repoProblems.size) {\n newIssueBody += '## Repository Problems\\n\\n';\n const repoProblemsHeader =\n config.customizeDashboard?.repoProblemsHeader ??\n 'Renovate tried to run on this repository, but found these problems.';\n newIssueBody += template.compile(repoProblemsHeader, config) + '\\n\\n';\n\n for (const repoProblem of repoProblems) {\n newIssueBody += ` - ${repoProblem}\\n`;\n }\n newIssueBody += '\\n';\n }\n return newIssueBody;\n}\n\nexport async function ensureDependencyDashboard(\n config: SelectAllConfig,\n allBranches: BranchConfig[],\n packageFiles: Record<string, PackageFile[]> = {},\n configMigrationRes: ConfigMigrationResult,\n): Promise<void> {\n logger.debug('ensureDependencyDashboard()');\n if (config.mode === 'silent') {\n logger.debug(\n 'Dependency Dashboard issue is not created, updated or closed when mode=silent',\n );\n return;\n }\n // legacy/migrated issue\n const reuseTitle = 'Update Dependencies (Renovate Bot)';\n const branches = allBranches.filter(\n (branch) =>\n branch.result !== 'automerged' &&\n !branch.upgrades?.every((upgrade) => upgrade.remediationNotPossible),\n );\n if (\n !(\n config.dependencyDashboard === true ||\n config.dependencyDashboardApproval === true ||\n config.packageRules?.some((rule) => rule.dependencyDashboardApproval) ===\n true ||\n branches.some(\n (branch) =>\n !!branch.dependencyDashboardApproval ||\n !!branch.dependencyDashboardPrApproval,\n )\n )\n ) {\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n { title: config.dependencyDashboardTitle },\n 'DRY-RUN: Would close Dependency Dashboard',\n );\n } else {\n logger.debug('Closing Dependency Dashboard');\n await platform.ensureIssueClosing(config.dependencyDashboardTitle!);\n }\n return;\n }\n // istanbul ignore if\n if (config.repoIsOnboarded === false) {\n logger.debug('Repo is onboarding - skipping dependency dashboard');\n return;\n }\n logger.debug('Ensuring Dependency Dashboard');\n\n // Check packageFiles for any deprecations or replacements\n let hasDeprecationsOrReplacements = false;\n const deprecatedPackages: Record<\n string,\n Record<string, { hasReplacement: boolean; sourceUrl?: string | null }>\n > = {};\n logger.debug('Checking packageFiles for deprecated or replacement packages');\n if (isNonEmptyObject(packageFiles)) {\n for (const [manager, fileNames] of Object.entries(packageFiles)) {\n for (const fileName of fileNames) {\n for (const dep of fileName.deps) {\n const name = dep.packageName ?? dep.depName;\n const hasReplacement = !!dep.updates?.find(\n (updates) => updates.updateType === 'replacement',\n );\n if (name && (dep.deprecationMessage ?? hasReplacement)) {\n hasDeprecationsOrReplacements = true;\n deprecatedPackages[manager] ??= {};\n deprecatedPackages[manager][name] ??= {\n hasReplacement,\n sourceUrl: dep.sourceUrl,\n };\n }\n }\n }\n }\n }\n\n const hasBranches = isNonEmptyArray(branches);\n if (\n config.dependencyDashboardAutoclose &&\n !hasBranches &&\n !hasDeprecationsOrReplacements\n ) {\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n { title: config.dependencyDashboardTitle },\n 'DRY-RUN: Would close Dependency Dashboard',\n );\n } else {\n logger.debug('Closing Dependency Dashboard');\n await platform.ensureIssueClosing(config.dependencyDashboardTitle!);\n }\n return;\n }\n let issueBody = '';\n\n if (config.dependencyDashboardHeader?.length) {\n issueBody +=\n template.compile(config.dependencyDashboardHeader, config) + '\\n\\n';\n }\n\n if (configMigrationRes.result === 'pr-exists') {\n issueBody +=\n '## Config Migration Needed\\n\\n' +\n getMarkdownComment(configMigrationPrInfo) +\n ` See Config Migration PR: #${configMigrationRes.prNumber}.\\n\\n`;\n } else if (configMigrationRes?.result === 'pr-modified') {\n issueBody +=\n '## Config Migration Needed (Blocked)\\n\\n' +\n getMarkdownComment(configMigrationPrInfo) +\n ` The Config Migration branch exists but has been modified by another user. Renovate will not push to this branch unless it is first deleted. \\n\\n See Config Migration PR: #${configMigrationRes.prNumber}.\\n\\n`;\n } else if (configMigrationRes?.result === 'add-checkbox') {\n issueBody +=\n '## Config Migration Needed\\n\\n' +\n getCheckbox(createConfigMigrationPr) +\n ' Select this checkbox to let Renovate create an automated Config Migration PR.' +\n '\\n\\n';\n }\n\n issueBody = appendRepoProblems(config, issueBody);\n\n if (hasDeprecationsOrReplacements) {\n issueBody += '## Deprecations / Replacements\\n';\n issueBody += emojify('> :warning: **Warning**\\n> \\n');\n issueBody +=\n 'The following dependencies are either deprecated or have replacements available.\\n\\n';\n issueBody += '| Datasource | Package | Replacement PR? |\\n';\n issueBody += '|------------|------|--------------|\\n';\n for (const manager of Object.keys(deprecatedPackages).sort()) {\n const deps = deprecatedPackages[manager];\n for (const depName of Object.keys(deps).sort()) {\n const { hasReplacement, sourceUrl } = deps[depName];\n const packageName = formatAsMarkdownLink(depName, sourceUrl);\n\n issueBody += `| ${manager} | ${packageName} | ${\n hasReplacement\n ? ''\n : ''\n } |\\n`;\n }\n }\n issueBody += '\\n';\n }\n\n if (config.dependencyDashboardReportAbandonment) {\n issueBody += getAbandonedPackagesMd(packageFiles);\n }\n\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'needs-approval',\n 'Pending Approval',\n 'The following branches are pending approval. To create them, click on a checkbox below.',\n 'approve',\n approveAllPendingPrs,\n 'Create all pending approval PRs at once',\n '🔐',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'minimum-group-size-not-met',\n 'Group Size Not Met',\n 'The following branches have not met their minimum group size. To create them, click on a checkbox below.',\n 'approveGroup',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'not-scheduled',\n 'Awaiting Schedule',\n 'The following updates are awaiting their schedule. To get an update now, click on a checkbox below.',\n 'unschedule',\n createAllAwaitingSchedulePrs,\n 'Create all awaiting schedule PRs at once',\n '🔐',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) =>\n branch.result === 'branch-limit-reached' ||\n branch.result === 'pr-limit-reached' ||\n branch.result === 'commit-per-run-limit-reached' ||\n branch.result === 'commit-hourly-limit-reached',\n 'Rate-Limited',\n 'The following updates are currently rate-limited. To force their creation now, click on a checkbox below.',\n 'unlimit',\n createAllRateLimitedPrs,\n 'Create all rate-limited PRs at once',\n '🔐',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'error',\n 'Errored',\n 'The following updates encountered an error and will be retried. To force a retry now, click on a checkbox below.',\n 'retry',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'needs-pr-approval',\n 'PR Creation Approval Required',\n 'The following branches exist but PR creation requires approval. To approve PR creation, click on a checkbox below.',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'pr-edited',\n 'PR Edited (Blocked)',\n 'The following updates have been manually edited so Renovate will no longer make changes. To discard all commits and start over, click on a checkbox below.',\n 'rebase',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'pending',\n 'Pending Status Checks',\n 'The following updates await pending status checks. To force their creation now, click on a checkbox below.',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.prBlockedBy === 'BranchAutomerge',\n 'Pending Branch Automerge',\n 'The following updates await pending status checks before automerging. To abort the branch automerge and create a PR instead, click on a checkbox below.',\n );\n\n const warn = getDepWarningsDashboard(packageFiles, config);\n if (warn) {\n issueBody += warn;\n issueBody += '\\n';\n }\n\n const otherRes = [\n 'pending',\n 'needs-approval',\n 'needs-pr-approval',\n 'not-scheduled',\n 'pr-limit-reached',\n 'commit-per-run-limit-reached',\n 'commit-hourly-limit-reached',\n 'branch-limit-reached',\n 'already-existed',\n 'error',\n 'automerged',\n 'pr-edited',\n 'minimum-group-size-not-met',\n ];\n const inProgress = branches.filter(\n (branch) =>\n !otherRes.includes(branch.result!) &&\n branch.prBlockedBy !== 'BranchAutomerge',\n );\n issueBody += getBranchesListMd(\n inProgress,\n (branch) => !!branch.prBlockedBy || !branch.prNo,\n 'Other Branches',\n 'The following updates are pending. To force the creation of a PR, click on a checkbox below.',\n 'other',\n );\n issueBody += getBranchesListMd(\n inProgress,\n (branch) => branch.prNo && !branch.prBlockedBy,\n 'Open',\n 'The following updates have all been created. To force a retry/rebase of any, click on a checkbox below.',\n 'rebase',\n rebaseAllOpenPrs,\n 'Click on this checkbox to rebase all open PRs at once',\n );\n\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'already-existed',\n 'PR Closed (Blocked)',\n 'The following updates are blocked by an existing closed PR. To recreate the PR, click on a checkbox below.',\n 'recreate',\n );\n\n if (!hasBranches) {\n issueBody +=\n 'This repository currently has no open or pending branches.\\n\\n';\n }\n\n // add CVE section\n issueBody += await getDashboardMarkdownVulnerabilities(config, packageFiles);\n\n // fit the detected dependencies section\n const footer = getFooter(config);\n issueBody += PackageFiles.getDashboardMarkdown(\n platform.maxBodyLength() - issueBody.length - footer.length,\n );\n\n issueBody += footer;\n\n if (config.dependencyDashboardIssue) {\n // If we're not changing the dashboard issue, then we can skip checking if the user changed it.\n // The cached issue we get back here will reflect its state at the _start_ of our run\n const cachedIssue = await platform.getIssue?.(\n config.dependencyDashboardIssue,\n );\n if (cachedIssue?.body === issueBody) {\n logger.debug('No changes to dependency dashboard issue needed');\n return;\n }\n\n // Skip cache when getting the issue to ensure we get the latest body,\n // including any updates the user made after we started the run\n const updatedIssue = await platform.getIssue?.(\n config.dependencyDashboardIssue,\n false,\n );\n if (updatedIssue) {\n const { dependencyDashboardChecks } = parseDashboardIssue(\n coerceString(updatedIssue.body),\n );\n for (const branchName of Object.keys(config.dependencyDashboardChecks!)) {\n delete dependencyDashboardChecks[branchName];\n }\n for (const branchName of Object.keys(dependencyDashboardChecks)) {\n const checkText = getCheckbox(\n `${dependencyDashboardChecks[branchName]}-branch=${branchName}`,\n );\n issueBody = issueBody.replace(\n checkText,\n checkText.replace('[ ]', '[x]'),\n );\n }\n }\n }\n\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n { title: config.dependencyDashboardTitle },\n 'DRY-RUN: Would ensure Dependency Dashboard',\n );\n } else {\n await platform.ensureIssue({\n title: config.dependencyDashboardTitle!,\n reuseTitle,\n body: platform.massageMarkdown(issueBody, config.rebaseLabel),\n labels: config.dependencyDashboardLabels,\n confidential: config.confidential,\n });\n }\n}\n\nexport function getAbandonedPackagesMd(\n packageFiles: Record<string, PackageFile[]>,\n): string {\n const abandonedPackages: Record<\n string,\n Record<\n string,\n { mostRecentTimestamp?: string | null; sourceUrl?: string | null }\n >\n > = {};\n let abandonedCount = 0;\n\n for (const [manager, managerPackageFiles] of Object.entries(packageFiles)) {\n for (const packageFile of managerPackageFiles) {\n for (const dep of coerceArray(packageFile.deps)) {\n if (dep.depName && dep.isAbandoned) {\n abandonedCount++;\n abandonedPackages[manager] = abandonedPackages[manager] || {};\n abandonedPackages[manager][dep.depName] = {\n mostRecentTimestamp: dep.mostRecentTimestamp,\n sourceUrl: dep.sourceUrl,\n };\n }\n }\n }\n }\n\n if (abandonedCount === 0) {\n return '';\n }\n\n let abandonedMd = '## Abandoned Dependencies\\n\\n';\n abandonedMd +=\n 'The following dependencies have not received updates for an extended period and may be unmaintained.\\n\\n';\n\n abandonedMd += '<details>\\n';\n abandonedMd += `<summary>View abandoned dependencies (${abandonedCount})</summary>\\n\\n`;\n\n abandonedMd += emojify('> :information_source: **Note**\\n> \\n');\n abandonedMd +=\n 'Packages are marked as abandoned when they exceed the [`abandonmentThreshold`](https://docs.renovatebot.com/configuration-options/#abandonmentthreshold) since their last release. ';\n abandonedMd +=\n 'Unlike deprecated packages with official notices, abandonment is detected by release inactivity.\\n> \\n';\n\n abandonedMd += '| Datasource | Package | Last Updated |\\n';\n abandonedMd += '|------------|------|-------------|\\n';\n\n for (const manager of Object.keys(abandonedPackages).sort()) {\n const deps = abandonedPackages[manager];\n for (const depName of Object.keys(deps).sort()) {\n const { mostRecentTimestamp, sourceUrl } = deps[depName];\n const formattedDate = mostRecentTimestamp\n ? DateTime.fromISO(mostRecentTimestamp).toFormat('yyyy-MM-dd')\n : 'unknown';\n const packageName = formatAsMarkdownLink(depName, sourceUrl);\n abandonedMd += `| ${manager} | ${packageName} | \\`${formattedDate}\\` |\\n`;\n }\n }\n\n abandonedMd += '\\n</details>\\n\\n\\n';\n\n return abandonedMd;\n}\n\nfunction getFooter(config: RenovateConfig): string {\n let footer = '';\n if (config.dependencyDashboardFooter?.length) {\n footer +=\n '---\\n' +\n template.compile(config.dependencyDashboardFooter, config) +\n '\\n';\n }\n\n return footer;\n}\n\nexport async function getDashboardMarkdownVulnerabilities(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n): Promise<string> {\n let result = '';\n\n if (\n isNullOrUndefined(config.dependencyDashboardOSVVulnerabilitySummary) ||\n config.dependencyDashboardOSVVulnerabilitySummary === 'none'\n ) {\n return result;\n }\n\n result += '## Vulnerabilities\\n\\n';\n\n const vulnerabilityFetcher = await Vulnerabilities.create();\n const vulnerabilities = await vulnerabilityFetcher.fetchVulnerabilities(\n config,\n packageFiles,\n );\n\n if (vulnerabilities.length === 0) {\n result +=\n 'Renovate has not found any CVEs on [osv.dev](https://osv.dev).\\n\\n';\n return result;\n }\n\n const unresolvedVulnerabilities = vulnerabilities.filter((value) =>\n isNullOrUndefined(value.fixedVersion),\n );\n const resolvedVulnerabilitiesLength =\n vulnerabilities.length - unresolvedVulnerabilities.length;\n\n result += emojify('> :exclamation: **Important**\\n> \\n');\n result += `> \\`${resolvedVulnerabilitiesLength}\\`/\\`${vulnerabilities.length}\\``;\n if (isTruthy(config.osvVulnerabilityAlerts)) {\n result += ' CVEs have Renovate fixes.\\n\\n';\n } else {\n result +=\n ' CVEs have possible Renovate fixes.\\n> See [`osvVulnerabilityAlerts`](https://docs.renovatebot.com/configuration-options/#osvvulnerabilityalerts) to allow Renovate to supply fixes.\\n\\n';\n }\n\n let renderedVulnerabilities: Vulnerability[];\n switch (config.dependencyDashboardOSVVulnerabilitySummary) {\n // filter vulnerabilities to display based on configuration\n case 'unresolved':\n renderedVulnerabilities = unresolvedVulnerabilities;\n break;\n default:\n renderedVulnerabilities = vulnerabilities;\n }\n\n const managerRecords: Record<\n string,\n Record<string, Record<string, Vulnerability[]>>\n > = {};\n for (const vulnerability of renderedVulnerabilities) {\n const { manager, packageFile } = vulnerability.packageFileConfig;\n if (isNullOrUndefined(managerRecords[manager!])) {\n managerRecords[manager!] = {};\n }\n if (isNullOrUndefined(managerRecords[manager!][packageFile])) {\n managerRecords[manager!][packageFile] = {};\n }\n if (\n isNullOrUndefined(\n managerRecords[manager!][packageFile][vulnerability.packageName],\n )\n ) {\n managerRecords[manager!][packageFile][vulnerability.packageName] = [];\n }\n managerRecords[manager!][packageFile][vulnerability.packageName].push(\n vulnerability,\n );\n }\n\n for (const [manager, packageFileRecords] of Object.entries(managerRecords)) {\n result += `<details><summary>${manager}</summary>\\n<blockquote>\\n\\n`;\n for (const [packageFile, packageNameRecords] of Object.entries(\n packageFileRecords,\n )) {\n result += `<details><summary>${packageFile}</summary>\\n<blockquote>\\n\\n`;\n for (const [packageName, cves] of Object.entries(packageNameRecords)) {\n result += `<details><summary>${packageName}</summary>\\n<blockquote>\\n\\n`;\n for (const vul of cves) {\n const id = vul.vulnerability.id;\n const suffix = isNonEmptyString(vul.fixedVersion)\n ? ` (fixed in ${vul.fixedVersion})`\n : '';\n result += `- [${id}](https://osv.dev/vulnerability/${id})${suffix}\\n`;\n }\n result += `</blockquote>\\n</details>\\n\\n`;\n }\n result += `</blockquote>\\n</details>\\n\\n`;\n }\n result += `</blockquote>\\n</details>\\n\\n`;\n }\n\n return result;\n}\n"],"mappings":";;;;;;;;;;;;;;;AAkCA,MAAM,gBAAgB,MACpB,cAAc,mBAAmB,2BAA2B,IAC5D,IACD;AACD,MAAM,oBAAoB,MACxB,cAAc,mBAAmB,2BAA2B,IAC5D,IACD;AACD,MAAM,qBAAqB,MACzB,cAAc,mBAAmB,8BAA8B,IAC/D,IACD;AACD,MAAM,kBAAkB,MACtB,IAAI,mBAAmB,+BAA+B,GACvD;AACD,MAAM,mBAAmB,MACvB,cAAc,mBAAmB,+BAA+B,IAChE,IACD;AAED,MAAM,uBAAuB;AAC7B,MAAM,0BAA0B;AAChC,MAAM,+BAA+B;AACrC,MAAM,0BAA0B;AAChC,MAAM,wBAAwB;AAC9B,MAAM,mBAAmB;AAEzB,SAAS,mBAAmB,SAAyB;AACnD,QAAO,QAAQ,QAAQ;;AAGzB,SAAS,aAAa,WAAmB,MAAuB;AAC9D,QAAO,UAAU,SAAS,YAAY,MAAM,KAAK,CAAC;;AAGpD,SAAS,eAAe,WAAmB,MAAuB;AAChE,QAAO,UAAU,SAAS,YAAY,KAAK,CAAC;;AAG9C,SAAS,YAAY,MAAc,UAAU,OAAe;AAC1D,QAAO,OAAO,UAAU,MAAM,IAAI,IAAI,mBAAmB,KAAK;;AAGhE,SAAS,0BAA0B,WAA4B;AAC7D,QAAO,aAAa,WAAW,wBAAwB;;AAGzD,SAAS,+BAA+B,WAA4B;AAClE,QAAO,aAAa,WAAW,6BAA6B;;AAG9D,SAAS,yBAAyB,WAA4B;AAC5D,QAAO,aAAa,WAAW,qBAAqB;;AAGtD,SAAS,eAAe,WAA4B;AAClD,QAAO,aAAa,WAAW,iBAAiB;;AAGlD,SAAS,gCACP,WACiE;AACjE,KAAI,UAAU,SAAS,mBAAmB,sBAAsB,CAAC,CAC/D,QAAO;AAGT,KAAI,aAAa,WAAW,wBAAwB,CAClD,QAAO;AAGT,KAAI,eAAe,WAAW,wBAAwB,CACpD,QAAO;AAGT,QAAO;;AAGT,SAAS,0BAA0B,WAA6B;CAC9D,MAAM,kBAAkB,EAAE;AAC1B,KAAI,0BAA0B,UAAU,CACtC,MAAK,MAAM,SAAS,UAAU,SAAS,cAAc,CACnD,iBAAgB,KAAK,MAAM,GAAG;AAGlC,KAAI,+BAA+B,UAAU,CAC3C,MAAK,MAAM,SAAS,UAAU,SAAS,mBAAmB,CACxD,iBAAgB,KAAK,MAAM,GAAG;AAGlC,KAAI,yBAAyB,UAAU,CACrC,MAAK,MAAM,SAAS,UAAU,SAAS,kBAAkB,CACvD,iBAAgB,KAAK,MAAM,GAAG;AAGlC,QAAO;;AAGT,SAAS,uBACP,WACA,2BACwB;CACxB,MAAM,sBAAsB,0BAA0B,UAAU;AAChE,MAAK,MAAM,UAAU,qBAAqB;EACxC,MAAM,GAAG,MAAM,cAAc,gBAAgB,KAAK,OAAO;AACzD,4BAA0B,cAAc;;AAE1C,QAAO;;AAGT,SAAS,mBAAmB,WAA2C;CACrE,IAAI,4BAAoD,EAAE;AAC1D,MAAK,MAAM,GAAG,MAAM,eAAe,UAAU,SAAS,iBAAiB,CACrE,2BAA0B,cAAc;AAE1C,6BAA4B,uBAC1B,WACA,0BACD;AACD,QAAO;;AAGT,SAAS,oBAAoB,WAAwC;CACnE,MAAM,4BAA4B,mBAAmB,UAAU;CAC/D,MAAM,mCAAmC,eAAe,UAAU;CAClE,MAAM,yCACJ,+BAA+B,UAAU;CAC3C,MAAM,gCAAgC,yBAAyB,UAAU;CACzE,MAAM,oCACJ,0BAA0B,UAAU;AACtC,2BAA0B,+BACxB,gCAAgC,UAAU;AAC5C,QAAO;EACL;EACA;EACA;EACA;EACA;EACD;;AAGH,eAAsB,kBACpB,QACe;CACf,IAAI,kBAAuC;EACzC,2BAA2B,EAAE;EAC7B,kCAAkC;EAClC,wCAAwC;EACxC,+BAA+B;EAC/B,mCAAmC;EACpC;CACD,MAAM,oBAAoB,KAAK,UAAU,OAAO;AAChD,KACE,OAAO,wBAAwB,QAC/B,kBAAkB,SAAS,uCAAqC,IAChE,kBAAkB,SAAS,8BAA0B,EACrD;AACA,SAAO,2BACL,OAAO,4BAA4B;EACrC,MAAM,QAAQ,MAAM,SAAS,UAAU,OAAO,yBAAyB;AACvE,MAAI,OAAO;AACT,UAAO,2BAA2B,MAAM;AACxC,qBAAkB,oBAAoB,MAAM,QAAQ,GAAG;;;AAI3D,KAAI,OAAO,iBAAiB;EAC1B,MAAM,qBAA6C,OAAO,YACxD,OAAO,gBAAgB,KAAK,eAAe,CAAC,YAAY,gBAAgB,CAAC,CAC1E;AACD,kBAAgB,4BAA4B;GAC1C,GAAG,gBAAgB;GACnB,GAAG;GACJ;;AAGH,QAAO,OAAO,QAAQ,gBAAgB;;AAGxC,SAAS,qBAAqB,MAAc,KAA6B;AACvE,QAAO,MAAM,IAAI,KAAK,IAAI,IAAI,KAAK,KAAK,KAAK;;AAG/C,SAAS,YAAY,QAAsB,MAAsB;CAC/D,IAAI,OAAO,YAAY,GAAG,KAAK,UAAU,OAAO,aAAa;AAC7D,KAAI,OAAO,KAET,SAAQ,IAAI,OAAO,QAAS,YAAY,OAAO,KAAK;KAEpD,SAAQ,OAAO;CAEjB,MAAM,iBAAiB,CAErB,GAAG,IAAI,IAAI,OAAO,SAAS,KAAK,YAAY,KAAK,QAAQ,QAAS,IAAI,CAAC,CACxE;AACD,KAAI,eAAe,SAAS,EAC1B,QAAO,OAAO;AAEhB,QAAO,OAAO,OAAO,eAAe,KAAK,KAAK,GAAG;;AAGnD,SAAS,wBAAwB,kBAK/B;CACA,MAAM,aAA6C,EAAE;CACrD,MAAM,gBAAgC,EAAE;CACxC,IAAI,iBAAiB;CACrB,IAAI,mBAAmB;AACvB,MAAK,MAAM,UAAU,kBAAkB;AACrC,MAAI,OAAO,6BAA6B;AACtC,cAAW,OAAO,iCAAiC,EAAE;AACrD,cAAW,OAAO,6BAA6B,KAAK,OAAO;AAC3D,oBAAiB;AACjB;;AAEF,gBAAc,KAAK,OAAO;AAC1B,qBAAmB;;AAErB,QAAO;EAAE;EAAY;EAAe;EAAgB;EAAkB;;AAGxE,SAAS,cAAc,UAA0B,cAA8B;AAC7E,QAAO,SACJ,KAAK,WAAiC,YAAY,QAAQ,aAAa,CAAC,CACxE,KAAK,GAAG;;AAGb,SAAS,kBACP,UACA,WAKA,OACA,aACA,eAAe,aACf,aACA,aACA,UACQ;CACR,MAAM,mBAAmB,SAAS,OAAO,UAAU;AACnD,KAAI,iBAAiB,WAAW,EAC9B,QAAO;CAET,IAAI,SAAS,MAAM,MAAM,MAAM,YAAY;CAC3C,MAAM,EAAE,YAAY,eAAe,gBAAgB,qBACjD,wBAAwB,iBAAiB;AAC3C,KAAI,gBAAgB;AAClB,OAAK,MAAM,CAAC,UAAU,aAAa,OAAO,QAAQ,WAAW,CAAC,MAC3D,CAAC,OAAO,CAAC,UACR,KAAK,cAAc,MAAM,KAAA,GAAW,EAAE,SAAS,MAAM,CAAC,CACzD,EAAE;AACD,YAAS,OAAO,SAAS,GAAG;AAC5B,aAAU,OAAO,SAAS;AAC1B,aAAU,cAAc,UAAU,aAAa;;AAEjD,MAAI,kBAAkB;AACpB,YAAS,OAAO,SAAS,GAAG;AAC5B,aAAU;;;AAGd,UAAS,OAAO,SAAS,GAAG;AAC5B,WAAU,cAAc,eAAe,aAAa;AAEpD,KAAI,eAAe,eAAe,iBAAiB,SAAS,GAAG;AAC7D,MAAI,gBAAgB;AAClB,YAAS,OAAO,SAAS,GAAG;AAC5B,aAAU;;AAEZ,YAAU,YAAY,YAAY;AAClC,YAAU,GAAG,WAAW,WAAW,MAAM,GAAG,IAAI,YAAY,IAAI,WAAW,MAAM,WAAW;;AAE9F,QAAO,OAAO,SAAS,GAAG;;AAG5B,SAAS,mBAAmB,QAAwB,WAA2B;CAC7E,IAAI,eAAe;CACnB,MAAM,eAAe,oBAAoB,OAAO,WAAW;AAC3D,KAAI,aAAa,MAAM;AACrB,kBAAgB;EAChB,MAAM,qBACJ,OAAO,oBAAoB,sBAC3B;AACF,kBAAgBA,QAAiB,oBAAoB,OAAO,GAAG;AAE/D,OAAK,MAAM,eAAe,aACxB,iBAAgB,MAAM,YAAY;AAEpC,kBAAgB;;AAElB,QAAO;;AAGT,eAAsB,0BACpB,QACA,aACA,eAA8C,EAAE,EAChD,oBACe;AACf,QAAO,MAAM,8BAA8B;AAC3C,KAAI,OAAO,SAAS,UAAU;AAC5B,SAAO,MACL,gFACD;AACD;;CAGF,MAAM,aAAa;CACnB,MAAM,WAAW,YAAY,QAC1B,WACC,OAAO,WAAW,gBAClB,CAAC,OAAO,UAAU,OAAO,YAAY,QAAQ,uBAAuB,CACvE;AACD,KACE,EACE,OAAO,wBAAwB,QAC/B,OAAO,gCAAgC,QACvC,OAAO,cAAc,MAAM,SAAS,KAAK,4BAA4B,KACnE,QACF,SAAS,MACN,WACC,CAAC,CAAC,OAAO,+BACT,CAAC,CAAC,OAAO,8BACZ,GAEH;AACA,MAAI,aAAa,IAAI,SAAS,CAC5B,QAAO,KACL,EAAE,OAAO,OAAO,0BAA0B,EAC1C,4CACD;OACI;AACL,UAAO,MAAM,+BAA+B;AAC5C,SAAM,SAAS,mBAAmB,OAAO,yBAA0B;;AAErE;;;AAGF,KAAI,OAAO,oBAAoB,OAAO;AACpC,SAAO,MAAM,qDAAqD;AAClE;;AAEF,QAAO,MAAM,gCAAgC;CAG7C,IAAI,gCAAgC;CACpC,MAAM,qBAGF,EAAE;AACN,QAAO,MAAM,+DAA+D;AAC5E,KAAI,iBAAiB,aAAa,CAChC,MAAK,MAAM,CAAC,SAAS,cAAc,OAAO,QAAQ,aAAa,CAC7D,MAAK,MAAM,YAAY,UACrB,MAAK,MAAM,OAAO,SAAS,MAAM;EAC/B,MAAM,OAAO,IAAI,eAAe,IAAI;EACpC,MAAM,iBAAiB,CAAC,CAAC,IAAI,SAAS,MACnC,YAAY,QAAQ,eAAe,cACrC;AACD,MAAI,SAAS,IAAI,sBAAsB,iBAAiB;AACtD,mCAAgC;AAChC,sBAAmB,aAAa,EAAE;AAClC,sBAAmB,SAAS,UAAU;IACpC;IACA,WAAW,IAAI;IAChB;;;CAOX,MAAM,cAAc,gBAAgB,SAAS;AAC7C,KACE,OAAO,gCACP,CAAC,eACD,CAAC,+BACD;AACA,MAAI,aAAa,IAAI,SAAS,CAC5B,QAAO,KACL,EAAE,OAAO,OAAO,0BAA0B,EAC1C,4CACD;OACI;AACL,UAAO,MAAM,+BAA+B;AAC5C,SAAM,SAAS,mBAAmB,OAAO,yBAA0B;;AAErE;;CAEF,IAAI,YAAY;AAEhB,KAAI,OAAO,2BAA2B,OACpC,cACEA,QAAiB,OAAO,2BAA2B,OAAO,GAAG;AAGjE,KAAI,mBAAmB,WAAW,YAChC,cACE,mCACA,mBAAmB,sBAAsB,GACzC,8BAA8B,mBAAmB,SAAS;UACnD,oBAAoB,WAAW,cACxC,cACE,6CACA,mBAAmB,sBAAsB,GACzC,+KAA+K,mBAAmB,SAAS;UACpM,oBAAoB,WAAW,eACxC,cACE,mCACA,YAAY,wBAAwB,GACpC;AAIJ,aAAY,mBAAmB,QAAQ,UAAU;AAEjD,KAAI,+BAA+B;AACjC,eAAa;AACb,eAAa,QAAQ,gCAAgC;AACrD,eACE;AACF,eAAa;AACb,eAAa;AACb,OAAK,MAAM,WAAW,OAAO,KAAK,mBAAmB,CAAC,MAAM,EAAE;GAC5D,MAAM,OAAO,mBAAmB;AAChC,QAAK,MAAM,WAAW,OAAO,KAAK,KAAK,CAAC,MAAM,EAAE;IAC9C,MAAM,EAAE,gBAAgB,cAAc,KAAK;IAC3C,MAAM,cAAc,qBAAqB,SAAS,UAAU;AAE5D,iBAAa,KAAK,QAAQ,KAAK,YAAY,KACzC,iBACI,iFACA,oFACL;;;AAGL,eAAa;;AAGf,KAAI,OAAO,qCACT,cAAa,uBAAuB,aAAa;AAGnD,cAAa,kBACX,WACC,WAAW,OAAO,WAAW,kBAC9B,oBACA,2FACA,WACA,sBACA,2CACA,KACD;AACD,cAAa,kBACX,WACC,WAAW,OAAO,WAAW,8BAC9B,sBACA,4GACA,eACD;AACD,cAAa,kBACX,WACC,WAAW,OAAO,WAAW,iBAC9B,qBACA,uGACA,cACA,8BACA,4CACA,KACD;AACD,cAAa,kBACX,WACC,WACC,OAAO,WAAW,0BAClB,OAAO,WAAW,sBAClB,OAAO,WAAW,kCAClB,OAAO,WAAW,+BACpB,gBACA,6GACA,WACA,yBACA,uCACA,KACD;AACD,cAAa,kBACX,WACC,WAAW,OAAO,WAAW,SAC9B,WACA,oHACA,QACD;AACD,cAAa,kBACX,WACC,WAAW,OAAO,WAAW,qBAC9B,iCACA,qHACD;AACD,cAAa,kBACX,WACC,WAAW,OAAO,WAAW,aAC9B,uBACA,8JACA,SACD;AACD,cAAa,kBACX,WACC,WAAW,OAAO,WAAW,WAC9B,yBACA,6GACD;AACD,cAAa,kBACX,WACC,WAAW,OAAO,gBAAgB,mBACnC,4BACA,0JACD;CAED,MAAM,OAAO,wBAAwB,cAAc,OAAO;AAC1D,KAAI,MAAM;AACR,eAAa;AACb,eAAa;;CAGf,MAAM,WAAW;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,MAAM,aAAa,SAAS,QACzB,WACC,CAAC,SAAS,SAAS,OAAO,OAAQ,IAClC,OAAO,gBAAgB,kBAC1B;AACD,cAAa,kBACX,aACC,WAAW,CAAC,CAAC,OAAO,eAAe,CAAC,OAAO,MAC5C,kBACA,gGACA,QACD;AACD,cAAa,kBACX,aACC,WAAW,OAAO,QAAQ,CAAC,OAAO,aACnC,QACA,2GACA,UACA,kBACA,wDACD;AAED,cAAa,kBACX,WACC,WAAW,OAAO,WAAW,mBAC9B,uBACA,8GACA,WACD;AAED,KAAI,CAAC,YACH,cACE;AAIJ,cAAa,MAAM,oCAAoC,QAAQ,aAAa;CAG5E,MAAM,SAAS,UAAU,OAAO;AAChC,cAAa,aAAa,qBACxB,SAAS,eAAe,GAAG,UAAU,SAAS,OAAO,OACtD;AAED,cAAa;AAEb,KAAI,OAAO,0BAA0B;AAMnC,OAHoB,MAAM,SAAS,WACjC,OAAO,yBACR,GACgB,SAAS,WAAW;AACnC,UAAO,MAAM,kDAAkD;AAC/D;;EAKF,MAAM,eAAe,MAAM,SAAS,WAClC,OAAO,0BACP,MACD;AACD,MAAI,cAAc;GAChB,MAAM,EAAE,8BAA8B,oBACpC,aAAa,aAAa,KAAK,CAChC;AACD,QAAK,MAAM,cAAc,OAAO,KAAK,OAAO,0BAA2B,CACrE,QAAO,0BAA0B;AAEnC,QAAK,MAAM,cAAc,OAAO,KAAK,0BAA0B,EAAE;IAC/D,MAAM,YAAY,YAChB,GAAG,0BAA0B,YAAY,UAAU,aACpD;AACD,gBAAY,UAAU,QACpB,WACA,UAAU,QAAQ,OAAO,MAAM,CAChC;;;;AAKP,KAAI,aAAa,IAAI,SAAS,CAC5B,QAAO,KACL,EAAE,OAAO,OAAO,0BAA0B,EAC1C,6CACD;KAED,OAAM,SAAS,YAAY;EACzB,OAAO,OAAO;EACd;EACA,MAAM,SAAS,gBAAgB,WAAW,OAAO,YAAY;EAC7D,QAAQ,OAAO;EACf,cAAc,OAAO;EACtB,CAAC;;AAIN,SAAgB,uBACd,cACQ;CACR,MAAM,oBAMF,EAAE;CACN,IAAI,iBAAiB;AAErB,MAAK,MAAM,CAAC,SAAS,wBAAwB,OAAO,QAAQ,aAAa,CACvE,MAAK,MAAM,eAAe,oBACxB,MAAK,MAAM,OAAO,YAAY,YAAY,KAAK,CAC7C,KAAI,IAAI,WAAW,IAAI,aAAa;AAClC;AACA,oBAAkB,WAAW,kBAAkB,YAAY,EAAE;AAC7D,oBAAkB,SAAS,IAAI,WAAW;GACxC,qBAAqB,IAAI;GACzB,WAAW,IAAI;GAChB;;AAMT,KAAI,mBAAmB,EACrB,QAAO;CAGT,IAAI,cAAc;AAClB,gBACE;AAEF,gBAAe;AACf,gBAAe,yCAAyC,eAAe;AAEvE,gBAAe,QAAQ,wCAAwC;AAC/D,gBACE;AACF,gBACE;AAEF,gBAAe;AACf,gBAAe;AAEf,MAAK,MAAM,WAAW,OAAO,KAAK,kBAAkB,CAAC,MAAM,EAAE;EAC3D,MAAM,OAAO,kBAAkB;AAC/B,OAAK,MAAM,WAAW,OAAO,KAAK,KAAK,CAAC,MAAM,EAAE;GAC9C,MAAM,EAAE,qBAAqB,cAAc,KAAK;GAChD,MAAM,gBAAgB,sBAClB,SAAS,QAAQ,oBAAoB,CAAC,SAAS,aAAa,GAC5D;GACJ,MAAM,cAAc,qBAAqB,SAAS,UAAU;AAC5D,kBAAe,KAAK,QAAQ,KAAK,YAAY,OAAO,cAAc;;;AAItE,gBAAe;AAEf,QAAO;;AAGT,SAAS,UAAU,QAAgC;CACjD,IAAI,SAAS;AACb,KAAI,OAAO,2BAA2B,OACpC,WACE,UACAA,QAAiB,OAAO,2BAA2B,OAAO,GAC1D;AAGJ,QAAO;;AAGT,eAAsB,oCACpB,QACA,cACiB;CACjB,IAAI,SAAS;AAEb,KACE,kBAAkB,OAAO,2CAA2C,IACpE,OAAO,+CAA+C,OAEtD,QAAO;AAGT,WAAU;CAGV,MAAM,kBAAkB,OADK,MAAM,gBAAgB,QAAQ,EACR,qBACjD,QACA,aACD;AAED,KAAI,gBAAgB,WAAW,GAAG;AAChC,YACE;AACF,SAAO;;CAGT,MAAM,4BAA4B,gBAAgB,QAAQ,UACxD,kBAAkB,MAAM,aAAa,CACtC;CACD,MAAM,gCACJ,gBAAgB,SAAS,0BAA0B;AAErD,WAAU,QAAQ,sCAAsC;AACxD,WAAU,OAAO,8BAA8B,OAAO,gBAAgB,OAAO;AAC7E,KAAI,SAAS,OAAO,uBAAuB,CACzC,WAAU;KAEV,WACE;CAGJ,IAAI;AACJ,SAAQ,OAAO,4CAAf;EAEE,KAAK;AACH,6BAA0B;AAC1B;EACF,QACE,2BAA0B;;CAG9B,MAAM,iBAGF,EAAE;AACN,MAAK,MAAM,iBAAiB,yBAAyB;EACnD,MAAM,EAAE,SAAS,gBAAgB,cAAc;AAC/C,MAAI,kBAAkB,eAAe,SAAU,CAC7C,gBAAe,WAAY,EAAE;AAE/B,MAAI,kBAAkB,eAAe,SAAU,aAAa,CAC1D,gBAAe,SAAU,eAAe,EAAE;AAE5C,MACE,kBACE,eAAe,SAAU,aAAa,cAAc,aACrD,CAED,gBAAe,SAAU,aAAa,cAAc,eAAe,EAAE;AAEvE,iBAAe,SAAU,aAAa,cAAc,aAAa,KAC/D,cACD;;AAGH,MAAK,MAAM,CAAC,SAAS,uBAAuB,OAAO,QAAQ,eAAe,EAAE;AAC1E,YAAU,qBAAqB,QAAQ;AACvC,OAAK,MAAM,CAAC,aAAa,uBAAuB,OAAO,QACrD,mBACD,EAAE;AACD,aAAU,qBAAqB,YAAY;AAC3C,QAAK,MAAM,CAAC,aAAa,SAAS,OAAO,QAAQ,mBAAmB,EAAE;AACpE,cAAU,qBAAqB,YAAY;AAC3C,SAAK,MAAM,OAAO,MAAM;KACtB,MAAM,KAAK,IAAI,cAAc;KAC7B,MAAM,SAAS,iBAAiB,IAAI,aAAa,GAC7C,cAAc,IAAI,aAAa,KAC/B;AACJ,eAAU,MAAM,GAAG,kCAAkC,GAAG,GAAG,OAAO;;AAEpE,cAAU;;AAEZ,aAAU;;AAEZ,YAAU;;AAGZ,QAAO"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "renovate",
|
|
3
3
|
"description": "Automated dependency updates. Flexible so you don't need to be.",
|
|
4
|
-
"version": "43.
|
|
4
|
+
"version": "43.112.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"renovate": "dist/renovate.js",
|
|
@@ -278,7 +278,7 @@
|
|
|
278
278
|
"npm-run-all2": "8.0.4",
|
|
279
279
|
"nyc": "18.0.0",
|
|
280
280
|
"oxlint": "1.57.0",
|
|
281
|
-
"oxlint-tsgolint": "0.
|
|
281
|
+
"oxlint-tsgolint": "0.20.0",
|
|
282
282
|
"rimraf": "6.1.3",
|
|
283
283
|
"semantic-release": "25.0.3",
|
|
284
284
|
"tar": "7.5.13",
|
package/renovate-schema.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$id": "https://docs.renovatebot.com/renovate-schema.json",
|
|
3
|
-
"title": "JSON schema for Renovate 43.
|
|
3
|
+
"title": "JSON schema for Renovate 43.112.1 config files (https://renovatebot.com/)",
|
|
4
4
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
5
|
-
"x-renovate-version": "43.
|
|
5
|
+
"x-renovate-version": "43.112.1",
|
|
6
6
|
"allowComments": true,
|
|
7
7
|
"type": "object",
|
|
8
8
|
"properties": {
|