renovate 43.228.0 → 43.228.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,7 +13,7 @@ import { parseGitUrl } from "../../../util/git/url.js";
13
13
  import { memCacheProvider } from "../../../util/http/cache/memory-http-cache-provider.js";
14
14
  import { getGoogleAuthToken } from "../util.js";
15
15
  import { BearerScheme, parse } from "../../../util/http/www-authenticate.js";
16
- import { ecrRegex, getECRAuthToken } from "./ecr.js";
16
+ import { ecrRegex, getECRAuthToken, isECRMaxResultsResponse } from "./ecr.js";
17
17
  import { googleRegex } from "./google.js";
18
18
  import { RegistryAuthToken } from "./schema.js";
19
19
  import { isNonEmptyString, isString } from "@sindresorhus/is";
@@ -43,6 +43,10 @@ async function getAuthHeaders(http, registryHost, dockerRepository, apiCheckUrl
43
43
  logger.debug(`Page Not Found ${apiCheckUrl}`);
44
44
  throw new Error(PAGE_NOT_FOUND_ERROR);
45
45
  }
46
+ if (isECRMaxResultsResponse(apiCheckResponse)) {
47
+ logger.debug({ apiCheckUrl }, "Registry rejected n>1000 on auth probe; retrying auth check via base /v2/ endpoint");
48
+ return getAuthHeaders(http, registryHost, dockerRepository);
49
+ }
46
50
  if (apiCheckResponse.statusCode !== 401 || !isNonEmptyString(apiCheckResponse.headers["www-authenticate"])) {
47
51
  logger.warn({
48
52
  apiCheckUrl,
@@ -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 { 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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"}
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, isECRMaxResultsResponse } 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 // Some ECR-compatible private registries (e.g. corporate Docker proxies) reject\n // n>1000 with 405 even on the auth-probe request. Fall back to probing the base\n // /v2/ endpoint so getAuthHeaders can still obtain a valid token; the main fetch\n // loop already retries with n=1000 when it encounters this same error.\n if (isECRMaxResultsResponse(apiCheckResponse)) {\n logger.debug(\n { apiCheckUrl },\n 'Registry rejected n>1000 on auth probe; retrying auth check via base /v2/ endpoint',\n );\n return getAuthHeaders(http, registryHost, dockerRepository);\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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"}
@@ -32,11 +32,15 @@ async function getECRAuthToken(region, opts) {
32
32
  }
33
33
  return null;
34
34
  }
35
+ function isECRMaxResultsResponse(resp) {
36
+ const body = resp.body;
37
+ return !!(resp.statusCode === 405 && resp.headers?.["docker-distribution-api-version"] && body?.errors?.[0]?.message?.includes("Member must have value less than or equal to 1000"));
38
+ }
35
39
  function isECRMaxResultsError(err) {
36
40
  const resp = err.response;
37
- return !!(resp?.statusCode === 405 && resp.headers?.["docker-distribution-api-version"] && resp.body?.errors?.[0]?.message?.includes("Member must have value less than or equal to 1000"));
41
+ return !!resp && isECRMaxResultsResponse(resp);
38
42
  }
39
43
  //#endregion
40
- export { ecrPublicRegex, ecrRegex, getECRAuthToken, isECRMaxResultsError };
44
+ export { ecrPublicRegex, ecrRegex, getECRAuthToken, isECRMaxResultsError, isECRMaxResultsResponse };
41
45
 
42
46
  //# sourceMappingURL=ecr.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ecr.js","names":[],"sources":["../../../../lib/modules/datasource/docker/ecr.ts"],"sourcesContent":["import type { ECRClientConfig } from '@aws-sdk/client-ecr';\nimport { ECR } from '@aws-sdk/client-ecr';\nimport { logger } from '../../../logger/index.ts';\nimport type { HostRule } from '../../../types/index.ts';\nimport type { HttpError } from '../../../util/http/index.ts';\nimport type { HttpResponse } from '../../../util/http/types.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { addSecretForSanitizing } from '../../../util/sanitize.ts';\n\nexport const ecrRegex = regEx(\n /\\d+\\.(?:dkr\\.ecr|dkr-ecr)(?:-fips)?\\.([-a-z0-9]+)\\.(?:amazonaws\\.com|on\\.aws)/,\n);\nexport const ecrPublicRegex = regEx(/public\\.ecr\\.aws|ecr-public\\.aws\\.com/);\n\nexport async function getECRAuthToken(\n region: string,\n opts: HostRule,\n): Promise<string | null> {\n const config: ECRClientConfig = { region };\n if (opts.username === `AWS` && opts.password) {\n logger.trace(\n `AWS user specified, encoding basic auth credentials for ECR registry`,\n );\n return Buffer.from(`AWS:${opts.password}`).toString('base64');\n } else if (opts.username && opts.password) {\n logger.trace(\n `Using AWS accessKey to get Authorization token for ECR registry`,\n );\n config.credentials = {\n accessKeyId: opts.username,\n secretAccessKey: opts.password,\n ...(opts.token && { sessionToken: opts.token }),\n };\n }\n\n const ecr = new ECR(config);\n try {\n const data = await ecr.getAuthorizationToken({});\n const authorizationToken = data?.authorizationData?.[0]?.authorizationToken;\n if (authorizationToken) {\n // sanitize token\n addSecretForSanitizing(authorizationToken);\n return authorizationToken;\n }\n logger.warn(\n 'Could not extract authorizationToken from ECR getAuthorizationToken response',\n );\n } catch (err) {\n logger.trace({ err }, 'err');\n logger.warn('ECR getAuthorizationToken error');\n }\n return null;\n}\n\nexport function isECRMaxResultsError(err: HttpError): boolean {\n const resp = err.response as HttpResponse<any> | undefined;\n return !!(\n resp?.statusCode === 405 &&\n resp.headers?.['docker-distribution-api-version'] &&\n // https://docs.aws.amazon.com/AmazonECR/latest/APIReference/API_DescribeRepositories.html#ECR-DescribeRepositories-request-maxResults\n resp.body?.errors?.[0]?.message?.includes(\n 'Member must have value less than or equal to 1000',\n )\n );\n}\n"],"mappings":";;;;;AASA,MAAa,WAAW,MACtB,+EACF;AACA,MAAa,iBAAiB,MAAM,uCAAuC;AAE3E,eAAsB,gBACpB,QACA,MACwB;CACxB,MAAM,SAA0B,EAAE,OAAO;CACzC,IAAI,KAAK,aAAa,SAAS,KAAK,UAAU;EAC5C,OAAO,MACL,sEACF;EACA,OAAO,OAAO,KAAK,OAAO,KAAK,UAAU,CAAC,CAAC,SAAS,QAAQ;CAC9D,OAAO,IAAI,KAAK,YAAY,KAAK,UAAU;EACzC,OAAO,MACL,iEACF;EACA,OAAO,cAAc;GACnB,aAAa,KAAK;GAClB,iBAAiB,KAAK;GACtB,GAAI,KAAK,SAAS,EAAE,cAAc,KAAK,MAAM;EAC/C;CACF;CAEA,MAAM,MAAM,IAAI,IAAI,MAAM;CAC1B,IAAI;EAEF,MAAM,sBAAqB,MADR,IAAI,sBAAsB,CAAC,CAAC,EAAA,EACd,oBAAoB,EAAE,EAAE;EACzD,IAAI,oBAAoB;GAEtB,uBAAuB,kBAAkB;GACzC,OAAO;EACT;EACA,OAAO,KACL,8EACF;CACF,SAAS,KAAK;EACZ,OAAO,MAAM,EAAE,IAAI,GAAG,KAAK;EAC3B,OAAO,KAAK,iCAAiC;CAC/C;CACA,OAAO;AACT;AAEA,SAAgB,qBAAqB,KAAyB;CAC5D,MAAM,OAAO,IAAI;CACjB,OAAO,CAAC,EACN,MAAM,eAAe,OACrB,KAAK,UAAU,sCAEf,KAAK,MAAM,SAAS,EAAE,EAAE,SAAS,SAC/B,mDACF;AAEJ"}
1
+ {"version":3,"file":"ecr.js","names":[],"sources":["../../../../lib/modules/datasource/docker/ecr.ts"],"sourcesContent":["import type { ECRClientConfig } from '@aws-sdk/client-ecr';\nimport { ECR } from '@aws-sdk/client-ecr';\nimport { logger } from '../../../logger/index.ts';\nimport type { HostRule } from '../../../types/index.ts';\nimport type { HttpError } from '../../../util/http/index.ts';\nimport type { HttpResponse } from '../../../util/http/types.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { addSecretForSanitizing } from '../../../util/sanitize.ts';\n\nexport const ecrRegex = regEx(\n /\\d+\\.(?:dkr\\.ecr|dkr-ecr)(?:-fips)?\\.([-a-z0-9]+)\\.(?:amazonaws\\.com|on\\.aws)/,\n);\nexport const ecrPublicRegex = regEx(/public\\.ecr\\.aws|ecr-public\\.aws\\.com/);\n\nexport async function getECRAuthToken(\n region: string,\n opts: HostRule,\n): Promise<string | null> {\n const config: ECRClientConfig = { region };\n if (opts.username === `AWS` && opts.password) {\n logger.trace(\n `AWS user specified, encoding basic auth credentials for ECR registry`,\n );\n return Buffer.from(`AWS:${opts.password}`).toString('base64');\n } else if (opts.username && opts.password) {\n logger.trace(\n `Using AWS accessKey to get Authorization token for ECR registry`,\n );\n config.credentials = {\n accessKeyId: opts.username,\n secretAccessKey: opts.password,\n ...(opts.token && { sessionToken: opts.token }),\n };\n }\n\n const ecr = new ECR(config);\n try {\n const data = await ecr.getAuthorizationToken({});\n const authorizationToken = data?.authorizationData?.[0]?.authorizationToken;\n if (authorizationToken) {\n // sanitize token\n addSecretForSanitizing(authorizationToken);\n return authorizationToken;\n }\n logger.warn(\n 'Could not extract authorizationToken from ECR getAuthorizationToken response',\n );\n } catch (err) {\n logger.trace({ err }, 'err');\n logger.warn('ECR getAuthorizationToken error');\n }\n return null;\n}\n\n// https://docs.aws.amazon.com/AmazonECR/latest/APIReference/API_DescribeRepositories.html#ECR-DescribeRepositories-request-maxResults\nexport function isECRMaxResultsResponse(resp: HttpResponse<unknown>): boolean {\n const body = resp.body as { errors?: { message?: string }[] } | undefined;\n return !!(\n resp.statusCode === 405 &&\n resp.headers?.['docker-distribution-api-version'] &&\n body?.errors?.[0]?.message?.includes(\n 'Member must have value less than or equal to 1000',\n )\n );\n}\n\nexport function isECRMaxResultsError(err: HttpError): boolean {\n const resp = err.response as HttpResponse<unknown> | undefined;\n return !!resp && isECRMaxResultsResponse(resp);\n}\n"],"mappings":";;;;;AASA,MAAa,WAAW,MACtB,+EACF;AACA,MAAa,iBAAiB,MAAM,uCAAuC;AAE3E,eAAsB,gBACpB,QACA,MACwB;CACxB,MAAM,SAA0B,EAAE,OAAO;CACzC,IAAI,KAAK,aAAa,SAAS,KAAK,UAAU;EAC5C,OAAO,MACL,sEACF;EACA,OAAO,OAAO,KAAK,OAAO,KAAK,UAAU,CAAC,CAAC,SAAS,QAAQ;CAC9D,OAAO,IAAI,KAAK,YAAY,KAAK,UAAU;EACzC,OAAO,MACL,iEACF;EACA,OAAO,cAAc;GACnB,aAAa,KAAK;GAClB,iBAAiB,KAAK;GACtB,GAAI,KAAK,SAAS,EAAE,cAAc,KAAK,MAAM;EAC/C;CACF;CAEA,MAAM,MAAM,IAAI,IAAI,MAAM;CAC1B,IAAI;EAEF,MAAM,sBAAqB,MADR,IAAI,sBAAsB,CAAC,CAAC,EAAA,EACd,oBAAoB,EAAE,EAAE;EACzD,IAAI,oBAAoB;GAEtB,uBAAuB,kBAAkB;GACzC,OAAO;EACT;EACA,OAAO,KACL,8EACF;CACF,SAAS,KAAK;EACZ,OAAO,MAAM,EAAE,IAAI,GAAG,KAAK;EAC3B,OAAO,KAAK,iCAAiC;CAC/C;CACA,OAAO;AACT;AAGA,SAAgB,wBAAwB,MAAsC;CAC5E,MAAM,OAAO,KAAK;CAClB,OAAO,CAAC,EACN,KAAK,eAAe,OACpB,KAAK,UAAU,sCACf,MAAM,SAAS,EAAE,EAAE,SAAS,SAC1B,mDACF;AAEJ;AAEA,SAAgB,qBAAqB,KAAyB;CAC5D,MAAM,OAAO,IAAI;CACjB,OAAO,CAAC,CAAC,QAAQ,wBAAwB,IAAI;AAC/C"}
@@ -26,7 +26,7 @@ const RepoContents = z.discriminatedUnion("type", [
26
26
  const ContentsListResponse = z.array(RepoContents);
27
27
  const User = DeepNullish(z.object({
28
28
  id: z.number(),
29
- email: EmailAddress.optional(),
29
+ email: EmailAddress.optional().catch(void 0),
30
30
  full_name: z.string().optional(),
31
31
  login: z.string()
32
32
  }));
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","names":[],"sources":["../../../../lib/modules/platform/forgejo/schema.ts"],"sourcesContent":["import { z } from 'zod/v4';\nimport { LongCommitSha } from '../../../util/schema-utils/git.ts';\nimport {\n DeepNullish,\n EmailAddress,\n LooseArray,\n} from '../../../util/schema-utils/index.ts';\nimport { fromBase64 } from '../../../util/string.ts';\n\nconst ContentsCommon = z.object({\n name: z.string(),\n path: z.string(),\n});\n\nconst ContentsFile = ContentsCommon.extend({\n type: z.literal('file'),\n content: z.string().nullable(),\n}).transform((input) => ({\n ...input,\n contentString: input.content ? fromBase64(input.content) : '',\n}));\n\nconst ContentsDir = ContentsCommon.extend({ type: z.literal('dir') });\nconst ContentsSymlink = ContentsCommon.extend({ type: z.literal('symlink') });\nconst ContentsSubmodule = ContentsCommon.extend({\n type: z.literal('submodule'),\n});\n\nexport const RepoContents = z.discriminatedUnion('type', [\n ContentsFile,\n ContentsDir,\n ContentsSymlink,\n ContentsSubmodule,\n]);\nexport type RepoContents = z.infer<typeof RepoContents>;\n\nexport const ContentsListResponse = z.array(RepoContents);\n\nexport const User = DeepNullish(\n z.object({\n id: z.number(),\n email: EmailAddress.optional(),\n full_name: z.string().optional(),\n login: z.string(),\n }),\n);\nexport type User = z.infer<typeof User>;\n\nexport const RepoPermission = z.object({\n admin: z.boolean(),\n pull: z.boolean(),\n push: z.boolean(),\n});\nexport type RepoPermission = z.infer<typeof RepoPermission>;\n\nexport const PRMergeMethod = z.enum([\n 'fast-forward-only',\n 'merge',\n 'rebase',\n 'rebase-merge',\n 'squash',\n]);\nexport type PRMergeMethod = z.infer<typeof PRMergeMethod>;\n\n// Lenient Repo schema - only validates fields Renovate reads, most are optional\nexport const Repo = DeepNullish(\n z.object({\n id: z.number(),\n allow_fast_forward_only_merge: z.boolean().default(false),\n allow_merge_commits: z.boolean().default(false),\n allow_rebase: z.boolean().default(false),\n allow_rebase_explicit: z.boolean().default(false),\n allow_squash_merge: z.boolean().default(false),\n archived: z.boolean().optional(),\n clone_url: z.string().optional(),\n // catch unknown merge methods e.g. `manually-merged`\n default_merge_style: PRMergeMethod.optional().catch(undefined),\n external_tracker: z.unknown().optional(),\n has_issues: z.boolean().optional().default(false),\n has_pull_requests: z.boolean().optional(),\n ssh_url: z.string().optional(),\n default_branch: z.string(),\n empty: z.boolean().optional(),\n fork: z.boolean().optional(),\n full_name: z.string(),\n mirror: z.boolean().optional(),\n owner: User,\n permissions: RepoPermission,\n }),\n);\nexport type Repo = z.infer<typeof Repo>;\n\nexport const Label = DeepNullish(\n z.object({\n id: z.number(),\n name: z.string(),\n description: z.string().optional(),\n color: z.string().optional(),\n }),\n);\nexport type Label = z.infer<typeof Label>;\n\nexport const PRState = z.enum(['open', 'closed', 'all']);\nexport type PRState = z.infer<typeof PRState>;\n\nexport const IssueState = z.enum(['open', 'closed', 'all']);\nexport type IssueState = z.infer<typeof IssueState>;\n\n// Lenient partial repo schema for embedded repo references in PRs (only full_name is read)\nconst PartialRepo = z.object({\n full_name: z.string(),\n});\n\nexport const PR = DeepNullish(\n z.object({\n number: z.number(),\n state: PRState,\n title: z.string(),\n body: z.string(),\n mergeable: z.boolean(),\n merged: z.boolean().optional(),\n created_at: z.string(),\n updated_at: z.string(),\n closed_at: z.string().optional(),\n diff_url: z.string().optional(),\n base: z\n .object({\n ref: z.string(),\n })\n .optional(),\n head: z\n .object({\n label: z.string(),\n sha: LongCommitSha,\n repo: PartialRepo.optional(),\n })\n .optional(),\n assignee: User.optional(),\n assignees: z.array(User).optional(),\n user: User.optional(),\n labels: z.array(Label).optional(),\n }),\n);\nexport type PR = z.infer<typeof PR>;\n\n// TODO remove when the TEMPORARY_ERROR in pr-cache.ts is no longer needed\nexport const NullablePR = PR.nullable();\n\nexport const PRList = LooseArray(NullablePR);\n\nexport const Issue = DeepNullish(\n z.object({\n number: z.number(),\n state: IssueState.optional(),\n title: z.string(),\n body: z.string(),\n assignees: z.array(User).optional(),\n labels: z.array(Label).optional(),\n }),\n);\nexport type Issue = z.infer<typeof Issue>;\n\nexport const Comment = z.object({\n id: z.number(),\n body: z.string(),\n});\nexport type Comment = z.infer<typeof Comment>;\n\nexport const CommitStatusType = z\n .enum(['pending', 'success', 'error', 'failure', 'warning', 'unknown'])\n .catch('unknown');\nexport type CommitStatusType = z.infer<typeof CommitStatusType>;\n\nexport const CommitStatus = DeepNullish(\n z.object({\n id: z.number(),\n status: CommitStatusType,\n context: z.string(),\n description: z.string().optional(),\n target_url: z.string().optional(),\n created_at: z.string(),\n }),\n);\nexport type CommitStatus = z.infer<typeof CommitStatus>;\n\nexport const Commit = z.object({\n id: z.string(),\n});\nexport type Commit = z.infer<typeof Commit>;\n\nexport const Branch = z.object({\n name: z.string(),\n commit: Commit,\n});\nexport type Branch = z.infer<typeof Branch>;\n\nexport const RepoSearchResults = z.object({\n ok: z.boolean(),\n data: z.array(Repo),\n});\n\nexport const Version = z.object({\n version: z.string(),\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","names":[],"sources":["../../../../lib/modules/platform/forgejo/schema.ts"],"sourcesContent":["import { z } from 'zod/v4';\nimport { LongCommitSha } from '../../../util/schema-utils/git.ts';\nimport {\n DeepNullish,\n EmailAddress,\n LooseArray,\n} from '../../../util/schema-utils/index.ts';\nimport { fromBase64 } from '../../../util/string.ts';\n\nconst ContentsCommon = z.object({\n name: z.string(),\n path: z.string(),\n});\n\nconst ContentsFile = ContentsCommon.extend({\n type: z.literal('file'),\n content: z.string().nullable(),\n}).transform((input) => ({\n ...input,\n contentString: input.content ? fromBase64(input.content) : '',\n}));\n\nconst ContentsDir = ContentsCommon.extend({ type: z.literal('dir') });\nconst ContentsSymlink = ContentsCommon.extend({ type: z.literal('symlink') });\nconst ContentsSubmodule = ContentsCommon.extend({\n type: z.literal('submodule'),\n});\n\nexport const RepoContents = z.discriminatedUnion('type', [\n ContentsFile,\n ContentsDir,\n ContentsSymlink,\n ContentsSubmodule,\n]);\nexport type RepoContents = z.infer<typeof RepoContents>;\n\nexport const ContentsListResponse = z.array(RepoContents);\n\nexport const User = DeepNullish(\n z.object({\n id: z.number(),\n // catch empty strings which are returned if an organization has no email\n email: EmailAddress.optional().catch(undefined),\n full_name: z.string().optional(),\n login: z.string(),\n }),\n);\nexport type User = z.infer<typeof User>;\n\nexport const RepoPermission = z.object({\n admin: z.boolean(),\n pull: z.boolean(),\n push: z.boolean(),\n});\nexport type RepoPermission = z.infer<typeof RepoPermission>;\n\nexport const PRMergeMethod = z.enum([\n 'fast-forward-only',\n 'merge',\n 'rebase',\n 'rebase-merge',\n 'squash',\n]);\nexport type PRMergeMethod = z.infer<typeof PRMergeMethod>;\n\n// Lenient Repo schema - only validates fields Renovate reads, most are optional\nexport const Repo = DeepNullish(\n z.object({\n id: z.number(),\n allow_fast_forward_only_merge: z.boolean().default(false),\n allow_merge_commits: z.boolean().default(false),\n allow_rebase: z.boolean().default(false),\n allow_rebase_explicit: z.boolean().default(false),\n allow_squash_merge: z.boolean().default(false),\n archived: z.boolean().optional(),\n clone_url: z.string().optional(),\n // catch unknown merge methods e.g. `manually-merged`\n default_merge_style: PRMergeMethod.optional().catch(undefined),\n external_tracker: z.unknown().optional(),\n has_issues: z.boolean().optional().default(false),\n has_pull_requests: z.boolean().optional(),\n ssh_url: z.string().optional(),\n default_branch: z.string(),\n empty: z.boolean().optional(),\n fork: z.boolean().optional(),\n full_name: z.string(),\n mirror: z.boolean().optional(),\n owner: User,\n permissions: RepoPermission,\n }),\n);\nexport type Repo = z.infer<typeof Repo>;\n\nexport const Label = DeepNullish(\n z.object({\n id: z.number(),\n name: z.string(),\n description: z.string().optional(),\n color: z.string().optional(),\n }),\n);\nexport type Label = z.infer<typeof Label>;\n\nexport const PRState = z.enum(['open', 'closed', 'all']);\nexport type PRState = z.infer<typeof PRState>;\n\nexport const IssueState = z.enum(['open', 'closed', 'all']);\nexport type IssueState = z.infer<typeof IssueState>;\n\n// Lenient partial repo schema for embedded repo references in PRs (only full_name is read)\nconst PartialRepo = z.object({\n full_name: z.string(),\n});\n\nexport const PR = DeepNullish(\n z.object({\n number: z.number(),\n state: PRState,\n title: z.string(),\n body: z.string(),\n mergeable: z.boolean(),\n merged: z.boolean().optional(),\n created_at: z.string(),\n updated_at: z.string(),\n closed_at: z.string().optional(),\n diff_url: z.string().optional(),\n base: z\n .object({\n ref: z.string(),\n })\n .optional(),\n head: z\n .object({\n label: z.string(),\n sha: LongCommitSha,\n repo: PartialRepo.optional(),\n })\n .optional(),\n assignee: User.optional(),\n assignees: z.array(User).optional(),\n user: User.optional(),\n labels: z.array(Label).optional(),\n }),\n);\nexport type PR = z.infer<typeof PR>;\n\n// TODO remove when the TEMPORARY_ERROR in pr-cache.ts is no longer needed\nexport const NullablePR = PR.nullable();\n\nexport const PRList = LooseArray(NullablePR);\n\nexport const Issue = DeepNullish(\n z.object({\n number: z.number(),\n state: IssueState.optional(),\n title: z.string(),\n body: z.string(),\n assignees: z.array(User).optional(),\n labels: z.array(Label).optional(),\n }),\n);\nexport type Issue = z.infer<typeof Issue>;\n\nexport const Comment = z.object({\n id: z.number(),\n body: z.string(),\n});\nexport type Comment = z.infer<typeof Comment>;\n\nexport const CommitStatusType = z\n .enum(['pending', 'success', 'error', 'failure', 'warning', 'unknown'])\n .catch('unknown');\nexport type CommitStatusType = z.infer<typeof CommitStatusType>;\n\nexport const CommitStatus = DeepNullish(\n z.object({\n id: z.number(),\n status: CommitStatusType,\n context: z.string(),\n description: z.string().optional(),\n target_url: z.string().optional(),\n created_at: z.string(),\n }),\n);\nexport type CommitStatus = z.infer<typeof CommitStatus>;\n\nexport const Commit = z.object({\n id: z.string(),\n});\nexport type Commit = z.infer<typeof Commit>;\n\nexport const Branch = z.object({\n name: z.string(),\n commit: Commit,\n});\nexport type Branch = z.infer<typeof Branch>;\n\nexport const RepoSearchResults = z.object({\n ok: z.boolean(),\n data: z.array(Repo),\n});\n\nexport const Version = z.object({\n version: z.string(),\n});\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "renovate",
3
3
  "description": "Automated dependency updates. Flexible so you don't need to be.",
4
- "version": "43.228.0",
4
+ "version": "43.228.1",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "renovate": "dist/renovate.js",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$id": "https://docs.renovatebot.com/renovate-schema.json",
3
- "title": "JSON schema for Renovate 43.228.0 config files (https://renovatebot.com/)",
3
+ "title": "JSON schema for Renovate 43.228.1 config files (https://renovatebot.com/)",
4
4
  "$schema": "http://json-schema.org/draft-07/schema#",
5
- "x-renovate-version": "43.228.0",
5
+ "x-renovate-version": "43.228.1",
6
6
  "allowComments": true,
7
7
  "type": "object",
8
8
  "definitions": {