renovate 44.101.0 → 44.101.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.
Files changed (56) hide show
  1. package/dist/modules/datasource/pypi/common.js +2 -1
  2. package/dist/modules/datasource/pypi/common.js.map +1 -1
  3. package/dist/modules/datasource/pypi/host-rules.js +43 -0
  4. package/dist/modules/datasource/pypi/host-rules.js.map +1 -0
  5. package/dist/modules/datasource/pypi/index.js +18 -19
  6. package/dist/modules/datasource/pypi/index.js.map +1 -1
  7. package/dist/modules/datasource/util.js +7 -1
  8. package/dist/modules/datasource/util.js.map +1 -1
  9. package/dist/modules/manager/fingerprint.generated.js +5 -5
  10. package/dist/modules/manager/fingerprint.generated.js.map +1 -1
  11. package/dist/modules/manager/helmv3/common.js +1 -1
  12. package/dist/modules/manager/helmv3/common.js.map +1 -1
  13. package/dist/modules/manager/pep621/processors/uv.js +3 -20
  14. package/dist/modules/manager/pep621/processors/uv.js.map +1 -1
  15. package/dist/modules/manager/pip-compile/artifacts.js +4 -3
  16. package/dist/modules/manager/pip-compile/artifacts.js.map +1 -1
  17. package/dist/modules/manager/pip-compile/common.js +10 -17
  18. package/dist/modules/manager/pip-compile/common.js.map +1 -1
  19. package/dist/modules/manager/pipenv/artifacts.js +9 -26
  20. package/dist/modules/manager/pipenv/artifacts.js.map +1 -1
  21. package/dist/modules/manager/poetry/artifacts.js +3 -26
  22. package/dist/modules/manager/poetry/artifacts.js.map +1 -1
  23. package/dist/modules/manager/swift/artifacts.js +12 -0
  24. package/dist/modules/manager/swift/artifacts.js.map +1 -1
  25. package/dist/util/git/index.d.ts +7 -1
  26. package/dist/util/git/index.js +9 -1
  27. package/dist/util/git/index.js.map +1 -1
  28. package/dist/util/host-rules.js +2 -2
  29. package/dist/util/host-rules.js.map +1 -1
  30. package/dist/util/url.d.ts +10 -1
  31. package/dist/util/url.js +10 -1
  32. package/dist/util/url.js.map +1 -1
  33. package/dist/workers/repository/process/lookup/bucket.js +23 -4
  34. package/dist/workers/repository/process/lookup/bucket.js.map +1 -1
  35. package/dist/workers/repository/process/lookup/current.js +28 -1
  36. package/dist/workers/repository/process/lookup/current.js.map +1 -1
  37. package/dist/workers/repository/process/lookup/digest.js +99 -0
  38. package/dist/workers/repository/process/lookup/digest.js.map +1 -0
  39. package/dist/workers/repository/process/lookup/filter-checks.js +28 -7
  40. package/dist/workers/repository/process/lookup/filter-checks.js.map +1 -1
  41. package/dist/workers/repository/process/lookup/generate.js +2 -2
  42. package/dist/workers/repository/process/lookup/generate.js.map +1 -1
  43. package/dist/workers/repository/process/lookup/index.js +24 -161
  44. package/dist/workers/repository/process/lookup/index.js.map +1 -1
  45. package/dist/workers/repository/process/lookup/range-strategy.js +18 -0
  46. package/dist/workers/repository/process/lookup/range-strategy.js.map +1 -0
  47. package/dist/workers/repository/process/lookup/update-type.js +14 -5
  48. package/dist/workers/repository/process/lookup/update-type.js.map +1 -1
  49. package/dist/workers/repository/process/lookup/utils.js +13 -2
  50. package/dist/workers/repository/process/lookup/utils.js.map +1 -1
  51. package/dist/workers/repository/process/lookup/version-compatibility.js +51 -0
  52. package/dist/workers/repository/process/lookup/version-compatibility.js.map +1 -0
  53. package/dist/workers/repository/process/lookup/vulnerability.js +53 -0
  54. package/dist/workers/repository/process/lookup/vulnerability.js.map +1 -0
  55. package/package.json +2 -2
  56. package/renovate-schema.json +2 -2
@@ -1,5 +1,6 @@
1
1
  import { regEx } from "../../../util/regex.js";
2
2
  //#region lib/modules/datasource/pypi/common.ts
3
+ const pypiDatasourceId = "pypi";
3
4
  const githubRepoPattern = regEx(/^https?:\/\/github\.com\/(?<owner>[^/]+)\/[^/]+$/);
