renovate 43.223.0 → 43.224.0

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.
@@ -15,6 +15,7 @@ import { getGoogleAuthToken } from "../util.js";
15
15
  import { BearerScheme, parse } from "../../../util/http/www-authenticate.js";
16
16
  import { ecrRegex, getECRAuthToken } from "./ecr.js";
17
17
  import { googleRegex } from "./google.js";
18
+ import { RegistryAuthToken } from "./schema.js";
18
19
  import { isNonEmptyString, isString } from "@sindresorhus/is";
19
20
  //#region lib/modules/datasource/docker/common.ts
20
21
  const dockerDatasourceId = "docker";
@@ -112,7 +113,7 @@ async function getAuthHeaders(http, registryHost, dockerRepository, apiCheckUrl
112
113
  }, `Obtaining docker registry token`);
113
114
  opts.noAuth = true;
114
115
  opts.cacheProvider = memCacheProvider;
115
- const authResponse = (await http.getJsonUnchecked(authUrl.href, opts)).body;
116
+ const authResponse = (await http.getJson(authUrl.href, opts, RegistryAuthToken)).body;
116
117
  const token = authResponse.token ?? authResponse.access_token;
117
118
  /* v8 ignore next 4 -- TODO: add test */
118
119
  if (!token) {
@@ -1 +1 @@
1
- {"version":3,"file":"common.js","names":["hostRules.find","dockerVersioning"],"sources":["../../../../lib/modules/datasource/docker/common.ts"],"sourcesContent":["import { isNonEmptyString, isString } from '@sindresorhus/is';\nimport {\n HOST_DISABLED,\n PAGE_NOT_FOUND_ERROR,\n} from '../../../constants/error-messages.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { ExternalHostError } from '../../../types/errors/external-host-error.ts';\nimport { coerceArray } from '../../../util/array.ts';\nimport { detectPlatform } from '../../../util/common.ts';\nimport { parseGitUrl } from '../../../util/git/url.ts';\nimport { toSha256 } from '../../../util/hash.ts';\nimport * as hostRules from '../../../util/host-rules.ts';\nimport { memCacheProvider } from '../../../util/http/cache/memory-http-cache-provider.ts';\nimport type { Http } from '../../../util/http/index.ts';\nimport type {\n HttpOptions,\n HttpResponse,\n OutgoingHttpHeaders,\n} from '../../../util/http/types.ts';\nimport type { ParamsChallenge } from '../../../util/http/www-authenticate.ts';\nimport { BearerScheme, parse } from '../../../util/http/www-authenticate.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { addSecretForSanitizing } from '../../../util/sanitize.ts';\nimport {\n ensureTrailingSlash,\n parseUrl,\n trimTrailingSlash,\n} from '../../../util/url.ts';\nimport { api as dockerVersioning } from '../../versioning/docker/index.ts';\nimport { getGoogleAuthToken } from '../util.ts';\nimport { ecrRegex, getECRAuthToken } from './ecr.ts';\nimport { googleRegex } from './google.ts';\nimport type { OciHelmConfig } from './schema.ts';\nimport type { RegistryRepository } from './types.ts';\n\nexport const dockerDatasourceId = 'docker';\n\nexport const imageUrlLabel = 'org.opencontainers.image.url';\n\nexport const sourceLabel = 'org.opencontainers.image.source';\nexport const sourceLabels = [sourceLabel, 'org.label-schema.vcs-url'] as const;\n\nexport const gitRefLabel = 'org.opencontainers.image.revision';\n\nexport const DOCKER_HUB = 'https://index.docker.io';\n\nexport function isDockerHost(host: string): boolean {\n const regex = regEx(/(?:^|\\.)docker\\.io$/);\n return regex.test(host);\n}\n\nexport async function getAuthHeaders(\n http: Http,\n registryHost: string,\n dockerRepository: string,\n apiCheckUrl = `${registryHost}/v2/`,\n): Promise<OutgoingHttpHeaders | null> {\n try {\n const options = {\n throwHttpErrors: false,\n noAuth: true,\n cacheProvider: memCacheProvider,\n };\n const apiCheckResponse = apiCheckUrl.endsWith('/v2/')\n ? await http.get(apiCheckUrl, options)\n : // use json request, as this will be cached for tags, so it returns json\n // TODO: add cache test\n await http.getJsonUnchecked(apiCheckUrl, options);\n\n if (apiCheckResponse.statusCode === 200) {\n logger.debug(`No registry auth required for ${apiCheckUrl}`);\n return {};\n }\n if (apiCheckResponse.statusCode === 404) {\n logger.debug(`Page Not Found ${apiCheckUrl}`);\n // throw error up to be caught and potentially retried with library/ prefix\n throw new Error(PAGE_NOT_FOUND_ERROR);\n }\n if (\n apiCheckResponse.statusCode !== 401 ||\n !isNonEmptyString(apiCheckResponse.headers['www-authenticate'])\n ) {\n logger.warn(\n { apiCheckUrl, res: apiCheckResponse },\n 'Invalid registry response',\n );\n return null;\n }\n\n const rule = hostRules.find({\n hostType: dockerDatasourceId,\n url: apiCheckUrl,\n });\n const opts: HttpOptions = {};\n\n if (ecrRegex.test(registryHost)) {\n logger.once.debug(`hostRules: ecr auth for ${registryHost}`);\n logger.trace(\n { registryHost, dockerRepository },\n `Using ecr auth for Docker registry`,\n );\n const [, region] = coerceArray(ecrRegex.exec(registryHost));\n const auth = await getECRAuthToken(region, rule);\n if (auth) {\n opts.headers = { authorization: `Basic ${auth}` };\n }\n } else if (\n googleRegex.test(registryHost) &&\n typeof rule.username === 'undefined' &&\n typeof rule.password === 'undefined' &&\n typeof rule.token === 'undefined'\n ) {\n logger.once.debug(`hostRules: google auth for ${registryHost}`);\n logger.trace(\n { registryHost, dockerRepository },\n `Using google auth for Docker registry`,\n );\n const auth = await getGoogleAuthToken();\n if (auth) {\n opts.headers = { authorization: `Basic ${auth}` };\n } else {\n logger.once.debug(\n { registryHost, dockerRepository },\n 'Could not get Google access token, using no auth',\n );\n }\n } else if (rule.username && rule.password) {\n logger.once.debug(`hostRules: basic auth for ${registryHost}`);\n logger.trace(\n { registryHost, dockerRepository },\n `Using basic auth for Docker registry`,\n );\n const auth = Buffer.from(`${rule.username}:${rule.password}`).toString(\n 'base64',\n );\n opts.headers = { authorization: `Basic ${auth}` };\n } else if (rule.token) {\n const authType = rule.authType ?? 'Bearer';\n logger.once.debug(\n `hostRules: ${authType} token auth for ${registryHost}`,\n );\n logger.trace(\n { registryHost, dockerRepository },\n `Using ${authType} token for Docker registry`,\n );\n opts.headers = { authorization: `${authType} ${rule.token}` };\n }\n\n const challenges = parse(apiCheckResponse.headers['www-authenticate']);\n const authenticateHeader = challenges.find(\n (c): c is ParamsChallenge => c.scheme === BearerScheme,\n );\n\n // If realm isn't an url, we should directly use auth header\n // Can happen when we get a Basic auth or some other auth type\n // * WWW-Authenticate: Basic realm=\"Artifactory Realm\"\n // * Www-Authenticate: Basic realm=\"https://123456789.dkr.ecr.eu-central-1.amazonaws.com/\",service=\"ecr.amazonaws.com\"\n // * www-authenticate: Bearer realm=\"https://ghcr.io/token\",service=\"ghcr.io\",scope=\"repository:user/image:pull\"\n // * www-authenticate: Bearer realm=\"https://auth.docker.io/token\",service=\"registry.docker.io\"\n // * www-authenticate: Bearer realm=\"https://codeberg.org/v2/token\",service=\"container_registry\",scope=\"*\",Basic realm=\"https://codeberg.org/v2\",service=\"container_registry\",scope=\"*\"\n if (\n !authenticateHeader ||\n !isString(authenticateHeader.params?.realm) ||\n parseUrl(authenticateHeader.params.realm) === null\n ) {\n logger.once.debug(`hostRules: testing direct auth for ${registryHost}`);\n logger.trace(\n { registryHost, dockerRepository, authenticateHeader },\n `Invalid realm, testing direct auth`,\n );\n return opts.headers ?? null;\n }\n\n // already guarded by above clause\n const authUrl = parseUrl(`${authenticateHeader.params.realm}`)!;\n\n // repo isn't known to server yet, so causing wrong scope `repository:user/image:pull`\n if (\n isString(authenticateHeader.params.scope) &&\n !apiCheckUrl.endsWith('/v2/')\n ) {\n authUrl.searchParams.append('scope', authenticateHeader.params.scope);\n } else {\n authUrl.searchParams.append(\n 'scope',\n `repository:${dockerRepository}:pull`,\n );\n }\n\n if (isString(authenticateHeader.params.service)) {\n authUrl.searchParams.append('service', authenticateHeader.params.service);\n }\n\n logger.trace(\n { registryHost, dockerRepository, authUrl: authUrl.href },\n `Obtaining docker registry token`,\n );\n opts.noAuth = true;\n opts.cacheProvider = memCacheProvider;\n const authResponse = (\n await http.getJsonUnchecked<{ token?: string; access_token?: string }>(\n authUrl.href,\n opts,\n )\n ).body;\n\n const token = authResponse.token ?? authResponse.access_token;\n /* v8 ignore next 4 -- TODO: add test */\n if (!token) {\n logger.warn('Failed to obtain docker registry token');\n return null;\n }\n // sanitize token\n addSecretForSanitizing(token);\n return {\n authorization: `Bearer ${token}`,\n };\n } catch (err) /* istanbul ignore next */ {\n /* v8 ignore if */\n if (err.host === 'quay.io') {\n // TODO: debug why quay throws errors (#9604)\n return null;\n }\n /* v8 ignore if */\n if (err.statusCode === 401) {\n logger.debug(\n { registryHost, dockerRepository },\n 'Unauthorized docker lookup',\n );\n logger.debug({ err });\n return null;\n }\n /* v8 ignore if */\n if (err.statusCode === 403) {\n logger.debug(\n { registryHost, dockerRepository },\n 'Not allowed to access docker registry',\n );\n logger.debug({ err });\n return null;\n }\n if (err.name === 'RequestError' && isDockerHost(registryHost)) {\n throw new ExternalHostError(err);\n }\n /* v8 ignore if */\n if (err.statusCode === 429 && isDockerHost(registryHost)) {\n throw new ExternalHostError(err);\n }\n /* v8 ignore if */\n if (err.statusCode >= 500 && err.statusCode < 600) {\n throw new ExternalHostError(err);\n }\n if (err.message === PAGE_NOT_FOUND_ERROR) {\n throw err;\n }\n /* v8 ignore if */\n if (err.message === HOST_DISABLED) {\n logger.trace({ registryHost, dockerRepository, err }, 'Host disabled');\n return null;\n }\n logger.warn(\n { registryHost, dockerRepository, err },\n 'Error obtaining docker token',\n );\n return null;\n }\n}\n\nexport function getRegistryRepository(\n packageName: string,\n registryUrl: string,\n): RegistryRepository {\n if (registryUrl !== DOCKER_HUB) {\n const registryEndingWithSlash = ensureTrailingSlash(\n registryUrl.replace(regEx(/^https?:\\/\\//), ''),\n );\n if (packageName.startsWith(registryEndingWithSlash)) {\n let registryHost = trimTrailingSlash(registryUrl);\n if (!regEx(/^https?:\\/\\//).test(registryHost)) {\n registryHost = `https://${registryHost}`;\n }\n let dockerRepository = packageName.replace(registryEndingWithSlash, '');\n const fullUrl = `${registryHost}/${dockerRepository}`;\n const parsedFullUrl = parseUrl(fullUrl);\n if (!parsedFullUrl) {\n return { registryHost, dockerRepository };\n }\n registryHost = parsedFullUrl.origin;\n dockerRepository = parsedFullUrl.pathname.substring(1);\n return {\n registryHost,\n dockerRepository,\n };\n }\n }\n let registryHost = registryUrl;\n const split = packageName.split('/');\n if (split.length > 1 && (split[0].includes('.') || split[0].includes(':'))) {\n [registryHost] = split;\n split.shift();\n }\n let dockerRepository = split.join('/');\n\n if (!regEx(/^https?:\\/\\//).test(registryHost)) {\n registryHost = `https://${registryHost}`;\n }\n\n const { path, base } =\n regEx(/^(?<base>https:\\/\\/[^/]+)\\/(?<path>.+)$/).exec(registryHost)\n ?.groups ?? {};\n if (base && path) {\n registryHost = base;\n dockerRepository = `${trimTrailingSlash(path)}/${dockerRepository}`;\n }\n\n registryHost = registryHost\n .replace('https://docker.io', 'https://index.docker.io')\n .replace('https://registry-1.docker.io', 'https://index.docker.io');\n\n const opts = hostRules.find({\n hostType: dockerDatasourceId,\n url: registryHost,\n });\n if (opts?.insecureRegistry) {\n registryHost = registryHost.replace('https', 'http');\n }\n if (registryHost.endsWith('.docker.io') && !dockerRepository.includes('/')) {\n dockerRepository = `library/${dockerRepository}`;\n }\n return {\n registryHost,\n dockerRepository,\n };\n}\n\nexport function extractDigestFromResponseBody(\n manifestResponse: HttpResponse,\n): string {\n return `sha256:${toSha256(manifestResponse.body)}`;\n}\n\nexport function findLatestStable(tags: string[]): string | null {\n let stable: string | null = null;\n\n for (const tag of tags) {\n if (!dockerVersioning.isValid(tag) || !dockerVersioning.isStable(tag)) {\n continue;\n }\n\n if (!stable || dockerVersioning.isGreaterThan(tag, stable)) {\n stable = tag;\n }\n }\n\n return stable;\n}\n\nconst chartRepo = regEx(/charts?|helm|helm-charts?/i);\n\nfunction isPossibleChartRepo(url: string): boolean {\n if (detectPlatform(url) === null) {\n return false;\n }\n\n const parsed = parseGitUrl(url);\n return chartRepo.test(parsed.name);\n}\n\nexport function findHelmSourceUrl(release: OciHelmConfig): string | null {\n if (release.home && isPossibleChartRepo(release.home)) {\n return release.home;\n }\n\n if (!release.sources?.length) {\n return null;\n }\n\n for (const url of release.sources) {\n if (isPossibleChartRepo(url)) {\n return url;\n }\n }\n\n // fallback\n return release.sources[0];\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"common.js","names":["hostRules.find","dockerVersioning"],"sources":["../../../../lib/modules/datasource/docker/common.ts"],"sourcesContent":["import { isNonEmptyString, isString } from '@sindresorhus/is';\nimport {\n HOST_DISABLED,\n PAGE_NOT_FOUND_ERROR,\n} from '../../../constants/error-messages.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { ExternalHostError } from '../../../types/errors/external-host-error.ts';\nimport { coerceArray } from '../../../util/array.ts';\nimport { detectPlatform } from '../../../util/common.ts';\nimport { parseGitUrl } from '../../../util/git/url.ts';\nimport { toSha256 } from '../../../util/hash.ts';\nimport * as hostRules from '../../../util/host-rules.ts';\nimport { memCacheProvider } from '../../../util/http/cache/memory-http-cache-provider.ts';\nimport type { Http } from '../../../util/http/index.ts';\nimport type {\n HttpOptions,\n HttpResponse,\n OutgoingHttpHeaders,\n} from '../../../util/http/types.ts';\nimport type { ParamsChallenge } from '../../../util/http/www-authenticate.ts';\nimport { BearerScheme, parse } from '../../../util/http/www-authenticate.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { addSecretForSanitizing } from '../../../util/sanitize.ts';\nimport {\n ensureTrailingSlash,\n parseUrl,\n trimTrailingSlash,\n} from '../../../util/url.ts';\nimport { api as dockerVersioning } from '../../versioning/docker/index.ts';\nimport { getGoogleAuthToken } from '../util.ts';\nimport { ecrRegex, getECRAuthToken } from './ecr.ts';\nimport { googleRegex } from './google.ts';\nimport type { OciHelmConfig } from './schema.ts';\nimport { RegistryAuthToken } from './schema.ts';\nimport type { RegistryRepository } from './types.ts';\n\nexport const dockerDatasourceId = 'docker';\n\nexport const imageUrlLabel = 'org.opencontainers.image.url';\n\nexport const sourceLabel = 'org.opencontainers.image.source';\nexport const sourceLabels = [sourceLabel, 'org.label-schema.vcs-url'] as const;\n\nexport const gitRefLabel = 'org.opencontainers.image.revision';\n\nexport const DOCKER_HUB = 'https://index.docker.io';\n\nexport function isDockerHost(host: string): boolean {\n const regex = regEx(/(?:^|\\.)docker\\.io$/);\n return regex.test(host);\n}\n\nexport async function getAuthHeaders(\n http: Http,\n registryHost: string,\n dockerRepository: string,\n apiCheckUrl = `${registryHost}/v2/`,\n): Promise<OutgoingHttpHeaders | null> {\n try {\n const options = {\n throwHttpErrors: false,\n noAuth: true,\n cacheProvider: memCacheProvider,\n };\n const apiCheckResponse = apiCheckUrl.endsWith('/v2/')\n ? await http.get(apiCheckUrl, options)\n : // use json request, as this will be cached for tags, so it returns json\n // TODO: add cache test\n await http.getJsonUnchecked(apiCheckUrl, options);\n\n if (apiCheckResponse.statusCode === 200) {\n logger.debug(`No registry auth required for ${apiCheckUrl}`);\n return {};\n }\n if (apiCheckResponse.statusCode === 404) {\n logger.debug(`Page Not Found ${apiCheckUrl}`);\n // throw error up to be caught and potentially retried with library/ prefix\n throw new Error(PAGE_NOT_FOUND_ERROR);\n }\n if (\n apiCheckResponse.statusCode !== 401 ||\n !isNonEmptyString(apiCheckResponse.headers['www-authenticate'])\n ) {\n logger.warn(\n { apiCheckUrl, res: apiCheckResponse },\n 'Invalid registry response',\n );\n return null;\n }\n\n const rule = hostRules.find({\n hostType: dockerDatasourceId,\n url: apiCheckUrl,\n });\n const opts: HttpOptions = {};\n\n if (ecrRegex.test(registryHost)) {\n logger.once.debug(`hostRules: ecr auth for ${registryHost}`);\n logger.trace(\n { registryHost, dockerRepository },\n `Using ecr auth for Docker registry`,\n );\n const [, region] = coerceArray(ecrRegex.exec(registryHost));\n const auth = await getECRAuthToken(region, rule);\n if (auth) {\n opts.headers = { authorization: `Basic ${auth}` };\n }\n } else if (\n googleRegex.test(registryHost) &&\n typeof rule.username === 'undefined' &&\n typeof rule.password === 'undefined' &&\n typeof rule.token === 'undefined'\n ) {\n logger.once.debug(`hostRules: google auth for ${registryHost}`);\n logger.trace(\n { registryHost, dockerRepository },\n `Using google auth for Docker registry`,\n );\n const auth = await getGoogleAuthToken();\n if (auth) {\n opts.headers = { authorization: `Basic ${auth}` };\n } else {\n logger.once.debug(\n { registryHost, dockerRepository },\n 'Could not get Google access token, using no auth',\n );\n }\n } else if (rule.username && rule.password) {\n logger.once.debug(`hostRules: basic auth for ${registryHost}`);\n logger.trace(\n { registryHost, dockerRepository },\n `Using basic auth for Docker registry`,\n );\n const auth = Buffer.from(`${rule.username}:${rule.password}`).toString(\n 'base64',\n );\n opts.headers = { authorization: `Basic ${auth}` };\n } else if (rule.token) {\n const authType = rule.authType ?? 'Bearer';\n logger.once.debug(\n `hostRules: ${authType} token auth for ${registryHost}`,\n );\n logger.trace(\n { registryHost, dockerRepository },\n `Using ${authType} token for Docker registry`,\n );\n opts.headers = { authorization: `${authType} ${rule.token}` };\n }\n\n const challenges = parse(apiCheckResponse.headers['www-authenticate']);\n const authenticateHeader = challenges.find(\n (c): c is ParamsChallenge => c.scheme === BearerScheme,\n );\n\n // If realm isn't an url, we should directly use auth header\n // Can happen when we get a Basic auth or some other auth type\n // * WWW-Authenticate: Basic realm=\"Artifactory Realm\"\n // * Www-Authenticate: Basic realm=\"https://123456789.dkr.ecr.eu-central-1.amazonaws.com/\",service=\"ecr.amazonaws.com\"\n // * www-authenticate: Bearer realm=\"https://ghcr.io/token\",service=\"ghcr.io\",scope=\"repository:user/image:pull\"\n // * www-authenticate: Bearer realm=\"https://auth.docker.io/token\",service=\"registry.docker.io\"\n // * www-authenticate: Bearer realm=\"https://codeberg.org/v2/token\",service=\"container_registry\",scope=\"*\",Basic realm=\"https://codeberg.org/v2\",service=\"container_registry\",scope=\"*\"\n if (\n !authenticateHeader ||\n !isString(authenticateHeader.params?.realm) ||\n parseUrl(authenticateHeader.params.realm) === null\n ) {\n logger.once.debug(`hostRules: testing direct auth for ${registryHost}`);\n logger.trace(\n { registryHost, dockerRepository, authenticateHeader },\n `Invalid realm, testing direct auth`,\n );\n return opts.headers ?? null;\n }\n\n // already guarded by above clause\n const authUrl = parseUrl(`${authenticateHeader.params.realm}`)!;\n\n // repo isn't known to server yet, so causing wrong scope `repository:user/image:pull`\n if (\n isString(authenticateHeader.params.scope) &&\n !apiCheckUrl.endsWith('/v2/')\n ) {\n authUrl.searchParams.append('scope', authenticateHeader.params.scope);\n } else {\n authUrl.searchParams.append(\n 'scope',\n `repository:${dockerRepository}:pull`,\n );\n }\n\n if (isString(authenticateHeader.params.service)) {\n authUrl.searchParams.append('service', authenticateHeader.params.service);\n }\n\n logger.trace(\n { registryHost, dockerRepository, authUrl: authUrl.href },\n `Obtaining docker registry token`,\n );\n opts.noAuth = true;\n opts.cacheProvider = memCacheProvider;\n const authResponse = (\n await http.getJson(authUrl.href, opts, RegistryAuthToken)\n ).body;\n\n const token = authResponse.token ?? authResponse.access_token;\n /* v8 ignore next 4 -- TODO: add test */\n if (!token) {\n logger.warn('Failed to obtain docker registry token');\n return null;\n }\n // sanitize token\n addSecretForSanitizing(token);\n return {\n authorization: `Bearer ${token}`,\n };\n } catch (err) /* istanbul ignore next */ {\n /* v8 ignore if */\n if (err.host === 'quay.io') {\n // TODO: debug why quay throws errors (#9604)\n return null;\n }\n /* v8 ignore if */\n if (err.statusCode === 401) {\n logger.debug(\n { registryHost, dockerRepository },\n 'Unauthorized docker lookup',\n );\n logger.debug({ err });\n return null;\n }\n /* v8 ignore if */\n if (err.statusCode === 403) {\n logger.debug(\n { registryHost, dockerRepository },\n 'Not allowed to access docker registry',\n );\n logger.debug({ err });\n return null;\n }\n if (err.name === 'RequestError' && isDockerHost(registryHost)) {\n throw new ExternalHostError(err);\n }\n /* v8 ignore if */\n if (err.statusCode === 429 && isDockerHost(registryHost)) {\n throw new ExternalHostError(err);\n }\n /* v8 ignore if */\n if (err.statusCode >= 500 && err.statusCode < 600) {\n throw new ExternalHostError(err);\n }\n if (err.message === PAGE_NOT_FOUND_ERROR) {\n throw err;\n }\n /* v8 ignore if */\n if (err.message === HOST_DISABLED) {\n logger.trace({ registryHost, dockerRepository, err }, 'Host disabled');\n return null;\n }\n logger.warn(\n { registryHost, dockerRepository, err },\n 'Error obtaining docker token',\n );\n return null;\n }\n}\n\nexport function getRegistryRepository(\n packageName: string,\n registryUrl: string,\n): RegistryRepository {\n if (registryUrl !== DOCKER_HUB) {\n const registryEndingWithSlash = ensureTrailingSlash(\n registryUrl.replace(regEx(/^https?:\\/\\//), ''),\n );\n if (packageName.startsWith(registryEndingWithSlash)) {\n let registryHost = trimTrailingSlash(registryUrl);\n if (!regEx(/^https?:\\/\\//).test(registryHost)) {\n registryHost = `https://${registryHost}`;\n }\n let dockerRepository = packageName.replace(registryEndingWithSlash, '');\n const fullUrl = `${registryHost}/${dockerRepository}`;\n const parsedFullUrl = parseUrl(fullUrl);\n if (!parsedFullUrl) {\n return { registryHost, dockerRepository };\n }\n registryHost = parsedFullUrl.origin;\n dockerRepository = parsedFullUrl.pathname.substring(1);\n return {\n registryHost,\n dockerRepository,\n };\n }\n }\n let registryHost = registryUrl;\n const split = packageName.split('/');\n if (split.length > 1 && (split[0].includes('.') || split[0].includes(':'))) {\n [registryHost] = split;\n split.shift();\n }\n let dockerRepository = split.join('/');\n\n if (!regEx(/^https?:\\/\\//).test(registryHost)) {\n registryHost = `https://${registryHost}`;\n }\n\n const { path, base } =\n regEx(/^(?<base>https:\\/\\/[^/]+)\\/(?<path>.+)$/).exec(registryHost)\n ?.groups ?? {};\n if (base && path) {\n registryHost = base;\n dockerRepository = `${trimTrailingSlash(path)}/${dockerRepository}`;\n }\n\n registryHost = registryHost\n .replace('https://docker.io', 'https://index.docker.io')\n .replace('https://registry-1.docker.io', 'https://index.docker.io');\n\n const opts = hostRules.find({\n hostType: dockerDatasourceId,\n url: registryHost,\n });\n if (opts?.insecureRegistry) {\n registryHost = registryHost.replace('https', 'http');\n }\n if (registryHost.endsWith('.docker.io') && !dockerRepository.includes('/')) {\n dockerRepository = `library/${dockerRepository}`;\n }\n return {\n registryHost,\n dockerRepository,\n };\n}\n\nexport function extractDigestFromResponseBody(\n manifestResponse: HttpResponse,\n): string {\n return `sha256:${toSha256(manifestResponse.body)}`;\n}\n\nexport function findLatestStable(tags: string[]): string | null {\n let stable: string | null = null;\n\n for (const tag of tags) {\n if (!dockerVersioning.isValid(tag) || !dockerVersioning.isStable(tag)) {\n continue;\n }\n\n if (!stable || dockerVersioning.isGreaterThan(tag, stable)) {\n stable = tag;\n }\n }\n\n return stable;\n}\n\nconst chartRepo = regEx(/charts?|helm|helm-charts?/i);\n\nfunction isPossibleChartRepo(url: string): boolean {\n if (detectPlatform(url) === null) {\n return false;\n }\n\n const parsed = parseGitUrl(url);\n return chartRepo.test(parsed.name);\n}\n\nexport function findHelmSourceUrl(release: OciHelmConfig): string | null {\n if (release.home && isPossibleChartRepo(release.home)) {\n return release.home;\n }\n\n if (!release.sources?.length) {\n return null;\n }\n\n for (const url of release.sources) {\n if (isPossibleChartRepo(url)) {\n return url;\n }\n }\n\n // fallback\n return release.sources[0];\n}\n"],"mappings":"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"}
@@ -16,9 +16,9 @@ import { memCacheProvider } from "../../../util/http/cache/memory-http-cache-pro
16
16
  import { isArtifactoryServer } from "../util.js";
17
17
  import { hasKey } from "../../../util/object.js";
18
18
  import { ecrPublicRegex, ecrRegex, isECRMaxResultsError } from "./ecr.js";
19
+ import { DockerHubTagsPage, ManifestJson, OciHelmConfig, OciImageConfig, QuayTagsResponse, RegistryTagsList } from "./schema.js";
19
20
  import { DOCKER_HUB, dockerDatasourceId, extractDigestFromResponseBody, findHelmSourceUrl, findLatestStable, getAuthHeaders, getRegistryRepository, gitRefLabel, imageUrlLabel, isDockerHost, sourceLabel, sourceLabels } from "./common.js";
20
21
  import { DockerHubCache } from "./dockerhub-cache.js";
21
- import { DockerHubTagsPage, ManifestJson, OciHelmConfig, OciImageConfig } from "./schema.js";
22
22
  import { isNonEmptyString } from "@sindresorhus/is";
23
23
  //#region lib/modules/datasource/docker/index.ts
24
24
  const defaultConfig = {
@@ -330,7 +330,7 @@ var DockerDatasource = class DockerDatasource extends Datasource {
330
330
  let page = 1;
331
331
  let url = pageUrl(page);
332
332
  while (url && page <= 20) {
333
- const res = await this.http.getJsonUnchecked(url);
333
+ const res = await this.http.getJson(url, QuayTagsResponse);
334
334
  const pageTags = res.body.tags.map((tag) => tag.name);
335
335
  tags = tags.concat(pageTags);
336
336
  page += 1;
@@ -358,10 +358,10 @@ var DockerDatasource = class DockerDatasource extends Datasource {
358
358
  do {
359
359
  let res;
360
360
  try {
361
- res = await this.http.getJsonUnchecked(url, {
361
+ res = await this.http.getJson(url, {
362
362
  headers,
363
363
  noAuth: true
364
- });
364
+ }, RegistryTagsList);
365
365
  } catch (err) {
366
366
  if (!foundMaxResultsError && err instanceof RequestError && isECRMaxResultsError(err)) {
367
367
  url = `${registryHost}/${dockerRepository}/tags/list?n=1000`;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["dockerVersioningId","HttpError"],"sources":["../../../../lib/modules/datasource/docker/index.ts"],"sourcesContent":["import { isNonEmptyString } from '@sindresorhus/is';\nimport { GlobalConfig } from '../../../config/global.ts';\nimport { PAGE_NOT_FOUND_ERROR } from '../../../constants/error-messages.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { ExternalHostError } from '../../../types/errors/external-host-error.ts';\nimport { withCache } from '../../../util/cache/package/with-cache.ts';\nimport { getEnv } from '../../../util/env.ts';\nimport { memCacheProvider } from '../../../util/http/cache/memory-http-cache-provider.ts';\nimport { HttpError } from '../../../util/http/index.ts';\nimport type { HttpResponse } from '../../../util/http/types.ts';\nimport { hasKey } from '../../../util/object.ts';\nimport { type AsyncResult, Result } from '../../../util/result.ts';\nimport { isDockerDigest } from '../../../util/string-match.ts';\nimport { asTimestamp } from '../../../util/timestamp.ts';\nimport {\n ensurePathPrefix,\n joinUrlParts,\n parseLinkHeader,\n parseUrl,\n} from '../../../util/url.ts';\nimport { id as dockerVersioningId } from '../../versioning/docker/index.ts';\nimport { Datasource } from '../datasource.ts';\nimport type {\n DigestConfig,\n GetReleasesConfig,\n Release,\n ReleaseResult,\n} from '../types.ts';\nimport { isArtifactoryServer } from '../util.ts';\nimport {\n DOCKER_HUB,\n dockerDatasourceId,\n extractDigestFromResponseBody,\n findHelmSourceUrl,\n findLatestStable,\n getAuthHeaders,\n getRegistryRepository,\n gitRefLabel,\n imageUrlLabel,\n isDockerHost,\n sourceLabel,\n sourceLabels,\n} from './common.ts';\nimport { DockerHubCache } from './dockerhub-cache.ts';\nimport { ecrPublicRegex, ecrRegex, isECRMaxResultsError } from './ecr.ts';\nimport type { DistributionManifest, OciImageManifest } from './schema.ts';\nimport {\n DockerHubTagsPage,\n ManifestJson,\n OciHelmConfig,\n OciImageConfig,\n} from './schema.ts';\n\nconst defaultConfig = {\n commitMessageTopic: '{{{depName}}} Docker tag',\n commitMessageExtra:\n 'to {{#if isPinDigest}}{{{newDigestShort}}}{{else}}{{#if isMajor}}{{{prettyNewMajor}}}{{else}}{{{prettyNewVersion}}}{{/if}}{{/if}}',\n digest: {\n branchTopic: '{{{depNameSanitized}}}-{{{currentValue}}}',\n commitMessageExtra: 'to {{newDigestShort}}',\n commitMessageTopic:\n '{{{depName}}}{{#if currentValue}}:{{{currentValue}}}{{/if}} Docker digest',\n group: {\n commitMessageTopic: '{{{groupName}}}',\n commitMessageExtra: '',\n },\n },\n pin: {\n commitMessageExtra: '',\n groupName: 'Docker digests',\n group: {\n commitMessageTopic: '{{{groupName}}}',\n branchTopic: 'digests-pin',\n },\n },\n};\n\nexport class DockerDatasource extends Datasource {\n static readonly id = dockerDatasourceId;\n\n override readonly defaultVersioning = dockerVersioningId;\n\n override readonly defaultRegistryUrls = [DOCKER_HUB];\n\n override readonly defaultConfig = defaultConfig;\n\n override readonly releaseTimestampSupport = true;\n override readonly releaseTimestampNote =\n 'Only supported on Docker Hub: The release timestamp is determined from the `tag_last_pushed` field in the results. **NOTE**: Currently, digests will receive the same release timestamp as the `tag_last_pushed`, which means that digests may appear newer than they are - see https://github.com/renovatebot/renovate/issues/38659';\n override readonly sourceUrlSupport = 'package';\n override readonly sourceUrlNote =\n 'The source URL is determined from the `org.opencontainers.image.source` and `org.label-schema.vcs-url` labels present in the metadata of the **latest stable** image found on the Docker registry.';\n\n constructor() {\n super(DockerDatasource.id);\n }\n\n // TODO: debug why quay throws errors (#9612)\n private async getManifestResponse(\n registryHost: string,\n dockerRepository: string,\n tag: string,\n mode: 'head' | 'getText' = 'getText',\n ): Promise<HttpResponse | null> {\n logger.debug(\n `getManifestResponse(${registryHost}, ${dockerRepository}, ${tag}, ${mode})`,\n );\n try {\n const headers = await getAuthHeaders(\n this.http,\n registryHost,\n dockerRepository,\n );\n if (!headers) {\n logger.warn('No docker auth found - returning');\n return null;\n }\n headers.accept = [\n 'application/vnd.docker.distribution.manifest.list.v2+json',\n 'application/vnd.docker.distribution.manifest.v2+json',\n 'application/vnd.oci.image.manifest.v1+json',\n 'application/vnd.oci.image.index.v1+json',\n ].join(', ');\n const url = `${registryHost}/v2/${dockerRepository}/manifests/${tag}`;\n const manifestResponse = await this.http[mode](url, {\n headers,\n noAuth: true,\n cacheProvider: memCacheProvider,\n });\n return manifestResponse;\n } catch (err) /* istanbul ignore next */ {\n if (err instanceof ExternalHostError) {\n throw err;\n }\n if (err.statusCode === 401) {\n logger.debug(\n { registryHost, dockerRepository },\n 'Unauthorized docker lookup',\n );\n logger.debug({ err });\n return null;\n }\n if (err.statusCode === 404) {\n logger.debug(\n {\n err,\n registryHost,\n dockerRepository,\n tag,\n },\n 'Docker Manifest is unknown',\n );\n return null;\n }\n if (err.statusCode === 429 && isDockerHost(registryHost)) {\n throw new ExternalHostError(err);\n }\n if (err.statusCode >= 500 && err.statusCode < 600) {\n throw new ExternalHostError(err);\n }\n if (err.code === 'ETIMEDOUT') {\n logger.debug(\n { registryHost },\n 'Timeout when attempting to connect to docker registry',\n );\n logger.debug({ err });\n return null;\n }\n logger.debug(\n {\n err,\n registryHost,\n dockerRepository,\n tag,\n },\n 'Unknown Error looking up docker manifest',\n );\n return null;\n }\n }\n\n private async _getImageConfig(\n registryHost: string,\n dockerRepository: string,\n configDigest: string,\n ): Promise<HttpResponse<OciImageConfig> | undefined> {\n logger.trace(\n `getImageConfig(${registryHost}, ${dockerRepository}, ${configDigest})`,\n );\n\n const headers = await getAuthHeaders(\n this.http,\n registryHost,\n dockerRepository,\n );\n /* v8 ignore next 4 -- should never happen */\n if (!headers) {\n logger.warn('No docker auth found - returning');\n return undefined;\n }\n const url = joinUrlParts(\n registryHost,\n 'v2',\n dockerRepository,\n 'blobs',\n configDigest,\n );\n return await this.http.getJson(\n url,\n {\n headers,\n noAuth: true,\n },\n OciImageConfig,\n );\n }\n\n getImageConfig(\n registryHost: string,\n dockerRepository: string,\n configDigest: string,\n ): Promise<HttpResponse<OciImageConfig> | undefined> {\n return withCache(\n {\n namespace: 'datasource-docker-imageconfig',\n key: `${registryHost}:${dockerRepository}@${configDigest}`,\n ttlMinutes: 1440 * 28,\n },\n () => this._getImageConfig(registryHost, dockerRepository, configDigest),\n );\n }\n\n private async _getHelmConfig(\n registryHost: string,\n dockerRepository: string,\n configDigest: string,\n ): Promise<HttpResponse<OciHelmConfig> | undefined> {\n logger.trace(\n `getImageConfig(${registryHost}, ${dockerRepository}, ${configDigest})`,\n );\n\n const headers = await getAuthHeaders(\n this.http,\n registryHost,\n dockerRepository,\n );\n /* v8 ignore next 4 -- should never happen */\n if (!headers) {\n logger.warn('No docker auth found - returning');\n return undefined;\n }\n const url = joinUrlParts(\n registryHost,\n 'v2',\n dockerRepository,\n 'blobs',\n configDigest,\n );\n return await this.http.getJson(\n url,\n {\n headers,\n noAuth: true,\n },\n OciHelmConfig,\n );\n }\n\n getHelmConfig(\n registryHost: string,\n dockerRepository: string,\n configDigest: string,\n ): Promise<HttpResponse<OciHelmConfig> | undefined> {\n return withCache(\n {\n namespace: 'datasource-docker-imageconfig',\n key: `${registryHost}:${dockerRepository}@${configDigest}`,\n ttlMinutes: 1440 * 28,\n },\n () => this._getHelmConfig(registryHost, dockerRepository, configDigest),\n );\n }\n\n private async getConfigDigest(\n registry: string,\n dockerRepository: string,\n tag: string,\n ): Promise<string | null> {\n return (\n (await this.getManifest(registry, dockerRepository, tag))?.config\n ?.digest ?? null\n );\n }\n\n private async getManifest(\n registry: string,\n dockerRepository: string,\n tag: string,\n ): Promise<OciImageManifest | DistributionManifest | null> {\n const manifestResponse = await this.getManifestResponse(\n registry,\n dockerRepository,\n tag,\n );\n\n // If getting the manifest fails here, then abort\n // This means that the latest tag doesn't have a manifest, which shouldn't\n // be possible\n /* v8 ignore next 3 -- should never happen */\n if (!manifestResponse) {\n return null;\n }\n\n // Softfail on invalid manifests\n const parsed = ManifestJson.safeParse(manifestResponse.body);\n if (!parsed.success) {\n logger.debug(\n {\n registry,\n dockerRepository,\n tag,\n body: manifestResponse.body,\n headers: manifestResponse.headers,\n err: parsed.error,\n },\n 'Invalid manifest response',\n );\n return null;\n }\n\n const manifest = parsed.data;\n\n switch (manifest.mediaType) {\n case 'application/vnd.docker.distribution.manifest.v2+json':\n case 'application/vnd.oci.image.manifest.v1+json':\n return manifest;\n case 'application/vnd.docker.distribution.manifest.list.v2+json':\n case 'application/vnd.oci.image.index.v1+json':\n if (!manifest.manifests.length) {\n logger.debug(\n { manifest },\n 'Invalid manifest list with no manifests - returning',\n );\n return null;\n }\n logger.trace(\n { registry, dockerRepository, tag },\n 'Found manifest list, using first image',\n );\n return this.getManifest(\n registry,\n dockerRepository,\n manifest.manifests[0].digest,\n );\n // istanbul ignore next: can't happen\n default:\n return null;\n }\n }\n\n private async _getImageArchitecture(\n registryHost: string,\n dockerRepository: string,\n currentDigest: string,\n ): Promise<string | null | undefined> {\n try {\n let manifestResponse: HttpResponse<string> | null;\n\n try {\n manifestResponse = await this.getManifestResponse(\n registryHost,\n dockerRepository,\n currentDigest,\n 'head',\n );\n } catch (_err) {\n const err =\n _err instanceof ExternalHostError\n ? _err.err\n : /* istanbul ignore next: can never happen */ _err;\n\n if (\n typeof err.statusCode === 'number' &&\n err.statusCode >= 500 &&\n err.statusCode < 600\n ) {\n // querying the digest manifest for a non existent image leads to a 500 statusCode\n return null;\n }\n\n /* istanbul ignore next */\n throw _err;\n }\n\n if (\n manifestResponse?.headers['content-type'] !==\n 'application/vnd.docker.distribution.manifest.v2+json' &&\n manifestResponse?.headers['content-type'] !==\n 'application/vnd.oci.image.manifest.v1+json'\n ) {\n return null;\n }\n\n const configDigest = await this.getConfigDigest(\n registryHost,\n dockerRepository,\n currentDigest,\n );\n if (!configDigest) {\n return null;\n }\n\n const configResponse = await this.getImageConfig(\n registryHost,\n dockerRepository,\n configDigest,\n );\n\n // TODO: fix me, architecture is required in spec\n if (\n configResponse &&\n ('config' in configResponse.body ||\n 'architecture' in configResponse.body)\n ) {\n const architecture = configResponse.body.architecture ?? null;\n logger.debug(\n `Current digest ${currentDigest} relates to architecture ${\n architecture ?? 'null'\n }`,\n );\n\n return architecture;\n }\n } catch (err) /* istanbul ignore next */ {\n if (err.statusCode !== 404 || err.message === PAGE_NOT_FOUND_ERROR) {\n throw err;\n }\n logger.debug(\n { registryHost, dockerRepository, currentDigest, err },\n 'Unknown error getting image architecture',\n );\n }\n\n return undefined;\n }\n\n getImageArchitecture(\n registryHost: string,\n dockerRepository: string,\n currentDigest: string,\n ): Promise<string | null | undefined> {\n return withCache(\n {\n namespace: 'datasource-docker-architecture',\n key: `${registryHost}:${dockerRepository}@${currentDigest}`,\n ttlMinutes: 1440 * 28,\n shouldCacheResult: isNonEmptyString,\n },\n () =>\n this._getImageArchitecture(\n registryHost,\n dockerRepository,\n currentDigest,\n ),\n );\n }\n\n /*\n * docker.getLabels\n *\n * This function will:\n * - Return the labels for the requested image\n */\n private async _getLabels(\n registryHost: string,\n dockerRepository: string,\n tag: string,\n ): Promise<Record<string, string> | undefined> {\n logger.debug(`getLabels(${registryHost}, ${dockerRepository}, ${tag})`);\n // Skip Docker Hub image if RENOVATE_X_DOCKER_HUB_DISABLE_LABEL_LOOKUP is set\n if (\n getEnv().RENOVATE_X_DOCKER_HUB_DISABLE_LABEL_LOOKUP &&\n registryHost === DOCKER_HUB\n ) {\n logger.debug(\n 'Docker Hub image - skipping label lookup due to RENOVATE_X_DOCKER_HUB_DISABLE_LABEL_LOOKUP',\n );\n return {};\n }\n // Docker Hub library images don't have labels we need\n if (\n registryHost === DOCKER_HUB &&\n dockerRepository.startsWith('library/')\n ) {\n logger.debug('Docker Hub library image - skipping label lookup');\n return {};\n }\n try {\n let labels: Record<string, string> | undefined = {};\n const manifest = await this.getManifest(\n registryHost,\n dockerRepository,\n tag,\n );\n\n if (!manifest) {\n logger.debug(\n { registryHost, dockerRepository, tag },\n 'No manifest found',\n );\n return undefined;\n }\n\n if ('annotations' in manifest && manifest.annotations) {\n labels = manifest.annotations;\n }\n\n switch (manifest.config.mediaType) {\n case 'application/vnd.cncf.helm.config.v1+json': {\n if (labels[sourceLabel]) {\n // we already have the source url, so no need to pull the config\n return labels;\n }\n const configResponse = await this.getHelmConfig(\n registryHost,\n dockerRepository,\n manifest.config.digest,\n );\n\n if (configResponse) {\n // Helm chart\n const url = findHelmSourceUrl(configResponse.body);\n if (url) {\n labels[sourceLabel] = url;\n }\n }\n break;\n }\n case 'application/vnd.oci.image.config.v1+json':\n case 'application/vnd.docker.container.image.v1+json': {\n if (labels[sourceLabel] && labels[gitRefLabel]) {\n // we already have the source url, so no need to pull the config\n return labels;\n }\n const configResponse = await this.getImageConfig(\n registryHost,\n dockerRepository,\n manifest.config.digest,\n );\n\n /* v8 ignore next 3 -- should never happen */\n if (!configResponse) {\n return labels;\n }\n\n const body = configResponse.body;\n if (body.config) {\n labels = { ...labels, ...body.config.Labels };\n } else {\n logger.debug(\n { headers: configResponse.headers, body },\n `manifest blob response body missing the \"config\" property`,\n );\n }\n break;\n }\n }\n\n if (labels) {\n logger.debug(\n {\n labels,\n },\n 'found labels in manifest',\n );\n }\n return labels;\n } catch (err) /* istanbul ignore next: should be tested in future */ {\n if (err instanceof ExternalHostError) {\n throw err;\n }\n if (err.statusCode === 400 || err.statusCode === 401) {\n logger.debug(\n { registryHost, dockerRepository, err },\n 'Unauthorized docker lookup',\n );\n } else if (err.statusCode === 404) {\n logger.warn(\n {\n err,\n registryHost,\n dockerRepository,\n tag,\n },\n 'Config Manifest is unknown',\n );\n } else if (err.statusCode === 429 && isDockerHost(registryHost)) {\n logger.warn({ err }, 'docker registry failure: too many requests');\n } else if (err.statusCode >= 500 && err.statusCode < 600) {\n logger.debug(\n {\n err,\n registryHost,\n dockerRepository,\n tag,\n },\n 'docker registry failure: internal error',\n );\n } else if (\n err.code === 'ERR_TLS_CERT_ALTNAME_INVALID' ||\n err.code === 'ETIMEDOUT'\n ) {\n logger.debug(\n { registryHost, err },\n 'Error connecting to docker registry',\n );\n } else if (registryHost === 'https://quay.io') {\n // istanbul ignore next\n logger.debug(\n 'Ignoring quay.io errors until they fully support v2 schema',\n );\n } else {\n logger.info(\n { registryHost, dockerRepository, tag, err },\n 'Unknown error getting Docker labels',\n );\n }\n return {};\n }\n }\n\n getLabels(\n registryHost: string,\n dockerRepository: string,\n tag: string,\n ): Promise<Record<string, string> | undefined> {\n return withCache(\n {\n namespace: 'datasource-docker-labels',\n key: `${registryHost}:${dockerRepository}:${tag}`,\n ttlMinutes: 24 * 60,\n },\n () => this._getLabels(registryHost, dockerRepository, tag),\n );\n }\n\n private async getTagsQuayRegistry(\n registry: string,\n repository: string,\n ): Promise<string[]> {\n let tags: string[] = [];\n const limit = 100;\n\n const pageUrl = (page: number): string =>\n `${registry}/api/v1/repository/${repository}/tag/?limit=${limit}&page=${page}&onlyActiveTags=true`;\n\n let page = 1;\n let url: string | null = pageUrl(page);\n while (url && page <= 20) {\n interface QuayRestDockerTags {\n tags: {\n name: string;\n }[];\n has_additional: boolean;\n }\n\n // typescript issue :-/\n // oxlint-disable typescript/no-unnecessary-type-assertion\n const res = (await this.http.getJsonUnchecked<QuayRestDockerTags>(\n url,\n )) as HttpResponse<QuayRestDockerTags>;\n // oxlint-enable typescript/no-unnecessary-type-assertion\n const pageTags = res.body.tags.map((tag) => tag.name);\n tags = tags.concat(pageTags);\n page += 1;\n url = res.body.has_additional ? pageUrl(page) : null;\n }\n return tags;\n }\n\n private async getDockerApiTags(\n registryHost: string,\n dockerRepository: string,\n ): Promise<string[] | null> {\n let tags: string[] = [];\n // AWS ECR limits the maximum number of results to 1000\n // See https://docs.aws.amazon.com/AmazonECR/latest/APIReference/API_DescribeRepositories.html#ECR-DescribeRepositories-request-maxResults\n // See https://docs.aws.amazon.com/AmazonECRPublic/latest/APIReference/API_DescribeRepositories.html#ecrpublic-DescribeRepositories-request-maxResults\n const limit =\n ecrRegex.test(registryHost) || ecrPublicRegex.test(registryHost)\n ? 1000\n : 10000;\n let url: string | null =\n `${registryHost}/${dockerRepository}/tags/list?n=${limit}`;\n url = ensurePathPrefix(url, '/v2');\n const headers = await getAuthHeaders(\n this.http,\n registryHost,\n dockerRepository,\n url,\n );\n if (!headers) {\n logger.debug('Failed to get authHeaders for getTags lookup');\n return null;\n }\n let page = 0;\n const hostsNeedingAllPages = [\n 'https://ghcr.io', // GHCR sorts from oldest to newest, so we need to get all pages\n 'https://quay.io', // Quay sorts from oldest to newest, so we need to get all pages\n ];\n const pages = hostsNeedingAllPages.includes(registryHost)\n ? 1000\n : GlobalConfig.get('dockerMaxPages');\n logger.trace({ registryHost, dockerRepository, pages }, 'docker.getTags');\n let foundMaxResultsError = false;\n do {\n let res: HttpResponse<{ tags: string[] }>;\n try {\n res = await this.http.getJsonUnchecked<{ tags: string[] }>(url, {\n headers,\n noAuth: true,\n });\n } catch (err) {\n if (\n !foundMaxResultsError &&\n err instanceof HttpError &&\n isECRMaxResultsError(err)\n ) {\n const maxResults = 1000;\n url = `${registryHost}/${dockerRepository}/tags/list?n=${maxResults}`;\n url = ensurePathPrefix(url, '/v2');\n foundMaxResultsError = true;\n continue;\n }\n throw err;\n }\n tags = tags.concat(res.body.tags);\n const linkHeader = parseLinkHeader(res.headers.link);\n if (isArtifactoryServer(res)) {\n // Artifactory bug: next link comes back without virtual-repo prefix (RTFACT-18971)\n if (linkHeader?.next?.last) {\n // parse the current URL, strip any old \"last\" param, then set the new one\n const parsed = parseUrl(url);\n // v8 ignore if: url is always a valid HTTP URL as `ensurePathPrefix`\n if (!parsed) {\n url = null;\n break;\n }\n parsed.searchParams.delete('last');\n parsed.searchParams.set('last', linkHeader.next.last);\n url = parsed.href;\n } else {\n url = null;\n }\n } else if (linkHeader?.next?.url) {\n // for the normal case we can still use URL to resolve relative-next\n url = new URL(linkHeader.next.url, url).href;\n } else {\n url = null;\n }\n page += 1;\n } while (url && page < pages);\n return tags;\n }\n\n private async _getTags(\n registryHost: string,\n dockerRepository: string,\n ): Promise<string[] | null> {\n try {\n const isQuay = registryHost === 'https://quay.io';\n let tags: string[] | null;\n if (isQuay) {\n try {\n // Due to pagination and sorting limits on Quay Docker v2 API implementation we try the Quay v1 API first\n tags = await this.getTagsQuayRegistry(registryHost, dockerRepository);\n } catch (err) {\n // If we get a 401 Unauthorized error (v1 API requires separate auth for private images), fall back to Docker v2 API\n if (err.statusCode === 401) {\n logger.debug(\n { registryHost, dockerRepository },\n 'Quay v1 API unauthorized, falling back to Docker v2 API',\n );\n tags = await this.getDockerApiTags(registryHost, dockerRepository);\n } else {\n throw err;\n }\n }\n } else {\n tags = await this.getDockerApiTags(registryHost, dockerRepository);\n }\n return tags;\n } catch (_err) /* istanbul ignore next */ {\n const err = _err instanceof ExternalHostError ? _err.err : _err;\n\n if (\n (err.statusCode === 404 || err.message === PAGE_NOT_FOUND_ERROR) &&\n !dockerRepository.includes('/')\n ) {\n logger.debug(\n `Retrying Tags for ${registryHost}/${dockerRepository} using library/ prefix`,\n );\n return this.getTags(registryHost, `library/${dockerRepository}`);\n }\n // JFrog Artifactory - Retry handling when resolving Docker Official Images\n // These follow the format of {{registryHost}}{{jFrogRepository}}/library/{{dockerRepository}}\n if (\n (err.statusCode === 404 || err.message === PAGE_NOT_FOUND_ERROR) &&\n isArtifactoryServer(err.response) &&\n dockerRepository.split('/').length === 2\n ) {\n logger.debug(\n `JFrog Artifactory: Retrying Tags for ${registryHost}/${dockerRepository} using library/ path between JFrog virtual repository and image`,\n );\n\n const dockerRepositoryParts = dockerRepository.split('/');\n const jfrogRepository = dockerRepositoryParts[0];\n const dockerImage = dockerRepositoryParts[1];\n\n return this.getTags(\n registryHost,\n `${jfrogRepository}/library/${dockerImage}`,\n );\n }\n if (err.statusCode === 429 && isDockerHost(registryHost)) {\n logger.warn(\n { registryHost, dockerRepository, err },\n 'docker registry failure: too many requests',\n );\n throw new ExternalHostError(err);\n }\n if (err.statusCode >= 500 && err.statusCode < 600) {\n logger.warn(\n { registryHost, dockerRepository, err },\n 'docker registry failure: internal error',\n );\n throw new ExternalHostError(err);\n }\n const errorCodes = ['ECONNRESET', 'ETIMEDOUT'];\n if (errorCodes.includes(err.code)) {\n logger.warn(\n { registryHost, dockerRepository, err },\n 'docker registry connection failure',\n );\n throw new ExternalHostError(err);\n }\n if (isDockerHost(registryHost)) {\n logger.info({ err }, 'Docker Hub lookup failure');\n }\n throw _err;\n }\n }\n\n getTags(\n registryHost: string,\n dockerRepository: string,\n ): Promise<string[] | null> {\n return withCache(\n {\n namespace: 'datasource-docker-tags',\n key: `${registryHost}:${dockerRepository}`,\n },\n () => this._getTags(registryHost, dockerRepository),\n );\n }\n\n /**\n * docker.getDigest\n *\n * The `newValue` supplied here should be a valid tag for the docker image.\n *\n * This function will:\n * - Look up a sha256 digest for a tag on its registry\n * - Return the digest as a string\n */\n private async _getDigest(\n { registryUrl, lookupName, packageName, currentDigest }: DigestConfig,\n newValue?: string,\n ): Promise<string | null> {\n let registryHost: string;\n let dockerRepository: string;\n if (registryUrl && lookupName) {\n // Reuse the resolved values from getReleases()\n registryHost = registryUrl;\n dockerRepository = lookupName;\n } else {\n // Resolve values independently\n ({ registryHost, dockerRepository } = getRegistryRepository(\n packageName,\n registryUrl!,\n ));\n }\n logger.debug(\n // TODO: types (#22198)\n `getDigest(${registryHost}, ${dockerRepository}, ${newValue})`,\n );\n const newTag = isNonEmptyString(newValue) ? newValue : 'latest';\n let digest: string | null = null;\n try {\n let architecture: string | null | undefined = null;\n if (currentDigest && isDockerDigest(currentDigest)) {\n architecture = await this.getImageArchitecture(\n registryHost,\n dockerRepository,\n currentDigest,\n );\n }\n\n let manifestResponse: HttpResponse | null = null;\n if (!architecture) {\n // Reuse the digest cached from the Docker Hub tag API\n if (registryHost === DOCKER_HUB) {\n const cache = await DockerHubCache.init(dockerRepository);\n const cachedDigest = cache.getDigestForTag(newTag);\n if (cachedDigest) {\n return cachedDigest;\n }\n }\n\n manifestResponse = await this.getManifestResponse(\n registryHost,\n dockerRepository,\n newTag,\n 'head',\n );\n\n if (\n manifestResponse &&\n hasKey('docker-content-digest', manifestResponse.headers)\n ) {\n digest =\n (manifestResponse.headers['docker-content-digest'] as string) ||\n null;\n }\n }\n\n if (\n isNonEmptyString(architecture) ||\n (manifestResponse &&\n !hasKey('docker-content-digest', manifestResponse.headers))\n ) {\n // Reuse the per-arch digest cached from the Docker Hub tag API\n if (isNonEmptyString(architecture) && registryHost === DOCKER_HUB) {\n const cache = await DockerHubCache.init(dockerRepository);\n const cachedDigest = cache.getArchDigestForTag(newTag, architecture);\n if (cachedDigest) {\n return cachedDigest;\n }\n }\n\n logger.debug(\n { registryHost, dockerRepository },\n 'Architecture-specific digest or missing docker-content-digest header - pulling full manifest',\n );\n manifestResponse = await this.getManifestResponse(\n registryHost,\n dockerRepository,\n newTag,\n );\n\n if (architecture && manifestResponse) {\n const parsed = ManifestJson.safeParse(manifestResponse.body);\n /* istanbul ignore else: hard to test */\n if (parsed.success) {\n const manifestList = parsed.data;\n if (\n manifestList.mediaType ===\n 'application/vnd.docker.distribution.manifest.list.v2+json' ||\n manifestList.mediaType ===\n 'application/vnd.oci.image.index.v1+json'\n ) {\n for (const manifest of manifestList.manifests) {\n if (manifest.platform?.architecture === architecture) {\n digest = manifest.digest;\n break;\n }\n }\n // TODO: return null if no matching architecture digest found\n // https://github.com/renovatebot/renovate/discussions/22639\n } else if (\n hasKey('docker-content-digest', manifestResponse.headers)\n ) {\n // TODO: return null if no matching architecture, requires to fetch the config manifest\n // https://github.com/renovatebot/renovate/discussions/22639\n digest = manifestResponse.headers[\n 'docker-content-digest'\n ] as string;\n }\n } else {\n logger.debug(\n {\n registryHost,\n dockerRepository,\n newTag,\n body: manifestResponse.body,\n headers: manifestResponse.headers,\n err: parsed.error,\n },\n 'Failed to parse manifest response',\n );\n }\n }\n\n if (!digest) {\n logger.debug(\n { registryHost, dockerRepository, newTag },\n 'Extraction digest from manifest response body is deprecated',\n );\n digest = extractDigestFromResponseBody(manifestResponse!);\n }\n }\n\n if (\n !manifestResponse &&\n !dockerRepository.includes('/') &&\n !packageName.includes('/')\n ) {\n logger.debug(\n `Retrying Digest for ${registryHost}/${dockerRepository} using library/ prefix`,\n );\n return this.getDigest(\n {\n registryUrl,\n packageName: `library/${packageName}`,\n currentDigest,\n },\n newValue,\n );\n }\n\n if (manifestResponse) {\n // TODO: fix types (#22198)\n logger.debug(`Got docker digest ${digest!}`);\n }\n } catch (err) /* istanbul ignore next */ {\n if (err instanceof ExternalHostError) {\n throw err;\n }\n logger.debug(\n {\n err,\n packageName,\n newTag,\n },\n 'Unknown Error looking up docker image digest',\n );\n }\n return digest;\n }\n\n override getDigest(\n config: DigestConfig,\n newValue?: string,\n ): Promise<string | null> {\n const newTag = newValue ?? 'latest';\n const { registryHost, dockerRepository } = getRegistryRepository(\n config.packageName,\n config.registryUrl!,\n );\n const digest = config.currentDigest ? `@${config.currentDigest}` : '';\n return withCache(\n {\n namespace: 'datasource-docker-digest',\n key: `${registryHost}:${dockerRepository}:${newTag}${digest}`,\n fallback: true,\n shouldCacheResult: isNonEmptyString,\n },\n () => this._getDigest(config, newValue),\n );\n }\n\n private async _getDockerHubTags(\n dockerRepository: string,\n ): Promise<Release[] | null> {\n let url = `https://hub.docker.com/v2/repositories/${dockerRepository}/tags?page_size=1000&ordering=last_updated`;\n\n const cache = await DockerHubCache.init(dockerRepository);\n const maxPages = GlobalConfig.get('dockerMaxPages');\n let page = 0,\n needNextPage = true;\n while (needNextPage && page < maxPages) {\n const { val, err } = await this.http\n .getJsonSafe(url, DockerHubTagsPage)\n .unwrap();\n\n if (err) {\n logger.debug({ err }, `Docker: error fetching data from DockerHub`);\n return null;\n }\n page++;\n const { results, next, count } = val;\n\n needNextPage = cache.reconcile(results, count);\n\n if (!next) {\n break;\n }\n\n url = next;\n }\n\n await cache.save();\n\n const items = cache.getItems();\n return items.map(({ name: version, tag_last_pushed }) => {\n const release: Release = { version };\n\n const releaseTimestamp = asTimestamp(tag_last_pushed);\n if (releaseTimestamp) {\n release.releaseTimestamp = releaseTimestamp;\n }\n\n // Digest is intentionally not propagated — the Docker Hub tag API\n // returns the manifest-list digest, which would bypass arch-aware\n // resolution in `getDigest()`. `getDigest()` consults the same cache\n // as a shortcut when no arch resolution is needed.\n return release;\n });\n }\n\n getDockerHubTags(dockerRepository: string): Promise<Release[] | null> {\n return withCache(\n {\n namespace: 'datasource-docker-hub-tags',\n key: `${dockerRepository}`,\n },\n () => this._getDockerHubTags(dockerRepository),\n );\n }\n\n /**\n * docker.getReleases\n *\n * A docker image usually looks something like this: somehost.io/owner/repo:8.1.0-alpine\n * In the above:\n * - 'somehost.io' is the registry\n * - 'owner/repo' is the package name\n * - '8.1.0-alpine' is the tag\n *\n * This function will filter only tags that contain a semver version\n */\n private async _getReleases({\n packageName,\n registryUrl,\n }: GetReleasesConfig): Promise<ReleaseResult | null> {\n const { registryHost, dockerRepository } = getRegistryRepository(\n packageName,\n registryUrl!,\n );\n\n type TagsResultType = AsyncResult<\n Release[],\n NonNullable<Error | 'tags-error' | 'dockerhub-error'>\n >;\n\n const getTags = (): TagsResultType =>\n Result.wrapNullable(\n this.getTags(registryHost, dockerRepository),\n 'tags-error' as const,\n ).transform((tags) => tags.map((version) => ({ version })));\n\n const getDockerHubTags = (): TagsResultType =>\n Result.wrapNullable(\n this.getDockerHubTags(dockerRepository),\n 'dockerhub-error' as const,\n ).catch(getTags);\n\n const tagsResult =\n registryHost === DOCKER_HUB &&\n !getEnv().RENOVATE_X_DOCKER_HUB_TAGS_DISABLE\n ? getDockerHubTags()\n : getTags();\n\n const { val: releases, err } = await tagsResult.unwrap();\n if (err instanceof Error) {\n throw err;\n } else if (err) {\n return null;\n }\n\n const ret: ReleaseResult = {\n registryUrl: registryHost,\n releases,\n };\n if (dockerRepository !== packageName) {\n // This will be reused later if a getDigest() call is made\n ret.lookupName = dockerRepository;\n }\n\n const tags = releases.map((release) => release.version);\n const latestTag = tags.includes('latest')\n ? 'latest'\n : (findLatestStable(tags) ?? tags[tags.length - 1]);\n\n /* v8 ignore next 3 -- TODO: add test */\n if (!latestTag) {\n return ret;\n }\n const labels = await this.getLabels(\n registryHost,\n dockerRepository,\n latestTag,\n );\n if (labels) {\n if (isNonEmptyString(labels[gitRefLabel])) {\n ret.gitRef = labels[gitRefLabel];\n }\n for (const label of sourceLabels) {\n if (isNonEmptyString(labels[label])) {\n ret.sourceUrl = labels[label];\n break;\n }\n }\n if (isNonEmptyString(labels[imageUrlLabel])) {\n ret.homepage = labels[imageUrlLabel];\n }\n }\n return ret;\n }\n\n getReleases(config: GetReleasesConfig): Promise<ReleaseResult | null> {\n const { registryHost, dockerRepository } = getRegistryRepository(\n config.packageName,\n config.registryUrl!,\n );\n return withCache(\n {\n namespace: 'datasource-docker-releases-v2',\n key: `${registryHost}:${dockerRepository}`,\n cacheable: registryHost === DOCKER_HUB,\n fallback: true,\n },\n () => this._getReleases(config),\n );\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["dockerVersioningId","HttpError"],"sources":["../../../../lib/modules/datasource/docker/index.ts"],"sourcesContent":["import { isNonEmptyString } from '@sindresorhus/is';\nimport { GlobalConfig } from '../../../config/global.ts';\nimport { PAGE_NOT_FOUND_ERROR } from '../../../constants/error-messages.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { ExternalHostError } from '../../../types/errors/external-host-error.ts';\nimport { withCache } from '../../../util/cache/package/with-cache.ts';\nimport { getEnv } from '../../../util/env.ts';\nimport { memCacheProvider } from '../../../util/http/cache/memory-http-cache-provider.ts';\nimport { HttpError } from '../../../util/http/index.ts';\nimport type { HttpResponse } from '../../../util/http/types.ts';\nimport { hasKey } from '../../../util/object.ts';\nimport { type AsyncResult, Result } from '../../../util/result.ts';\nimport { isDockerDigest } from '../../../util/string-match.ts';\nimport { asTimestamp } from '../../../util/timestamp.ts';\nimport {\n ensurePathPrefix,\n joinUrlParts,\n parseLinkHeader,\n parseUrl,\n} from '../../../util/url.ts';\nimport { id as dockerVersioningId } from '../../versioning/docker/index.ts';\nimport { Datasource } from '../datasource.ts';\nimport type {\n DigestConfig,\n GetReleasesConfig,\n Release,\n ReleaseResult,\n} from '../types.ts';\nimport { isArtifactoryServer } from '../util.ts';\nimport {\n DOCKER_HUB,\n dockerDatasourceId,\n extractDigestFromResponseBody,\n findHelmSourceUrl,\n findLatestStable,\n getAuthHeaders,\n getRegistryRepository,\n gitRefLabel,\n imageUrlLabel,\n isDockerHost,\n sourceLabel,\n sourceLabels,\n} from './common.ts';\nimport { DockerHubCache } from './dockerhub-cache.ts';\nimport { ecrPublicRegex, ecrRegex, isECRMaxResultsError } from './ecr.ts';\nimport type { DistributionManifest, OciImageManifest } from './schema.ts';\nimport {\n DockerHubTagsPage,\n ManifestJson,\n OciHelmConfig,\n OciImageConfig,\n QuayTagsResponse,\n RegistryTagsList,\n} from './schema.ts';\n\nconst defaultConfig = {\n commitMessageTopic: '{{{depName}}} Docker tag',\n commitMessageExtra:\n 'to {{#if isPinDigest}}{{{newDigestShort}}}{{else}}{{#if isMajor}}{{{prettyNewMajor}}}{{else}}{{{prettyNewVersion}}}{{/if}}{{/if}}',\n digest: {\n branchTopic: '{{{depNameSanitized}}}-{{{currentValue}}}',\n commitMessageExtra: 'to {{newDigestShort}}',\n commitMessageTopic:\n '{{{depName}}}{{#if currentValue}}:{{{currentValue}}}{{/if}} Docker digest',\n group: {\n commitMessageTopic: '{{{groupName}}}',\n commitMessageExtra: '',\n },\n },\n pin: {\n commitMessageExtra: '',\n groupName: 'Docker digests',\n group: {\n commitMessageTopic: '{{{groupName}}}',\n branchTopic: 'digests-pin',\n },\n },\n};\n\nexport class DockerDatasource extends Datasource {\n static readonly id = dockerDatasourceId;\n\n override readonly defaultVersioning = dockerVersioningId;\n\n override readonly defaultRegistryUrls = [DOCKER_HUB];\n\n override readonly defaultConfig = defaultConfig;\n\n override readonly releaseTimestampSupport = true;\n override readonly releaseTimestampNote =\n 'Only supported on Docker Hub: The release timestamp is determined from the `tag_last_pushed` field in the results. **NOTE**: Currently, digests will receive the same release timestamp as the `tag_last_pushed`, which means that digests may appear newer than they are - see https://github.com/renovatebot/renovate/issues/38659';\n override readonly sourceUrlSupport = 'package';\n override readonly sourceUrlNote =\n 'The source URL is determined from the `org.opencontainers.image.source` and `org.label-schema.vcs-url` labels present in the metadata of the **latest stable** image found on the Docker registry.';\n\n constructor() {\n super(DockerDatasource.id);\n }\n\n // TODO: debug why quay throws errors (#9612)\n private async getManifestResponse(\n registryHost: string,\n dockerRepository: string,\n tag: string,\n mode: 'head' | 'getText' = 'getText',\n ): Promise<HttpResponse | null> {\n logger.debug(\n `getManifestResponse(${registryHost}, ${dockerRepository}, ${tag}, ${mode})`,\n );\n try {\n const headers = await getAuthHeaders(\n this.http,\n registryHost,\n dockerRepository,\n );\n if (!headers) {\n logger.warn('No docker auth found - returning');\n return null;\n }\n headers.accept = [\n 'application/vnd.docker.distribution.manifest.list.v2+json',\n 'application/vnd.docker.distribution.manifest.v2+json',\n 'application/vnd.oci.image.manifest.v1+json',\n 'application/vnd.oci.image.index.v1+json',\n ].join(', ');\n const url = `${registryHost}/v2/${dockerRepository}/manifests/${tag}`;\n const manifestResponse = await this.http[mode](url, {\n headers,\n noAuth: true,\n cacheProvider: memCacheProvider,\n });\n return manifestResponse;\n } catch (err) /* istanbul ignore next */ {\n if (err instanceof ExternalHostError) {\n throw err;\n }\n if (err.statusCode === 401) {\n logger.debug(\n { registryHost, dockerRepository },\n 'Unauthorized docker lookup',\n );\n logger.debug({ err });\n return null;\n }\n if (err.statusCode === 404) {\n logger.debug(\n {\n err,\n registryHost,\n dockerRepository,\n tag,\n },\n 'Docker Manifest is unknown',\n );\n return null;\n }\n if (err.statusCode === 429 && isDockerHost(registryHost)) {\n throw new ExternalHostError(err);\n }\n if (err.statusCode >= 500 && err.statusCode < 600) {\n throw new ExternalHostError(err);\n }\n if (err.code === 'ETIMEDOUT') {\n logger.debug(\n { registryHost },\n 'Timeout when attempting to connect to docker registry',\n );\n logger.debug({ err });\n return null;\n }\n logger.debug(\n {\n err,\n registryHost,\n dockerRepository,\n tag,\n },\n 'Unknown Error looking up docker manifest',\n );\n return null;\n }\n }\n\n private async _getImageConfig(\n registryHost: string,\n dockerRepository: string,\n configDigest: string,\n ): Promise<HttpResponse<OciImageConfig> | undefined> {\n logger.trace(\n `getImageConfig(${registryHost}, ${dockerRepository}, ${configDigest})`,\n );\n\n const headers = await getAuthHeaders(\n this.http,\n registryHost,\n dockerRepository,\n );\n /* v8 ignore next 4 -- should never happen */\n if (!headers) {\n logger.warn('No docker auth found - returning');\n return undefined;\n }\n const url = joinUrlParts(\n registryHost,\n 'v2',\n dockerRepository,\n 'blobs',\n configDigest,\n );\n return await this.http.getJson(\n url,\n {\n headers,\n noAuth: true,\n },\n OciImageConfig,\n );\n }\n\n getImageConfig(\n registryHost: string,\n dockerRepository: string,\n configDigest: string,\n ): Promise<HttpResponse<OciImageConfig> | undefined> {\n return withCache(\n {\n namespace: 'datasource-docker-imageconfig',\n key: `${registryHost}:${dockerRepository}@${configDigest}`,\n ttlMinutes: 1440 * 28,\n },\n () => this._getImageConfig(registryHost, dockerRepository, configDigest),\n );\n }\n\n private async _getHelmConfig(\n registryHost: string,\n dockerRepository: string,\n configDigest: string,\n ): Promise<HttpResponse<OciHelmConfig> | undefined> {\n logger.trace(\n `getImageConfig(${registryHost}, ${dockerRepository}, ${configDigest})`,\n );\n\n const headers = await getAuthHeaders(\n this.http,\n registryHost,\n dockerRepository,\n );\n /* v8 ignore next 4 -- should never happen */\n if (!headers) {\n logger.warn('No docker auth found - returning');\n return undefined;\n }\n const url = joinUrlParts(\n registryHost,\n 'v2',\n dockerRepository,\n 'blobs',\n configDigest,\n );\n return await this.http.getJson(\n url,\n {\n headers,\n noAuth: true,\n },\n OciHelmConfig,\n );\n }\n\n getHelmConfig(\n registryHost: string,\n dockerRepository: string,\n configDigest: string,\n ): Promise<HttpResponse<OciHelmConfig> | undefined> {\n return withCache(\n {\n namespace: 'datasource-docker-imageconfig',\n key: `${registryHost}:${dockerRepository}@${configDigest}`,\n ttlMinutes: 1440 * 28,\n },\n () => this._getHelmConfig(registryHost, dockerRepository, configDigest),\n );\n }\n\n private async getConfigDigest(\n registry: string,\n dockerRepository: string,\n tag: string,\n ): Promise<string | null> {\n return (\n (await this.getManifest(registry, dockerRepository, tag))?.config\n ?.digest ?? null\n );\n }\n\n private async getManifest(\n registry: string,\n dockerRepository: string,\n tag: string,\n ): Promise<OciImageManifest | DistributionManifest | null> {\n const manifestResponse = await this.getManifestResponse(\n registry,\n dockerRepository,\n tag,\n );\n\n // If getting the manifest fails here, then abort\n // This means that the latest tag doesn't have a manifest, which shouldn't\n // be possible\n /* v8 ignore next 3 -- should never happen */\n if (!manifestResponse) {\n return null;\n }\n\n // Softfail on invalid manifests\n const parsed = ManifestJson.safeParse(manifestResponse.body);\n if (!parsed.success) {\n logger.debug(\n {\n registry,\n dockerRepository,\n tag,\n body: manifestResponse.body,\n headers: manifestResponse.headers,\n err: parsed.error,\n },\n 'Invalid manifest response',\n );\n return null;\n }\n\n const manifest = parsed.data;\n\n switch (manifest.mediaType) {\n case 'application/vnd.docker.distribution.manifest.v2+json':\n case 'application/vnd.oci.image.manifest.v1+json':\n return manifest;\n case 'application/vnd.docker.distribution.manifest.list.v2+json':\n case 'application/vnd.oci.image.index.v1+json':\n if (!manifest.manifests.length) {\n logger.debug(\n { manifest },\n 'Invalid manifest list with no manifests - returning',\n );\n return null;\n }\n logger.trace(\n { registry, dockerRepository, tag },\n 'Found manifest list, using first image',\n );\n return this.getManifest(\n registry,\n dockerRepository,\n manifest.manifests[0].digest,\n );\n // istanbul ignore next: can't happen\n default:\n return null;\n }\n }\n\n private async _getImageArchitecture(\n registryHost: string,\n dockerRepository: string,\n currentDigest: string,\n ): Promise<string | null | undefined> {\n try {\n let manifestResponse: HttpResponse<string> | null;\n\n try {\n manifestResponse = await this.getManifestResponse(\n registryHost,\n dockerRepository,\n currentDigest,\n 'head',\n );\n } catch (_err) {\n const err =\n _err instanceof ExternalHostError\n ? _err.err\n : /* istanbul ignore next: can never happen */ _err;\n\n if (\n typeof err.statusCode === 'number' &&\n err.statusCode >= 500 &&\n err.statusCode < 600\n ) {\n // querying the digest manifest for a non existent image leads to a 500 statusCode\n return null;\n }\n\n /* istanbul ignore next */\n throw _err;\n }\n\n if (\n manifestResponse?.headers['content-type'] !==\n 'application/vnd.docker.distribution.manifest.v2+json' &&\n manifestResponse?.headers['content-type'] !==\n 'application/vnd.oci.image.manifest.v1+json'\n ) {\n return null;\n }\n\n const configDigest = await this.getConfigDigest(\n registryHost,\n dockerRepository,\n currentDigest,\n );\n if (!configDigest) {\n return null;\n }\n\n const configResponse = await this.getImageConfig(\n registryHost,\n dockerRepository,\n configDigest,\n );\n\n // TODO: fix me, architecture is required in spec\n if (\n configResponse &&\n ('config' in configResponse.body ||\n 'architecture' in configResponse.body)\n ) {\n const architecture = configResponse.body.architecture ?? null;\n logger.debug(\n `Current digest ${currentDigest} relates to architecture ${\n architecture ?? 'null'\n }`,\n );\n\n return architecture;\n }\n } catch (err) /* istanbul ignore next */ {\n if (err.statusCode !== 404 || err.message === PAGE_NOT_FOUND_ERROR) {\n throw err;\n }\n logger.debug(\n { registryHost, dockerRepository, currentDigest, err },\n 'Unknown error getting image architecture',\n );\n }\n\n return undefined;\n }\n\n getImageArchitecture(\n registryHost: string,\n dockerRepository: string,\n currentDigest: string,\n ): Promise<string | null | undefined> {\n return withCache(\n {\n namespace: 'datasource-docker-architecture',\n key: `${registryHost}:${dockerRepository}@${currentDigest}`,\n ttlMinutes: 1440 * 28,\n shouldCacheResult: isNonEmptyString,\n },\n () =>\n this._getImageArchitecture(\n registryHost,\n dockerRepository,\n currentDigest,\n ),\n );\n }\n\n /*\n * docker.getLabels\n *\n * This function will:\n * - Return the labels for the requested image\n */\n private async _getLabels(\n registryHost: string,\n dockerRepository: string,\n tag: string,\n ): Promise<Record<string, string> | undefined> {\n logger.debug(`getLabels(${registryHost}, ${dockerRepository}, ${tag})`);\n // Skip Docker Hub image if RENOVATE_X_DOCKER_HUB_DISABLE_LABEL_LOOKUP is set\n if (\n getEnv().RENOVATE_X_DOCKER_HUB_DISABLE_LABEL_LOOKUP &&\n registryHost === DOCKER_HUB\n ) {\n logger.debug(\n 'Docker Hub image - skipping label lookup due to RENOVATE_X_DOCKER_HUB_DISABLE_LABEL_LOOKUP',\n );\n return {};\n }\n // Docker Hub library images don't have labels we need\n if (\n registryHost === DOCKER_HUB &&\n dockerRepository.startsWith('library/')\n ) {\n logger.debug('Docker Hub library image - skipping label lookup');\n return {};\n }\n try {\n let labels: Record<string, string> | undefined = {};\n const manifest = await this.getManifest(\n registryHost,\n dockerRepository,\n tag,\n );\n\n if (!manifest) {\n logger.debug(\n { registryHost, dockerRepository, tag },\n 'No manifest found',\n );\n return undefined;\n }\n\n if ('annotations' in manifest && manifest.annotations) {\n labels = manifest.annotations;\n }\n\n switch (manifest.config.mediaType) {\n case 'application/vnd.cncf.helm.config.v1+json': {\n if (labels[sourceLabel]) {\n // we already have the source url, so no need to pull the config\n return labels;\n }\n const configResponse = await this.getHelmConfig(\n registryHost,\n dockerRepository,\n manifest.config.digest,\n );\n\n if (configResponse) {\n // Helm chart\n const url = findHelmSourceUrl(configResponse.body);\n if (url) {\n labels[sourceLabel] = url;\n }\n }\n break;\n }\n case 'application/vnd.oci.image.config.v1+json':\n case 'application/vnd.docker.container.image.v1+json': {\n if (labels[sourceLabel] && labels[gitRefLabel]) {\n // we already have the source url, so no need to pull the config\n return labels;\n }\n const configResponse = await this.getImageConfig(\n registryHost,\n dockerRepository,\n manifest.config.digest,\n );\n\n /* v8 ignore next 3 -- should never happen */\n if (!configResponse) {\n return labels;\n }\n\n const body = configResponse.body;\n if (body.config) {\n labels = { ...labels, ...body.config.Labels };\n } else {\n logger.debug(\n { headers: configResponse.headers, body },\n `manifest blob response body missing the \"config\" property`,\n );\n }\n break;\n }\n }\n\n if (labels) {\n logger.debug(\n {\n labels,\n },\n 'found labels in manifest',\n );\n }\n return labels;\n } catch (err) /* istanbul ignore next: should be tested in future */ {\n if (err instanceof ExternalHostError) {\n throw err;\n }\n if (err.statusCode === 400 || err.statusCode === 401) {\n logger.debug(\n { registryHost, dockerRepository, err },\n 'Unauthorized docker lookup',\n );\n } else if (err.statusCode === 404) {\n logger.warn(\n {\n err,\n registryHost,\n dockerRepository,\n tag,\n },\n 'Config Manifest is unknown',\n );\n } else if (err.statusCode === 429 && isDockerHost(registryHost)) {\n logger.warn({ err }, 'docker registry failure: too many requests');\n } else if (err.statusCode >= 500 && err.statusCode < 600) {\n logger.debug(\n {\n err,\n registryHost,\n dockerRepository,\n tag,\n },\n 'docker registry failure: internal error',\n );\n } else if (\n err.code === 'ERR_TLS_CERT_ALTNAME_INVALID' ||\n err.code === 'ETIMEDOUT'\n ) {\n logger.debug(\n { registryHost, err },\n 'Error connecting to docker registry',\n );\n } else if (registryHost === 'https://quay.io') {\n // istanbul ignore next\n logger.debug(\n 'Ignoring quay.io errors until they fully support v2 schema',\n );\n } else {\n logger.info(\n { registryHost, dockerRepository, tag, err },\n 'Unknown error getting Docker labels',\n );\n }\n return {};\n }\n }\n\n getLabels(\n registryHost: string,\n dockerRepository: string,\n tag: string,\n ): Promise<Record<string, string> | undefined> {\n return withCache(\n {\n namespace: 'datasource-docker-labels',\n key: `${registryHost}:${dockerRepository}:${tag}`,\n ttlMinutes: 24 * 60,\n },\n () => this._getLabels(registryHost, dockerRepository, tag),\n );\n }\n\n private async getTagsQuayRegistry(\n registry: string,\n repository: string,\n ): Promise<string[]> {\n let tags: string[] = [];\n const limit = 100;\n\n const pageUrl = (page: number): string =>\n `${registry}/api/v1/repository/${repository}/tag/?limit=${limit}&page=${page}&onlyActiveTags=true`;\n\n let page = 1;\n let url: string | null = pageUrl(page);\n while (url && page <= 20) {\n const res: HttpResponse<QuayTagsResponse> = await this.http.getJson(\n url,\n QuayTagsResponse,\n );\n const pageTags = res.body.tags.map((tag) => tag.name);\n tags = tags.concat(pageTags);\n page += 1;\n url = res.body.has_additional ? pageUrl(page) : null;\n }\n return tags;\n }\n\n private async getDockerApiTags(\n registryHost: string,\n dockerRepository: string,\n ): Promise<string[] | null> {\n let tags: string[] = [];\n // AWS ECR limits the maximum number of results to 1000\n // See https://docs.aws.amazon.com/AmazonECR/latest/APIReference/API_DescribeRepositories.html#ECR-DescribeRepositories-request-maxResults\n // See https://docs.aws.amazon.com/AmazonECRPublic/latest/APIReference/API_DescribeRepositories.html#ecrpublic-DescribeRepositories-request-maxResults\n const limit =\n ecrRegex.test(registryHost) || ecrPublicRegex.test(registryHost)\n ? 1000\n : 10000;\n let url: string | null =\n `${registryHost}/${dockerRepository}/tags/list?n=${limit}`;\n url = ensurePathPrefix(url, '/v2');\n const headers = await getAuthHeaders(\n this.http,\n registryHost,\n dockerRepository,\n url,\n );\n if (!headers) {\n logger.debug('Failed to get authHeaders for getTags lookup');\n return null;\n }\n let page = 0;\n const hostsNeedingAllPages = [\n 'https://ghcr.io', // GHCR sorts from oldest to newest, so we need to get all pages\n 'https://quay.io', // Quay sorts from oldest to newest, so we need to get all pages\n ];\n const pages = hostsNeedingAllPages.includes(registryHost)\n ? 1000\n : GlobalConfig.get('dockerMaxPages');\n logger.trace({ registryHost, dockerRepository, pages }, 'docker.getTags');\n let foundMaxResultsError = false;\n do {\n let res: HttpResponse<RegistryTagsList>;\n try {\n res = await this.http.getJson(\n url,\n { headers, noAuth: true },\n RegistryTagsList,\n );\n } catch (err) {\n if (\n !foundMaxResultsError &&\n err instanceof HttpError &&\n isECRMaxResultsError(err)\n ) {\n const maxResults = 1000;\n url = `${registryHost}/${dockerRepository}/tags/list?n=${maxResults}`;\n url = ensurePathPrefix(url, '/v2');\n foundMaxResultsError = true;\n continue;\n }\n throw err;\n }\n tags = tags.concat(res.body.tags);\n const linkHeader = parseLinkHeader(res.headers.link);\n if (isArtifactoryServer(res)) {\n // Artifactory bug: next link comes back without virtual-repo prefix (RTFACT-18971)\n if (linkHeader?.next?.last) {\n // parse the current URL, strip any old \"last\" param, then set the new one\n const parsed = parseUrl(url);\n // v8 ignore if: url is always a valid HTTP URL as `ensurePathPrefix`\n if (!parsed) {\n url = null;\n break;\n }\n parsed.searchParams.delete('last');\n parsed.searchParams.set('last', linkHeader.next.last);\n url = parsed.href;\n } else {\n url = null;\n }\n } else if (linkHeader?.next?.url) {\n // for the normal case we can still use URL to resolve relative-next\n url = new URL(linkHeader.next.url, url).href;\n } else {\n url = null;\n }\n page += 1;\n } while (url && page < pages);\n return tags;\n }\n\n private async _getTags(\n registryHost: string,\n dockerRepository: string,\n ): Promise<string[] | null> {\n try {\n const isQuay = registryHost === 'https://quay.io';\n let tags: string[] | null;\n if (isQuay) {\n try {\n // Due to pagination and sorting limits on Quay Docker v2 API implementation we try the Quay v1 API first\n tags = await this.getTagsQuayRegistry(registryHost, dockerRepository);\n } catch (err) {\n // If we get a 401 Unauthorized error (v1 API requires separate auth for private images), fall back to Docker v2 API\n if (err.statusCode === 401) {\n logger.debug(\n { registryHost, dockerRepository },\n 'Quay v1 API unauthorized, falling back to Docker v2 API',\n );\n tags = await this.getDockerApiTags(registryHost, dockerRepository);\n } else {\n throw err;\n }\n }\n } else {\n tags = await this.getDockerApiTags(registryHost, dockerRepository);\n }\n return tags;\n } catch (_err) /* istanbul ignore next */ {\n const err = _err instanceof ExternalHostError ? _err.err : _err;\n\n if (\n (err.statusCode === 404 || err.message === PAGE_NOT_FOUND_ERROR) &&\n !dockerRepository.includes('/')\n ) {\n logger.debug(\n `Retrying Tags for ${registryHost}/${dockerRepository} using library/ prefix`,\n );\n return this.getTags(registryHost, `library/${dockerRepository}`);\n }\n // JFrog Artifactory - Retry handling when resolving Docker Official Images\n // These follow the format of {{registryHost}}{{jFrogRepository}}/library/{{dockerRepository}}\n if (\n (err.statusCode === 404 || err.message === PAGE_NOT_FOUND_ERROR) &&\n isArtifactoryServer(err.response) &&\n dockerRepository.split('/').length === 2\n ) {\n logger.debug(\n `JFrog Artifactory: Retrying Tags for ${registryHost}/${dockerRepository} using library/ path between JFrog virtual repository and image`,\n );\n\n const dockerRepositoryParts = dockerRepository.split('/');\n const jfrogRepository = dockerRepositoryParts[0];\n const dockerImage = dockerRepositoryParts[1];\n\n return this.getTags(\n registryHost,\n `${jfrogRepository}/library/${dockerImage}`,\n );\n }\n if (err.statusCode === 429 && isDockerHost(registryHost)) {\n logger.warn(\n { registryHost, dockerRepository, err },\n 'docker registry failure: too many requests',\n );\n throw new ExternalHostError(err);\n }\n if (err.statusCode >= 500 && err.statusCode < 600) {\n logger.warn(\n { registryHost, dockerRepository, err },\n 'docker registry failure: internal error',\n );\n throw new ExternalHostError(err);\n }\n const errorCodes = ['ECONNRESET', 'ETIMEDOUT'];\n if (errorCodes.includes(err.code)) {\n logger.warn(\n { registryHost, dockerRepository, err },\n 'docker registry connection failure',\n );\n throw new ExternalHostError(err);\n }\n if (isDockerHost(registryHost)) {\n logger.info({ err }, 'Docker Hub lookup failure');\n }\n throw _err;\n }\n }\n\n getTags(\n registryHost: string,\n dockerRepository: string,\n ): Promise<string[] | null> {\n return withCache(\n {\n namespace: 'datasource-docker-tags',\n key: `${registryHost}:${dockerRepository}`,\n },\n () => this._getTags(registryHost, dockerRepository),\n );\n }\n\n /**\n * docker.getDigest\n *\n * The `newValue` supplied here should be a valid tag for the docker image.\n *\n * This function will:\n * - Look up a sha256 digest for a tag on its registry\n * - Return the digest as a string\n */\n private async _getDigest(\n { registryUrl, lookupName, packageName, currentDigest }: DigestConfig,\n newValue?: string,\n ): Promise<string | null> {\n let registryHost: string;\n let dockerRepository: string;\n if (registryUrl && lookupName) {\n // Reuse the resolved values from getReleases()\n registryHost = registryUrl;\n dockerRepository = lookupName;\n } else {\n // Resolve values independently\n ({ registryHost, dockerRepository } = getRegistryRepository(\n packageName,\n registryUrl!,\n ));\n }\n logger.debug(\n // TODO: types (#22198)\n `getDigest(${registryHost}, ${dockerRepository}, ${newValue})`,\n );\n const newTag = isNonEmptyString(newValue) ? newValue : 'latest';\n let digest: string | null = null;\n try {\n let architecture: string | null | undefined = null;\n if (currentDigest && isDockerDigest(currentDigest)) {\n architecture = await this.getImageArchitecture(\n registryHost,\n dockerRepository,\n currentDigest,\n );\n }\n\n let manifestResponse: HttpResponse | null = null;\n if (!architecture) {\n // Reuse the digest cached from the Docker Hub tag API\n if (registryHost === DOCKER_HUB) {\n const cache = await DockerHubCache.init(dockerRepository);\n const cachedDigest = cache.getDigestForTag(newTag);\n if (cachedDigest) {\n return cachedDigest;\n }\n }\n\n manifestResponse = await this.getManifestResponse(\n registryHost,\n dockerRepository,\n newTag,\n 'head',\n );\n\n if (\n manifestResponse &&\n hasKey('docker-content-digest', manifestResponse.headers)\n ) {\n digest =\n (manifestResponse.headers['docker-content-digest'] as string) ||\n null;\n }\n }\n\n if (\n isNonEmptyString(architecture) ||\n (manifestResponse &&\n !hasKey('docker-content-digest', manifestResponse.headers))\n ) {\n // Reuse the per-arch digest cached from the Docker Hub tag API\n if (isNonEmptyString(architecture) && registryHost === DOCKER_HUB) {\n const cache = await DockerHubCache.init(dockerRepository);\n const cachedDigest = cache.getArchDigestForTag(newTag, architecture);\n if (cachedDigest) {\n return cachedDigest;\n }\n }\n\n logger.debug(\n { registryHost, dockerRepository },\n 'Architecture-specific digest or missing docker-content-digest header - pulling full manifest',\n );\n manifestResponse = await this.getManifestResponse(\n registryHost,\n dockerRepository,\n newTag,\n );\n\n if (architecture && manifestResponse) {\n const parsed = ManifestJson.safeParse(manifestResponse.body);\n /* istanbul ignore else: hard to test */\n if (parsed.success) {\n const manifestList = parsed.data;\n if (\n manifestList.mediaType ===\n 'application/vnd.docker.distribution.manifest.list.v2+json' ||\n manifestList.mediaType ===\n 'application/vnd.oci.image.index.v1+json'\n ) {\n for (const manifest of manifestList.manifests) {\n if (manifest.platform?.architecture === architecture) {\n digest = manifest.digest;\n break;\n }\n }\n // TODO: return null if no matching architecture digest found\n // https://github.com/renovatebot/renovate/discussions/22639\n } else if (\n hasKey('docker-content-digest', manifestResponse.headers)\n ) {\n // TODO: return null if no matching architecture, requires to fetch the config manifest\n // https://github.com/renovatebot/renovate/discussions/22639\n digest = manifestResponse.headers[\n 'docker-content-digest'\n ] as string;\n }\n } else {\n logger.debug(\n {\n registryHost,\n dockerRepository,\n newTag,\n body: manifestResponse.body,\n headers: manifestResponse.headers,\n err: parsed.error,\n },\n 'Failed to parse manifest response',\n );\n }\n }\n\n if (!digest) {\n logger.debug(\n { registryHost, dockerRepository, newTag },\n 'Extraction digest from manifest response body is deprecated',\n );\n digest = extractDigestFromResponseBody(manifestResponse!);\n }\n }\n\n if (\n !manifestResponse &&\n !dockerRepository.includes('/') &&\n !packageName.includes('/')\n ) {\n logger.debug(\n `Retrying Digest for ${registryHost}/${dockerRepository} using library/ prefix`,\n );\n return this.getDigest(\n {\n registryUrl,\n packageName: `library/${packageName}`,\n currentDigest,\n },\n newValue,\n );\n }\n\n if (manifestResponse) {\n // TODO: fix types (#22198)\n logger.debug(`Got docker digest ${digest!}`);\n }\n } catch (err) /* istanbul ignore next */ {\n if (err instanceof ExternalHostError) {\n throw err;\n }\n logger.debug(\n {\n err,\n packageName,\n newTag,\n },\n 'Unknown Error looking up docker image digest',\n );\n }\n return digest;\n }\n\n override getDigest(\n config: DigestConfig,\n newValue?: string,\n ): Promise<string | null> {\n const newTag = newValue ?? 'latest';\n const { registryHost, dockerRepository } = getRegistryRepository(\n config.packageName,\n config.registryUrl!,\n );\n const digest = config.currentDigest ? `@${config.currentDigest}` : '';\n return withCache(\n {\n namespace: 'datasource-docker-digest',\n key: `${registryHost}:${dockerRepository}:${newTag}${digest}`,\n fallback: true,\n shouldCacheResult: isNonEmptyString,\n },\n () => this._getDigest(config, newValue),\n );\n }\n\n private async _getDockerHubTags(\n dockerRepository: string,\n ): Promise<Release[] | null> {\n let url = `https://hub.docker.com/v2/repositories/${dockerRepository}/tags?page_size=1000&ordering=last_updated`;\n\n const cache = await DockerHubCache.init(dockerRepository);\n const maxPages = GlobalConfig.get('dockerMaxPages');\n let page = 0,\n needNextPage = true;\n while (needNextPage && page < maxPages) {\n const { val, err } = await this.http\n .getJsonSafe(url, DockerHubTagsPage)\n .unwrap();\n\n if (err) {\n logger.debug({ err }, `Docker: error fetching data from DockerHub`);\n return null;\n }\n page++;\n const { results, next, count } = val;\n\n needNextPage = cache.reconcile(results, count);\n\n if (!next) {\n break;\n }\n\n url = next;\n }\n\n await cache.save();\n\n const items = cache.getItems();\n return items.map(({ name: version, tag_last_pushed }) => {\n const release: Release = { version };\n\n const releaseTimestamp = asTimestamp(tag_last_pushed);\n if (releaseTimestamp) {\n release.releaseTimestamp = releaseTimestamp;\n }\n\n // Digest is intentionally not propagated — the Docker Hub tag API\n // returns the manifest-list digest, which would bypass arch-aware\n // resolution in `getDigest()`. `getDigest()` consults the same cache\n // as a shortcut when no arch resolution is needed.\n return release;\n });\n }\n\n getDockerHubTags(dockerRepository: string): Promise<Release[] | null> {\n return withCache(\n {\n namespace: 'datasource-docker-hub-tags',\n key: `${dockerRepository}`,\n },\n () => this._getDockerHubTags(dockerRepository),\n );\n }\n\n /**\n * docker.getReleases\n *\n * A docker image usually looks something like this: somehost.io/owner/repo:8.1.0-alpine\n * In the above:\n * - 'somehost.io' is the registry\n * - 'owner/repo' is the package name\n * - '8.1.0-alpine' is the tag\n *\n * This function will filter only tags that contain a semver version\n */\n private async _getReleases({\n packageName,\n registryUrl,\n }: GetReleasesConfig): Promise<ReleaseResult | null> {\n const { registryHost, dockerRepository } = getRegistryRepository(\n packageName,\n registryUrl!,\n );\n\n type TagsResultType = AsyncResult<\n Release[],\n NonNullable<Error | 'tags-error' | 'dockerhub-error'>\n >;\n\n const getTags = (): TagsResultType =>\n Result.wrapNullable(\n this.getTags(registryHost, dockerRepository),\n 'tags-error' as const,\n ).transform((tags) => tags.map((version) => ({ version })));\n\n const getDockerHubTags = (): TagsResultType =>\n Result.wrapNullable(\n this.getDockerHubTags(dockerRepository),\n 'dockerhub-error' as const,\n ).catch(getTags);\n\n const tagsResult =\n registryHost === DOCKER_HUB &&\n !getEnv().RENOVATE_X_DOCKER_HUB_TAGS_DISABLE\n ? getDockerHubTags()\n : getTags();\n\n const { val: releases, err } = await tagsResult.unwrap();\n if (err instanceof Error) {\n throw err;\n } else if (err) {\n return null;\n }\n\n const ret: ReleaseResult = {\n registryUrl: registryHost,\n releases,\n };\n if (dockerRepository !== packageName) {\n // This will be reused later if a getDigest() call is made\n ret.lookupName = dockerRepository;\n }\n\n const tags = releases.map((release) => release.version);\n const latestTag = tags.includes('latest')\n ? 'latest'\n : (findLatestStable(tags) ?? tags[tags.length - 1]);\n\n /* v8 ignore next 3 -- TODO: add test */\n if (!latestTag) {\n return ret;\n }\n const labels = await this.getLabels(\n registryHost,\n dockerRepository,\n latestTag,\n );\n if (labels) {\n if (isNonEmptyString(labels[gitRefLabel])) {\n ret.gitRef = labels[gitRefLabel];\n }\n for (const label of sourceLabels) {\n if (isNonEmptyString(labels[label])) {\n ret.sourceUrl = labels[label];\n break;\n }\n }\n if (isNonEmptyString(labels[imageUrlLabel])) {\n ret.homepage = labels[imageUrlLabel];\n }\n }\n return ret;\n }\n\n getReleases(config: GetReleasesConfig): Promise<ReleaseResult | null> {\n const { registryHost, dockerRepository } = getRegistryRepository(\n config.packageName,\n config.registryUrl!,\n );\n return withCache(\n {\n namespace: 'datasource-docker-releases-v2',\n key: `${registryHost}:${dockerRepository}`,\n cacheable: registryHost === DOCKER_HUB,\n fallback: true,\n },\n () => this._getReleases(config),\n );\n }\n}\n"],"mappings":"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"}
@@ -130,7 +130,27 @@ onError: ({ error }) => {
130
130
  logger.debug({ error }, "Docker: Failed to parse some tags from Docker Hub");
131
131
  } })
132
132
  });
133
+ /**
134
+ * Docker registry auth token response.
135
+ * https://distribution.github.io/distribution/spec/auth/token/
136
+ */
137
+ const RegistryAuthToken = z.object({
138
+ token: z.string().optional(),
139
+ access_token: z.string().optional()
140
+ });
141
+ /**
142
+ * Docker registry tags list response.
143
+ * https://distribution.github.io/distribution/spec/api/#listing-image-tags
144
+ */
145
+ const RegistryTagsList = z.object({ tags: z.array(z.string()) });
146
+ /**
147
+ * Quay registry tags list response (Quay v1 API).
148
+ */
149
+ const QuayTagsResponse = z.object({
150
+ tags: LooseArray(z.object({ name: z.string() })),
151
+ has_additional: z.boolean().default(false)
152
+ });
133
153
  //#endregion
134
- export { DockerHubTagsPage, ManifestJson, OciHelmConfig, OciImageConfig };
154
+ export { DockerHubTagsPage, ManifestJson, OciHelmConfig, OciImageConfig, QuayTagsResponse, RegistryAuthToken, RegistryTagsList };
135
155
 
136
156
  //# sourceMappingURL=schema.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","names":[],"sources":["../../../../lib/modules/datasource/docker/schema.ts"],"sourcesContent":["import { z } from 'zod/v4';\nimport { logger } from '../../../logger/index.ts';\nimport { Json, LooseArray } from '../../../util/schema-utils/index.ts';\n\n// OCI manifests\n\n/**\n * OCI manifest object\n */\nexport const ManifestObject = z.object({\n schemaVersion: z.literal(2),\n mediaType: z.string().nullish(),\n});\n\n/**\n * Oci descriptor\n * https://github.com/opencontainers/image-spec/blob/main/descriptor.md\n */\nexport const Descriptor = z.object({\n mediaType: z.string(),\n digest: z.string(),\n size: z.number().int().gte(0).nullish(),\n});\n/**\n * OCI platform properties\n * https://github.com/opencontainers/image-spec/blob/main/image-index.md\n */\nconst OciPlatform = z\n .object({\n architecture: z.string().nullish(),\n })\n .nullish();\n\n/**\n * OCI Image Configuration.\n *\n * Compatible with old docker configiguration.\n * https://github.com/opencontainers/image-spec/blob/main/config.md\n */\nexport const OciImageConfig = z.object({\n // This is required by the spec, but probably not present in the wild.\n architecture: z.string().nullish(),\n config: z\n .object({ Labels: z.record(z.string(), z.string()).nullish() })\n .nullish(),\n});\nexport type OciImageConfig = z.infer<typeof OciImageConfig>;\n\n/**\n * OCI Helm Configuration\n * https://helm.sh/docs/topics/charts/#the-chartyaml-file\n */\nexport const OciHelmConfig = z.object({\n name: z.string(),\n version: z.string(),\n home: z.string().nullish(),\n sources: z.array(z.string()).nullish(),\n});\nexport type OciHelmConfig = z.infer<typeof OciHelmConfig>;\n\n/**\n * OCI Image Manifest\n * The same structure as docker image manifest, but mediaType is not required and is not present in the wild.\n * https://github.com/opencontainers/image-spec/blob/main/manifest.md\n */\nexport const OciImageManifest = ManifestObject.extend({\n mediaType: z.literal('application/vnd.oci.image.manifest.v1+json'),\n config: Descriptor.extend({\n mediaType: z.enum([\n 'application/vnd.oci.image.config.v1+json',\n 'application/vnd.cncf.helm.config.v1+json',\n 'application/vnd.devcontainers',\n 'application/vnd.oci.empty.v1+json',\n 'application/vnd.cncf.flux.config.v1+json',\n ]),\n }),\n annotations: z.record(z.string(), z.string()).nullish(),\n});\nexport type OciImageManifest = z.infer<typeof OciImageManifest>;\n\n/**\n * OCI Image List\n * mediaType is not required.\n * https://github.com/opencontainers/image-spec/blob/main/image-index.md\n */\nexport const OciImageIndexManifest = ManifestObject.extend({\n mediaType: z.literal('application/vnd.oci.image.index.v1+json'),\n manifests: LooseArray(\n Descriptor.extend({\n mediaType: z.enum([\n 'application/vnd.oci.image.manifest.v1+json',\n 'application/vnd.oci.image.index.v1+json',\n ]),\n platform: OciPlatform,\n }),\n ),\n annotations: z.record(z.string(), z.string()).nullish(),\n});\n\n// Old Docker manifests\n\n/**\n * Image Manifest\n * https://docs.docker.com/registry/spec/manifest-v2-2/#image-manifest\n */\nexport const DistributionManifest = ManifestObject.extend({\n mediaType: z.literal('application/vnd.docker.distribution.manifest.v2+json'),\n config: Descriptor.extend({\n mediaType: z.literal('application/vnd.docker.container.image.v1+json'),\n }),\n});\nexport type DistributionManifest = z.infer<typeof DistributionManifest>;\n\n/**\n * Manifest List\n * https://docs.docker.com/registry/spec/manifest-v2-2/#manifest-list\n */\nexport const DistributionListManifest = ManifestObject.extend({\n mediaType: z.literal(\n 'application/vnd.docker.distribution.manifest.list.v2+json',\n ),\n manifests: z.array(\n Descriptor.extend({\n mediaType: z.literal(\n 'application/vnd.docker.distribution.manifest.v2+json',\n ),\n platform: OciPlatform,\n }),\n ),\n});\n\n// Combined manifests\nexport const Manifest = ManifestObject.passthrough()\n .transform((value, ctx) => {\n if (value.mediaType === undefined) {\n if ('config' in value) {\n value.mediaType = 'application/vnd.oci.image.manifest.v1+json';\n } else if ('manifests' in value) {\n value.mediaType = 'application/vnd.oci.image.index.v1+json';\n } else {\n ctx.addIssue({\n code: 'custom',\n message: 'Invalid manifest, missing mediaType.',\n });\n return z.NEVER;\n }\n }\n return value;\n })\n .pipe(\n z.discriminatedUnion('mediaType', [\n DistributionManifest,\n DistributionListManifest,\n OciImageManifest,\n OciImageIndexManifest,\n ]),\n );\n\nexport type Manifest = z.infer<typeof Manifest>;\nexport const ManifestJson = Json.pipe(Manifest);\n\nexport const DockerHubTagImage = z.object({\n architecture: z.string().nullable().catch(null),\n digest: z.string().nullable().catch(null),\n});\nexport type DockerHubTagImage = z.infer<typeof DockerHubTagImage>;\n\nexport const DockerHubTag = z.object({\n id: z.number(),\n last_updated: z.string().datetime(),\n name: z.string(),\n tag_last_pushed: z.string().datetime().nullable().catch(null),\n digest: z.string().nullable().catch(null),\n images: z.array(DockerHubTagImage).catch([]),\n});\nexport type DockerHubTag = z.infer<typeof DockerHubTag>;\n\nexport const DockerHubTagsPage = z.object({\n count: z.number(),\n next: z.string().nullable().catch(null),\n results: LooseArray(DockerHubTag, {\n /* v8 ignore next -- TODO: add test */\n onError: ({ error }) => {\n logger.debug(\n { error },\n 'Docker: Failed to parse some tags from Docker Hub',\n );\n },\n }),\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","names":[],"sources":["../../../../lib/modules/datasource/docker/schema.ts"],"sourcesContent":["import { z } from 'zod/v4';\nimport { logger } from '../../../logger/index.ts';\nimport { Json, LooseArray } from '../../../util/schema-utils/index.ts';\n\n// OCI manifests\n\n/**\n * OCI manifest object\n */\nexport const ManifestObject = z.object({\n schemaVersion: z.literal(2),\n mediaType: z.string().nullish(),\n});\n\n/**\n * Oci descriptor\n * https://github.com/opencontainers/image-spec/blob/main/descriptor.md\n */\nexport const Descriptor = z.object({\n mediaType: z.string(),\n digest: z.string(),\n size: z.number().int().gte(0).nullish(),\n});\n/**\n * OCI platform properties\n * https://github.com/opencontainers/image-spec/blob/main/image-index.md\n */\nconst OciPlatform = z\n .object({\n architecture: z.string().nullish(),\n })\n .nullish();\n\n/**\n * OCI Image Configuration.\n *\n * Compatible with old docker configiguration.\n * https://github.com/opencontainers/image-spec/blob/main/config.md\n */\nexport const OciImageConfig = z.object({\n // This is required by the spec, but probably not present in the wild.\n architecture: z.string().nullish(),\n config: z\n .object({ Labels: z.record(z.string(), z.string()).nullish() })\n .nullish(),\n});\nexport type OciImageConfig = z.infer<typeof OciImageConfig>;\n\n/**\n * OCI Helm Configuration\n * https://helm.sh/docs/topics/charts/#the-chartyaml-file\n */\nexport const OciHelmConfig = z.object({\n name: z.string(),\n version: z.string(),\n home: z.string().nullish(),\n sources: z.array(z.string()).nullish(),\n});\nexport type OciHelmConfig = z.infer<typeof OciHelmConfig>;\n\n/**\n * OCI Image Manifest\n * The same structure as docker image manifest, but mediaType is not required and is not present in the wild.\n * https://github.com/opencontainers/image-spec/blob/main/manifest.md\n */\nexport const OciImageManifest = ManifestObject.extend({\n mediaType: z.literal('application/vnd.oci.image.manifest.v1+json'),\n config: Descriptor.extend({\n mediaType: z.enum([\n 'application/vnd.oci.image.config.v1+json',\n 'application/vnd.cncf.helm.config.v1+json',\n 'application/vnd.devcontainers',\n 'application/vnd.oci.empty.v1+json',\n 'application/vnd.cncf.flux.config.v1+json',\n ]),\n }),\n annotations: z.record(z.string(), z.string()).nullish(),\n});\nexport type OciImageManifest = z.infer<typeof OciImageManifest>;\n\n/**\n * OCI Image List\n * mediaType is not required.\n * https://github.com/opencontainers/image-spec/blob/main/image-index.md\n */\nexport const OciImageIndexManifest = ManifestObject.extend({\n mediaType: z.literal('application/vnd.oci.image.index.v1+json'),\n manifests: LooseArray(\n Descriptor.extend({\n mediaType: z.enum([\n 'application/vnd.oci.image.manifest.v1+json',\n 'application/vnd.oci.image.index.v1+json',\n ]),\n platform: OciPlatform,\n }),\n ),\n annotations: z.record(z.string(), z.string()).nullish(),\n});\n\n// Old Docker manifests\n\n/**\n * Image Manifest\n * https://docs.docker.com/registry/spec/manifest-v2-2/#image-manifest\n */\nexport const DistributionManifest = ManifestObject.extend({\n mediaType: z.literal('application/vnd.docker.distribution.manifest.v2+json'),\n config: Descriptor.extend({\n mediaType: z.literal('application/vnd.docker.container.image.v1+json'),\n }),\n});\nexport type DistributionManifest = z.infer<typeof DistributionManifest>;\n\n/**\n * Manifest List\n * https://docs.docker.com/registry/spec/manifest-v2-2/#manifest-list\n */\nexport const DistributionListManifest = ManifestObject.extend({\n mediaType: z.literal(\n 'application/vnd.docker.distribution.manifest.list.v2+json',\n ),\n manifests: z.array(\n Descriptor.extend({\n mediaType: z.literal(\n 'application/vnd.docker.distribution.manifest.v2+json',\n ),\n platform: OciPlatform,\n }),\n ),\n});\n\n// Combined manifests\nexport const Manifest = ManifestObject.passthrough()\n .transform((value, ctx) => {\n if (value.mediaType === undefined) {\n if ('config' in value) {\n value.mediaType = 'application/vnd.oci.image.manifest.v1+json';\n } else if ('manifests' in value) {\n value.mediaType = 'application/vnd.oci.image.index.v1+json';\n } else {\n ctx.addIssue({\n code: 'custom',\n message: 'Invalid manifest, missing mediaType.',\n });\n return z.NEVER;\n }\n }\n return value;\n })\n .pipe(\n z.discriminatedUnion('mediaType', [\n DistributionManifest,\n DistributionListManifest,\n OciImageManifest,\n OciImageIndexManifest,\n ]),\n );\n\nexport type Manifest = z.infer<typeof Manifest>;\nexport const ManifestJson = Json.pipe(Manifest);\n\nexport const DockerHubTagImage = z.object({\n architecture: z.string().nullable().catch(null),\n digest: z.string().nullable().catch(null),\n});\nexport type DockerHubTagImage = z.infer<typeof DockerHubTagImage>;\n\nexport const DockerHubTag = z.object({\n id: z.number(),\n last_updated: z.string().datetime(),\n name: z.string(),\n tag_last_pushed: z.string().datetime().nullable().catch(null),\n digest: z.string().nullable().catch(null),\n images: z.array(DockerHubTagImage).catch([]),\n});\nexport type DockerHubTag = z.infer<typeof DockerHubTag>;\n\nexport const DockerHubTagsPage = z.object({\n count: z.number(),\n next: z.string().nullable().catch(null),\n results: LooseArray(DockerHubTag, {\n /* v8 ignore next -- TODO: add test */\n onError: ({ error }) => {\n logger.debug(\n { error },\n 'Docker: Failed to parse some tags from Docker Hub',\n );\n },\n }),\n});\n\n/**\n * Docker registry auth token response.\n * https://distribution.github.io/distribution/spec/auth/token/\n */\nexport const RegistryAuthToken = z.object({\n token: z.string().optional(),\n access_token: z.string().optional(),\n});\nexport type RegistryAuthToken = z.infer<typeof RegistryAuthToken>;\n\n/**\n * Docker registry tags list response.\n * https://distribution.github.io/distribution/spec/api/#listing-image-tags\n */\nexport const RegistryTagsList = z.object({\n tags: z.array(z.string()),\n});\nexport type RegistryTagsList = z.infer<typeof RegistryTagsList>;\n\n/**\n * Quay registry tags list response (Quay v1 API).\n */\nexport const QuayTagsResponse = z.object({\n tags: LooseArray(\n z.object({\n name: z.string(),\n }),\n ),\n has_additional: z.boolean().default(false),\n});\nexport type QuayTagsResponse = z.infer<typeof QuayTagsResponse>;\n"],"mappings":"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"}
@@ -149,8 +149,8 @@ const DenoPackageFile = z.object({
149
149
  tasks: z.optional(Tasks).default([]),
150
150
  compilerOptions: z.optional(z.object({
151
151
  types: CompilerOptionsTypes,
152
- jsxImportSource: CompilerOptionsJsxImportSource,
153
- jsxImportSourceTypes: CompilerOptionsJsxImportSourceTypes
152
+ jsxImportSource: CompilerOptionsJsxImportSource.optional().default([]),
153
+ jsxImportSourceTypes: CompilerOptionsJsxImportSourceTypes.optional().default([])
154
154
  })).default({
155
155
  types: [],
156
156
  jsxImportSource: [],
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","names":["denoVersioningId"],"sources":["../../../../lib/modules/manager/deno/schema.ts"],"sourcesContent":["import validateNpmPackageName from 'validate-npm-package-name';\nimport { z } from 'zod/v4';\nimport { regEx } from '../../../util/regex.ts';\nimport {\n Json,\n Jsonc,\n LooseArray,\n LooseRecord,\n} from '../../../util/schema-utils/index.ts';\nimport { joinUrlParts } from '../../../util/url.ts';\nimport { extractJsrPackageName } from '../../datasource/jsr/util.ts';\nimport {\n id as denoVersioningId,\n isValid,\n} from '../../versioning/deno/index.ts';\nimport type { PackageDependency } from '../types.ts';\nimport type { DenoManagerData } from './types.ts';\nimport { denoLandRegex, depValueRegex } from './utils.ts';\n\nexport const DenoLock = Json.pipe(\n // this schema is version 5\n // https://github.com/denoland/vscode_deno/blob/7e125c6ffcdcdebd587f97be5341d404f5335b87/schemas/lockfile.schema.json\n z.object({\n version: z.string(),\n specifiers: LooseRecord(z.string()).catch({}),\n redirects: LooseRecord(z.string()).catch({}),\n remote: LooseRecord(z.string()).catch({}),\n }),\n).transform(({ version, specifiers, redirects, remote }) => {\n const lockedVersions: Record<string, string> = {};\n for (const [key, val] of Object.entries(specifiers)) {\n // pick \"7.1.3\" from \"7.1.3_pkgname@4.0.3_@types+pkgname@1.0.1\"\n const match = regEx(/^(?<lockedVersion>[^_\\s]+)/).exec(val);\n if (match?.groups?.lockedVersion) {\n lockedVersions[key] = match.groups.lockedVersion;\n }\n }\n\n const redirectVersions: Record<string, string> = {};\n for (const [key, val] of Object.entries(redirects)) {\n redirectVersions[key] = val;\n }\n\n const remoteVersions = new Set<string>();\n for (const key of Object.keys(remote)) {\n remoteVersions.add(key);\n }\n return {\n lockedVersions,\n redirectVersions,\n remoteVersions,\n lockfileVersion: parseInt(version, 10),\n };\n});\n\nexport const DenoDependency = z\n .object({\n depValue: z.string(),\n depType: z.string(),\n })\n .transform(({ depValue, depType }): PackageDependency<DenoManagerData> => {\n // deno datasource\n // Check for https://deno.land/x/ URLs first\n const denoLandMatch = denoLandRegex.exec(depValue);\n if (denoLandMatch?.groups?.rawPackageName) {\n return {\n datasource: 'deno',\n depType,\n depName: joinUrlParts(\n 'https://deno.land',\n denoLandMatch.groups.rawPackageName,\n ),\n currentValue: denoLandMatch.groups.currentValue,\n // set full URL for getLockedVersion\n currentRawValue: denoLandMatch[0],\n };\n }\n\n // other datasources\n\n const match = depValueRegex.exec(depValue);\n if (match?.groups?.datasource && match?.groups.depName) {\n const datasource = match.groups.datasource;\n const depName = match.groups.depName;\n const currentValue = match.groups.currentValue;\n const currentRawValue = match[0];\n // npm datasource\n if (datasource === 'npm') {\n const dep: PackageDependency = {\n datasource,\n versioning: denoVersioningId,\n };\n\n if (depName && !validateNpmPackageName(depName).validForOldPackages) {\n dep.skipReason = 'invalid-name';\n return dep;\n }\n\n if (currentValue && !isValid(currentValue)) {\n dep.skipReason = 'invalid-version';\n return dep;\n }\n return {\n ...dep,\n depName,\n currentValue,\n depType,\n currentRawValue,\n };\n }\n // jsr datasource\n if (datasource === 'jsr') {\n const dep: PackageDependency = {\n datasource,\n versioning: denoVersioningId,\n };\n\n if (depName && !extractJsrPackageName(depName)) {\n dep.skipReason = 'invalid-name';\n return dep;\n }\n\n if (currentValue && !isValid(currentValue)) {\n dep.skipReason = 'invalid-version';\n return dep;\n }\n return {\n ...dep,\n depName,\n currentValue,\n depType,\n currentRawValue,\n };\n }\n }\n\n return {\n depType,\n depName: depValue,\n skipStage: 'extract',\n skipReason: 'unsupported',\n };\n });\n\nexport const Imports = LooseRecord(z.string())\n .catch({})\n .transform((imports) =>\n Object.values(imports).map((depValue) => ({\n depValue,\n depType: 'imports',\n })),\n )\n .pipe(z.array(DenoDependency));\n\nexport const Scopes = LooseRecord(LooseRecord(z.string()))\n .catch({})\n .transform((scopes) =>\n Object.values(scopes).flatMap((scopeDependencies) =>\n Object.values(scopeDependencies).map((depValue) => ({\n depValue,\n depType: 'scopes',\n })),\n ),\n )\n .pipe(z.array(DenoDependency));\n\n/**\n * dependency in `tasks` can't sync lock file updating due to `deno install` is not supported\n */\nexport const Tasks = LooseRecord(\n z.union([\n z.string().transform((depValue) => ({ depValue, depType: 'tasks' })),\n z.object({ command: z.string() }).transform(({ command }) => ({\n depValue: command,\n depType: 'tasks.command',\n })),\n ]),\n)\n .catch({})\n .transform((tasks) =>\n Object.values(tasks).map(({ depValue, depType }) => ({\n depValue,\n depType,\n })),\n )\n .pipe(z.array(DenoDependency));\n\nexport const CompilerOptionsTypes = LooseArray(z.string())\n .catch([])\n .transform((types) =>\n types.map((depValue) => ({ depValue, depType: 'compilerOptions.types' })),\n )\n .pipe(z.array(DenoDependency));\n\nexport const CompilerOptionsJsxImportSource = z\n .union([\n z\n .string()\n .transform((depValue) => [\n { depValue, depType: 'compilerOptions.jsxImportSource' },\n ]),\n z.undefined().transform(() => []),\n ])\n .pipe(z.array(DenoDependency));\n\nexport const CompilerOptionsJsxImportSourceTypes = z\n .union([\n z\n .string()\n .transform((depValue) => [\n { depValue, depType: 'compilerOptions.jsxImportSourceTypes' },\n ]),\n z.undefined().transform(() => []),\n ])\n .pipe(z.array(DenoDependency));\n\nexport const Lint = z\n .object({\n plugins: LooseArray(z.string()).catch([]),\n })\n .transform((lint) =>\n lint.plugins.map((depValue) => ({ depValue, depType: 'lint.plugins' })),\n )\n .pipe(z.array(DenoDependency));\n\nexport const Lock = z.union([\n z.string().transform((path) => path),\n z.boolean().transform((enabled) => enabled && 'deno.lock'),\n z\n .object({\n path: z.string().optional(),\n })\n .transform((obj) => obj.path),\n]);\n\nexport const Workspace = z.union([\n z.array(z.string()).transform((workspaces) => workspaces),\n z\n .object({\n members: z.array(z.string()),\n })\n .transform((workspace) => workspace.members),\n]);\n\nconst DenoPackageFile = z\n .object({\n lock: z.optional(Lock),\n workspace: z.optional(Workspace),\n importMap: z.string().optional(),\n imports: z.optional(Imports).default([]),\n scopes: z.optional(Scopes).default([]),\n tasks: z.optional(Tasks).default([]),\n compilerOptions: z\n .optional(\n z.object({\n types: CompilerOptionsTypes,\n jsxImportSource: CompilerOptionsJsxImportSource,\n jsxImportSourceTypes: CompilerOptionsJsxImportSourceTypes,\n }),\n )\n .default({ types: [], jsxImportSource: [], jsxImportSourceTypes: [] }),\n lint: z.optional(Lint).default([]),\n })\n .transform(\n ({\n lock,\n imports,\n scopes,\n tasks,\n compilerOptions,\n lint,\n importMap,\n workspace,\n }) => ({\n lock,\n importMap,\n managerData: {\n workspaces: workspace,\n },\n dependencies: [\n ...imports,\n ...scopes,\n ...tasks,\n ...compilerOptions.types,\n ...compilerOptions.jsxImportSource,\n ...compilerOptions.jsxImportSourceTypes,\n ...lint,\n ],\n }),\n );\n\nexport const DenoExtract = z.object({\n content: Jsonc.pipe(DenoPackageFile),\n fileName: z.string(),\n});\nexport type DenoExtract = z.infer<typeof DenoExtract>;\n\nexport const ImportMapExtract = Json.pipe(\n z.object({\n imports: z.optional(Imports).default([]),\n scopes: z.optional(Scopes).default([]),\n }),\n).transform(({ imports, scopes }) => ({\n dependencies: [...imports, ...scopes],\n}));\nexport type ImportMapExtract = z.infer<typeof ImportMapExtract>;\n\n// All object needs passthrough to keep original field of package file and all field should be optional\nexport const UpdateDenoJsonFile = Jsonc.pipe(\n z\n .object({\n imports: z.record(z.string(), z.string()).optional(),\n scopes: z.record(z.string(), z.record(z.string(), z.string())).optional(),\n tasks: z\n .record(\n z.string(),\n z.union([\n z.string(),\n z.object({ command: z.string().optional() }).passthrough(),\n ]),\n )\n .optional(),\n compilerOptions: z\n .object({\n types: z.array(z.string()).optional(),\n jsxImportSource: z.string().optional(),\n jsxImportSourceTypes: z.string().optional(),\n })\n .passthrough()\n .optional(),\n lint: z\n .object({\n plugins: z.array(z.string()).optional(),\n })\n .passthrough()\n .optional(),\n })\n .passthrough(),\n);\nexport type UpdateDenoJsonFile = z.infer<typeof UpdateDenoJsonFile>;\n\n// All object needs passthrough to keep original field of package file and all field should be optional\nexport const UpdateImportMapJsonFile = Json.pipe(\n z\n .object({\n imports: z.record(z.string(), z.string()).optional(),\n scopes: z.record(z.string(), z.record(z.string(), z.string())).optional(),\n })\n .passthrough(),\n);\nexport type UpdateImportMapJsonFile = z.infer<typeof UpdateImportMapJsonFile>;\n"],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","names":["denoVersioningId"],"sources":["../../../../lib/modules/manager/deno/schema.ts"],"sourcesContent":["import validateNpmPackageName from 'validate-npm-package-name';\nimport { z } from 'zod/v4';\nimport { regEx } from '../../../util/regex.ts';\nimport {\n Json,\n Jsonc,\n LooseArray,\n LooseRecord,\n} from '../../../util/schema-utils/index.ts';\nimport { joinUrlParts } from '../../../util/url.ts';\nimport { extractJsrPackageName } from '../../datasource/jsr/util.ts';\nimport {\n id as denoVersioningId,\n isValid,\n} from '../../versioning/deno/index.ts';\nimport type { PackageDependency } from '../types.ts';\nimport type { DenoManagerData } from './types.ts';\nimport { denoLandRegex, depValueRegex } from './utils.ts';\n\nexport const DenoLock = Json.pipe(\n // this schema is version 5\n // https://github.com/denoland/vscode_deno/blob/7e125c6ffcdcdebd587f97be5341d404f5335b87/schemas/lockfile.schema.json\n z.object({\n version: z.string(),\n specifiers: LooseRecord(z.string()).catch({}),\n redirects: LooseRecord(z.string()).catch({}),\n remote: LooseRecord(z.string()).catch({}),\n }),\n).transform(({ version, specifiers, redirects, remote }) => {\n const lockedVersions: Record<string, string> = {};\n for (const [key, val] of Object.entries(specifiers)) {\n // pick \"7.1.3\" from \"7.1.3_pkgname@4.0.3_@types+pkgname@1.0.1\"\n const match = regEx(/^(?<lockedVersion>[^_\\s]+)/).exec(val);\n if (match?.groups?.lockedVersion) {\n lockedVersions[key] = match.groups.lockedVersion;\n }\n }\n\n const redirectVersions: Record<string, string> = {};\n for (const [key, val] of Object.entries(redirects)) {\n redirectVersions[key] = val;\n }\n\n const remoteVersions = new Set<string>();\n for (const key of Object.keys(remote)) {\n remoteVersions.add(key);\n }\n return {\n lockedVersions,\n redirectVersions,\n remoteVersions,\n lockfileVersion: parseInt(version, 10),\n };\n});\n\nexport const DenoDependency = z\n .object({\n depValue: z.string(),\n depType: z.string(),\n })\n .transform(({ depValue, depType }): PackageDependency<DenoManagerData> => {\n // deno datasource\n // Check for https://deno.land/x/ URLs first\n const denoLandMatch = denoLandRegex.exec(depValue);\n if (denoLandMatch?.groups?.rawPackageName) {\n return {\n datasource: 'deno',\n depType,\n depName: joinUrlParts(\n 'https://deno.land',\n denoLandMatch.groups.rawPackageName,\n ),\n currentValue: denoLandMatch.groups.currentValue,\n // set full URL for getLockedVersion\n currentRawValue: denoLandMatch[0],\n };\n }\n\n // other datasources\n\n const match = depValueRegex.exec(depValue);\n if (match?.groups?.datasource && match?.groups.depName) {\n const datasource = match.groups.datasource;\n const depName = match.groups.depName;\n const currentValue = match.groups.currentValue;\n const currentRawValue = match[0];\n // npm datasource\n if (datasource === 'npm') {\n const dep: PackageDependency = {\n datasource,\n versioning: denoVersioningId,\n };\n\n if (depName && !validateNpmPackageName(depName).validForOldPackages) {\n dep.skipReason = 'invalid-name';\n return dep;\n }\n\n if (currentValue && !isValid(currentValue)) {\n dep.skipReason = 'invalid-version';\n return dep;\n }\n return {\n ...dep,\n depName,\n currentValue,\n depType,\n currentRawValue,\n };\n }\n // jsr datasource\n if (datasource === 'jsr') {\n const dep: PackageDependency = {\n datasource,\n versioning: denoVersioningId,\n };\n\n if (depName && !extractJsrPackageName(depName)) {\n dep.skipReason = 'invalid-name';\n return dep;\n }\n\n if (currentValue && !isValid(currentValue)) {\n dep.skipReason = 'invalid-version';\n return dep;\n }\n return {\n ...dep,\n depName,\n currentValue,\n depType,\n currentRawValue,\n };\n }\n }\n\n return {\n depType,\n depName: depValue,\n skipStage: 'extract',\n skipReason: 'unsupported',\n };\n });\n\nexport const Imports = LooseRecord(z.string())\n .catch({})\n .transform((imports) =>\n Object.values(imports).map((depValue) => ({\n depValue,\n depType: 'imports',\n })),\n )\n .pipe(z.array(DenoDependency));\n\nexport const Scopes = LooseRecord(LooseRecord(z.string()))\n .catch({})\n .transform((scopes) =>\n Object.values(scopes).flatMap((scopeDependencies) =>\n Object.values(scopeDependencies).map((depValue) => ({\n depValue,\n depType: 'scopes',\n })),\n ),\n )\n .pipe(z.array(DenoDependency));\n\n/**\n * dependency in `tasks` can't sync lock file updating due to `deno install` is not supported\n */\nexport const Tasks = LooseRecord(\n z.union([\n z.string().transform((depValue) => ({ depValue, depType: 'tasks' })),\n z.object({ command: z.string() }).transform(({ command }) => ({\n depValue: command,\n depType: 'tasks.command',\n })),\n ]),\n)\n .catch({})\n .transform((tasks) =>\n Object.values(tasks).map(({ depValue, depType }) => ({\n depValue,\n depType,\n })),\n )\n .pipe(z.array(DenoDependency));\n\nexport const CompilerOptionsTypes = LooseArray(z.string())\n .catch([])\n .transform((types) =>\n types.map((depValue) => ({ depValue, depType: 'compilerOptions.types' })),\n )\n .pipe(z.array(DenoDependency));\n\nexport const CompilerOptionsJsxImportSource = z\n .union([\n z\n .string()\n .transform((depValue) => [\n { depValue, depType: 'compilerOptions.jsxImportSource' },\n ]),\n z.undefined().transform(() => []),\n ])\n .pipe(z.array(DenoDependency));\n\nexport const CompilerOptionsJsxImportSourceTypes = z\n .union([\n z\n .string()\n .transform((depValue) => [\n { depValue, depType: 'compilerOptions.jsxImportSourceTypes' },\n ]),\n z.undefined().transform(() => []),\n ])\n .pipe(z.array(DenoDependency));\n\nexport const Lint = z\n .object({\n plugins: LooseArray(z.string()).catch([]),\n })\n .transform((lint) =>\n lint.plugins.map((depValue) => ({ depValue, depType: 'lint.plugins' })),\n )\n .pipe(z.array(DenoDependency));\n\nexport const Lock = z.union([\n z.string().transform((path) => path),\n z.boolean().transform((enabled) => enabled && 'deno.lock'),\n z\n .object({\n path: z.string().optional(),\n })\n .transform((obj) => obj.path),\n]);\n\nexport const Workspace = z.union([\n z.array(z.string()).transform((workspaces) => workspaces),\n z\n .object({\n members: z.array(z.string()),\n })\n .transform((workspace) => workspace.members),\n]);\n\nconst DenoPackageFile = z\n .object({\n lock: z.optional(Lock),\n workspace: z.optional(Workspace),\n importMap: z.string().optional(),\n imports: z.optional(Imports).default([]),\n scopes: z.optional(Scopes).default([]),\n tasks: z.optional(Tasks).default([]),\n compilerOptions: z\n .optional(\n z.object({\n types: CompilerOptionsTypes,\n jsxImportSource: CompilerOptionsJsxImportSource.optional().default(\n [],\n ),\n jsxImportSourceTypes:\n CompilerOptionsJsxImportSourceTypes.optional().default([]),\n }),\n )\n .default({ types: [], jsxImportSource: [], jsxImportSourceTypes: [] }),\n lint: z.optional(Lint).default([]),\n })\n .transform(\n ({\n lock,\n imports,\n scopes,\n tasks,\n compilerOptions,\n lint,\n importMap,\n workspace,\n }) => ({\n lock,\n importMap,\n managerData: {\n workspaces: workspace,\n },\n dependencies: [\n ...imports,\n ...scopes,\n ...tasks,\n ...compilerOptions.types,\n ...compilerOptions.jsxImportSource,\n ...compilerOptions.jsxImportSourceTypes,\n ...lint,\n ],\n }),\n );\n\nexport const DenoExtract = z.object({\n content: Jsonc.pipe(DenoPackageFile),\n fileName: z.string(),\n});\nexport type DenoExtract = z.infer<typeof DenoExtract>;\n\nexport const ImportMapExtract = Json.pipe(\n z.object({\n imports: z.optional(Imports).default([]),\n scopes: z.optional(Scopes).default([]),\n }),\n).transform(({ imports, scopes }) => ({\n dependencies: [...imports, ...scopes],\n}));\nexport type ImportMapExtract = z.infer<typeof ImportMapExtract>;\n\n// All object needs passthrough to keep original field of package file and all field should be optional\nexport const UpdateDenoJsonFile = Jsonc.pipe(\n z\n .object({\n imports: z.record(z.string(), z.string()).optional(),\n scopes: z.record(z.string(), z.record(z.string(), z.string())).optional(),\n tasks: z\n .record(\n z.string(),\n z.union([\n z.string(),\n z.object({ command: z.string().optional() }).passthrough(),\n ]),\n )\n .optional(),\n compilerOptions: z\n .object({\n types: z.array(z.string()).optional(),\n jsxImportSource: z.string().optional(),\n jsxImportSourceTypes: z.string().optional(),\n })\n .passthrough()\n .optional(),\n lint: z\n .object({\n plugins: z.array(z.string()).optional(),\n })\n .passthrough()\n .optional(),\n })\n .passthrough(),\n);\nexport type UpdateDenoJsonFile = z.infer<typeof UpdateDenoJsonFile>;\n\n// All object needs passthrough to keep original field of package file and all field should be optional\nexport const UpdateImportMapJsonFile = Json.pipe(\n z\n .object({\n imports: z.record(z.string(), z.string()).optional(),\n scopes: z.record(z.string(), z.record(z.string(), z.string())).optional(),\n })\n .passthrough(),\n);\nexport type UpdateImportMapJsonFile = z.infer<typeof UpdateImportMapJsonFile>;\n"],"mappings":"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"}
@@ -31,7 +31,7 @@ hashMap.set("copier", "b26904512023c7785e86ee57744f16b336a380ae80d2b85924bf7c30e
31
31
  hashMap.set("cpanfile", "6a1d67d9c8751123deaf0c7f3ac38a07024e960c140f8228fcbcb93954fdca01");
32
32
  hashMap.set("crossplane", "5c26b1201a1a51454ffb94d829e223a76a781569bf79cdb1e47087c30233ec40");
33
33
  hashMap.set("crow", "eb9a5f9f95041855dded67bcce3dd54724f690995ed6268d272e8a666ff28fd0");
34
- hashMap.set("deno", "2d79ef509b7249a318e94e5dacd8e13a945f2b44007b9a17438a2c915b596120");
34
+ hashMap.set("deno", "4c9fd606dd598a4e0bd5cb4b679738ff67e75ba269ca021d90b4f661429cb2ac");
35
35
  hashMap.set("deps-edn", "c87dd5e88587147ad1a78f047b814f3c4aa60d6de30d0c49d849391eeaf1b64c");
36
36
  hashMap.set("devbox", "ac472ae4897dc1df85326dbd89a8c3488579ae2b180014ffcf085ce422e19dbd");
37
37
  hashMap.set("devcontainer", "24320ed1cb6191d04cb8b2707214d82c08c682597aed1d84f250aa00ad1632ec");