4
5
  function isGitHubRepo(url) {
5
6
  const m = url.match(githubRepoPattern);
@@ -9,6 +10,6 @@ function normalizePythonDepName(name) {
9
10
  return name.replace(regEx(/[-_.]+/g), "-").toLowerCase();
10
11
  }
11
12
  //#endregion
12
- export { isGitHubRepo, normalizePythonDepName };
13
+ export { isGitHubRepo, normalizePythonDepName, pypiDatasourceId };
13
14
 
14
15
  //# sourceMappingURL=common.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"common.js","names":[],"sources":["../../../../lib/modules/datasource/pypi/common.ts"],"sourcesContent":["import { regEx } from '../../../util/regex.ts';\n\nconst githubRepoPattern = regEx(\n /^https?:\\/\\/github\\.com\\/(?<owner>[^/]+)\\/[^/]+$/,\n);\n\nexport function isGitHubRepo(url: string): boolean {\n const m = url.match(githubRepoPattern);\n return !!m && m.groups!.owner !== 'sponsors';\n}\n\n// https://packaging.python.org/en/latest/specifications/name-normalization/\nexport function normalizePythonDepName(name: string): string {\n return name.replace(regEx(/[-_.]+/g), '-').toLowerCase();\n}\n"],"mappings":";;AAEA,MAAM,oBAAoB,MACxB,kDACF;AAEA,SAAgB,aAAa,KAAsB;CACjD,MAAM,IAAI,IAAI,MAAM,iBAAiB;CACrC,OAAO,CAAC,CAAC,KAAK,EAAE,OAAQ,UAAU;AACpC;AAGA,SAAgB,uBAAuB,MAAsB;CAC3D,OAAO,KAAK,QAAQ,MAAM,SAAS,GAAG,GAAG,CAAC,CAAC,YAAY;AACzD"}
1
+ {"version":3,"file":"common.js","names":[],"sources":["../../../../lib/modules/datasource/pypi/common.ts"],"sourcesContent":["import { regEx } from '../../../util/regex.ts';\n\nexport const pypiDatasourceId = 'pypi';\n\nconst githubRepoPattern = regEx(\n /^https?:\\/\\/github\\.com\\/(?<owner>[^/]+)\\/[^/]+$/,\n);\n\nexport function isGitHubRepo(url: string): boolean {\n const m = url.match(githubRepoPattern);\n return !!m && m.groups!.owner !== 'sponsors';\n}\n\n// https://packaging.python.org/en/latest/specifications/name-normalization/\nexport function normalizePythonDepName(name: string): string {\n return name.replace(regEx(/[-_.]+/g), '-').toLowerCase();\n}\n"],"mappings":";;AAEA,MAAa,mBAAmB;AAEhC,MAAM,oBAAoB,MACxB,kDACF;AAEA,SAAgB,aAAa,KAAsB;CACjD,MAAM,IAAI,IAAI,MAAM,iBAAiB;CACrC,OAAO,CAAC,CAAC,KAAK,EAAE,OAAQ,UAAU;AACpC;AAGA,SAAgB,uBAAuB,MAAsB;CAC3D,OAAO,KAAK,QAAQ,MAAM,SAAS,GAAG,GAAG,CAAC,CAAC,YAAY;AACzD"}
@@ -0,0 +1,43 @@
1
+ import { logger } from "../../../logger/index.js";
2
+ import { parseUrl } from "../../../util/url.js";
3
+ import { find } from "../../../util/host-rules.js";
4
+ import { getGoogleAuthHostRule, isGoogleArtifactRegistry } from "../util.js";
5
+ import { pypiDatasourceId } from "./common.js";
6
+ //#region lib/modules/datasource/pypi/host-rules.ts
7
+ /**
8
+ * Resolves the credentials for a Python package index URL.
9
+ *
10
+ * The URL's own `user:password@` part - which is often a placeholder such as
11
+ * `${USER}:${PASS}@` - does not stop it matching a `matchHost` without
12
+ * credentials, as `find()` ignores userinfo when matching. Google Artifact
13
+ * Registry is only asked for a token when no host rule supplies credentials,
14
+ * so an explicitly configured username/password always wins.
15
+ */
16
+ async function findPypiIndexCredentials(indexUrl) {
17
+ const parsedUrl = parseUrl(indexUrl);
18
+ if (!parsedUrl) {
19
+ logger.once.debug(`Failed to parse index URL ${indexUrl}`);
20
+ return {};
21
+ }
22
+ const { username, password } = find({
23
+ hostType: pypiDatasourceId,
24
+ url: parsedUrl.toString()
25
+ });
26
+ if (username ?? password) return {
27
+ username,
28
+ password
29
+ };
30
+ if (isGoogleArtifactRegistry(parsedUrl.hostname)) {
31
+ const googleHostRule = await getGoogleAuthHostRule();
32
+ if (googleHostRule) return {
33
+ username: googleHostRule.username,
34
+ password: googleHostRule.password
35
+ };
36
+ logger.once.debug(`Could not get Google access token (url=${parsedUrl.toString()})`);
37
+ }
38
+ return {};
39
+ }
40
+ //#endregion
41
+ export { findPypiIndexCredentials };
42
+
43
+ //# sourceMappingURL=host-rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host-rules.js","names":[],"sources":["../../../../lib/modules/datasource/pypi/host-rules.ts"],"sourcesContent":["import { logger } from '../../../logger/index.ts';\nimport { find } from '../../../util/host-rules.ts';\nimport { parseUrl } from '../../../util/url.ts';\nimport { getGoogleAuthHostRule, isGoogleArtifactRegistry } from '../util.ts';\nimport { pypiDatasourceId } from './common.ts';\nimport type { PypiIndexCredentials } from './types.ts';\n\n/**\n * Resolves the credentials for a Python package index URL.\n *\n * The URL's own `user:password@` part - which is often a placeholder such as\n * `${USER}:${PASS}@` - does not stop it matching a `matchHost` without\n * credentials, as `find()` ignores userinfo when matching. Google Artifact\n * Registry is only asked for a token when no host rule supplies credentials,\n * so an explicitly configured username/password always wins.\n */\nexport async function findPypiIndexCredentials(\n indexUrl: string | undefined,\n): Promise<PypiIndexCredentials> {\n const parsedUrl = parseUrl(indexUrl);\n if (!parsedUrl) {\n logger.once.debug(`Failed to parse index URL ${indexUrl}`);\n return {};\n }\n\n const { username, password } = find({\n hostType: pypiDatasourceId,\n url: parsedUrl.toString(),\n });\n if (username ?? password) {\n return { username, password };\n }\n\n if (isGoogleArtifactRegistry(parsedUrl.hostname)) {\n const googleHostRule = await getGoogleAuthHostRule();\n if (googleHostRule) {\n return {\n username: googleHostRule.username,\n password: googleHostRule.password,\n };\n }\n logger.once.debug(\n `Could not get Google access token (url=${parsedUrl.toString()})`,\n );\n }\n\n return {};\n}\n"],"mappings":";;;;;;;;;;;;;;;AAgBA,eAAsB,yBACpB,UAC+B;CAC/B,MAAM,YAAY,SAAS,QAAQ;CACnC,IAAI,CAAC,WAAW;EACd,OAAO,KAAK,MAAM,6BAA6B,UAAU;EACzD,OAAO,CAAC;CACV;CAEA,MAAM,EAAE,UAAU,aAAa,KAAK;EAClC,UAAU;EACV,KAAK,UAAU,SAAS;CAC1B,CAAC;CACD,IAAI,YAAY,UACd,OAAO;EAAE;EAAU;CAAS;CAG9B,IAAI,yBAAyB,UAAU,QAAQ,GAAG;EAChD,MAAM,iBAAiB,MAAM,sBAAsB;EACnD,IAAI,gBACF,OAAO;GACL,UAAU,eAAe;GACzB,UAAU,eAAe;EAC3B;EAEF,OAAO,KAAK,MACV,0CAA0C,UAAU,SAAS,EAAE,EACjE;CACF;CAEA,OAAO,CAAC;AACV"}
@@ -1,6 +1,8 @@
1
1
  import { getEnv } from "../../../util/env.js";
2
2
  import { regEx } from "../../../util/regex.js";
3
3
  import { coerceArray, deduplicateArray } from "../../../util/array.js";
4
+ import { toBase64 } from "../../../util/string.js";
5
+ import { addSecretForSanitizing } from "../../../util/sanitize.js";
4
6
  import { logger } from "../../../logger/index.js";
5
7
  import { ensureTrailingSlash, parseUrl } from "../../../util/url.js";
6
8
  import { ExternalHostError } from "../../../types/errors/external-host-error.js";
@@ -11,14 +13,15 @@ import "../../../util/http/index.js";
11
13
  import { asTimestamp } from "../../../util/timestamp.js";
12
14
  import { Datasource } from "../datasource.js";
13
15
  import { parse } from "../../../util/html.js";
14
- import { getGoogleAuthToken } from "../util.js";
15
- import { isGitHubRepo, normalizePythonDepName } from "./common.js";
16
+ import { isGoogleArtifactRegistry } from "../util.js";
17
+ import { isGitHubRepo, normalizePythonDepName, pypiDatasourceId } from "./common.js";
18
+ import { findPypiIndexCredentials } from "./host-rules.js";
16
19
  import { PypiResponse, PypiSimpleResponse } from "./schema.js";
17
20
  import { isNonEmptyString } from "@sindresorhus/is";
18
21
  import changelogFilenameRegex from "changelog-filename-regex";
19
22
  //#region lib/modules/datasource/pypi/index.ts
20
23
  var PypiDatasource = class PypiDatasource extends Datasource {
21
- static id = "pypi";
24
+ static id = pypiDatasourceId;
22
25
  constructor() {
23
26
  super(PypiDatasource.id);
24
27
  }
@@ -76,25 +79,21 @@ var PypiDatasource = class PypiDatasource extends Datasource {
76
79
  lookupUrl
77
80
  };
78
81
  }
79
- if (parsedUrl.hostname.endsWith(".pkg.dev")) {
80
- const auth = await getGoogleAuthToken();
81
- if (auth) {
82
- const sanitizedLookupUrl = this.sanitizeLookupUrl(lookupUrl, parsedUrl);
83
- return {
84
- headers: { authorization: `Basic ${auth}` },
85
- lookupUrl: sanitizedLookupUrl
86
- };
87
- }
88
- logger.once.debug({ lookupUrl }, "Could not get Google access token");
89
- return {
90
- headers: {},
91
- lookupUrl
92
- };
93
- }
94
- return {
82
+ if (!isGoogleArtifactRegistry(parsedUrl.hostname)) return {
83
+ headers: {},
84
+ lookupUrl
85
+ };
86
+ const { username, password } = await findPypiIndexCredentials(lookupUrl);
87
+ if (!username && !password) return {
95
88
  headers: {},
96
89
  lookupUrl
97
90
  };
91
+ const auth = toBase64(`${username ?? ""}:${password ?? ""}`);
92
+ addSecretForSanitizing(auth);
93
+ return {
94
+ headers: { authorization: `Basic ${auth}` },
95
+ lookupUrl: this.sanitizeLookupUrl(lookupUrl, parsedUrl)
96
+ };
98
97
  }
99
98
  async getDependency(packageName, hostUrl) {
100
99
  const lookupUrl = new URL(`${normalizePythonDepName(packageName)}/json`, hostUrl).href;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["pep440.id","HttpError"],"sources":["../../../../lib/modules/datasource/pypi/index.ts"],"sourcesContent":["import { isNonEmptyString } from '@sindresorhus/is';\nimport changelogFilenameRegex from 'changelog-filename-regex';\nimport { logger } from '../../../logger/index.ts';\nimport { ExternalHostError } from '../../../types/errors/external-host-error.ts';\nimport { coerceArray, deduplicateArray } from '../../../util/array.ts';\nimport { getEnv } from '../../../util/env.ts';\nimport { parse } from '../../../util/html.ts';\nimport { HttpError } from '../../../util/http/index.ts';\nimport type {\n HttpResponse,\n OutgoingHttpHeaders,\n} from '../../../util/http/types.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { Json } from '../../../util/schema-utils/index.ts';\nimport type { Timestamp } from '../../../util/timestamp.ts';\nimport { asTimestamp } from '../../../util/timestamp.ts';\nimport { ensureTrailingSlash, parseUrl } from '../../../util/url.ts';\nimport * as pep440 from '../../versioning/pep440/index.ts';\nimport { Datasource } from '../datasource.ts';\nimport type { GetReleasesConfig, Release, ReleaseResult } from '../types.ts';\nimport { getGoogleAuthToken } from '../util.ts';\nimport { isGitHubRepo, normalizePythonDepName } from './common.ts';\nimport type { PypiRelease } from './schema.ts';\nimport { PypiResponse, PypiSimpleResponse } from './schema.ts';\nimport type { Releases } from './types.ts';\n\nexport class PypiDatasource extends Datasource {\n static readonly id = 'pypi';\n\n constructor() {\n super(PypiDatasource.id);\n }\n\n override readonly caching = true;\n\n override readonly customRegistrySupport = true;\n\n static readonly defaultURL =\n getEnv().PIP_INDEX_URL ?? 'https://pypi.org/pypi/';\n override readonly defaultRegistryUrls = [PypiDatasource.defaultURL];\n\n override readonly defaultVersioning = pep440.id;\n\n override readonly registryStrategy = 'merge';\n\n override readonly releaseTimestampSupport = true;\n override readonly releaseTimestampNote =\n 'The release timestamp is determined from the earliest `upload_time` field of the files of a version. When using the Simple API, timestamps are available if the server supports the JSON-based Simple API (PEP 691).';\n override readonly sourceUrlSupport = 'release';\n override readonly sourceUrlNote =\n 'The source URL is determined from the `homepage` field if it is a github repository, else we use the `project_urls` field.';\n\n async getReleases({\n packageName,\n registryUrl,\n }: GetReleasesConfig): Promise<ReleaseResult | null> {\n let dependency: ReleaseResult | null = null;\n // TODO: null check (#22198)\n const hostUrl = ensureTrailingSlash(\n registryUrl!.replace('https://pypi.org/simple', 'https://pypi.org/pypi'),\n );\n const normalizedLookupName = normalizePythonDepName(packageName);\n\n // not all simple indexes use this identifier, but most do\n if (hostUrl.endsWith('/simple/') || hostUrl.endsWith('/+simple/')) {\n logger.trace(\n { packageName, hostUrl },\n 'Looking up pypi simple dependency',\n );\n dependency = await this.getSimpleDependency(\n normalizedLookupName,\n hostUrl,\n );\n } else {\n logger.trace({ packageName, hostUrl }, 'Looking up pypi api dependency');\n try {\n // we need to resolve early here so we can catch any 404s and fallback to a simple lookup\n dependency = await this.getDependency(normalizedLookupName, hostUrl);\n } catch (err) {\n // error contacting json-style api -- attempt to fallback to a simple-style api\n logger.trace(\n { packageName, hostUrl, err },\n 'Looking up pypi simple dependency via fallback',\n );\n dependency = await this.getSimpleDependency(\n normalizedLookupName,\n hostUrl,\n );\n }\n }\n return dependency;\n }\n\n private sanitizeLookupUrl(lookupUrl: string, parsedUrl: URL): string {\n if (!parsedUrl.username && !parsedUrl.password) {\n return lookupUrl;\n }\n\n parsedUrl.username = '';\n parsedUrl.password = '';\n return parsedUrl.toString();\n }\n\n private async getAuthHeaders(\n lookupUrl: string,\n ): Promise<{ headers: OutgoingHttpHeaders; lookupUrl: string }> {\n const parsedUrl = parseUrl(lookupUrl);\n // v8 ignore if -- TODO: refactor to cover this branch through public behavior again\n if (!parsedUrl) {\n logger.once.debug({ lookupUrl }, 'Failed to parse URL');\n return { headers: {}, lookupUrl };\n }\n if (parsedUrl.hostname.endsWith('.pkg.dev')) {\n const auth = await getGoogleAuthToken();\n if (auth) {\n const sanitizedLookupUrl = this.sanitizeLookupUrl(lookupUrl, parsedUrl);\n return {\n headers: { authorization: `Basic ${auth}` },\n lookupUrl: sanitizedLookupUrl,\n };\n }\n logger.once.debug({ lookupUrl }, 'Could not get Google access token');\n return { headers: {}, lookupUrl };\n }\n return { headers: {}, lookupUrl };\n }\n\n private async getDependency(\n packageName: string,\n hostUrl: string,\n ): Promise<ReleaseResult | null> {\n const lookupUrl = new URL(\n `${normalizePythonDepName(packageName)}/json`,\n hostUrl,\n ).href;\n const dependency: ReleaseResult = { releases: [] };\n logger.trace({ lookupUrl }, 'Pypi api got lookup');\n const { headers, lookupUrl: sanitizedUrl } =\n await this.getAuthHeaders(lookupUrl);\n const rep = await this.http.getJson(\n sanitizedUrl,\n { headers },\n PypiResponse,\n );\n const dep = rep?.body;\n if (rep.authorization) {\n dependency.isPrivate = true;\n }\n logger.trace({ lookupUrl }, 'Got pypi api result');\n\n if (dep.info?.home_page) {\n dependency.homepage = dep.info.home_page;\n if (isGitHubRepo(dep.info.home_page)) {\n dependency.sourceUrl = dep.info.home_page.replace(\n 'http://',\n 'https://',\n );\n }\n }\n\n if (dep.info?.project_urls) {\n for (const [name, projectUrl] of Object.entries(dep.info.project_urls)) {\n const lower = name.toLowerCase();\n\n if (\n projectUrl &&\n !dependency.sourceUrl &&\n (lower.startsWith('repo') ||\n lower === 'code' ||\n lower === 'source' ||\n isGitHubRepo(projectUrl))\n ) {\n dependency.sourceUrl = projectUrl;\n }\n\n if (\n !dependency.changelogUrl &&\n ([\n 'changelog',\n 'change log',\n 'changes',\n 'release notes',\n 'news',\n \"what's new\",\n ].includes(lower) ||\n changelogFilenameRegex.exec(lower))\n ) {\n // from https://github.com/pypa/warehouse/blob/418c7511dc367fb410c71be139545d0134ccb0df/warehouse/templates/packaging/detail.html#L24\n dependency.changelogUrl = projectUrl;\n }\n }\n }\n\n if (dep.releases) {\n dependency.releases = PypiDatasource.toReleases(dep.releases);\n }\n return dependency;\n }\n\n private static getEarliestTimestamp(\n releases: PypiRelease[],\n ): Timestamp | null {\n let earliest: Timestamp | null = null;\n for (const { upload_time } of releases) {\n const timestamp = asTimestamp(upload_time);\n // `asTimestamp` normalizes to UTC ISO 8601, so comparing the strings compares the instants\n if (timestamp && (!earliest || timestamp < earliest)) {\n earliest = timestamp;\n }\n }\n return earliest;\n }\n\n private static extractVersionFromLinkText(\n text: string,\n packageName: string,\n ): string | null {\n // source packages\n const lcText = text.toLowerCase();\n const normalizedSrcText = normalizePythonDepName(text);\n const srcPrefix = `${packageName}-`;\n\n // source distribution format: `{name}-{version}.tar.gz` (https://packaging.python.org/en/latest/specifications/source-distribution-format/#source-distribution-file-name)\n // binary distribution: `{distribution}-{version}(-{build tag})?-{python tag}-{abi tag}-{platform tag}.whl` (https://packaging.python.org/en/latest/specifications/binary-distribution-format/#file-name-convention)\n // officially both `name` and `distribution` should be normalized and then the - replaced with _, but in reality this is not the case\n // We therefore normalize the name we have (replacing `_-.` with -) and then check if the text starts with the normalized name\n\n if (!normalizedSrcText.startsWith(srcPrefix)) {\n return null;\n }\n\n // strip off the prefix using the prefix length as we may have normalized the srcPrefix/packageName\n // We assume that neither the version nor the suffix contains multiple `-` like `0.1.2---rc1.tar.gz`\n // and use the difference in length to strip off the prefix in case the name contains double `--` characters\n const normalizedLengthDiff = lcText.length - normalizedSrcText.length;\n const res = lcText.slice(srcPrefix.length + normalizedLengthDiff);\n\n // source distribution\n const srcSuffixes = ['.tar.gz', '.tar.bz2', '.tar.xz', '.zip', '.tgz'];\n const srcSuffix = srcSuffixes.find((suffix) => lcText.endsWith(suffix));\n if (srcSuffix) {\n // strip off the suffix using character length\n return res.slice(0, -srcSuffix.length);\n }\n\n // binary distribution\n // for binary distributions the version is the first part after the removed distribution name\n const wheelSuffix = '.whl';\n if (lcText.endsWith(wheelSuffix) && lcText.split('-').length > 2) {\n return res.split('-')[0];\n }\n return null;\n }\n\n private static cleanSimpleHtml(html: string): string {\n return (\n html\n .replace(regEx(/<\\/?pre>/), '')\n // Certain simple repositories like artifactory don't escape > and <\n .replace(\n regEx(/data-requires-python=\"(?<before>[^\"]*?)>(?<after>[^\"]*?)\"/g),\n 'data-requires-python=\"$<before>&gt;$<after>\"',\n )\n .replace(\n regEx(/data-requires-python=\"(?<before>[^\"]*?)<(?<after>[^\"]*?)\"/g),\n 'data-requires-python=\"$<before>&lt;$<after>\"',\n )\n );\n }\n\n private static getSimpleReleasesFromHtml(\n html: string,\n packageName: string,\n ): Releases {\n const root = parse(PypiDatasource.cleanSimpleHtml(html));\n const links = root.querySelectorAll('a');\n const releases: Releases = {};\n for (const link of Array.from(links)) {\n const version = PypiDatasource.extractVersionFromLinkText(\n link.text?.trim(),\n packageName,\n );\n if (version) {\n const release: PypiRelease = {\n yanked: link.hasAttribute('data-yanked'),\n };\n const requiresPython = link.getAttribute('data-requires-python');\n if (requiresPython) {\n release.requires_python = requiresPython;\n }\n (releases[version] ??= []).push(release);\n }\n }\n return releases;\n }\n\n private static getSimpleReleasesFromJson(\n json: string,\n packageName: string,\n ): Releases | null {\n const releases: Releases = {};\n const parsed = Json.pipe(PypiSimpleResponse).safeParse(json);\n if (!parsed.success) {\n logger.once.warn(\n { packageName, err: parsed.error },\n 'Failed to parse JSON-based Simple API response',\n );\n // Distinguish a malformed response from a package with genuinely no files, so the caller doesn't mistake an error for an empty result.\n return null;\n }\n for (const file of parsed.data.files) {\n const version = PypiDatasource.extractVersionFromLinkText(\n file.filename,\n packageName,\n );\n if (version) {\n (releases[version] ??= []).push(file);\n }\n }\n return releases;\n }\n\n private async getSimpleDependency(\n packageName: string,\n hostUrl: string,\n ): Promise<ReleaseResult | null> {\n const lookupUrl = new URL(\n ensureTrailingSlash(normalizePythonDepName(packageName)),\n hostUrl,\n ).href;\n const dependency: ReleaseResult = { releases: [] };\n const { headers: authHeaders, lookupUrl: sanitizedUrl } =\n await this.getAuthHeaders(lookupUrl);\n const headers: OutgoingHttpHeaders = {\n ...authHeaders,\n // Request the JSON serialization (PEP 691), falling back to the legacy HTML serialization (PEP 503) via content negotiation.\n // https://github.com/pypa/pip/blob/6b0011b49a068c62f65389bf4cea7af5d28cb002/src/pip/_internal/index/collector.py#L128-L134\n accept:\n 'application/vnd.pypi.simple.v1+json, application/vnd.pypi.simple.v1+html; q=0.1, text/html; q=0.01',\n };\n let response: HttpResponse;\n try {\n response = await this.http.getText(sanitizedUrl, { headers });\n } catch (err) {\n // An `abortOnError` host rule makes `Http` wrap the original error, so unwrap it before looking at the status code.\n const httpErr = err instanceof ExternalHostError ? err.err : err;\n const statusCode =\n httpErr instanceof HttpError ? httpErr.response?.statusCode : undefined;\n // A registry which cannot serve any of the negotiated types may pick a content type of its own, answer `406`, or answer `300`; the spec mandates none of them, but `406` is the common choice.\n // https://packaging.python.org/en/latest/specifications/simple-repository-api/#version-format-selection\n // Retry once without the negotiated `accept` header to preserve the pre-PEP-691 behaviour of a plain request.\n if (statusCode !== 406) {\n throw err;\n }\n\n logger.trace(\n { packageName, hostUrl, statusCode },\n 'Registry rejected negotiated Accept header, retrying without it',\n );\n response = await this.http.getText(sanitizedUrl, {\n headers: authHeaders,\n });\n }\n const dep = response?.body;\n if (!dep) {\n logger.trace({ dependency: packageName }, 'pip package not found');\n return null;\n }\n if (response.authorization) {\n dependency.isPrivate = true;\n }\n\n // Dispatch on the response content-type: JSON serialization (PEP 691) or the legacy HTML serialization (PEP 503). Matched loosely (any `json` media type) rather than the exact vendor type, as some registries/proxies relabel or strip the vendor-specific media type while still returning JSON.\n const contentType = response.headers['content-type'];\n const isJson = !!contentType && contentType.includes('json');\n const looksLikeJson = dep.trimStart().startsWith('{');\n\n if (isJson) {\n if (looksLikeJson) {\n const releases = PypiDatasource.getSimpleReleasesFromJson(\n dep,\n packageName,\n );\n // A parse failure is distinct from a package with genuinely no files, so don't report an empty release list as if it were a real (if empty) result, which would be cached as such.\n if (!releases) {\n return null;\n }\n dependency.releases = PypiDatasource.toReleases(releases);\n return dependency;\n }\n\n // The registry mislabeled a non-JSON body as JSON, so fall through to the HTML parser instead of reporting the package as not found.\n logger.debug(\n { packageName, hostUrl, contentType },\n 'Parsing Simple API response as HTML, as it is labeled as JSON but does not look like it',\n );\n }\n\n const htmlReleases = PypiDatasource.getSimpleReleasesFromHtml(\n dep,\n packageName,\n );\n dependency.releases = PypiDatasource.toReleases(htmlReleases);\n if (dependency.releases.length > 0 || !looksLikeJson) {\n return dependency;\n }\n\n // The registry honored the `Accept` header but omitted or mislabeled the `content-type`, so a JSON body went through the HTML parser and found nothing. Parse it as JSON instead of silently reporting no releases.\n logger.debug(\n { packageName, hostUrl, contentType },\n 'Retrying Simple API response as JSON, as it is not labeled as JSON but looks like it',\n );\n const jsonReleases = PypiDatasource.getSimpleReleasesFromJson(\n dep,\n packageName,\n );\n if (!jsonReleases) {\n return null;\n }\n dependency.releases = PypiDatasource.toReleases(jsonReleases);\n return dependency;\n }\n\n /**\n * The files of a version are not ordered by upload time, so use the earliest one: that is when the version was first published, which is what `minimumReleaseAge` needs.\n */\n private static toReleases(releases: Releases): Release[] {\n const versions = Object.keys(releases);\n return versions.map((version) => {\n const versionReleases = coerceArray(releases[version]);\n const isDeprecated = versionReleases.some(({ yanked }) => yanked);\n const result: Release = { version };\n const releaseTimestamp =\n PypiDatasource.getEarliestTimestamp(versionReleases);\n if (releaseTimestamp) {\n result.releaseTimestamp = releaseTimestamp;\n }\n if (isDeprecated) {\n result.isDeprecated = isDeprecated;\n }\n const pythonConstraints = versionReleases.map(\n ({ requires_python }) => requires_python,\n );\n // A file without `requires_python` can be installed on any Python version, so the version as a whole is unconstrained\n const isUnconstrained = pythonConstraints.some(\n (constraint) => !isNonEmptyString(constraint),\n );\n // There may be multiple releases with different requires_python, so we return all in an array.\n // Report no constraints at all for an unconstrained version, instead of only those of its other files, which would drop the version under `constraintsFiltering=strict`.\n result.constraints = {\n python: isUnconstrained\n ? []\n : deduplicateArray(pythonConstraints.filter(isNonEmptyString)),\n };\n return result;\n });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["pep440.id","HttpError"],"sources":["../../../../lib/modules/datasource/pypi/index.ts"],"sourcesContent":["import { isNonEmptyString } from '@sindresorhus/is';\nimport changelogFilenameRegex from 'changelog-filename-regex';\nimport { logger } from '../../../logger/index.ts';\nimport { ExternalHostError } from '../../../types/errors/external-host-error.ts';\nimport { coerceArray, deduplicateArray } from '../../../util/array.ts';\nimport { getEnv } from '../../../util/env.ts';\nimport { parse } from '../../../util/html.ts';\nimport { HttpError } from '../../../util/http/index.ts';\nimport type {\n HttpResponse,\n OutgoingHttpHeaders,\n} from '../../../util/http/types.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { addSecretForSanitizing } from '../../../util/sanitize.ts';\nimport { Json } from '../../../util/schema-utils/index.ts';\nimport { toBase64 } from '../../../util/string.ts';\nimport type { Timestamp } from '../../../util/timestamp.ts';\nimport { asTimestamp } from '../../../util/timestamp.ts';\nimport { ensureTrailingSlash, parseUrl } from '../../../util/url.ts';\nimport * as pep440 from '../../versioning/pep440/index.ts';\nimport { Datasource } from '../datasource.ts';\nimport type { GetReleasesConfig, Release, ReleaseResult } from '../types.ts';\nimport { isGoogleArtifactRegistry } from '../util.ts';\nimport {\n isGitHubRepo,\n normalizePythonDepName,\n pypiDatasourceId,\n} from './common.ts';\nimport { findPypiIndexCredentials } from './host-rules.ts';\nimport type { PypiRelease } from './schema.ts';\nimport { PypiResponse, PypiSimpleResponse } from './schema.ts';\nimport type { Releases } from './types.ts';\n\nexport class PypiDatasource extends Datasource {\n static readonly id = pypiDatasourceId;\n\n constructor() {\n super(PypiDatasource.id);\n }\n\n override readonly caching = true;\n\n override readonly customRegistrySupport = true;\n\n static readonly defaultURL =\n getEnv().PIP_INDEX_URL ?? 'https://pypi.org/pypi/';\n override readonly defaultRegistryUrls = [PypiDatasource.defaultURL];\n\n override readonly defaultVersioning = pep440.id;\n\n override readonly registryStrategy = 'merge';\n\n override readonly releaseTimestampSupport = true;\n override readonly releaseTimestampNote =\n 'The release timestamp is determined from the earliest `upload_time` field of the files of a version. When using the Simple API, timestamps are available if the server supports the JSON-based Simple API (PEP 691).';\n override readonly sourceUrlSupport = 'release';\n override readonly sourceUrlNote =\n 'The source URL is determined from the `homepage` field if it is a github repository, else we use the `project_urls` field.';\n\n async getReleases({\n packageName,\n registryUrl,\n }: GetReleasesConfig): Promise<ReleaseResult | null> {\n let dependency: ReleaseResult | null = null;\n // TODO: null check (#22198)\n const hostUrl = ensureTrailingSlash(\n registryUrl!.replace('https://pypi.org/simple', 'https://pypi.org/pypi'),\n );\n const normalizedLookupName = normalizePythonDepName(packageName);\n\n // not all simple indexes use this identifier, but most do\n if (hostUrl.endsWith('/simple/') || hostUrl.endsWith('/+simple/')) {\n logger.trace(\n { packageName, hostUrl },\n 'Looking up pypi simple dependency',\n );\n dependency = await this.getSimpleDependency(\n normalizedLookupName,\n hostUrl,\n );\n } else {\n logger.trace({ packageName, hostUrl }, 'Looking up pypi api dependency');\n try {\n // we need to resolve early here so we can catch any 404s and fallback to a simple lookup\n dependency = await this.getDependency(normalizedLookupName, hostUrl);\n } catch (err) {\n // error contacting json-style api -- attempt to fallback to a simple-style api\n logger.trace(\n { packageName, hostUrl, err },\n 'Looking up pypi simple dependency via fallback',\n );\n dependency = await this.getSimpleDependency(\n normalizedLookupName,\n hostUrl,\n );\n }\n }\n return dependency;\n }\n\n private sanitizeLookupUrl(lookupUrl: string, parsedUrl: URL): string {\n if (!parsedUrl.username && !parsedUrl.password) {\n return lookupUrl;\n }\n\n parsedUrl.username = '';\n parsedUrl.password = '';\n return parsedUrl.toString();\n }\n\n private async getAuthHeaders(\n lookupUrl: string,\n ): Promise<{ headers: OutgoingHttpHeaders; lookupUrl: string }> {\n const parsedUrl = parseUrl(lookupUrl);\n // v8 ignore if -- TODO: refactor to cover this branch through public behavior again\n if (!parsedUrl) {\n logger.once.debug({ lookupUrl }, 'Failed to parse URL');\n return { headers: {}, lookupUrl };\n }\n // Only Google Artifact Registry needs a header of our own: for every other host `applyHostRule` already turns the matching host rule into request auth\n if (!isGoogleArtifactRegistry(parsedUrl.hostname)) {\n return { headers: {}, lookupUrl };\n }\n\n const { username, password } = await findPypiIndexCredentials(lookupUrl);\n if (!username && !password) {\n return { headers: {}, lookupUrl };\n }\n\n const auth = toBase64(`${username ?? ''}:${password ?? ''}`);\n addSecretForSanitizing(auth);\n return {\n headers: { authorization: `Basic ${auth}` },\n lookupUrl: this.sanitizeLookupUrl(lookupUrl, parsedUrl),\n };\n }\n\n private async getDependency(\n packageName: string,\n hostUrl: string,\n ): Promise<ReleaseResult | null> {\n const lookupUrl = new URL(\n `${normalizePythonDepName(packageName)}/json`,\n hostUrl,\n ).href;\n const dependency: ReleaseResult = { releases: [] };\n logger.trace({ lookupUrl }, 'Pypi api got lookup');\n const { headers, lookupUrl: sanitizedUrl } =\n await this.getAuthHeaders(lookupUrl);\n const rep = await this.http.getJson(\n sanitizedUrl,\n { headers },\n PypiResponse,\n );\n const dep = rep?.body;\n if (rep.authorization) {\n dependency.isPrivate = true;\n }\n logger.trace({ lookupUrl }, 'Got pypi api result');\n\n if (dep.info?.home_page) {\n dependency.homepage = dep.info.home_page;\n if (isGitHubRepo(dep.info.home_page)) {\n dependency.sourceUrl = dep.info.home_page.replace(\n 'http://',\n 'https://',\n );\n }\n }\n\n if (dep.info?.project_urls) {\n for (const [name, projectUrl] of Object.entries(dep.info.project_urls)) {\n const lower = name.toLowerCase();\n\n if (\n projectUrl &&\n !dependency.sourceUrl &&\n (lower.startsWith('repo') ||\n lower === 'code' ||\n lower === 'source' ||\n isGitHubRepo(projectUrl))\n ) {\n dependency.sourceUrl = projectUrl;\n }\n\n if (\n !dependency.changelogUrl &&\n ([\n 'changelog',\n 'change log',\n 'changes',\n 'release notes',\n 'news',\n \"what's new\",\n ].includes(lower) ||\n changelogFilenameRegex.exec(lower))\n ) {\n // from https://github.com/pypa/warehouse/blob/418c7511dc367fb410c71be139545d0134ccb0df/warehouse/templates/packaging/detail.html#L24\n dependency.changelogUrl = projectUrl;\n }\n }\n }\n\n if (dep.releases) {\n dependency.releases = PypiDatasource.toReleases(dep.releases);\n }\n return dependency;\n }\n\n private static getEarliestTimestamp(\n releases: PypiRelease[],\n ): Timestamp | null {\n let earliest: Timestamp | null = null;\n for (const { upload_time } of releases) {\n const timestamp = asTimestamp(upload_time);\n // `asTimestamp` normalizes to UTC ISO 8601, so comparing the strings compares the instants\n if (timestamp && (!earliest || timestamp < earliest)) {\n earliest = timestamp;\n }\n }\n return earliest;\n }\n\n private static extractVersionFromLinkText(\n text: string,\n packageName: string,\n ): string | null {\n // source packages\n const lcText = text.toLowerCase();\n const normalizedSrcText = normalizePythonDepName(text);\n const srcPrefix = `${packageName}-`;\n\n // source distribution format: `{name}-{version}.tar.gz` (https://packaging.python.org/en/latest/specifications/source-distribution-format/#source-distribution-file-name)\n // binary distribution: `{distribution}-{version}(-{build tag})?-{python tag}-{abi tag}-{platform tag}.whl` (https://packaging.python.org/en/latest/specifications/binary-distribution-format/#file-name-convention)\n // officially both `name` and `distribution` should be normalized and then the - replaced with _, but in reality this is not the case\n // We therefore normalize the name we have (replacing `_-.` with -) and then check if the text starts with the normalized name\n\n if (!normalizedSrcText.startsWith(srcPrefix)) {\n return null;\n }\n\n // strip off the prefix using the prefix length as we may have normalized the srcPrefix/packageName\n // We assume that neither the version nor the suffix contains multiple `-` like `0.1.2---rc1.tar.gz`\n // and use the difference in length to strip off the prefix in case the name contains double `--` characters\n const normalizedLengthDiff = lcText.length - normalizedSrcText.length;\n const res = lcText.slice(srcPrefix.length + normalizedLengthDiff);\n\n // source distribution\n const srcSuffixes = ['.tar.gz', '.tar.bz2', '.tar.xz', '.zip', '.tgz'];\n const srcSuffix = srcSuffixes.find((suffix) => lcText.endsWith(suffix));\n if (srcSuffix) {\n // strip off the suffix using character length\n return res.slice(0, -srcSuffix.length);\n }\n\n // binary distribution\n // for binary distributions the version is the first part after the removed distribution name\n const wheelSuffix = '.whl';\n if (lcText.endsWith(wheelSuffix) && lcText.split('-').length > 2) {\n return res.split('-')[0];\n }\n return null;\n }\n\n private static cleanSimpleHtml(html: string): string {\n return (\n html\n .replace(regEx(/<\\/?pre>/), '')\n // Certain simple repositories like artifactory don't escape > and <\n .replace(\n regEx(/data-requires-python=\"(?<before>[^\"]*?)>(?<after>[^\"]*?)\"/g),\n 'data-requires-python=\"$<before>&gt;$<after>\"',\n )\n .replace(\n regEx(/data-requires-python=\"(?<before>[^\"]*?)<(?<after>[^\"]*?)\"/g),\n 'data-requires-python=\"$<before>&lt;$<after>\"',\n )\n );\n }\n\n private static getSimpleReleasesFromHtml(\n html: string,\n packageName: string,\n ): Releases {\n const root = parse(PypiDatasource.cleanSimpleHtml(html));\n const links = root.querySelectorAll('a');\n const releases: Releases = {};\n for (const link of Array.from(links)) {\n const version = PypiDatasource.extractVersionFromLinkText(\n link.text?.trim(),\n packageName,\n );\n if (version) {\n const release: PypiRelease = {\n yanked: link.hasAttribute('data-yanked'),\n };\n const requiresPython = link.getAttribute('data-requires-python');\n if (requiresPython) {\n release.requires_python = requiresPython;\n }\n (releases[version] ??= []).push(release);\n }\n }\n return releases;\n }\n\n private static getSimpleReleasesFromJson(\n json: string,\n packageName: string,\n ): Releases | null {\n const releases: Releases = {};\n const parsed = Json.pipe(PypiSimpleResponse).safeParse(json);\n if (!parsed.success) {\n logger.once.warn(\n { packageName, err: parsed.error },\n 'Failed to parse JSON-based Simple API response',\n );\n // Distinguish a malformed response from a package with genuinely no files, so the caller doesn't mistake an error for an empty result.\n return null;\n }\n for (const file of parsed.data.files) {\n const version = PypiDatasource.extractVersionFromLinkText(\n file.filename,\n packageName,\n );\n if (version) {\n (releases[version] ??= []).push(file);\n }\n }\n return releases;\n }\n\n private async getSimpleDependency(\n packageName: string,\n hostUrl: string,\n ): Promise<ReleaseResult | null> {\n const lookupUrl = new URL(\n ensureTrailingSlash(normalizePythonDepName(packageName)),\n hostUrl,\n ).href;\n const dependency: ReleaseResult = { releases: [] };\n const { headers: authHeaders, lookupUrl: sanitizedUrl } =\n await this.getAuthHeaders(lookupUrl);\n const headers: OutgoingHttpHeaders = {\n ...authHeaders,\n // Request the JSON serialization (PEP 691), falling back to the legacy HTML serialization (PEP 503) via content negotiation.\n // https://github.com/pypa/pip/blob/6b0011b49a068c62f65389bf4cea7af5d28cb002/src/pip/_internal/index/collector.py#L128-L134\n accept:\n 'application/vnd.pypi.simple.v1+json, application/vnd.pypi.simple.v1+html; q=0.1, text/html; q=0.01',\n };\n let response: HttpResponse;\n try {\n response = await this.http.getText(sanitizedUrl, { headers });\n } catch (err) {\n // An `abortOnError` host rule makes `Http` wrap the original error, so unwrap it before looking at the status code.\n const httpErr = err instanceof ExternalHostError ? err.err : err;\n const statusCode =\n httpErr instanceof HttpError ? httpErr.response?.statusCode : undefined;\n // A registry which cannot serve any of the negotiated types may pick a content type of its own, answer `406`, or answer `300`; the spec mandates none of them, but `406` is the common choice.\n // https://packaging.python.org/en/latest/specifications/simple-repository-api/#version-format-selection\n // Retry once without the negotiated `accept` header to preserve the pre-PEP-691 behaviour of a plain request.\n if (statusCode !== 406) {\n throw err;\n }\n\n logger.trace(\n { packageName, hostUrl, statusCode },\n 'Registry rejected negotiated Accept header, retrying without it',\n );\n response = await this.http.getText(sanitizedUrl, {\n headers: authHeaders,\n });\n }\n const dep = response?.body;\n if (!dep) {\n logger.trace({ dependency: packageName }, 'pip package not found');\n return null;\n }\n if (response.authorization) {\n dependency.isPrivate = true;\n }\n\n // Dispatch on the response content-type: JSON serialization (PEP 691) or the legacy HTML serialization (PEP 503). Matched loosely (any `json` media type) rather than the exact vendor type, as some registries/proxies relabel or strip the vendor-specific media type while still returning JSON.\n const contentType = response.headers['content-type'];\n const isJson = !!contentType && contentType.includes('json');\n const looksLikeJson = dep.trimStart().startsWith('{');\n\n if (isJson) {\n if (looksLikeJson) {\n const releases = PypiDatasource.getSimpleReleasesFromJson(\n dep,\n packageName,\n );\n // A parse failure is distinct from a package with genuinely no files, so don't report an empty release list as if it were a real (if empty) result, which would be cached as such.\n if (!releases) {\n return null;\n }\n dependency.releases = PypiDatasource.toReleases(releases);\n return dependency;\n }\n\n // The registry mislabeled a non-JSON body as JSON, so fall through to the HTML parser instead of reporting the package as not found.\n logger.debug(\n { packageName, hostUrl, contentType },\n 'Parsing Simple API response as HTML, as it is labeled as JSON but does not look like it',\n );\n }\n\n const htmlReleases = PypiDatasource.getSimpleReleasesFromHtml(\n dep,\n packageName,\n );\n dependency.releases = PypiDatasource.toReleases(htmlReleases);\n if (dependency.releases.length > 0 || !looksLikeJson) {\n return dependency;\n }\n\n // The registry honored the `Accept` header but omitted or mislabeled the `content-type`, so a JSON body went through the HTML parser and found nothing. Parse it as JSON instead of silently reporting no releases.\n logger.debug(\n { packageName, hostUrl, contentType },\n 'Retrying Simple API response as JSON, as it is not labeled as JSON but looks like it',\n );\n const jsonReleases = PypiDatasource.getSimpleReleasesFromJson(\n dep,\n packageName,\n );\n if (!jsonReleases) {\n return null;\n }\n dependency.releases = PypiDatasource.toReleases(jsonReleases);\n return dependency;\n }\n\n /**\n * The files of a version are not ordered by upload time, so use the earliest one: that is when the version was first published, which is what `minimumReleaseAge` needs.\n */\n private static toReleases(releases: Releases): Release[] {\n const versions = Object.keys(releases);\n return versions.map((version) => {\n const versionReleases = coerceArray(releases[version]);\n const isDeprecated = versionReleases.some(({ yanked }) => yanked);\n const result: Release = { version };\n const releaseTimestamp =\n PypiDatasource.getEarliestTimestamp(versionReleases);\n if (releaseTimestamp) {\n result.releaseTimestamp = releaseTimestamp;\n }\n if (isDeprecated) {\n result.isDeprecated = isDeprecated;\n }\n const pythonConstraints = versionReleases.map(\n ({ requires_python }) => requires_python,\n );\n // A file without `requires_python` can be installed on any Python version, so the version as a whole is unconstrained\n const isUnconstrained = pythonConstraints.some(\n (constraint) => !isNonEmptyString(constraint),\n );\n // There may be multiple releases with different requires_python, so we return all in an array.\n // Report no constraints at all for an unconstrained version, instead of only those of its other files, which would drop the version under `constraintsFiltering=strict`.\n result.constraints = {\n python: isUnconstrained\n ? []\n : deduplicateArray(pythonConstraints.filter(isNonEmptyString)),\n };\n return result;\n });\n }\n}\n"],"mappings":"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"}
@@ -51,6 +51,12 @@ function resolvePaginationUrl(baseUrl, nextUrl, allowCrossOrigin) {
51
51
  function isArtifactoryServer(res) {
52
52
  return isString(res?.headers[JFROG_ARTIFACTORY_RES_HEADER]);
53
53
  }
54
+ /**
55
+ * Whether the host is a Google Artifact Registry endpoint, which authenticates with a short-lived Google access token instead of static credentials.
56
+ */
57
+ function isGoogleArtifactRegistry(hostname) {
58
+ return hostname.endsWith(".pkg.dev");
59
+ }
54
60
  async function getGoogleAuthHostRule() {
55
61
  try {
56
62
  const accessToken = await new GoogleAuth({ scopes: "https://www.googleapis.com/auth/cloud-platform" }).getAccessToken();
@@ -78,6 +84,6 @@ async function getGoogleAuthToken() {
78
84
  return null;
79
85
  }
80
86
  //#endregion
81
- export { getGoogleAuthHostRule, getGoogleAuthToken, isArtifactoryServer, isCrossOriginPaginationAllowed, resolvePaginationUrl };
87
+ export { getGoogleAuthHostRule, getGoogleAuthToken, isArtifactoryServer, isCrossOriginPaginationAllowed, isGoogleArtifactRegistry, resolvePaginationUrl };
82
88
 
83
89
  //# sourceMappingURL=util.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"util.js","names":[],"sources":["../../../lib/modules/datasource/util.ts"],"sourcesContent":["import { isString } from '@sindresorhus/is';\nimport { GoogleAuth } from 'google-auth-library';\nimport { logger } from '../../logger/index.ts';\nimport type { HostRule } from '../../types/index.ts';\nimport { getEnv } from '../../util/env.ts';\nimport type { HttpResponse } from '../../util/http/types.ts';\nimport { addSecretForSanitizing } from '../../util/sanitize.ts';\nimport { parseUrl, resolveSameOriginUrl } from '../../util/url.ts';\n\nconst JFROG_ARTIFACTORY_RES_HEADER = 'x-jfrog-version';\n\n/**\n * Experimental, per-datasource env var that opts a datasource into following\n * server-provided pagination links across origins. Each datasource has its own\n * flag so relaxing the restriction for one registry cannot weaken the others.\n */\nconst crossOriginPaginationEnv: Record<string, string> = {\n docker: 'RENOVATE_X_DOCKER_PAGINATION_ALLOW_CROSS_ORIGIN',\n nuget: 'RENOVATE_X_NUGET_PAGINATION_ALLOW_CROSS_ORIGIN',\n};\n\n/**\n * Whether a datasource is opted in to following server-provided pagination\n * links across origins, via its experimental `RENOVATE_X_<DATASOURCE>_PAGINATION_ALLOW_CROSS_ORIGIN`\n * env var.\n *\n * By default such links are restricted to the same origin as the request so a\n * malicious or compromised registry cannot attempt to redirect our requests in an attempt for Server Side Request Forgery.\n */\nexport function isCrossOriginPaginationAllowed(datasource: string): boolean {\n const envVar = crossOriginPaginationEnv[datasource];\n return envVar ? !!getEnv()[envVar] : false;\n}\n\n/**\n * Resolves a server-provided pagination `next` URL against `baseUrl`, returning\n * the URL to follow or `null` if it must not be followed.\n *\n * When `allowCrossOrigin` is false (the default; see\n * {@link isCrossOriginPaginationAllowed}) the link is dropped unless it stays on\n * the same origin. When true, the link is followed regardless of origin.\n */\nexport function resolvePaginationUrl(\n baseUrl: string,\n nextUrl: string,\n allowCrossOrigin: boolean,\n): string | null {\n if (!allowCrossOrigin) {\n return resolveSameOriginUrl(baseUrl, nextUrl);\n }\n try {\n const resolved = new URL(nextUrl, baseUrl).href;\n if (parseUrl(baseUrl)?.origin !== parseUrl(resolved)?.origin) {\n logger.once.warn(\n { baseUrl, nextUrl },\n 'Following cross-origin pagination link',\n );\n }\n return resolved;\n } catch {\n return null;\n }\n}\n\nexport function isArtifactoryServer<T = unknown>(\n res: HttpResponse<T> | undefined,\n): boolean {\n return isString(res?.headers[JFROG_ARTIFACTORY_RES_HEADER]);\n}\n\nexport async function getGoogleAuthHostRule(): Promise<HostRule | null> {\n try {\n const googleAuth: GoogleAuth = new GoogleAuth({\n scopes: 'https://www.googleapis.com/auth/cloud-platform',\n });\n const accessToken = await googleAuth.getAccessToken();\n if (accessToken) {\n // sanitize token\n addSecretForSanitizing(accessToken);\n return {\n username: 'oauth2accesstoken',\n password: accessToken,\n };\n }\n logger.warn(\n 'Could not retrieve access token using google-auth-library getAccessToken',\n );\n } catch (err) {\n if (err.message?.includes('Could not load the default credentials')) {\n return null;\n }\n throw err;\n }\n return null;\n}\n\nexport async function getGoogleAuthToken(): Promise<string | null> {\n const rule = await getGoogleAuthHostRule();\n if (rule) {\n const token = Buffer.from(`${rule.username}:${rule.password}`).toString(\n 'base64',\n );\n addSecretForSanitizing(token);\n return token;\n }\n return null;\n}\n"],"mappings":";;;;;;;AASA,MAAM,+BAA+B;;;;;;AAOrC,MAAM,2BAAmD;CACvD,QAAQ;CACR,OAAO;AACT;;;;;;;;;AAUA,SAAgB,+BAA+B,YAA6B;CAC1E,MAAM,SAAS,yBAAyB;CACxC,OAAO,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU;AACvC;;;;;;;;;AAUA,SAAgB,qBACd,SACA,SACA,kBACe;CACf,IAAI,CAAC,kBACH,OAAO,qBAAqB,SAAS,OAAO;CAE9C,IAAI;EACF,MAAM,WAAW,IAAI,IAAI,SAAS,OAAO,CAAC,CAAC;EAC3C,IAAI,SAAS,OAAO,CAAC,EAAE,WAAW,SAAS,QAAQ,CAAC,EAAE,QACpD,OAAO,KAAK,KACV;GAAE;GAAS;EAAQ,GACnB,wCACF;EAEF,OAAO;CACT,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAgB,oBACd,KACS;CACT,OAAO,SAAS,KAAK,QAAQ,6BAA6B;AAC5D;AAEA,eAAsB,wBAAkD;CACtE,IAAI;EAIF,MAAM,cAAc,MAAM,IAHS,WAAW,EAC5C,QAAQ,iDACV,CACmC,CAAC,CAAC,eAAe;EACpD,IAAI,aAAa;GAEf,uBAAuB,WAAW;GAClC,OAAO;IACL,UAAU;IACV,UAAU;GACZ;EACF;EACA,OAAO,KACL,0EACF;CACF,SAAS,KAAK;EACZ,IAAI,IAAI,SAAS,SAAS,wCAAwC,GAChE,OAAO;EAET,MAAM;CACR;CACA,OAAO;AACT;AAEA,eAAsB,qBAA6C;CACjE,MAAM,OAAO,MAAM,sBAAsB;CACzC,IAAI,MAAM;EACR,MAAM,QAAQ,OAAO,KAAK,GAAG,KAAK,SAAS,GAAG,KAAK,UAAU,CAAC,CAAC,SAC7D,QACF;EACA,uBAAuB,KAAK;EAC5B,OAAO;CACT;CACA,OAAO;AACT"}
1
+ {"version":3,"file":"util.js","names":[],"sources":["../../../lib/modules/datasource/util.ts"],"sourcesContent":["import { isString } from '@sindresorhus/is';\nimport { GoogleAuth } from 'google-auth-library';\nimport { logger } from '../../logger/index.ts';\nimport type { HostRule } from '../../types/index.ts';\nimport { getEnv } from '../../util/env.ts';\nimport type { HttpResponse } from '../../util/http/types.ts';\nimport { addSecretForSanitizing } from '../../util/sanitize.ts';\nimport { parseUrl, resolveSameOriginUrl } from '../../util/url.ts';\n\nconst JFROG_ARTIFACTORY_RES_HEADER = 'x-jfrog-version';\n\n/**\n * Experimental, per-datasource env var that opts a datasource into following\n * server-provided pagination links across origins. Each datasource has its own\n * flag so relaxing the restriction for one registry cannot weaken the others.\n */\nconst crossOriginPaginationEnv: Record<string, string> = {\n docker: 'RENOVATE_X_DOCKER_PAGINATION_ALLOW_CROSS_ORIGIN',\n nuget: 'RENOVATE_X_NUGET_PAGINATION_ALLOW_CROSS_ORIGIN',\n};\n\n/**\n * Whether a datasource is opted in to following server-provided pagination\n * links across origins, via its experimental `RENOVATE_X_<DATASOURCE>_PAGINATION_ALLOW_CROSS_ORIGIN`\n * env var.\n *\n * By default such links are restricted to the same origin as the request so a\n * malicious or compromised registry cannot attempt to redirect our requests in an attempt for Server Side Request Forgery.\n */\nexport function isCrossOriginPaginationAllowed(datasource: string): boolean {\n const envVar = crossOriginPaginationEnv[datasource];\n return envVar ? !!getEnv()[envVar] : false;\n}\n\n/**\n * Resolves a server-provided pagination `next` URL against `baseUrl`, returning\n * the URL to follow or `null` if it must not be followed.\n *\n * When `allowCrossOrigin` is false (the default; see\n * {@link isCrossOriginPaginationAllowed}) the link is dropped unless it stays on\n * the same origin. When true, the link is followed regardless of origin.\n */\nexport function resolvePaginationUrl(\n baseUrl: string,\n nextUrl: string,\n allowCrossOrigin: boolean,\n): string | null {\n if (!allowCrossOrigin) {\n return resolveSameOriginUrl(baseUrl, nextUrl);\n }\n try {\n const resolved = new URL(nextUrl, baseUrl).href;\n if (parseUrl(baseUrl)?.origin !== parseUrl(resolved)?.origin) {\n logger.once.warn(\n { baseUrl, nextUrl },\n 'Following cross-origin pagination link',\n );\n }\n return resolved;\n } catch {\n return null;\n }\n}\n\nexport function isArtifactoryServer<T = unknown>(\n res: HttpResponse<T> | undefined,\n): boolean {\n return isString(res?.headers[JFROG_ARTIFACTORY_RES_HEADER]);\n}\n\n/**\n * Whether the host is a Google Artifact Registry endpoint, which authenticates with a short-lived Google access token instead of static credentials.\n */\nexport function isGoogleArtifactRegistry(hostname: string): boolean {\n return hostname.endsWith('.pkg.dev');\n}\n\nexport async function getGoogleAuthHostRule(): Promise<HostRule | null> {\n try {\n const googleAuth: GoogleAuth = new GoogleAuth({\n scopes: 'https://www.googleapis.com/auth/cloud-platform',\n });\n const accessToken = await googleAuth.getAccessToken();\n if (accessToken) {\n // sanitize token\n addSecretForSanitizing(accessToken);\n return {\n username: 'oauth2accesstoken',\n password: accessToken,\n };\n }\n logger.warn(\n 'Could not retrieve access token using google-auth-library getAccessToken',\n );\n } catch (err) {\n if (err.message?.includes('Could not load the default credentials')) {\n return null;\n }\n throw err;\n }\n return null;\n}\n\nexport async function getGoogleAuthToken(): Promise<string | null> {\n const rule = await getGoogleAuthHostRule();\n if (rule) {\n const token = Buffer.from(`${rule.username}:${rule.password}`).toString(\n 'base64',\n );\n addSecretForSanitizing(token);\n return token;\n }\n return null;\n}\n"],"mappings":";;;;;;;AASA,MAAM,+BAA+B;;;;;;AAOrC,MAAM,2BAAmD;CACvD,QAAQ;CACR,OAAO;AACT;;;;;;;;;AAUA,SAAgB,+BAA+B,YAA6B;CAC1E,MAAM,SAAS,yBAAyB;CACxC,OAAO,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU;AACvC;;;;;;;;;AAUA,SAAgB,qBACd,SACA,SACA,kBACe;CACf,IAAI,CAAC,kBACH,OAAO,qBAAqB,SAAS,OAAO;CAE9C,IAAI;EACF,MAAM,WAAW,IAAI,IAAI,SAAS,OAAO,CAAC,CAAC;EAC3C,IAAI,SAAS,OAAO,CAAC,EAAE,WAAW,SAAS,QAAQ,CAAC,EAAE,QACpD,OAAO,KAAK,KACV;GAAE;GAAS;EAAQ,GACnB,wCACF;EAEF,OAAO;CACT,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAgB,oBACd,KACS;CACT,OAAO,SAAS,KAAK,QAAQ,6BAA6B;AAC5D;;;;AAKA,SAAgB,yBAAyB,UAA2B;CAClE,OAAO,SAAS,SAAS,UAAU;AACrC;AAEA,eAAsB,wBAAkD;CACtE,IAAI;EAIF,MAAM,cAAc,MAAM,IAHS,WAAW,EAC5C,QAAQ,iDACV,CACmC,CAAC,CAAC,eAAe;EACpD,IAAI,aAAa;GAEf,uBAAuB,WAAW;GAClC,OAAO;IACL,UAAU;IACV,UAAU;GACZ;EACF;EACA,OAAO,KACL,0EACF;CACF,SAAS,KAAK;EACZ,IAAI,IAAI,SAAS,SAAS,wCAAwC,GAChE,OAAO;EAET,MAAM;CACR;CACA,OAAO;AACT;AAEA,eAAsB,qBAA6C;CACjE,MAAM,OAAO,MAAM,sBAAsB;CACzC,IAAI,MAAM;EACR,MAAM,QAAQ,OAAO,KAAK,GAAG,KAAK,SAAS,GAAG,KAAK,UAAU,CAAC,CAAC,SAC7D,QACF;EACA,uBAAuB,KAAK;EAC5B,OAAO;CACT;CACA,OAAO;AACT"}
@@ -56,7 +56,7 @@ hashMap.set("helm-requirements", "7ee9dace4c036dfe113c0c0e46369d8b83a739caa83166
56
56
  hashMap.set("helm-values", "0aa79bb0257d0d72e54dfd2653e59bfef63b97e46c035b7443593bdf6e6382aa");
57
57
  hashMap.set("helmfile", "28572dd24b6746ca7065ee467aa13bbc8c3e8c0f88ae48e33bce88468c600100");
58
58
  hashMap.set("helmsman", "951deeb3355da751ef39c9e932b26ea749450e32e75759e4b5fc29359e100b37");
59
- hashMap.set("helmv3", "4a3cf47072978eb131d70cd13f3d0bbd4408b0290be2a798a4cbf6103189269b");
59
+ hashMap.set("helmv3", "e2d464055503d3702d3cf7323ce593747fe482def8ee59aea2dcaadb0bb0f72c");
60
60
  hashMap.set("hermit", "0fb25b7766c3a264fbb765ff75b1542b24136c4c9f933696d4a5aecfed637071");
61
61
  hashMap.set("homeassistant-manifest", "05043c6db870cffbb6f8f3e351c025e3de227eaae0b24134b796aec46f84b65f");
62
62
  hashMap.set("homebrew", "dffe954a4e18c2dc4bfdaa12222fe8ddc3395869afd5afa603fc2b6264747984");
@@ -82,12 +82,12 @@ hashMap.set("ocb", "032b216684c14b0954e0bb019513a2aca3faaee5748587acb668d377d7c8
82
82
  hashMap.set("osgi", "d6567a733ef3983112b46fdccd7ceebfcd48411104e0c6b6e714d4310db48024");
83
83
  hashMap.set("pep621", "52450676f8b0e05134b3e8947b832195ef40bcaec1ce43d71351a2f797b80d75");
84
84
  hashMap.set("pep723", "77022a0eae6a3cbb74a1e6d596db1276e379768e40448192b3fa81edd14ca73f");
85
- hashMap.set("pip-compile", "7e418b8bdaeed38c1372eb19e0ae1c64999000e128d8754e37368638037b4c5c");
85
+ hashMap.set("pip-compile", "a98dc76a002e1dc21662237f009ff8fea36236bb4e24cb82ee30c6a78f57271f");
86
86
  hashMap.set("pip_requirements", "bf3a407f72abf711230247bef94ba5dc84c08a35107b0f017912fad66afa716a");
87
87
  hashMap.set("pip_setup", "df18fba2bdcf48f3ca12a8f7e5cd28df31e2368d5528127277038ef4206eca79");
88
- hashMap.set("pipenv", "cd974eadd649ba8c9c2e3c7b564a49c8bb2ce95d6df043a7e942364f574c7613");
88
+ hashMap.set("pipenv", "baf237cd77173c1a7a9c7fa2a8bfb214f3c488ba0cc27f0e8f334df192e3a398");
89
89
  hashMap.set("pixi", "e31c397982ffa34222b061f23f3b3683f42523dd5dca45ecce2448b0ebc55ea2");
90
- hashMap.set("poetry", "b2b917c200d25e01a3a198deb3bf33353535f27430142111cfab816c03bb966d");
90
+ hashMap.set("poetry", "e9dea5d591c87956b9f018414cb3dab8f2e13580a13be00550fdce198fdf08e6");
91
91
  hashMap.set("pre-commit", "760f2c291ae084db889f722390798a0e2d431ccdc3bc676e73b14901ebea19ac");
92
92
  hashMap.set("proto", "412053d4550026b4ace490b46e970915b87ec1abf0b0a0c6c8c58ccf1fc16843");
93
93
  hashMap.set("pub", "8e7c65dfd1999de4f7c44392e949a4d8f4701eb86df59d550e4657feb06b1872");
@@ -103,7 +103,7 @@ hashMap.set("scalafmt", "9d36159b56835e96498af026a1fb0543200db0581681ef95ec54988
103
103
  hashMap.set("setup-cfg", "4a3a7c812d34739c07685691e7e64c7d3127f9d7d4aff99dc45a25df97ed9745");
104
104
  hashMap.set("smithy", "9641b91d065ffb63be0dd888139a0402dba41e550f8b44c592db9daf52109100");
105
105
  hashMap.set("sveltos", "60dd75bb53ace31217211100d622fdb65068c6162758b6ae7103a6ce8bdc9f90");
106
- hashMap.set("swift", "6932c904b0d18ad4845c46ce3f7d4c54dd8e411e16c31a782b399fe0b7dc550b");
106
+ hashMap.set("swift", "cdf063debdbf36888523ff8cec6d2d1b0ec6f49b37b2fbcd80b0d4f6a31114e1");
107
107
  hashMap.set("tekton", "33948f5bdf7553909fa63744adb26da97ddf366e9499bccab1250879570267c9");
108
108
  hashMap.set("terraform", "5b0037e4a88e06efe6f006eff15c24d9e1fefdda40d282aa99f54c2637d21c4d");
109
109
  hashMap.set("terraform-version", "ec8f786b9731d47f2c2fe0307caf64d7ddd83046fe7ff1f7d8423239f8b0f2aa");
@@ -1 +1 @@
1
- {"version":3,"file":"fingerprint.generated.js","names":[],"sources":["../../../lib/modules/manager/fingerprint.generated.ts"],"sourcesContent":["export const hashMap = new Map<string, string>();\n\nhashMap.set('ansible','a52394a36ac5517f7330473c31d93aa05b2ce607c5e951b48f25a4693cd20a81');\nhashMap.set('ansible-galaxy','0a264d6be73953d801510fdeff271e4071c274339569c6dab4e2a128eaf4869f');\nhashMap.set('ant','2df5943cf0ed19a21b94df13729dbb925655548130caf37e3e22bebaed518e17');\nhashMap.set('apm','bdb6931cc03f4ac02ebfdb56c4b3483bb6c5250fa952545f1a25584d502bbffd');\nhashMap.set('argocd','cff9cd22257bc460ae4b9936570bf0ed5585f280a55d26629deaeeb0bfee8eb5');\nhashMap.set('asdf','430eb99b58171700c8a59c78b9e648575e9b176b781d90dd10a710f7b69015bb');\nhashMap.set('azure-pipelines','a051fe5e7e4fef8208b5864131a2b52b4ae319936f1dd8ee5a4e1ef11359ec09');\nhashMap.set('batect','375d39b432013bedb1330cf40a2199dd822751b28578214f219e7bab98594b8d');\nhashMap.set('batect-wrapper','d999355511ea7f4053325a18b8cfc8d2b586c61e6760c35e557d383a673e3939');\nhashMap.set('bazel','c31bc0a0e23d32726bcc09aa67533ebc5058124bf89c88e09c837419f550801a');\nhashMap.set('bazel-module','9fbba0339f9f7785d52ab85c5f0f6385003093c063483c13feccba13ae438bef');\nhashMap.set('bazelisk','770f75a746dc6ba90c518788d5987d7df4243ef9eee122d1bb0556a93d6e1b11');\nhashMap.set('bicep','7246e0bfc06e0e28cbb03ac088c5591f648956b086e106aeb251fe5d628329db');\nhashMap.set('bitbucket-pipelines','59c0503494ab1442b127914503c01b97ac17b6742b19c632292d5aa24de115cd');\nhashMap.set('bitrise','478dfd316221fad7c29e177c70d1018d832fb2626b53308a5d0f1f0380e69f42');\nhashMap.set('buildkite','b8b404f53cd5d61c39153fddf93945e621471c4ac6aa9960c881cd868922bb4c');\nhashMap.set('buildpacks','6bef3cb04d66b5cfbb195adb4829bcbccae6408518706744d291bacf0610421f');\nhashMap.set('bun','5820cfb6ebe018b8c336d481ea9ae319daaee6a2e368c45196fc8bc67cb3e755');\nhashMap.set('bun-version','df3ae8e4a5de1fa1b4544f3d7fc8117e80adb1e151c46d1ede54a4dbea6521e4');\nhashMap.set('bundler','6e4784dd98c1f86ef64cc8cbf3128df48aebf920032d7792b54fdedd3dd9d4d5');\nhashMap.set('cake','9ebd8b481220b30a8860121d26184540a1a2fcc05ef780df9295dea39b386fad');\nhashMap.set('cargo','fe8136135c895dd08819f91a60cf105f8b951251b057092700101ace991ae1d7');\nhashMap.set('cdnurl','9a81c8e3c6ad6c788498c99fc1067ffdfcd92a427c3afaf8c0130975d83131f2');\nhashMap.set('circleci','91cbeb33ea20f9838e2c81a1195eb806f0b38fa282bc3679f62552f20575ca85');\nhashMap.set('cloudbuild','f4e40388944652c8a19f8518771ac8d3f3c4ccf81ddef0e68b463aca833cb73c');\nhashMap.set('cocoapods','f832e2beef885bb3fd697ed9bb3e8cd742926bfec37ff41212edd2dbb4edb3ba');\nhashMap.set('composer','f1294fb3866ff65a75d98fdef80b1df3d3a8856535b8c690d1799e1205e4b639');\nhashMap.set('conan','8d46e9a30ae628e26118aea10a98d1b846f7c5d96d51ce24693437d555f6d125');\nhashMap.set('copier','10ae4d7f8ff35faf3a3f9f25bf4c969ea960e19aaf8c012aee11f93f4d10533e');\nhashMap.set('cpanfile','07813fec3f3c2197056500e9266a0553b9774c02f2c74d5ca2e213188c7c12d3');\nhashMap.set('crossplane','5c26b1201a1a51454ffb94d829e223a76a781569bf79cdb1e47087c30233ec40');\nhashMap.set('crow','eb9a5f9f95041855dded67bcce3dd54724f690995ed6268d272e8a666ff28fd0');\nhashMap.set('deno','05e7ab60494a20a5e7477f06a9e723e443d37643b6e1d9ba8d3d87126a051175');\nhashMap.set('deps-edn','06783dbc8b9c7bb84e162d1f75b7db56dfa021cc6f809dfd2314cee8b64af08d');\nhashMap.set('devbox','a40050cc61bd9b5d500ec111abb17bb15d5f82ab5b7699f66f628307ba8382c9');\nhashMap.set('devcontainer','24320ed1cb6191d04cb8b2707214d82c08c682597aed1d84f250aa00ad1632ec');\nhashMap.set('docker-compose','fba87b82cb0f2bfd66526631fbe928b8153e7ca701a5790d02b944df17417bb9');\nhashMap.set('dockerfile','78cb1e8b58653289dd4b73425c45495a4c4b41badd3614b8345aaf8ab73de09c');\nhashMap.set('droneci','661d2a2d7295af8dd7a1234c7090c42a89306bd574c3adf1fc67782efaad3998');\nhashMap.set('fleet','4942d52e82f35c41e2d46cf76f426e2d91b350338cfc0bbcb97e8aaae2a1ac0b');\nhashMap.set('flux','aad8c786c4a2b5820663027452eeb8fe84c3af8c8399261e85f0eade2e484fe8');\nhashMap.set('fvm','9b161df0f14bc6e536368952adf373e343630097121a913cea60ee284027fb90');\nhashMap.set('git-submodules','df8bb92b2906d8cddda2d4b302ee503f8002e3554d32d74cef2f584fe891f38f');\nhashMap.set('github-actions','7adddc8e590786084855ffe53292bff3098ac672f91c21cc39d45bcf0af2271f');\nhashMap.set('gitlabci','a5e1e66ef461e1c1e71062f85f35a212417e23627f4b002810f9a98295d6e672');\nhashMap.set('gitlabci-include','8860a15ab516fde00694f9bd9bf56fce4addafe5a55b5ddb9a4ec477d301d351');\nhashMap.set('glasskube','93e7b9000a17efa15a1abaaf320b5af9169b1ecd828fc0c881d98570ef9d9e30');\nhashMap.set('gleam','5e9b9f5f914afe5ed7b526c06c65111e3716d2dea9b0cbe7907bbc96db1064a3');\nhashMap.set('gomod','de042f3b5a900346c5f2df41f793f1716dc12145c38705c3064c6a7150b49495');\nhashMap.set('gradle','9e3ff52ce4ad2555929acdd4d32c417c4ef8714c23a92f2893ecc580fa4d6064');\nhashMap.set('gradle-wrapper','73ba30c34955fab7737454b5cff9aca6d1b5607d53c17c9e13d8ad96f6eaae87');\nhashMap.set('haskell-cabal','f158b7725e3143dfd2950e3de0bbccc2a61cd7eba87f7a54c5057e01252348e2');\nhashMap.set('helm-requirements','7ee9dace4c036dfe113c0c0e46369d8b83a739caa831660142ca98d3236a180a');\nhashMap.set('helm-values','0aa79bb0257d0d72e54dfd2653e59bfef63b97e46c035b7443593bdf6e6382aa');\nhashMap.set('helmfile','28572dd24b6746ca7065ee467aa13bbc8c3e8c0f88ae48e33bce88468c600100');\nhashMap.set('helmsman','951deeb3355da751ef39c9e932b26ea749450e32e75759e4b5fc29359e100b37');\nhashMap.set('helmv3','4a3cf47072978eb131d70cd13f3d0bbd4408b0290be2a798a4cbf6103189269b');\nhashMap.set('hermit','0fb25b7766c3a264fbb765ff75b1542b24136c4c9f933696d4a5aecfed637071');\nhashMap.set('homeassistant-manifest','05043c6db870cffbb6f8f3e351c025e3de227eaae0b24134b796aec46f84b65f');\nhashMap.set('homebrew','dffe954a4e18c2dc4bfdaa12222fe8ddc3395869afd5afa603fc2b6264747984');\nhashMap.set('html','81fa6c2bf2b868596584a48b949645207a2aa3081951ed99183ee50b70b77d5f');\nhashMap.set('jenkins','7fda0e7e0f3d5e18088ccb3594f727f4cfc48b064706bdaaf1a0a075b6a2cff5');\nhashMap.set('jsonnet-bundler','4cedeb0394e5c38361d1868ff45b4f34747ab8c492378b6e63dcaf1f4f3c024d');\nhashMap.set('kotlin-script','95ebc844c040ca047321b207d525220e29774a2a1fe06f9639e8353c66908564');\nhashMap.set('kubernetes','321e7d77fb3600dd4c00a86eaa1294927e7f92300b74fa2977d813dcaa3bb4de');\nhashMap.set('kustomize','aa830c27302555e12d7f04e342c96125d68c231028a2d3c459c4431516382584');\nhashMap.set('leiningen','c8397e376f1717c2f771ae9ea3ba6b720d2422b133cf937e762c44e42be146a2');\nhashMap.set('maven','c110b99291c2a5bc82cf7a69330275e9bbd7dc8ba3e9e987611dfcffbe002d8d');\nhashMap.set('maven-wrapper','6e53b6e4abf1d20b75094c7a70d66b4a5ac39954f009aa401f5e55dada8be4d0');\nhashMap.set('meteor','4636a47ba4dcfff19fe662572ef7a40d17146be3c966e00ef437e1fc8de92776');\nhashMap.set('mint','248fe4f1ea5c985921c286785792c97e06fc41f402b2d45df82f6aecd17f710e');\nhashMap.set('mise','279da4690751c3abee10badd12eb4ac6ef31d824c6bd3ada824859eca3109ebe');\nhashMap.set('mix','0f79163dc2a1c896599d152be635c23beaf16812ae3d8fbfffec98c7bd0de872');\nhashMap.set('nix','0f80f0b81f2197a7e588be5c115a32a826fc184593f4e879f7b60fafd97a977e');\nhashMap.set('nodenv','ac652c28481b001f7471f4183eac07b45d98ecbe83efc275830b0a1b2e0459b8');\nhashMap.set('npm','30c78bc1c29eeecbdedb4eacc52bd93eedfb07279fd385f893193dcac6196466');\nhashMap.set('nuget','b81fb0ca6cfeb86b004592b38ce176673e056d6a2ed41a9807afb0eb7ad405d2');\nhashMap.set('nvm','3eb77c7b0acf6d64753de78fad2499b352719853aa6872878c40675d14152322');\nhashMap.set('ocb','032b216684c14b0954e0bb019513a2aca3faaee5748587acb668d377d7c891ca');\nhashMap.set('osgi','d6567a733ef3983112b46fdccd7ceebfcd48411104e0c6b6e714d4310db48024');\nhashMap.set('pep621','52450676f8b0e05134b3e8947b832195ef40bcaec1ce43d71351a2f797b80d75');\nhashMap.set('pep723','77022a0eae6a3cbb74a1e6d596db1276e379768e40448192b3fa81edd14ca73f');\nhashMap.set('pip-compile','7e418b8bdaeed38c1372eb19e0ae1c64999000e128d8754e37368638037b4c5c');\nhashMap.set('pip_requirements','bf3a407f72abf711230247bef94ba5dc84c08a35107b0f017912fad66afa716a');\nhashMap.set('pip_setup','df18fba2bdcf48f3ca12a8f7e5cd28df31e2368d5528127277038ef4206eca79');\nhashMap.set('pipenv','cd974eadd649ba8c9c2e3c7b564a49c8bb2ce95d6df043a7e942364f574c7613');\nhashMap.set('pixi','e31c397982ffa34222b061f23f3b3683f42523dd5dca45ecce2448b0ebc55ea2');\nhashMap.set('poetry','b2b917c200d25e01a3a198deb3bf33353535f27430142111cfab816c03bb966d');\nhashMap.set('pre-commit','760f2c291ae084db889f722390798a0e2d431ccdc3bc676e73b14901ebea19ac');\nhashMap.set('proto','412053d4550026b4ace490b46e970915b87ec1abf0b0a0c6c8c58ccf1fc16843');\nhashMap.set('pub','8e7c65dfd1999de4f7c44392e949a4d8f4701eb86df59d550e4657feb06b1872');\nhashMap.set('puppet','ba58ab689e44acc8f61c3569ab8b40fde01b8a9d3aad712708e2a419e57d8b45');\nhashMap.set('pyenv','9ede8becc97774f9040b40f4472d3e933534b596e04c360bfe0f3c6f95f25182');\nhashMap.set('quadlet','e1fc88a4e14cd595e89bb3d79b4adf2add3ce5eb80f75276e712c32598cca53d');\nhashMap.set('renovate-config','dfaf3f03ddaf70c332f7916106648f36dbfa6a36dd76d15dd27fa116ab3c174c');\nhashMap.set('ruby-version','2db2140d9eee8c555e729a4de0396fa2d78846d3149890ee12fa515bd654be97');\nhashMap.set('runtime-version','b582b168c0cc595e39010feb10f4b97a82683eb269e9598216fbb11cc186e160');\nhashMap.set('rust-toolchain','6ace53db02874d73620d2d872291839820a512a9529c42d174358c692e5db720');\nhashMap.set('sbt','e1eb5c7f0171a9bb1b6bd4a36a91039a31b6c84e0983d91d930be31a69506d9e');\nhashMap.set('scalafmt','9d36159b56835e96498af026a1fb0543200db0581681ef95ec54988f411e180f');\nhashMap.set('setup-cfg','4a3a7c812d34739c07685691e7e64c7d3127f9d7d4aff99dc45a25df97ed9745');\nhashMap.set('smithy','9641b91d065ffb63be0dd888139a0402dba41e550f8b44c592db9daf52109100');\nhashMap.set('sveltos','60dd75bb53ace31217211100d622fdb65068c6162758b6ae7103a6ce8bdc9f90');\nhashMap.set('swift','6932c904b0d18ad4845c46ce3f7d4c54dd8e411e16c31a782b399fe0b7dc550b');\nhashMap.set('tekton','33948f5bdf7553909fa63744adb26da97ddf366e9499bccab1250879570267c9');\nhashMap.set('terraform','5b0037e4a88e06efe6f006eff15c24d9e1fefdda40d282aa99f54c2637d21c4d');\nhashMap.set('terraform-version','ec8f786b9731d47f2c2fe0307caf64d7ddd83046fe7ff1f7d8423239f8b0f2aa');\nhashMap.set('terragrunt','300f8fb3c09667654412d2f5dd8ab4882e0f5d1d7a8bc39794993d2e7e58d1b7');\nhashMap.set('terragrunt-version','eea6087b33717d22ede2fc68c2f64df8390b75abe82110ed831a180648feb51d');\nhashMap.set('tflint-plugin','f423bfa2b42a2bfc0e38a33ebd4f9d452473e7ed4e7ad6384a99eb9a35d97479');\nhashMap.set('travis','f3e2f38e699c390b00ff481be5e91dceaa81609e93caf9a4214933de759c84fc');\nhashMap.set('typst','d080a79fbd961c6e21fcc505d544b7e0ff2126142acb1dcabdf6abbcd9339248');\nhashMap.set('unity3d','f13e25e115e3443f4e16cf31578acffa78fb1a5e23339680a92d8d6de6052920');\nhashMap.set('velaci','fda00ddb7cc23e9a37e0a8a253151df0a6930b4276d3e4f78cc54b9ac09af7de');\nhashMap.set('vendir','7db907b3b77ef5f3465f3c4339fbab56bbcdfd1bf34b3d33e4c178d2e07e23e7');\nhashMap.set('woodpecker','6110d3bec33aaeb3511d4bbfa896cec3c8e02fb04a6cff50c9ba81061c851045');\nhashMap.set('xcodegen','dad511d88a9ce1dbdde8b9731f3da7f2bdaa4ca8a083294ee58d56da62ab1683');\nhashMap.set('jsonata','416bcf61144b276b3112814c6e6d261aa29608f46fbb0516c471d35c16f8f0d7');\nhashMap.set('regex','20be5247fdc164173871a051acb0527da017d0c155c653d7563601f55e7b3ff5');"],"mappings":"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"}
1
+ {"version":3,"file":"fingerprint.generated.js","names":[],"sources":["../../../lib/modules/manager/fingerprint.generated.ts"],"sourcesContent":["export const hashMap = new Map<string, string>();\n\nhashMap.set('ansible','a52394a36ac5517f7330473c31d93aa05b2ce607c5e951b48f25a4693cd20a81');\nhashMap.set('ansible-galaxy','0a264d6be73953d801510fdeff271e4071c274339569c6dab4e2a128eaf4869f');\nhashMap.set('ant','2df5943cf0ed19a21b94df13729dbb925655548130caf37e3e22bebaed518e17');\nhashMap.set('apm','bdb6931cc03f4ac02ebfdb56c4b3483bb6c5250fa952545f1a25584d502bbffd');\nhashMap.set('argocd','cff9cd22257bc460ae4b9936570bf0ed5585f280a55d26629deaeeb0bfee8eb5');\nhashMap.set('asdf','430eb99b58171700c8a59c78b9e648575e9b176b781d90dd10a710f7b69015bb');\nhashMap.set('azure-pipelines','a051fe5e7e4fef8208b5864131a2b52b4ae319936f1dd8ee5a4e1ef11359ec09');\nhashMap.set('batect','375d39b432013bedb1330cf40a2199dd822751b28578214f219e7bab98594b8d');\nhashMap.set('batect-wrapper','d999355511ea7f4053325a18b8cfc8d2b586c61e6760c35e557d383a673e3939');\nhashMap.set('bazel','c31bc0a0e23d32726bcc09aa67533ebc5058124bf89c88e09c837419f550801a');\nhashMap.set('bazel-module','9fbba0339f9f7785d52ab85c5f0f6385003093c063483c13feccba13ae438bef');\nhashMap.set('bazelisk','770f75a746dc6ba90c518788d5987d7df4243ef9eee122d1bb0556a93d6e1b11');\nhashMap.set('bicep','7246e0bfc06e0e28cbb03ac088c5591f648956b086e106aeb251fe5d628329db');\nhashMap.set('bitbucket-pipelines','59c0503494ab1442b127914503c01b97ac17b6742b19c632292d5aa24de115cd');\nhashMap.set('bitrise','478dfd316221fad7c29e177c70d1018d832fb2626b53308a5d0f1f0380e69f42');\nhashMap.set('buildkite','b8b404f53cd5d61c39153fddf93945e621471c4ac6aa9960c881cd868922bb4c');\nhashMap.set('buildpacks','6bef3cb04d66b5cfbb195adb4829bcbccae6408518706744d291bacf0610421f');\nhashMap.set('bun','5820cfb6ebe018b8c336d481ea9ae319daaee6a2e368c45196fc8bc67cb3e755');\nhashMap.set('bun-version','df3ae8e4a5de1fa1b4544f3d7fc8117e80adb1e151c46d1ede54a4dbea6521e4');\nhashMap.set('bundler','6e4784dd98c1f86ef64cc8cbf3128df48aebf920032d7792b54fdedd3dd9d4d5');\nhashMap.set('cake','9ebd8b481220b30a8860121d26184540a1a2fcc05ef780df9295dea39b386fad');\nhashMap.set('cargo','fe8136135c895dd08819f91a60cf105f8b951251b057092700101ace991ae1d7');\nhashMap.set('cdnurl','9a81c8e3c6ad6c788498c99fc1067ffdfcd92a427c3afaf8c0130975d83131f2');\nhashMap.set('circleci','91cbeb33ea20f9838e2c81a1195eb806f0b38fa282bc3679f62552f20575ca85');\nhashMap.set('cloudbuild','f4e40388944652c8a19f8518771ac8d3f3c4ccf81ddef0e68b463aca833cb73c');\nhashMap.set('cocoapods','f832e2beef885bb3fd697ed9bb3e8cd742926bfec37ff41212edd2dbb4edb3ba');\nhashMap.set('composer','f1294fb3866ff65a75d98fdef80b1df3d3a8856535b8c690d1799e1205e4b639');\nhashMap.set('conan','8d46e9a30ae628e26118aea10a98d1b846f7c5d96d51ce24693437d555f6d125');\nhashMap.set('copier','10ae4d7f8ff35faf3a3f9f25bf4c969ea960e19aaf8c012aee11f93f4d10533e');\nhashMap.set('cpanfile','07813fec3f3c2197056500e9266a0553b9774c02f2c74d5ca2e213188c7c12d3');\nhashMap.set('crossplane','5c26b1201a1a51454ffb94d829e223a76a781569bf79cdb1e47087c30233ec40');\nhashMap.set('crow','eb9a5f9f95041855dded67bcce3dd54724f690995ed6268d272e8a666ff28fd0');\nhashMap.set('deno','05e7ab60494a20a5e7477f06a9e723e443d37643b6e1d9ba8d3d87126a051175');\nhashMap.set('deps-edn','06783dbc8b9c7bb84e162d1f75b7db56dfa021cc6f809dfd2314cee8b64af08d');\nhashMap.set('devbox','a40050cc61bd9b5d500ec111abb17bb15d5f82ab5b7699f66f628307ba8382c9');\nhashMap.set('devcontainer','24320ed1cb6191d04cb8b2707214d82c08c682597aed1d84f250aa00ad1632ec');\nhashMap.set('docker-compose','fba87b82cb0f2bfd66526631fbe928b8153e7ca701a5790d02b944df17417bb9');\nhashMap.set('dockerfile','78cb1e8b58653289dd4b73425c45495a4c4b41badd3614b8345aaf8ab73de09c');\nhashMap.set('droneci','661d2a2d7295af8dd7a1234c7090c42a89306bd574c3adf1fc67782efaad3998');\nhashMap.set('fleet','4942d52e82f35c41e2d46cf76f426e2d91b350338cfc0bbcb97e8aaae2a1ac0b');\nhashMap.set('flux','aad8c786c4a2b5820663027452eeb8fe84c3af8c8399261e85f0eade2e484fe8');\nhashMap.set('fvm','9b161df0f14bc6e536368952adf373e343630097121a913cea60ee284027fb90');\nhashMap.set('git-submodules','df8bb92b2906d8cddda2d4b302ee503f8002e3554d32d74cef2f584fe891f38f');\nhashMap.set('github-actions','7adddc8e590786084855ffe53292bff3098ac672f91c21cc39d45bcf0af2271f');\nhashMap.set('gitlabci','a5e1e66ef461e1c1e71062f85f35a212417e23627f4b002810f9a98295d6e672');\nhashMap.set('gitlabci-include','8860a15ab516fde00694f9bd9bf56fce4addafe5a55b5ddb9a4ec477d301d351');\nhashMap.set('glasskube','93e7b9000a17efa15a1abaaf320b5af9169b1ecd828fc0c881d98570ef9d9e30');\nhashMap.set('gleam','5e9b9f5f914afe5ed7b526c06c65111e3716d2dea9b0cbe7907bbc96db1064a3');\nhashMap.set('gomod','de042f3b5a900346c5f2df41f793f1716dc12145c38705c3064c6a7150b49495');\nhashMap.set('gradle','9e3ff52ce4ad2555929acdd4d32c417c4ef8714c23a92f2893ecc580fa4d6064');\nhashMap.set('gradle-wrapper','73ba30c34955fab7737454b5cff9aca6d1b5607d53c17c9e13d8ad96f6eaae87');\nhashMap.set('haskell-cabal','f158b7725e3143dfd2950e3de0bbccc2a61cd7eba87f7a54c5057e01252348e2');\nhashMap.set('helm-requirements','7ee9dace4c036dfe113c0c0e46369d8b83a739caa831660142ca98d3236a180a');\nhashMap.set('helm-values','0aa79bb0257d0d72e54dfd2653e59bfef63b97e46c035b7443593bdf6e6382aa');\nhashMap.set('helmfile','28572dd24b6746ca7065ee467aa13bbc8c3e8c0f88ae48e33bce88468c600100');\nhashMap.set('helmsman','951deeb3355da751ef39c9e932b26ea749450e32e75759e4b5fc29359e100b37');\nhashMap.set('helmv3','e2d464055503d3702d3cf7323ce593747fe482def8ee59aea2dcaadb0bb0f72c');\nhashMap.set('hermit','0fb25b7766c3a264fbb765ff75b1542b24136c4c9f933696d4a5aecfed637071');\nhashMap.set('homeassistant-manifest','05043c6db870cffbb6f8f3e351c025e3de227eaae0b24134b796aec46f84b65f');\nhashMap.set('homebrew','dffe954a4e18c2dc4bfdaa12222fe8ddc3395869afd5afa603fc2b6264747984');\nhashMap.set('html','81fa6c2bf2b868596584a48b949645207a2aa3081951ed99183ee50b70b77d5f');\nhashMap.set('jenkins','7fda0e7e0f3d5e18088ccb3594f727f4cfc48b064706bdaaf1a0a075b6a2cff5');\nhashMap.set('jsonnet-bundler','4cedeb0394e5c38361d1868ff45b4f34747ab8c492378b6e63dcaf1f4f3c024d');\nhashMap.set('kotlin-script','95ebc844c040ca047321b207d525220e29774a2a1fe06f9639e8353c66908564');\nhashMap.set('kubernetes','321e7d77fb3600dd4c00a86eaa1294927e7f92300b74fa2977d813dcaa3bb4de');\nhashMap.set('kustomize','aa830c27302555e12d7f04e342c96125d68c231028a2d3c459c4431516382584');\nhashMap.set('leiningen','c8397e376f1717c2f771ae9ea3ba6b720d2422b133cf937e762c44e42be146a2');\nhashMap.set('maven','c110b99291c2a5bc82cf7a69330275e9bbd7dc8ba3e9e987611dfcffbe002d8d');\nhashMap.set('maven-wrapper','6e53b6e4abf1d20b75094c7a70d66b4a5ac39954f009aa401f5e55dada8be4d0');\nhashMap.set('meteor','4636a47ba4dcfff19fe662572ef7a40d17146be3c966e00ef437e1fc8de92776');\nhashMap.set('mint','248fe4f1ea5c985921c286785792c97e06fc41f402b2d45df82f6aecd17f710e');\nhashMap.set('mise','279da4690751c3abee10badd12eb4ac6ef31d824c6bd3ada824859eca3109ebe');\nhashMap.set('mix','0f79163dc2a1c896599d152be635c23beaf16812ae3d8fbfffec98c7bd0de872');\nhashMap.set('nix','0f80f0b81f2197a7e588be5c115a32a826fc184593f4e879f7b60fafd97a977e');\nhashMap.set('nodenv','ac652c28481b001f7471f4183eac07b45d98ecbe83efc275830b0a1b2e0459b8');\nhashMap.set('npm','30c78bc1c29eeecbdedb4eacc52bd93eedfb07279fd385f893193dcac6196466');\nhashMap.set('nuget','b81fb0ca6cfeb86b004592b38ce176673e056d6a2ed41a9807afb0eb7ad405d2');\nhashMap.set('nvm','3eb77c7b0acf6d64753de78fad2499b352719853aa6872878c40675d14152322');\nhashMap.set('ocb','032b216684c14b0954e0bb019513a2aca3faaee5748587acb668d377d7c891ca');\nhashMap.set('osgi','d6567a733ef3983112b46fdccd7ceebfcd48411104e0c6b6e714d4310db48024');\nhashMap.set('pep621','52450676f8b0e05134b3e8947b832195ef40bcaec1ce43d71351a2f797b80d75');\nhashMap.set('pep723','77022a0eae6a3cbb74a1e6d596db1276e379768e40448192b3fa81edd14ca73f');\nhashMap.set('pip-compile','a98dc76a002e1dc21662237f009ff8fea36236bb4e24cb82ee30c6a78f57271f');\nhashMap.set('pip_requirements','bf3a407f72abf711230247bef94ba5dc84c08a35107b0f017912fad66afa716a');\nhashMap.set('pip_setup','df18fba2bdcf48f3ca12a8f7e5cd28df31e2368d5528127277038ef4206eca79');\nhashMap.set('pipenv','baf237cd77173c1a7a9c7fa2a8bfb214f3c488ba0cc27f0e8f334df192e3a398');\nhashMap.set('pixi','e31c397982ffa34222b061f23f3b3683f42523dd5dca45ecce2448b0ebc55ea2');\nhashMap.set('poetry','e9dea5d591c87956b9f018414cb3dab8f2e13580a13be00550fdce198fdf08e6');\nhashMap.set('pre-commit','760f2c291ae084db889f722390798a0e2d431ccdc3bc676e73b14901ebea19ac');\nhashMap.set('proto','412053d4550026b4ace490b46e970915b87ec1abf0b0a0c6c8c58ccf1fc16843');\nhashMap.set('pub','8e7c65dfd1999de4f7c44392e949a4d8f4701eb86df59d550e4657feb06b1872');\nhashMap.set('puppet','ba58ab689e44acc8f61c3569ab8b40fde01b8a9d3aad712708e2a419e57d8b45');\nhashMap.set('pyenv','9ede8becc97774f9040b40f4472d3e933534b596e04c360bfe0f3c6f95f25182');\nhashMap.set('quadlet','e1fc88a4e14cd595e89bb3d79b4adf2add3ce5eb80f75276e712c32598cca53d');\nhashMap.set('renovate-config','dfaf3f03ddaf70c332f7916106648f36dbfa6a36dd76d15dd27fa116ab3c174c');\nhashMap.set('ruby-version','2db2140d9eee8c555e729a4de0396fa2d78846d3149890ee12fa515bd654be97');\nhashMap.set('runtime-version','b582b168c0cc595e39010feb10f4b97a82683eb269e9598216fbb11cc186e160');\nhashMap.set('rust-toolchain','6ace53db02874d73620d2d872291839820a512a9529c42d174358c692e5db720');\nhashMap.set('sbt','e1eb5c7f0171a9bb1b6bd4a36a91039a31b6c84e0983d91d930be31a69506d9e');\nhashMap.set('scalafmt','9d36159b56835e96498af026a1fb0543200db0581681ef95ec54988f411e180f');\nhashMap.set('setup-cfg','4a3a7c812d34739c07685691e7e64c7d3127f9d7d4aff99dc45a25df97ed9745');\nhashMap.set('smithy','9641b91d065ffb63be0dd888139a0402dba41e550f8b44c592db9daf52109100');\nhashMap.set('sveltos','60dd75bb53ace31217211100d622fdb65068c6162758b6ae7103a6ce8bdc9f90');\nhashMap.set('swift','cdf063debdbf36888523ff8cec6d2d1b0ec6f49b37b2fbcd80b0d4f6a31114e1');\nhashMap.set('tekton','33948f5bdf7553909fa63744adb26da97ddf366e9499bccab1250879570267c9');\nhashMap.set('terraform','5b0037e4a88e06efe6f006eff15c24d9e1fefdda40d282aa99f54c2637d21c4d');\nhashMap.set('terraform-version','ec8f786b9731d47f2c2fe0307caf64d7ddd83046fe7ff1f7d8423239f8b0f2aa');\nhashMap.set('terragrunt','300f8fb3c09667654412d2f5dd8ab4882e0f5d1d7a8bc39794993d2e7e58d1b7');\nhashMap.set('terragrunt-version','eea6087b33717d22ede2fc68c2f64df8390b75abe82110ed831a180648feb51d');\nhashMap.set('tflint-plugin','f423bfa2b42a2bfc0e38a33ebd4f9d452473e7ed4e7ad6384a99eb9a35d97479');\nhashMap.set('travis','f3e2f38e699c390b00ff481be5e91dceaa81609e93caf9a4214933de759c84fc');\nhashMap.set('typst','d080a79fbd961c6e21fcc505d544b7e0ff2126142acb1dcabdf6abbcd9339248');\nhashMap.set('unity3d','f13e25e115e3443f4e16cf31578acffa78fb1a5e23339680a92d8d6de6052920');\nhashMap.set('velaci','fda00ddb7cc23e9a37e0a8a253151df0a6930b4276d3e4f78cc54b9ac09af7de');\nhashMap.set('vendir','7db907b3b77ef5f3465f3c4339fbab56bbcdfd1bf34b3d33e4c178d2e07e23e7');\nhashMap.set('woodpecker','6110d3bec33aaeb3511d4bbfa896cec3c8e02fb04a6cff50c9ba81061c851045');\nhashMap.set('xcodegen','dad511d88a9ce1dbdde8b9731f3da7f2bdaa4ca8a083294ee58d56da62ab1683');\nhashMap.set('jsonata','416bcf61144b276b3112814c6e6d261aa29608f46fbb0516c471d35c16f8f0d7');\nhashMap.set('regex','20be5247fdc164173871a051acb0527da017d0c155c653d7563601f55e7b3ff5');"],"mappings":"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"}
@@ -27,7 +27,7 @@ async function generateLoginCmd(repositoryRule) {
27
27
  logger.trace({ repository }, `Using basic auth for Helm registry`);
28
28
  const hostPart = repository.split("/")[0];
29
29
  const cmd = `${loginCMD} --username ${quote(username)} --password ${quote(password)} ${quote(hostPart)}`;
30
- logger.trace({ cmd }, "Generated Helm registry login command");
30
+ logger.trace({ host: hostPart }, "Generated Helm registry login command");
31
31
  return cmd;
32
32
  }
33
33
  return null;
@@ -1 +1 @@
1
- {"version":3,"file":"common.js","names":[],"sources":["../../../../lib/modules/manager/helmv3/common.ts"],"sourcesContent":["import { quote } from 'shlex';\nimport upath from 'upath';\n\nimport { logger } from '../../../logger/index.ts';\nimport { coerceArray } from '../../../util/array.ts';\nimport type { ExtraEnv } from '../../../util/exec/types.ts';\nimport { privateCacheDir } from '../../../util/fs/index.ts';\nimport { addSecretForSanitizing } from '../../../util/sanitize.ts';\nimport { fromBase64 } from '../../../util/string.ts';\nimport { ecrRegex, getECRAuthToken } from '../../datasource/docker/ecr.ts';\nimport type { RepositoryRule } from './types.ts';\n\nexport async function generateLoginCmd(\n repositoryRule: RepositoryRule,\n): Promise<string | null> {\n logger.trace({ repositoryRule }, 'Generating Helm registry login command');\n const { hostRule, repository } = repositoryRule;\n const { username, password } = hostRule;\n const loginCMD = 'helm registry login';\n if (username !== 'AWS' && ecrRegex.test(repository)) {\n logger.trace({ repository }, `Using ecr auth for Helm registry`);\n const [, region] = coerceArray(ecrRegex.exec(repository));\n const auth = await getECRAuthToken(region, hostRule);\n if (!auth) {\n return null;\n }\n const [username, password] = fromBase64(auth).split(':');\n if (!username || !password) {\n return null;\n }\n addSecretForSanitizing(username);\n addSecretForSanitizing(password);\n return `${loginCMD} --username ${quote(username)} --password ${quote(\n password,\n )} ${quote(repository)}`;\n }\n if (username && password) {\n logger.trace({ repository }, `Using basic auth for Helm registry`);\n // Split off any path as it's not valid for the helm registry login command\n const hostPart = repository.split('/')[0];\n const cmd = `${loginCMD} --username ${quote(username)} --password ${quote(\n password,\n )} ${quote(hostPart)}`;\n logger.trace({ cmd }, 'Generated Helm registry login command');\n return cmd;\n }\n return null;\n}\n\nexport function generateHelmEnvs(): ExtraEnv {\n return {\n HELM_EXPERIMENTAL_OCI: '1',\n // set cache and config files to a path in privateCacheDir to prevent file and credential leakage\n HELM_REGISTRY_CONFIG: `${upath.join(privateCacheDir(), 'registry.json')}`,\n HELM_REPOSITORY_CONFIG: `${upath.join(\n privateCacheDir(),\n 'repositories.yaml',\n )}`,\n HELM_REPOSITORY_CACHE: `${upath.join(privateCacheDir(), 'repositories')}`,\n };\n}\n"],"mappings":";;;;;;;;;AAYA,eAAsB,iBACpB,gBACwB;CACxB,OAAO,MAAM,EAAE,eAAe,GAAG,wCAAwC;CACzE,MAAM,EAAE,UAAU,eAAe;CACjC,MAAM,EAAE,UAAU,aAAa;CAC/B,MAAM,WAAW;CACjB,IAAI,aAAa,SAAS,SAAS,KAAK,UAAU,GAAG;EACnD,OAAO,MAAM,EAAE,WAAW,GAAG,kCAAkC;EAC/D,MAAM,GAAG,UAAU,YAAY,SAAS,KAAK,UAAU,CAAC;EACxD,MAAM,OAAO,MAAM,gBAAgB,QAAQ,QAAQ;EACnD,IAAI,CAAC,MACH,OAAO;EAET,MAAM,CAAC,UAAU,YAAY,WAAW,IAAI,CAAC,CAAC,MAAM,GAAG;EACvD,IAAI,CAAC,YAAY,CAAC,UAChB,OAAO;EAET,uBAAuB,QAAQ;EAC/B,uBAAuB,QAAQ;EAC/B,OAAO,GAAG,SAAS,cAAc,MAAM,QAAQ,EAAE,cAAc,MAC7D,QACF,EAAE,GAAG,MAAM,UAAU;CACvB;CACA,IAAI,YAAY,UAAU;EACxB,OAAO,MAAM,EAAE,WAAW,GAAG,oCAAoC;EAEjE,MAAM,WAAW,WAAW,MAAM,GAAG,CAAC,CAAC;EACvC,MAAM,MAAM,GAAG,SAAS,cAAc,MAAM,QAAQ,EAAE,cAAc,MAClE,QACF,EAAE,GAAG,MAAM,QAAQ;EACnB,OAAO,MAAM,EAAE,IAAI,GAAG,uCAAuC;EAC7D,OAAO;CACT;CACA,OAAO;AACT;AAEA,SAAgB,mBAA6B;CAC3C,OAAO;EACL,uBAAuB;EAEvB,sBAAsB,GAAG,MAAM,KAAK,gBAAgB,GAAG,eAAe;EACtE,wBAAwB,GAAG,MAAM,KAC/B,gBAAgB,GAChB,mBACF;EACA,uBAAuB,GAAG,MAAM,KAAK,gBAAgB,GAAG,cAAc;CACxE;AACF"}
1
+ {"version":3,"file":"common.js","names":[],"sources":["../../../../lib/modules/manager/helmv3/common.ts"],"sourcesContent":["import { quote } from 'shlex';\nimport upath from 'upath';\n\nimport { logger } from '../../../logger/index.ts';\nimport { coerceArray } from '../../../util/array.ts';\nimport type { ExtraEnv } from '../../../util/exec/types.ts';\nimport { privateCacheDir } from '../../../util/fs/index.ts';\nimport { addSecretForSanitizing } from '../../../util/sanitize.ts';\nimport { fromBase64 } from '../../../util/string.ts';\nimport { ecrRegex, getECRAuthToken } from '../../datasource/docker/ecr.ts';\nimport type { RepositoryRule } from './types.ts';\n\nexport async function generateLoginCmd(\n repositoryRule: RepositoryRule,\n): Promise<string | null> {\n logger.trace({ repositoryRule }, 'Generating Helm registry login command');\n const { hostRule, repository } = repositoryRule;\n const { username, password } = hostRule;\n const loginCMD = 'helm registry login';\n if (username !== 'AWS' && ecrRegex.test(repository)) {\n logger.trace({ repository }, `Using ecr auth for Helm registry`);\n const [, region] = coerceArray(ecrRegex.exec(repository));\n const auth = await getECRAuthToken(region, hostRule);\n if (!auth) {\n return null;\n }\n const [username, password] = fromBase64(auth).split(':');\n if (!username || !password) {\n return null;\n }\n addSecretForSanitizing(username);\n addSecretForSanitizing(password);\n return `${loginCMD} --username ${quote(username)} --password ${quote(\n password,\n )} ${quote(repository)}`;\n }\n if (username && password) {\n logger.trace({ repository }, `Using basic auth for Helm registry`);\n // Split off any path as it's not valid for the helm registry login command\n const hostPart = repository.split('/')[0];\n const cmd = `${loginCMD} --username ${quote(username)} --password ${quote(\n password,\n )} ${quote(hostPart)}`;\n // the command carries the password, so log the target host only\n logger.trace({ host: hostPart }, 'Generated Helm registry login command');\n return cmd;\n }\n return null;\n}\n\nexport function generateHelmEnvs(): ExtraEnv {\n return {\n HELM_EXPERIMENTAL_OCI: '1',\n // set cache and config files to a path in privateCacheDir to prevent file and credential leakage\n HELM_REGISTRY_CONFIG: `${upath.join(privateCacheDir(), 'registry.json')}`,\n HELM_REPOSITORY_CONFIG: `${upath.join(\n privateCacheDir(),\n 'repositories.yaml',\n )}`,\n HELM_REPOSITORY_CACHE: `${upath.join(privateCacheDir(), 'repositories')}`,\n };\n}\n"],"mappings":";;;;;;;;;AAYA,eAAsB,iBACpB,gBACwB;CACxB,OAAO,MAAM,EAAE,eAAe,GAAG,wCAAwC;CACzE,MAAM,EAAE,UAAU,eAAe;CACjC,MAAM,EAAE,UAAU,aAAa;CAC/B,MAAM,WAAW;CACjB,IAAI,aAAa,SAAS,SAAS,KAAK,UAAU,GAAG;EACnD,OAAO,MAAM,EAAE,WAAW,GAAG,kCAAkC;EAC/D,MAAM,GAAG,UAAU,YAAY,SAAS,KAAK,UAAU,CAAC;EACxD,MAAM,OAAO,MAAM,gBAAgB,QAAQ,QAAQ;EACnD,IAAI,CAAC,MACH,OAAO;EAET,MAAM,CAAC,UAAU,YAAY,WAAW,IAAI,CAAC,CAAC,MAAM,GAAG;EACvD,IAAI,CAAC,YAAY,CAAC,UAChB,OAAO;EAET,uBAAuB,QAAQ;EAC/B,uBAAuB,QAAQ;EAC/B,OAAO,GAAG,SAAS,cAAc,MAAM,QAAQ,EAAE,cAAc,MAC7D,QACF,EAAE,GAAG,MAAM,UAAU;CACvB;CACA,IAAI,YAAY,UAAU;EACxB,OAAO,MAAM,EAAE,WAAW,GAAG,oCAAoC;EAEjE,MAAM,WAAW,WAAW,MAAM,GAAG,CAAC,CAAC;EACvC,MAAM,MAAM,GAAG,SAAS,cAAc,MAAM,QAAQ,EAAE,cAAc,MAClE,QACF,EAAE,GAAG,MAAM,QAAQ;EAEnB,OAAO,MAAM,EAAE,MAAM,SAAS,GAAG,uCAAuC;EACxE,OAAO;CACT;CACA,OAAO;AACT;AAEA,SAAgB,mBAA6B;CAC3C,OAAO;EACL,uBAAuB;EAEvB,sBAAsB,GAAG,MAAM,KAAK,gBAAgB,GAAG,eAAe;EACtE,wBAAwB,GAAG,MAAM,KAC/B,gBAAgB,GAChB,mBACF;EACA,uBAAuB,GAAG,MAAM,KAAK,gBAAgB,GAAG,cAAc;CACxE;AACF"}
@@ -3,10 +3,9 @@ import { regEx } from "../../../../util/regex.js";
3
3
  import { coerceArray } from "../../../../util/array.js";
4
4
  import { logger } from "../../../../logger/index.js";
5
5
  import { parseUrl } from "../../../../util/url.js";
6
- import { find } from "../../../../util/host-rules.js";
7
6
  import { findLocalSiblingOrParent, readLocalFile } from "../../../../util/fs/index.js";
8
7
  import { Result } from "../../../../util/result.js";
9
- import { getGoogleAuthHostRule } from "../../../datasource/util.js";
8
+ import { findPypiIndexCredentials } from "../../../datasource/pypi/host-rules.js";
10
9
  import { PypiDatasource } from "../../../datasource/pypi/index.js";
11
10
  import { applyGitSource, artifactErrorResult, resolveToolConstraint, updateLockFile } from "../../util.js";
12
11
  import { withGitEnvironment } from "../../../../util/git/exec.js";
@@ -141,22 +140,6 @@ function generateCMD(updatedDeps) {
141
140
  }
142
141
  return `${uvUpdateCMD} ${deps.map((dep) => `--upgrade-package ${quote(dep)}`).join(" ")}`;
143
142
  }
144
- function getMatchingHostRule(url) {
145
- return find({
146
- hostType: PypiDatasource.id,
147
- url
148
- });
149
- }
150
- async function getUsernamePassword(url) {
151
- const rule = getMatchingHostRule(url.toString());
152
- if (rule.username || rule.password) return rule;
153
- if (url.hostname.endsWith(".pkg.dev")) {
154
- const hostRule = await getGoogleAuthHostRule();
155
- if (hostRule) return hostRule;
156
- logger.once.debug({ url }, "Could not get Google access token");
157
- }
158
- return {};
159
- }
160
143
  async function getUvExtraIndexUrl(project, deps) {
161
144
  const pyPiRegistryUrls = deps.filter((dep) => dep.datasource === PypiDatasource.id).filter((dep) => {
162
145
  const sources = project.tool?.uv?.sources;
@@ -171,7 +154,7 @@ async function getUvExtraIndexUrl(project, deps) {
171
154
  for (const registryUrl of registryUrls) {
172
155
  const parsedUrl = parseUrl(registryUrl);
173
156
  if (!parsedUrl) continue;
174
- const { username, password } = await getUsernamePassword(parsedUrl);
157
+ const { username, password } = await findPypiIndexCredentials(parsedUrl.toString());
175
158
  if (username || password) {
176
159
  // v8 ignore else -- needs a host rule carrying only one of the two
177
160
  if (username) parsedUrl.username = username;
@@ -191,7 +174,7 @@ async function getUvIndexCredentials(project) {
191
174
  /* v8 ignore next -- needs test */
192
175
  if (!parsedUrl) continue;
193
176
  if (!name) continue;
194
- const { username, password } = await getUsernamePassword(parsedUrl);
177
+ const { username, password } = await findPypiIndexCredentials(parsedUrl.toString());
195
178
  const NAME = name.toUpperCase().replace(regEx(/[^A-Z0-9]/g), "_");
196
179
  // v8 ignore else -- needs a host rule carrying only one of the two
197
180
  if (username) entries.push([`UV_INDEX_${NAME}_USERNAME`, username]);
@@ -1 +1 @@
1
- {"version":3,"file":"uv.js","names":[],"sources":["../../../../../lib/modules/manager/pep621/processors/uv.ts"],"sourcesContent":["import { isString } from '@sindresorhus/is';\nimport { quote } from 'shlex';\nimport { TEMPORARY_ERROR } from '../../../../constants/error-messages.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport type { HostRule } from '../../../../types/index.ts';\nimport { coerceArray } from '../../../../util/array.ts';\nimport type {\n ExecOptions,\n ToolConstraint,\n} from '../../../../util/exec/types.ts';\nimport {\n findLocalSiblingOrParent,\n readLocalFile,\n} from '../../../../util/fs/index.ts';\nimport { withGitEnvironment } from '../../../../util/git/exec.ts';\nimport { find } from '../../../../util/host-rules.ts';\nimport { regEx } from '../../../../util/regex.ts';\nimport { Result } from '../../../../util/result.ts';\nimport { parseUrl } from '../../../../util/url.ts';\nimport { PypiDatasource } from '../../../datasource/pypi/index.ts';\nimport { getGoogleAuthHostRule } from '../../../datasource/util.ts';\nimport type {\n PackageDependency,\n UpdateArtifact,\n UpdateArtifactsResult,\n Upgrade,\n} from '../../types.ts';\nimport {\n applyGitSource,\n artifactErrorResult,\n resolveToolConstraint,\n updateLockFile,\n} from '../../util.ts';\nimport { type PyProject, UvLockfile, type UvSource } from '../schema.ts';\nimport { depTypes } from '../utils.ts';\nimport { BasePyProjectProcessor } from './abstract.ts';\n\nconst uvUpdateCMD = 'uv lock';\nconst gitExec = withGitEnvironment(['pep621']);\n\nfunction isUvIndexSource(\n source: UvSource,\n): source is Extract<UvSource, { index: string }> {\n return 'index' in source;\n}\n\nexport class UvProcessor extends BasePyProjectProcessor {\n override lockfileName = 'uv.lock';\n\n process(project: PyProject, deps: PackageDependency[]): PackageDependency[] {\n const uv = project.tool?.uv;\n if (!uv) {\n return deps;\n }\n\n const hasExplicitDefault = uv.index?.some(\n (index) => index.default && index.explicit,\n );\n const defaultIndex = uv.index?.find(\n (index) => index.default && !index.explicit,\n );\n const implicitIndexUrls = uv.index\n ?.filter((index) => !index.explicit && index.name !== defaultIndex?.name)\n ?.map(({ url }) => url);\n\n const devDependencies = uv['dev-dependencies'];\n if (devDependencies) {\n deps.push(...devDependencies);\n }\n\n // https://docs.astral.sh/uv/concepts/dependencies/#dependency-sources\n // Skip sources that do not make sense to handle (e.g. path).\n if (uv.sources || defaultIndex || implicitIndexUrls) {\n for (const dep of deps) {\n /* v8 ignore next -- needs test */\n if (!dep.packageName) {\n continue;\n }\n\n if (dep.depType === 'requires-python') {\n continue;\n }\n\n // Using `packageName` as it applies PEP 508 normalization, which is\n // also applied by uv when matching a source to a dependency.\n const depSources = uv.sources?.[dep.packageName];\n if (depSources) {\n // Dependency is pinned to one or more specific sources.\n dep.depType = depTypes.uvSources;\n if (depSources.every(isUvIndexSource)) {\n // Sources referencing an index, possibly disambiguated by\n // environment markers. Any of the indexes can serve the package,\n // so use all of them as registries.\n const registryUrls: string[] = [];\n for (const depSource of depSources) {\n const index = uv.index?.find(\n ({ name }) => name === depSource.index,\n );\n if (index) {\n registryUrls.push(index.url);\n }\n }\n if (registryUrls.length) {\n dep.registryUrls = [...new Set(registryUrls)];\n }\n } else if (depSources.length === 1) {\n const depSource = depSources[0];\n if ('git' in depSource) {\n applyGitSource(\n dep,\n depSource.git,\n depSource.rev,\n depSource.tag,\n depSource.branch,\n );\n } else if ('url' in depSource) {\n dep.skipReason = 'unsupported-url';\n } else if ('path' in depSource) {\n dep.skipReason = 'path-dependency';\n } else if ('workspace' in depSource) {\n dep.skipReason = 'inherited-dependency';\n } else {\n dep.skipReason = 'unknown-registry';\n }\n } else {\n // Multiple sources that are not all indexes (e.g. a git source\n // per platform) cannot be represented as a single update.\n dep.skipReason = 'unsupported';\n }\n } else {\n // Dependency is not pinned to a specific source, so we need to\n // determine the source based on the index configuration.\n if (hasExplicitDefault) {\n // don't fall back to pypi if there is an explicit default index\n dep.registryUrls = [];\n } else if (defaultIndex) {\n // There is a default index configured, so use it.\n dep.registryUrls = [defaultIndex.url];\n }\n\n if (implicitIndexUrls?.length) {\n // If there are implicit indexes, check them first and fall back\n // to the default.\n dep.registryUrls = implicitIndexUrls.concat(\n dep.registryUrls ?? PypiDatasource.defaultURL,\n );\n }\n }\n }\n }\n\n return deps;\n }\n\n async extractLockedVersions(\n project: PyProject,\n deps: PackageDependency[],\n packageFile: string,\n ): Promise<PackageDependency[]> {\n const lockFileName = await findLocalSiblingOrParent(\n packageFile,\n this.lockfileName,\n );\n if (lockFileName === null) {\n logger.debug({ packageFile }, `No uv lock file found`);\n } else {\n const lockFileContent = await readLocalFile(lockFileName, 'utf8');\n if (lockFileContent) {\n const { val: lockFileMapping, err } = Result.parse(\n lockFileContent,\n UvLockfile,\n ).unwrap();\n\n if (err) {\n logger.debug({ packageFile, err }, `Error parsing uv lock file`);\n } else {\n for (const dep of deps) {\n const packageName = dep.packageName;\n if (packageName && packageName in lockFileMapping) {\n dep.lockedVersion = lockFileMapping[packageName];\n }\n }\n }\n }\n }\n\n return Promise.resolve(deps);\n }\n\n async updateArtifacts(\n updateArtifact: UpdateArtifact,\n project: PyProject,\n ): Promise<UpdateArtifactsResult[] | null> {\n const { config, updatedDeps, packageFileName } = updateArtifact;\n\n const { isLockFileMaintenance } = config;\n\n // abort if no lockfile is defined\n const lockFileName = await findLocalSiblingOrParent(\n packageFileName,\n 'uv.lock',\n );\n if (lockFileName === null) {\n logger.debug({ packageFileName }, `No uv lock file found`);\n return null;\n }\n try {\n const existingLockFileContent = await readLocalFile(lockFileName, 'utf8');\n if (!existingLockFileContent) {\n logger.debug('No uv.lock found');\n return null;\n }\n\n const pythonConstraint: ToolConstraint = {\n toolName: 'python',\n constraint: await resolveToolConstraint(\n config,\n 'python',\n () => project.project?.['requires-python'],\n ),\n };\n const uvConstraint: ToolConstraint = {\n toolName: 'uv',\n constraint: await resolveToolConstraint(\n config,\n 'uv',\n () => project.tool?.uv?.['required-version'],\n ),\n };\n\n const extraEnv = {\n ...(await getUvExtraIndexUrl(project, updateArtifact.updatedDeps)),\n ...(await getUvIndexCredentials(project)),\n };\n const execOptions: ExecOptions = {\n cwdFile: packageFileName,\n extraEnv,\n docker: {},\n toolConstraints: [pythonConstraint, uvConstraint],\n };\n\n // on lockFileMaintenance do not specify any packages and update the complete lock file\n // else only update specific packages\n let cmd: string;\n if (isLockFileMaintenance) {\n cmd = `${uvUpdateCMD} --upgrade`;\n } else {\n cmd = generateCMD(updatedDeps);\n }\n return await updateLockFile({\n lockFileName,\n existingLockFileContent,\n run: () => gitExec(cmd, execOptions),\n });\n } catch (err) {\n if (err.message === TEMPORARY_ERROR) {\n throw err;\n }\n logger.debug({ err }, 'Failed to update uv lock file');\n return artifactErrorResult(lockFileName, err);\n }\n }\n}\n\nfunction generateCMD(updatedDeps: Upgrade[]): string {\n const deps: string[] = [];\n\n for (const dep of updatedDeps) {\n switch (dep.depType) {\n case depTypes.optionalDependencies: {\n deps.push(dep.depName!);\n break;\n }\n case depTypes.uvDevDependencies:\n case depTypes.uvSources: {\n deps.push(dep.depName!);\n break;\n }\n case depTypes.buildSystemRequires:\n // build requirements are not locked in the lock files, no need to update.\n break;\n default: {\n deps.push(dep.packageName!);\n }\n }\n }\n\n return `${uvUpdateCMD} ${deps.map((dep) => `--upgrade-package ${quote(dep)}`).join(' ')}`;\n}\n\nfunction getMatchingHostRule(url: string | undefined): HostRule {\n return find({ hostType: PypiDatasource.id, url });\n}\n\nasync function getUsernamePassword(\n url: URL,\n): Promise<{ username?: string; password?: string }> {\n const rule = getMatchingHostRule(url.toString());\n if (rule.username || rule.password) {\n return rule;\n }\n\n if (url.hostname.endsWith('.pkg.dev')) {\n const hostRule = await getGoogleAuthHostRule();\n if (hostRule) {\n return hostRule;\n }\n logger.once.debug({ url }, 'Could not get Google access token');\n }\n\n return {};\n}\n\nasync function getUvExtraIndexUrl(\n project: PyProject,\n deps: Upgrade[],\n): Promise<NodeJS.ProcessEnv> {\n const pyPiRegistryUrls = deps\n .filter((dep) => dep.datasource === PypiDatasource.id)\n .filter((dep) => {\n // Remove dependencies that are pinned to a specific index\n const sources = project.tool?.uv?.sources;\n const packageName = dep.packageName!;\n return !sources || !(packageName in sources);\n })\n .flatMap((dep) => dep.registryUrls)\n .filter(isString)\n .filter((registryUrl) => {\n // Check if the registry URL is not the default one and not already configured\n const configuredIndexUrls = coerceArray(\n project.tool?.uv?.index?.map(({ url }) => url),\n );\n return (\n registryUrl !== PypiDatasource.defaultURL &&\n !configuredIndexUrls.includes(registryUrl)\n );\n });\n\n const registryUrls = new Set(pyPiRegistryUrls);\n const extraIndexUrls: string[] = [];\n\n for (const registryUrl of registryUrls) {\n const parsedUrl = parseUrl(registryUrl);\n if (!parsedUrl) {\n continue;\n }\n\n const { username, password } = await getUsernamePassword(parsedUrl);\n if (username || password) {\n // v8 ignore else -- needs a host rule carrying only one of the two\n if (username) {\n parsedUrl.username = username;\n }\n // v8 ignore else -- needs a host rule carrying only one of the two\n if (password) {\n parsedUrl.password = password;\n }\n }\n\n extraIndexUrls.push(parsedUrl.toString());\n }\n\n return {\n UV_EXTRA_INDEX_URL: extraIndexUrls.join(' '),\n };\n}\n\nasync function getUvIndexCredentials(\n project: PyProject,\n): Promise<NodeJS.ProcessEnv> {\n const uv_indexes = project.tool?.uv?.index;\n\n if (!uv_indexes) {\n return {};\n }\n\n const entries = [];\n\n for (const { name, url } of uv_indexes) {\n const parsedUrl = parseUrl(url);\n /* v8 ignore next -- needs test */\n if (!parsedUrl) {\n continue;\n }\n\n // If no name is provided for the index, authentication information must be passed through alternative methods\n if (!name) {\n continue;\n }\n\n const { username, password } = await getUsernamePassword(parsedUrl);\n\n const NAME = name.toUpperCase().replace(regEx(/[^A-Z0-9]/g), '_');\n\n // v8 ignore else -- needs a host rule carrying only one of the two\n if (username) {\n entries.push([`UV_INDEX_${NAME}_USERNAME`, username]);\n }\n\n // v8 ignore else -- needs a host rule carrying only one of the two\n if (password) {\n entries.push([`UV_INDEX_${NAME}_PASSWORD`, password]);\n }\n }\n\n return Object.fromEntries(entries);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"uv.js","names":[],"sources":["../../../../../lib/modules/manager/pep621/processors/uv.ts"],"sourcesContent":["import { isString } from '@sindresorhus/is';\nimport { quote } from 'shlex';\nimport { TEMPORARY_ERROR } from '../../../../constants/error-messages.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport { coerceArray } from '../../../../util/array.ts';\nimport type {\n ExecOptions,\n ToolConstraint,\n} from '../../../../util/exec/types.ts';\nimport {\n findLocalSiblingOrParent,\n readLocalFile,\n} from '../../../../util/fs/index.ts';\nimport { withGitEnvironment } from '../../../../util/git/exec.ts';\nimport { regEx } from '../../../../util/regex.ts';\nimport { Result } from '../../../../util/result.ts';\nimport { parseUrl } from '../../../../util/url.ts';\nimport { findPypiIndexCredentials } from '../../../datasource/pypi/host-rules.ts';\nimport { PypiDatasource } from '../../../datasource/pypi/index.ts';\nimport type {\n PackageDependency,\n UpdateArtifact,\n UpdateArtifactsResult,\n Upgrade,\n} from '../../types.ts';\nimport {\n applyGitSource,\n artifactErrorResult,\n resolveToolConstraint,\n updateLockFile,\n} from '../../util.ts';\nimport { type PyProject, UvLockfile, type UvSource } from '../schema.ts';\nimport { depTypes } from '../utils.ts';\nimport { BasePyProjectProcessor } from './abstract.ts';\n\nconst uvUpdateCMD = 'uv lock';\nconst gitExec = withGitEnvironment(['pep621']);\n\nfunction isUvIndexSource(\n source: UvSource,\n): source is Extract<UvSource, { index: string }> {\n return 'index' in source;\n}\n\nexport class UvProcessor extends BasePyProjectProcessor {\n override lockfileName = 'uv.lock';\n\n process(project: PyProject, deps: PackageDependency[]): PackageDependency[] {\n const uv = project.tool?.uv;\n if (!uv) {\n return deps;\n }\n\n const hasExplicitDefault = uv.index?.some(\n (index) => index.default && index.explicit,\n );\n const defaultIndex = uv.index?.find(\n (index) => index.default && !index.explicit,\n );\n const implicitIndexUrls = uv.index\n ?.filter((index) => !index.explicit && index.name !== defaultIndex?.name)\n ?.map(({ url }) => url);\n\n const devDependencies = uv['dev-dependencies'];\n if (devDependencies) {\n deps.push(...devDependencies);\n }\n\n // https://docs.astral.sh/uv/concepts/dependencies/#dependency-sources\n // Skip sources that do not make sense to handle (e.g. path).\n if (uv.sources || defaultIndex || implicitIndexUrls) {\n for (const dep of deps) {\n /* v8 ignore next -- needs test */\n if (!dep.packageName) {\n continue;\n }\n\n if (dep.depType === 'requires-python') {\n continue;\n }\n\n // Using `packageName` as it applies PEP 508 normalization, which is\n // also applied by uv when matching a source to a dependency.\n const depSources = uv.sources?.[dep.packageName];\n if (depSources) {\n // Dependency is pinned to one or more specific sources.\n dep.depType = depTypes.uvSources;\n if (depSources.every(isUvIndexSource)) {\n // Sources referencing an index, possibly disambiguated by\n // environment markers. Any of the indexes can serve the package,\n // so use all of them as registries.\n const registryUrls: string[] = [];\n for (const depSource of depSources) {\n const index = uv.index?.find(\n ({ name }) => name === depSource.index,\n );\n if (index) {\n registryUrls.push(index.url);\n }\n }\n if (registryUrls.length) {\n dep.registryUrls = [...new Set(registryUrls)];\n }\n } else if (depSources.length === 1) {\n const depSource = depSources[0];\n if ('git' in depSource) {\n applyGitSource(\n dep,\n depSource.git,\n depSource.rev,\n depSource.tag,\n depSource.branch,\n );\n } else if ('url' in depSource) {\n dep.skipReason = 'unsupported-url';\n } else if ('path' in depSource) {\n dep.skipReason = 'path-dependency';\n } else if ('workspace' in depSource) {\n dep.skipReason = 'inherited-dependency';\n } else {\n dep.skipReason = 'unknown-registry';\n }\n } else {\n // Multiple sources that are not all indexes (e.g. a git source\n // per platform) cannot be represented as a single update.\n dep.skipReason = 'unsupported';\n }\n } else {\n // Dependency is not pinned to a specific source, so we need to\n // determine the source based on the index configuration.\n if (hasExplicitDefault) {\n // don't fall back to pypi if there is an explicit default index\n dep.registryUrls = [];\n } else if (defaultIndex) {\n // There is a default index configured, so use it.\n dep.registryUrls = [defaultIndex.url];\n }\n\n if (implicitIndexUrls?.length) {\n // If there are implicit indexes, check them first and fall back\n // to the default.\n dep.registryUrls = implicitIndexUrls.concat(\n dep.registryUrls ?? PypiDatasource.defaultURL,\n );\n }\n }\n }\n }\n\n return deps;\n }\n\n async extractLockedVersions(\n project: PyProject,\n deps: PackageDependency[],\n packageFile: string,\n ): Promise<PackageDependency[]> {\n const lockFileName = await findLocalSiblingOrParent(\n packageFile,\n this.lockfileName,\n );\n if (lockFileName === null) {\n logger.debug({ packageFile }, `No uv lock file found`);\n } else {\n const lockFileContent = await readLocalFile(lockFileName, 'utf8');\n if (lockFileContent) {\n const { val: lockFileMapping, err } = Result.parse(\n lockFileContent,\n UvLockfile,\n ).unwrap();\n\n if (err) {\n logger.debug({ packageFile, err }, `Error parsing uv lock file`);\n } else {\n for (const dep of deps) {\n const packageName = dep.packageName;\n if (packageName && packageName in lockFileMapping) {\n dep.lockedVersion = lockFileMapping[packageName];\n }\n }\n }\n }\n }\n\n return Promise.resolve(deps);\n }\n\n async updateArtifacts(\n updateArtifact: UpdateArtifact,\n project: PyProject,\n ): Promise<UpdateArtifactsResult[] | null> {\n const { config, updatedDeps, packageFileName } = updateArtifact;\n\n const { isLockFileMaintenance } = config;\n\n // abort if no lockfile is defined\n const lockFileName = await findLocalSiblingOrParent(\n packageFileName,\n 'uv.lock',\n );\n if (lockFileName === null) {\n logger.debug({ packageFileName }, `No uv lock file found`);\n return null;\n }\n try {\n const existingLockFileContent = await readLocalFile(lockFileName, 'utf8');\n if (!existingLockFileContent) {\n logger.debug('No uv.lock found');\n return null;\n }\n\n const pythonConstraint: ToolConstraint = {\n toolName: 'python',\n constraint: await resolveToolConstraint(\n config,\n 'python',\n () => project.project?.['requires-python'],\n ),\n };\n const uvConstraint: ToolConstraint = {\n toolName: 'uv',\n constraint: await resolveToolConstraint(\n config,\n 'uv',\n () => project.tool?.uv?.['required-version'],\n ),\n };\n\n const extraEnv = {\n ...(await getUvExtraIndexUrl(project, updateArtifact.updatedDeps)),\n ...(await getUvIndexCredentials(project)),\n };\n const execOptions: ExecOptions = {\n cwdFile: packageFileName,\n extraEnv,\n docker: {},\n toolConstraints: [pythonConstraint, uvConstraint],\n };\n\n // on lockFileMaintenance do not specify any packages and update the complete lock file\n // else only update specific packages\n let cmd: string;\n if (isLockFileMaintenance) {\n cmd = `${uvUpdateCMD} --upgrade`;\n } else {\n cmd = generateCMD(updatedDeps);\n }\n return await updateLockFile({\n lockFileName,\n existingLockFileContent,\n run: () => gitExec(cmd, execOptions),\n });\n } catch (err) {\n if (err.message === TEMPORARY_ERROR) {\n throw err;\n }\n logger.debug({ err }, 'Failed to update uv lock file');\n return artifactErrorResult(lockFileName, err);\n }\n }\n}\n\nfunction generateCMD(updatedDeps: Upgrade[]): string {\n const deps: string[] = [];\n\n for (const dep of updatedDeps) {\n switch (dep.depType) {\n case depTypes.optionalDependencies: {\n deps.push(dep.depName!);\n break;\n }\n case depTypes.uvDevDependencies:\n case depTypes.uvSources: {\n deps.push(dep.depName!);\n break;\n }\n case depTypes.buildSystemRequires:\n // build requirements are not locked in the lock files, no need to update.\n break;\n default: {\n deps.push(dep.packageName!);\n }\n }\n }\n\n return `${uvUpdateCMD} ${deps.map((dep) => `--upgrade-package ${quote(dep)}`).join(' ')}`;\n}\n\nasync function getUvExtraIndexUrl(\n project: PyProject,\n deps: Upgrade[],\n): Promise<NodeJS.ProcessEnv> {\n const pyPiRegistryUrls = deps\n .filter((dep) => dep.datasource === PypiDatasource.id)\n .filter((dep) => {\n // Remove dependencies that are pinned to a specific index\n const sources = project.tool?.uv?.sources;\n const packageName = dep.packageName!;\n return !sources || !(packageName in sources);\n })\n .flatMap((dep) => dep.registryUrls)\n .filter(isString)\n .filter((registryUrl) => {\n // Check if the registry URL is not the default one and not already configured\n const configuredIndexUrls = coerceArray(\n project.tool?.uv?.index?.map(({ url }) => url),\n );\n return (\n registryUrl !== PypiDatasource.defaultURL &&\n !configuredIndexUrls.includes(registryUrl)\n );\n });\n\n const registryUrls = new Set(pyPiRegistryUrls);\n const extraIndexUrls: string[] = [];\n\n for (const registryUrl of registryUrls) {\n const parsedUrl = parseUrl(registryUrl);\n if (!parsedUrl) {\n continue;\n }\n\n const { username, password } = await findPypiIndexCredentials(\n parsedUrl.toString(),\n );\n if (username || password) {\n // v8 ignore else -- needs a host rule carrying only one of the two\n if (username) {\n parsedUrl.username = username;\n }\n // v8 ignore else -- needs a host rule carrying only one of the two\n if (password) {\n parsedUrl.password = password;\n }\n }\n\n extraIndexUrls.push(parsedUrl.toString());\n }\n\n return {\n UV_EXTRA_INDEX_URL: extraIndexUrls.join(' '),\n };\n}\n\nasync function getUvIndexCredentials(\n project: PyProject,\n): Promise<NodeJS.ProcessEnv> {\n const uv_indexes = project.tool?.uv?.index;\n\n if (!uv_indexes) {\n return {};\n }\n\n const entries = [];\n\n for (const { name, url } of uv_indexes) {\n const parsedUrl = parseUrl(url);\n /* v8 ignore next -- needs test */\n if (!parsedUrl) {\n continue;\n }\n\n // If no name is provided for the index, authentication information must be passed through alternative methods\n if (!name) {\n continue;\n }\n\n const { username, password } = await findPypiIndexCredentials(\n parsedUrl.toString(),\n );\n\n const NAME = name.toUpperCase().replace(regEx(/[^A-Z0-9]/g), '_');\n\n // v8 ignore else -- needs a host rule carrying only one of the two\n if (username) {\n entries.push([`UV_INDEX_${NAME}_USERNAME`, username]);\n }\n\n // v8 ignore else -- needs a host rule carrying only one of the two\n if (password) {\n entries.push([`UV_INDEX_${NAME}_PASSWORD`, password]);\n }\n }\n\n return Object.fromEntries(entries);\n}\n"],"mappings":"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"}