renovate 44.46.1 → 44.46.2

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.
@@ -16,7 +16,7 @@ import { BearerScheme, parse } from "../../../util/http/www-authenticate.js";
16
16
  import { ecrRegex, getECRAuthToken, isECRMaxResultsResponse } from "./ecr.js";
17
17
  import { googleRegex } from "./google.js";
18
18
  import { RegistryAuthToken } from "./schema.js";
19
- import { isNonEmptyString, isString } from "@sindresorhus/is";
19
+ import { isNonEmptyString, isString, isUndefined } from "@sindresorhus/is";
20
20
  //#region lib/modules/datasource/docker/common.ts
21
21
  const dockerDatasourceId = "docker";
22
22
  const imageUrlLabel = "org.opencontainers.image.url";
@@ -68,7 +68,7 @@ async function getAuthHeaders(http, registryHost, dockerRepository, apiCheckUrl
68
68
  const [, region] = coerceArray(ecrRegex.exec(registryHost));
69
69
  const auth = await getECRAuthToken(region, rule);
70
70
  if (auth) opts.headers = { authorization: `Basic ${auth}` };
71
- } else if (googleRegex.test(registryHost) && typeof rule.username === "undefined" && typeof rule.password === "undefined" && typeof rule.token === "undefined") {
71
+ } else if (googleRegex.test(registryHost) && isUndefined(rule.username) && isUndefined(rule.password) && isUndefined(rule.token)) {
72
72
  logger.once.debug(`hostRules: google auth for ${registryHost}`);
73
73
  logger.trace({
74
74
  registryHost,
@@ -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, 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 -- 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 -- quay.io errors are swallowed pending #9604, not reproduced in specs */\n if (err.host === 'quay.io') {\n // TODO: debug why quay throws errors (#9604)\n return null;\n }\n /* v8 ignore if -- registry auth rejection is logged and swallowed, not mocked in specs */\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 -- registry permission rejection is logged and swallowed, not mocked in specs */\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 -- Docker Hub rate limiting maps to ExternalHostError, not mocked in specs */\n if (err.statusCode === 429 && isDockerHost(registryHost)) {\n throw new ExternalHostError(err);\n }\n /* v8 ignore if -- registry server errors map to ExternalHostError, not mocked in specs */\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 -- hostRules-disabled host is swallowed silently, not mocked in specs */\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, isUndefined } 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 isUndefined(rule.username) &&\n isUndefined(rule.password) &&\n isUndefined(rule.token)\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 -- 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 -- quay.io errors are swallowed pending #9604, not reproduced in specs */\n if (err.host === 'quay.io') {\n // TODO: debug why quay throws errors (#9604)\n return null;\n }\n /* v8 ignore if -- registry auth rejection is logged and swallowed, not mocked in specs */\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 -- registry permission rejection is logged and swallowed, not mocked in specs */\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 -- Docker Hub rate limiting maps to ExternalHostError, not mocked in specs */\n if (err.statusCode === 429 && isDockerHost(registryHost)) {\n throw new ExternalHostError(err);\n }\n /* v8 ignore if -- registry server errors map to ExternalHostError, not mocked in specs */\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 -- hostRules-disabled host is swallowed silently, not mocked in specs */\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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"}
@@ -2,7 +2,7 @@ import { regEx } from "../../../util/regex.js";
2
2
  import { logger } from "../../../logger/index.js";
3
3
  import { isSkipComment } from "../../../util/ignore.js";
4
4
  import { upgradeableTooling } from "./upgradeable-tooling.js";
5
- import { isTruthy } from "@sindresorhus/is";
5
+ import { isFunction, isTruthy } from "@sindresorhus/is";
6
6
  //#region lib/modules/manager/asdf/extract.ts
7
7
  function extractPackageFile(content) {
8
8
  logger.trace(`asdf.extractPackageFile()`);
@@ -13,7 +13,7 @@ function extractPackageFile(content) {
13
13
  const version = groups.version.trim();
14
14
  const toolConfig = upgradeableTooling[depName];
15
15
  let toolDefinition;
16
- if (toolConfig) toolDefinition = typeof toolConfig.config === "function" ? toolConfig.config(version) : toolConfig.config;
16
+ if (toolConfig) toolDefinition = isFunction(toolConfig.config) ? toolConfig.config(version) : toolConfig.config;
17
17
  if (toolDefinition) {
18
18
  const dep = {
19
19
  currentValue: version,
@@ -1 +1 @@
1
- {"version":3,"file":"extract.js","names":[],"sources":["../../../../lib/modules/manager/asdf/extract.ts"],"sourcesContent":["import { isTruthy } from '@sindresorhus/is';\nimport { logger } from '../../../logger/index.ts';\nimport { isSkipComment } from '../../../util/ignore.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport type { PackageDependency, PackageFileContent } from '../types.ts';\nimport type { StaticTooling } from './upgradeable-tooling.ts';\nimport { upgradeableTooling } from './upgradeable-tooling.ts';\n\nexport function extractPackageFile(content: string): PackageFileContent | null {\n logger.trace(`asdf.extractPackageFile()`);\n\n const regex = regEx(\n /^(?<toolName>([\\w_-]+)) +(?<version>[^\\s#]+)(?: +[^\\s#]+)* *(?: #(?<comment>.*))?$/gm,\n );\n\n const deps: PackageDependency[] = [];\n\n for (const groups of [...content.matchAll(regex)]\n .map((m) => m.groups)\n .filter(isTruthy)) {\n const depName = groups.toolName.trim();\n const version = groups.version.trim();\n\n const toolConfig = upgradeableTooling[depName];\n let toolDefinition: StaticTooling | undefined;\n if (toolConfig) {\n toolDefinition =\n typeof toolConfig.config === 'function'\n ? toolConfig.config(version)\n : toolConfig.config;\n }\n\n if (toolDefinition) {\n const dep: PackageDependency = {\n currentValue: version,\n depName,\n ...toolDefinition,\n };\n if (isSkipComment((groups.comment ?? '').trim())) {\n dep.skipReason = 'ignored';\n }\n\n deps.push(dep);\n } else {\n const dep: PackageDependency = {\n depName,\n skipReason: 'unsupported-datasource',\n };\n\n deps.push(dep);\n }\n }\n\n return deps.length ? { deps } : null;\n}\n"],"mappings":";;;;;;AAQA,SAAgB,mBAAmB,SAA4C;CAC7E,OAAO,MAAM,2BAA2B;CAExC,MAAM,QAAQ,MACZ,sFACF;CAEA,MAAM,OAA4B,CAAC;CAEnC,KAAK,MAAM,UAAU,CAAC,GAAG,QAAQ,SAAS,KAAK,CAAC,CAAC,CAC9C,KAAK,MAAM,EAAE,MAAM,CAAC,CACpB,OAAO,QAAQ,GAAG;EACnB,MAAM,UAAU,OAAO,SAAS,KAAK;EACrC,MAAM,UAAU,OAAO,QAAQ,KAAK;EAEpC,MAAM,aAAa,mBAAmB;EACtC,IAAI;EACJ,IAAI,YACF,iBACE,OAAO,WAAW,WAAW,aACzB,WAAW,OAAO,OAAO,IACzB,WAAW;EAGnB,IAAI,gBAAgB;GAClB,MAAM,MAAyB;IAC7B,cAAc;IACd;IACA,GAAG;GACL;GACA,IAAI,eAAe,OAAO,WAAW,GAAA,CAAI,KAAK,CAAC,GAC7C,IAAI,aAAa;GAGnB,KAAK,KAAK,GAAG;EACf,OAAO;GACL,MAAM,MAAyB;IAC7B;IACA,YAAY;GACd;GAEA,KAAK,KAAK,GAAG;EACf;CACF;CAEA,OAAO,KAAK,SAAS,EAAE,KAAK,IAAI;AAClC"}
1
+ {"version":3,"file":"extract.js","names":[],"sources":["../../../../lib/modules/manager/asdf/extract.ts"],"sourcesContent":["import { isFunction, isTruthy } from '@sindresorhus/is';\nimport { logger } from '../../../logger/index.ts';\nimport { isSkipComment } from '../../../util/ignore.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport type { PackageDependency, PackageFileContent } from '../types.ts';\nimport type { StaticTooling } from './upgradeable-tooling.ts';\nimport { upgradeableTooling } from './upgradeable-tooling.ts';\n\nexport function extractPackageFile(content: string): PackageFileContent | null {\n logger.trace(`asdf.extractPackageFile()`);\n\n const regex = regEx(\n /^(?<toolName>([\\w_-]+)) +(?<version>[^\\s#]+)(?: +[^\\s#]+)* *(?: #(?<comment>.*))?$/gm,\n );\n\n const deps: PackageDependency[] = [];\n\n for (const groups of [...content.matchAll(regex)]\n .map((m) => m.groups)\n .filter(isTruthy)) {\n const depName = groups.toolName.trim();\n const version = groups.version.trim();\n\n const toolConfig = upgradeableTooling[depName];\n let toolDefinition: StaticTooling | undefined;\n if (toolConfig) {\n toolDefinition = isFunction(toolConfig.config)\n ? toolConfig.config(version)\n : toolConfig.config;\n }\n\n if (toolDefinition) {\n const dep: PackageDependency = {\n currentValue: version,\n depName,\n ...toolDefinition,\n };\n if (isSkipComment((groups.comment ?? '').trim())) {\n dep.skipReason = 'ignored';\n }\n\n deps.push(dep);\n } else {\n const dep: PackageDependency = {\n depName,\n skipReason: 'unsupported-datasource',\n };\n\n deps.push(dep);\n }\n }\n\n return deps.length ? { deps } : null;\n}\n"],"mappings":";;;;;;AAQA,SAAgB,mBAAmB,SAA4C;CAC7E,OAAO,MAAM,2BAA2B;CAExC,MAAM,QAAQ,MACZ,sFACF;CAEA,MAAM,OAA4B,CAAC;CAEnC,KAAK,MAAM,UAAU,CAAC,GAAG,QAAQ,SAAS,KAAK,CAAC,CAAC,CAC9C,KAAK,MAAM,EAAE,MAAM,CAAC,CACpB,OAAO,QAAQ,GAAG;EACnB,MAAM,UAAU,OAAO,SAAS,KAAK;EACrC,MAAM,UAAU,OAAO,QAAQ,KAAK;EAEpC,MAAM,aAAa,mBAAmB;EACtC,IAAI;EACJ,IAAI,YACF,iBAAiB,WAAW,WAAW,MAAM,IACzC,WAAW,OAAO,OAAO,IACzB,WAAW;EAGjB,IAAI,gBAAgB;GAClB,MAAM,MAAyB;IAC7B,cAAc;IACd;IACA,GAAG;GACL;GACA,IAAI,eAAe,OAAO,WAAW,GAAA,CAAI,KAAK,CAAC,GAC7C,IAAI,aAAa;GAGnB,KAAK,KAAK,GAAG;EACf,OAAO;GACL,MAAM,MAAyB;IAC7B;IACA,YAAY;GACd;GAEA,KAAK,KAAK,GAAG;EACf;CACF;CAEA,OAAO,KAAK,SAAS,EAAE,KAAK,IAAI;AAClC"}
@@ -1,4 +1,5 @@
1
1
  import { regEx } from "../../util/regex.js";
2
+ import "@sindresorhus/is";
2
3
  regEx(/\[[^\]]+\]\([^)]+\)/);
3
4
  function getExcludedVersions(range) {
4
5
  return range.split(",").map((v) => v.trim()).filter((version) => regEx(/^!=/).test(version)).map((version) => version.replace("!=", "").trim());
@@ -1 +1 @@
1
- {"version":3,"file":"common.js","names":[],"sources":["../../../lib/modules/versioning/common.ts"],"sourcesContent":["import { regEx } from '../../util/regex.ts';\nimport type { VersioningApi, VersioningApiConstructor } from './types.ts';\n\nexport const markdownLinkRegex = regEx(/\\[[^\\]]+\\]\\([^)]+\\)/);\n\nexport function isVersioningApiConstructor(\n obj: VersioningApi | VersioningApiConstructor,\n): obj is VersioningApiConstructor {\n return typeof obj === 'function';\n}\n\nexport function getExcludedVersions(range: string): string[] {\n return range\n .split(',')\n .map((v) => v.trim())\n .filter((version) => regEx(/^!=/).test(version))\n .map((version) => version.replace('!=', '').trim());\n}\n\nexport function getFilteredRange(range: string): string {\n return range\n .split(',')\n .map((v) => v.trim())\n .filter((version) => !regEx(/^!=/).test(version))\n .join(',');\n}\n"],"mappings":";AAGiC,MAAM,qBAAqB;AAQ5D,SAAgB,oBAAoB,OAAyB;CAC3D,OAAO,MACJ,MAAM,GAAG,CAAC,CACV,KAAK,MAAM,EAAE,KAAK,CAAC,CAAC,CACpB,QAAQ,YAAY,MAAM,KAAK,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAC/C,KAAK,YAAY,QAAQ,QAAQ,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC;AACtD;AAEA,SAAgB,iBAAiB,OAAuB;CACtD,OAAO,MACJ,MAAM,GAAG,CAAC,CACV,KAAK,MAAM,EAAE,KAAK,CAAC,CAAC,CACpB,QAAQ,YAAY,CAAC,MAAM,KAAK,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAChD,KAAK,GAAG;AACb"}
1
+ {"version":3,"file":"common.js","names":[],"sources":["../../../lib/modules/versioning/common.ts"],"sourcesContent":["import { isFunction } from '@sindresorhus/is';\nimport { regEx } from '../../util/regex.ts';\nimport type { VersioningApi, VersioningApiConstructor } from './types.ts';\n\nexport const markdownLinkRegex = regEx(/\\[[^\\]]+\\]\\([^)]+\\)/);\n\nexport function isVersioningApiConstructor(\n obj: VersioningApi | VersioningApiConstructor,\n): obj is VersioningApiConstructor {\n return isFunction(obj);\n}\n\nexport function getExcludedVersions(range: string): string[] {\n return range\n .split(',')\n .map((v) => v.trim())\n .filter((version) => regEx(/^!=/).test(version))\n .map((version) => version.replace('!=', '').trim());\n}\n\nexport function getFilteredRange(range: string): string {\n return range\n .split(',')\n .map((v) => v.trim())\n .filter((version) => !regEx(/^!=/).test(version))\n .join(',');\n}\n"],"mappings":";;AAIiC,MAAM,qBAAqB;AAQ5D,SAAgB,oBAAoB,OAAyB;CAC3D,OAAO,MACJ,MAAM,GAAG,CAAC,CACV,KAAK,MAAM,EAAE,KAAK,CAAC,CAAC,CACpB,QAAQ,YAAY,MAAM,KAAK,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAC/C,KAAK,YAAY,QAAQ,QAAQ,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC;AACtD;AAEA,SAAgB,iBAAiB,OAAuB;CACtD,OAAO,MACJ,MAAM,GAAG,CAAC,CACV,KAAK,MAAM,EAAE,KAAK,CAAC,CAAC,CACpB,QAAQ,YAAY,CAAC,MAAM,KAAK,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAChD,KAAK,GAAG;AACb"}
@@ -1,4 +1,5 @@
1
1
  import { RegExpVersioningApi } from "../regex/index.js";
2
+ import { isUndefined } from "@sindresorhus/is";
2
3
  import { satisfies } from "semver";
3
4
  //#region lib/modules/versioning/hermit/index.ts
4
5
  const id = "hermit";
@@ -16,9 +17,9 @@ var HermitVersioning = class HermitVersioning extends RegExpVersioningApi {
16
17
  const { major, minor, patch, supplement, build, prerelease, compatibility } = groups;
17
18
  const release = [
18
19
  Number.parseInt(major, 10),
19
- typeof minor === "undefined" ? 0 : Number.parseInt(minor, 10),
20
- typeof patch === "undefined" ? 0 : Number.parseInt(patch, 10),
21
- typeof supplement === "undefined" ? 0 : Number.parseInt(supplement, 10)
20
+ isUndefined(minor) ? 0 : Number.parseInt(minor, 10),
21
+ isUndefined(patch) ? 0 : Number.parseInt(patch, 10),
22
+ isUndefined(supplement) ? 0 : Number.parseInt(supplement, 10)
22
23
  ];
23
24
  if (build) release.push(Number.parseInt(build, 10));
24
25
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../lib/modules/versioning/hermit/index.ts"],"sourcesContent":["import { satisfies } from 'semver';\nimport type { RegExpVersion } from '../regex/index.ts';\nimport { RegExpVersioningApi } from '../regex/index.ts';\nimport type { VersioningApiConstructor } from '../types.ts';\n\nexport const id = 'hermit';\nexport const displayName = 'Hermit';\nexport const urls = [\n '[Hermit packaging reference - Versions](https://cashapp.github.io/hermit/packaging/reference/#versions)',\n];\nexport const supportsRanges = false;\n\nexport class HermitVersioning extends RegExpVersioningApi {\n // add <supplement> element to accomondate openjdk versioning defined in JEP322\n // https://openjdk.org/jeps/322\n static versionRegex =\n '^(?<major>\\\\d+)(\\\\.(?<minor>\\\\d+))?(\\\\.(?<patch>\\\\d+))?(\\\\.(?<supplement>\\\\d+))?(_(?<build>\\\\d+))?([-]?(?<prerelease>[^.+][^+]*))?([+](?<compatibility>[^.-][^+]*))?$';\n\n public constructor() {\n super(HermitVersioning.versionRegex);\n }\n\n private _isValid(version: string): boolean {\n return super._parse(version) !== null;\n }\n\n private _parseHermitVersioning(version: string): RegExpVersion | null {\n const groups = this._config?.exec(version)?.groups;\n if (!groups) {\n return null;\n }\n\n const {\n major,\n minor,\n patch,\n supplement,\n build,\n prerelease,\n compatibility,\n } = groups;\n const release = [\n Number.parseInt(major, 10),\n typeof minor === 'undefined' ? 0 : Number.parseInt(minor, 10),\n typeof patch === 'undefined' ? 0 : Number.parseInt(patch, 10),\n typeof supplement === 'undefined' ? 0 : Number.parseInt(supplement, 10),\n ];\n\n if (build) {\n release.push(Number.parseInt(build, 10));\n }\n\n return {\n release,\n prerelease,\n compatibility,\n };\n }\n\n protected override _parse(version: string): RegExpVersion | null {\n const parsed = this._parseHermitVersioning(version);\n if (parsed) {\n return parsed;\n }\n const channelVer = HermitVersioning._getChannel(version);\n\n const groups = this._config?.exec(channelVer)?.groups;\n\n if (!groups) {\n return null;\n }\n\n const {\n major,\n minor,\n patch,\n supplement,\n build,\n prerelease,\n compatibility,\n } = groups;\n const release = [];\n\n if (major) {\n release.push(Number.parseInt(major, 10));\n }\n\n if (minor) {\n release.push(Number.parseInt(minor, 10));\n }\n if (patch) {\n release.push(Number.parseInt(patch, 10));\n }\n if (supplement) {\n release.push(Number.parseInt(supplement, 10));\n }\n if (build) {\n release.push(Number.parseInt(build, 10));\n }\n\n return {\n release,\n prerelease,\n compatibility,\n };\n }\n\n private static _isChannel(version: string): boolean {\n return version.startsWith('@');\n }\n\n private static _getChannel(version: string): string {\n return version.substring(1);\n }\n\n override isStable(version: string): boolean {\n if (this._isValid(version)) {\n return super.isStable(version);\n }\n\n // channel and the rest should be considered unstable version\n // as channels are changing values\n return false;\n }\n\n override isValid(version: string): boolean {\n return this._isValid(version) || HermitVersioning._isChannel(version);\n }\n\n override isLessThanRange(version: string, range: string): boolean {\n return this._compare(version, range) < 0;\n }\n\n protected override _compare(version: string, other: string): number {\n if (this._isValid(version) && this._isValid(other)) {\n return super._compare(version, other);\n }\n\n const parsedVersion = this._parse(version);\n const parsedOther = this._parse(other);\n\n if (parsedVersion === null || parsedOther === null) {\n if (parsedVersion === null && parsedOther === null) {\n return version.localeCompare(other);\n }\n return parsedVersion === null ? -1 : 1;\n }\n\n const versionReleases = parsedVersion.release;\n const otherReleases = parsedOther.release;\n\n const maxLength =\n versionReleases.length > otherReleases.length\n ? versionReleases.length\n : otherReleases.length;\n\n for (let i = 0; i < maxLength; i++) {\n const verVal = versionReleases[i];\n const otherVal = otherReleases[i];\n\n if (\n verVal !== undefined &&\n otherVal !== undefined &&\n verVal !== otherVal\n ) {\n return verVal - otherVal;\n }\n if (verVal === undefined) {\n return 1;\n }\n if (otherVal === undefined) {\n return -1;\n }\n }\n\n return 0;\n }\n\n override matches(version: string, range: string): boolean {\n if (\n HermitVersioning._isChannel(version) ||\n HermitVersioning._isChannel(range)\n ) {\n return this.equals(version, range);\n }\n\n return satisfies(version, range);\n }\n}\n\nexport const api: VersioningApiConstructor = HermitVersioning;\n\nexport default api;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../lib/modules/versioning/hermit/index.ts"],"sourcesContent":["import { isUndefined } from '@sindresorhus/is';\nimport { satisfies } from 'semver';\nimport type { RegExpVersion } from '../regex/index.ts';\nimport { RegExpVersioningApi } from '../regex/index.ts';\nimport type { VersioningApiConstructor } from '../types.ts';\n\nexport const id = 'hermit';\nexport const displayName = 'Hermit';\nexport const urls = [\n '[Hermit packaging reference - Versions](https://cashapp.github.io/hermit/packaging/reference/#versions)',\n];\nexport const supportsRanges = false;\n\nexport class HermitVersioning extends RegExpVersioningApi {\n // add <supplement> element to accomondate openjdk versioning defined in JEP322\n // https://openjdk.org/jeps/322\n static versionRegex =\n '^(?<major>\\\\d+)(\\\\.(?<minor>\\\\d+))?(\\\\.(?<patch>\\\\d+))?(\\\\.(?<supplement>\\\\d+))?(_(?<build>\\\\d+))?([-]?(?<prerelease>[^.+][^+]*))?([+](?<compatibility>[^.-][^+]*))?$';\n\n public constructor() {\n super(HermitVersioning.versionRegex);\n }\n\n private _isValid(version: string): boolean {\n return super._parse(version) !== null;\n }\n\n private _parseHermitVersioning(version: string): RegExpVersion | null {\n const groups = this._config?.exec(version)?.groups;\n if (!groups) {\n return null;\n }\n\n const {\n major,\n minor,\n patch,\n supplement,\n build,\n prerelease,\n compatibility,\n } = groups;\n const release = [\n Number.parseInt(major, 10),\n isUndefined(minor) ? 0 : Number.parseInt(minor, 10),\n isUndefined(patch) ? 0 : Number.parseInt(patch, 10),\n isUndefined(supplement) ? 0 : Number.parseInt(supplement, 10),\n ];\n\n if (build) {\n release.push(Number.parseInt(build, 10));\n }\n\n return {\n release,\n prerelease,\n compatibility,\n };\n }\n\n protected override _parse(version: string): RegExpVersion | null {\n const parsed = this._parseHermitVersioning(version);\n if (parsed) {\n return parsed;\n }\n const channelVer = HermitVersioning._getChannel(version);\n\n const groups = this._config?.exec(channelVer)?.groups;\n\n if (!groups) {\n return null;\n }\n\n const {\n major,\n minor,\n patch,\n supplement,\n build,\n prerelease,\n compatibility,\n } = groups;\n const release = [];\n\n if (major) {\n release.push(Number.parseInt(major, 10));\n }\n\n if (minor) {\n release.push(Number.parseInt(minor, 10));\n }\n if (patch) {\n release.push(Number.parseInt(patch, 10));\n }\n if (supplement) {\n release.push(Number.parseInt(supplement, 10));\n }\n if (build) {\n release.push(Number.parseInt(build, 10));\n }\n\n return {\n release,\n prerelease,\n compatibility,\n };\n }\n\n private static _isChannel(version: string): boolean {\n return version.startsWith('@');\n }\n\n private static _getChannel(version: string): string {\n return version.substring(1);\n }\n\n override isStable(version: string): boolean {\n if (this._isValid(version)) {\n return super.isStable(version);\n }\n\n // channel and the rest should be considered unstable version\n // as channels are changing values\n return false;\n }\n\n override isValid(version: string): boolean {\n return this._isValid(version) || HermitVersioning._isChannel(version);\n }\n\n override isLessThanRange(version: string, range: string): boolean {\n return this._compare(version, range) < 0;\n }\n\n protected override _compare(version: string, other: string): number {\n if (this._isValid(version) && this._isValid(other)) {\n return super._compare(version, other);\n }\n\n const parsedVersion = this._parse(version);\n const parsedOther = this._parse(other);\n\n if (parsedVersion === null || parsedOther === null) {\n if (parsedVersion === null && parsedOther === null) {\n return version.localeCompare(other);\n }\n return parsedVersion === null ? -1 : 1;\n }\n\n const versionReleases = parsedVersion.release;\n const otherReleases = parsedOther.release;\n\n const maxLength =\n versionReleases.length > otherReleases.length\n ? versionReleases.length\n : otherReleases.length;\n\n for (let i = 0; i < maxLength; i++) {\n const verVal = versionReleases[i];\n const otherVal = otherReleases[i];\n\n if (\n verVal !== undefined &&\n otherVal !== undefined &&\n verVal !== otherVal\n ) {\n return verVal - otherVal;\n }\n if (verVal === undefined) {\n return 1;\n }\n if (otherVal === undefined) {\n return -1;\n }\n }\n\n return 0;\n }\n\n override matches(version: string, range: string): boolean {\n if (\n HermitVersioning._isChannel(version) ||\n HermitVersioning._isChannel(range)\n ) {\n return this.equals(version, range);\n }\n\n return satisfies(version, range);\n }\n}\n\nexport const api: VersioningApiConstructor = HermitVersioning;\n\nexport default api;\n"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { regEx } from "../../../util/regex.js";
2
2
  import { GenericVersioningApi } from "../generic.js";
3
+ import { isUndefined } from "@sindresorhus/is";
3
4
  //#region lib/modules/versioning/redhat/index.ts
4
5
  const id = "redhat";
5
6
  const pattern = regEx(/^v?(?<major>\d+)(?:\.(?<minor>\d+))?(?:\.(?<patch>\d+))?(\.GA)?(?:-(?<releaseMajor>\d+)(?:\.(?<releaseMinor>\d+))?)?$/);
@@ -11,10 +12,10 @@ var RedhatVersioningApi = class extends GenericVersioningApi {
11
12
  return {
12
13
  release: [
13
14
  Number.parseInt(major, 10),
14
- typeof minor === "undefined" ? 0 : Number.parseInt(minor, 10),
15
- typeof patch === "undefined" ? 0 : Number.parseInt(patch, 10),
16
- typeof releaseMajor === "undefined" ? 0 : Number.parseInt(releaseMajor, 10),
17
- typeof releaseMinor === "undefined" ? 0 : Number.parseInt(releaseMinor, 10)
15
+ isUndefined(minor) ? 0 : Number.parseInt(minor, 10),
16
+ isUndefined(patch) ? 0 : Number.parseInt(patch, 10),
17
+ isUndefined(releaseMajor) ? 0 : Number.parseInt(releaseMajor, 10),
18
+ isUndefined(releaseMinor) ? 0 : Number.parseInt(releaseMinor, 10)
18
19
  ],
19
20
  prerelease: ""
20
21
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../lib/modules/versioning/redhat/index.ts"],"sourcesContent":["import { regEx } from '../../../util/regex.ts';\nimport type { GenericVersion } from '../generic.ts';\nimport { GenericVersioningApi } from '../generic.ts';\nimport type { VersioningApi } from '../types.ts';\n\nexport const id = 'redhat';\nexport const displayName = 'Red Hat';\nexport const urls = [];\nexport const supportsRanges = false;\n\nconst pattern = regEx(\n /^v?(?<major>\\d+)(?:\\.(?<minor>\\d+))?(?:\\.(?<patch>\\d+))?(\\.GA)?(?:-(?<releaseMajor>\\d+)(?:\\.(?<releaseMinor>\\d+))?)?$/,\n);\n\nclass RedhatVersioningApi extends GenericVersioningApi {\n protected _parse(version: string): GenericVersion | null {\n const matches = pattern.exec(version)?.groups;\n if (!matches) {\n return null;\n }\n\n const { major, minor, patch, releaseMajor, releaseMinor } = matches;\n const release = [\n Number.parseInt(major, 10),\n typeof minor === 'undefined' ? 0 : Number.parseInt(minor, 10),\n typeof patch === 'undefined' ? 0 : Number.parseInt(patch, 10),\n typeof releaseMajor === 'undefined'\n ? 0\n : Number.parseInt(releaseMajor, 10),\n typeof releaseMinor === 'undefined'\n ? 0\n : Number.parseInt(releaseMinor, 10),\n ];\n\n return { release, prerelease: '' };\n }\n}\n\nexport const api: VersioningApi = new RedhatVersioningApi();\n\nexport default api;\n"],"mappings":";;;AAKA,MAAa,KAAK;AAKlB,MAAM,UAAU,MACd,uHACF;AAEA,IAAM,sBAAN,cAAkC,qBAAqB;CACrD,OAAiB,SAAwC;EACvD,MAAM,UAAU,QAAQ,KAAK,OAAO,CAAC,EAAE;EACvC,IAAI,CAAC,SACH,OAAO;EAGT,MAAM,EAAE,OAAO,OAAO,OAAO,cAAc,iBAAiB;EAa5D,OAAO;GAAE,SAAA;IAXP,OAAO,SAAS,OAAO,EAAE;IACzB,OAAO,UAAU,cAAc,IAAI,OAAO,SAAS,OAAO,EAAE;IAC5D,OAAO,UAAU,cAAc,IAAI,OAAO,SAAS,OAAO,EAAE;IAC5D,OAAO,iBAAiB,cACpB,IACA,OAAO,SAAS,cAAc,EAAE;IACpC,OAAO,iBAAiB,cACpB,IACA,OAAO,SAAS,cAAc,EAAE;GAGvB;GAAG,YAAY;EAAG;CACnC;AACF;AAEA,MAAa,MAAqB,IAAI,oBAAoB"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../lib/modules/versioning/redhat/index.ts"],"sourcesContent":["import { isUndefined } from '@sindresorhus/is';\nimport { regEx } from '../../../util/regex.ts';\nimport type { GenericVersion } from '../generic.ts';\nimport { GenericVersioningApi } from '../generic.ts';\nimport type { VersioningApi } from '../types.ts';\n\nexport const id = 'redhat';\nexport const displayName = 'Red Hat';\nexport const urls = [];\nexport const supportsRanges = false;\n\nconst pattern = regEx(\n /^v?(?<major>\\d+)(?:\\.(?<minor>\\d+))?(?:\\.(?<patch>\\d+))?(\\.GA)?(?:-(?<releaseMajor>\\d+)(?:\\.(?<releaseMinor>\\d+))?)?$/,\n);\n\nclass RedhatVersioningApi extends GenericVersioningApi {\n protected _parse(version: string): GenericVersion | null {\n const matches = pattern.exec(version)?.groups;\n if (!matches) {\n return null;\n }\n\n const { major, minor, patch, releaseMajor, releaseMinor } = matches;\n const release = [\n Number.parseInt(major, 10),\n isUndefined(minor) ? 0 : Number.parseInt(minor, 10),\n isUndefined(patch) ? 0 : Number.parseInt(patch, 10),\n isUndefined(releaseMajor) ? 0 : Number.parseInt(releaseMajor, 10),\n isUndefined(releaseMinor) ? 0 : Number.parseInt(releaseMinor, 10),\n ];\n\n return { release, prerelease: '' };\n }\n}\n\nexport const api: VersioningApi = new RedhatVersioningApi();\n\nexport default api;\n"],"mappings":";;;;AAMA,MAAa,KAAK;AAKlB,MAAM,UAAU,MACd,uHACF;AAEA,IAAM,sBAAN,cAAkC,qBAAqB;CACrD,OAAiB,SAAwC;EACvD,MAAM,UAAU,QAAQ,KAAK,OAAO,CAAC,EAAE;EACvC,IAAI,CAAC,SACH,OAAO;EAGT,MAAM,EAAE,OAAO,OAAO,OAAO,cAAc,iBAAiB;EAS5D,OAAO;GAAE,SAAA;IAPP,OAAO,SAAS,OAAO,EAAE;IACzB,YAAY,KAAK,IAAI,IAAI,OAAO,SAAS,OAAO,EAAE;IAClD,YAAY,KAAK,IAAI,IAAI,OAAO,SAAS,OAAO,EAAE;IAClD,YAAY,YAAY,IAAI,IAAI,OAAO,SAAS,cAAc,EAAE;IAChE,YAAY,YAAY,IAAI,IAAI,OAAO,SAAS,cAAc,EAAE;GAGnD;GAAG,YAAY;EAAG;CACnC;AACF;AAEA,MAAa,MAAqB,IAAI,oBAAoB"}
@@ -1,6 +1,7 @@
1
1
  import { CONFIG_VALIDATION } from "../../../constants/error-messages.js";
2
2
  import { regEx } from "../../../util/regex.js";
3
3
  import { GenericVersioningApi } from "../generic.js";
4
+ import { isUndefined } from "@sindresorhus/is";
4
5
  //#region lib/modules/versioning/regex/index.ts
5
6
  const id = "regex";
6
7
  var RegExpVersioningApi = class extends GenericVersioningApi {
@@ -21,9 +22,9 @@ var RegExpVersioningApi = class extends GenericVersioningApi {
21
22
  if (!groups) return null;
22
23
  const { major, minor, patch, build, revision, prerelease, compatibility } = groups;
23
24
  const release = [
24
- typeof major === "undefined" ? 0 : Number.parseInt(major, 10),
25
- typeof minor === "undefined" ? 0 : Number.parseInt(minor, 10),
26
- typeof patch === "undefined" ? 0 : Number.parseInt(patch, 10)
25
+ isUndefined(major) ? 0 : Number.parseInt(major, 10),
26
+ isUndefined(minor) ? 0 : Number.parseInt(minor, 10),
27
+ isUndefined(patch) ? 0 : Number.parseInt(patch, 10)
27
28
  ];
28
29
  if (build) {
29
30
  release.push(Number.parseInt(build, 10));
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../lib/modules/versioning/regex/index.ts"],"sourcesContent":["import { CONFIG_VALIDATION } from '../../../constants/error-messages.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport type { GenericVersion } from '../generic.ts';\nimport { GenericVersioningApi } from '../generic.ts';\nimport type { VersioningApiConstructor } from '../types.ts';\n\nexport const id = 'regex';\nexport const displayName = 'Regular Expression';\nexport const urls = [];\nexport const supportsRanges = false;\n\nexport interface RegExpVersion extends GenericVersion {\n /**\n * compatibility, if present, are treated as a compatibility layer: we will\n * never try to update to a version with a different compatibility.\n */\n compatibility: string;\n}\n\nexport class RegExpVersioningApi extends GenericVersioningApi<RegExpVersion> {\n // config is expected to be overridden by a user-specified RegExp value\n // sample values:\n //\n // * emulates the \"semver\" configuration:\n // RegExp('^(?<major>\\\\d+)\\\\.(?<minor>\\\\d+)\\\\.(?<patch>\\\\d+)(-(?<prerelease>.*))?$')\n // * emulates the \"docker\" configuration:\n // RegExp('^(?<major>\\\\d+)\\\\.(?<minor>\\\\d+)\\\\.(?<patch>\\\\d+)(-(?<compatibility>.*))?$')\n // * matches the versioning approach used by the Python images on DockerHub:\n // RegExp('^(?<major>\\\\d+)\\\\.(?<minor>\\\\d+)\\\\.(?<patch>\\\\d+)(?<prerelease>[^.-]+)?(-(?<compatibility>.*))?$');\n // * matches the versioning approach used by the Bitnami images on DockerHub:\n // RegExp('^(?<major>\\\\d+)\\\\.(?<minor>\\\\d+)\\\\.(?<patch>\\\\d+)(:?-(?<compatibility>.*-r)(?<build>\\\\d+))?$');\n protected readonly _config: RegExp;\n\n constructor(_new_config: string | undefined) {\n super();\n const new_config = _new_config ?? '^(?<major>\\\\d+)?$';\n\n // without at least one of {major, minor, patch} specified in the regex,\n // this versioner will not work properly\n if (\n !new_config.includes('<major>') &&\n !new_config.includes('<minor>') &&\n !new_config.includes('<patch>')\n ) {\n const error = new Error(CONFIG_VALIDATION);\n error.validationSource = new_config;\n error.validationError =\n 'regex versioning needs at least one major, minor or patch group defined';\n throw error;\n }\n\n // TODO: should we validate the user has not added extra unsupported\n // capture groups? (#9717)\n this._config = regEx(new_config);\n }\n\n // convenience method for passing a string into a Version given current config.\n protected _parse(version: string): RegExpVersion | null {\n const groups = this._config?.exec(version)?.groups;\n if (!groups) {\n return null;\n }\n\n const { major, minor, patch, build, revision, prerelease, compatibility } =\n groups;\n const release = [\n typeof major === 'undefined' ? 0 : Number.parseInt(major, 10),\n typeof minor === 'undefined' ? 0 : Number.parseInt(minor, 10),\n typeof patch === 'undefined' ? 0 : Number.parseInt(patch, 10),\n ];\n\n if (build) {\n release.push(Number.parseInt(build, 10));\n if (revision) {\n release.push(Number.parseInt(revision, 10));\n }\n }\n\n return {\n release,\n prerelease,\n compatibility,\n };\n }\n\n override isCompatible(version: string, current: string): boolean {\n const parsedVersion = this._parse(version);\n const parsedCurrent = this._parse(current);\n return !!(\n parsedVersion &&\n parsedVersion.compatibility === parsedCurrent?.compatibility\n );\n }\n}\n\nexport const api: VersioningApiConstructor = RegExpVersioningApi;\n\nexport default api;\n"],"mappings":";;;;AAMA,MAAa,KAAK;AAalB,IAAa,sBAAb,cAAyC,qBAAoC;CAY3E;CAEA,YAAY,aAAiC;EAC3C,MAAM;EACN,MAAM,aAAa,eAAe;EAIlC,IACE,CAAC,WAAW,SAAS,SAAS,KAC9B,CAAC,WAAW,SAAS,SAAS,KAC9B,CAAC,WAAW,SAAS,SAAS,GAC9B;GACA,MAAM,QAAQ,IAAI,MAAM,iBAAiB;GACzC,MAAM,mBAAmB;GACzB,MAAM,kBACJ;GACF,MAAM;EACR;EAIA,KAAK,UAAU,MAAM,UAAU;CACjC;CAGA,OAAiB,SAAuC;EACtD,MAAM,SAAS,KAAK,SAAS,KAAK,OAAO,CAAC,EAAE;EAC5C,IAAI,CAAC,QACH,OAAO;EAGT,MAAM,EAAE,OAAO,OAAO,OAAO,OAAO,UAAU,YAAY,kBACxD;EACF,MAAM,UAAU;GACd,OAAO,UAAU,cAAc,IAAI,OAAO,SAAS,OAAO,EAAE;GAC5D,OAAO,UAAU,cAAc,IAAI,OAAO,SAAS,OAAO,EAAE;GAC5D,OAAO,UAAU,cAAc,IAAI,OAAO,SAAS,OAAO,EAAE;EAC9D;EAEA,IAAI,OAAO;GACT,QAAQ,KAAK,OAAO,SAAS,OAAO,EAAE,CAAC;GACvC,IAAI,UACF,QAAQ,KAAK,OAAO,SAAS,UAAU,EAAE,CAAC;EAE9C;EAEA,OAAO;GACL;GACA;GACA;EACF;CACF;CAEA,aAAsB,SAAiB,SAA0B;EAC/D,MAAM,gBAAgB,KAAK,OAAO,OAAO;EACzC,MAAM,gBAAgB,KAAK,OAAO,OAAO;EACzC,OAAO,CAAC,EACN,iBACA,cAAc,kBAAkB,eAAe;CAEnD;AACF;AAEA,MAAa,MAAgC"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../lib/modules/versioning/regex/index.ts"],"sourcesContent":["import { isUndefined } from '@sindresorhus/is';\nimport { CONFIG_VALIDATION } from '../../../constants/error-messages.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport type { GenericVersion } from '../generic.ts';\nimport { GenericVersioningApi } from '../generic.ts';\nimport type { VersioningApiConstructor } from '../types.ts';\n\nexport const id = 'regex';\nexport const displayName = 'Regular Expression';\nexport const urls = [];\nexport const supportsRanges = false;\n\nexport interface RegExpVersion extends GenericVersion {\n /**\n * compatibility, if present, are treated as a compatibility layer: we will\n * never try to update to a version with a different compatibility.\n */\n compatibility: string;\n}\n\nexport class RegExpVersioningApi extends GenericVersioningApi<RegExpVersion> {\n // config is expected to be overridden by a user-specified RegExp value\n // sample values:\n //\n // * emulates the \"semver\" configuration:\n // RegExp('^(?<major>\\\\d+)\\\\.(?<minor>\\\\d+)\\\\.(?<patch>\\\\d+)(-(?<prerelease>.*))?$')\n // * emulates the \"docker\" configuration:\n // RegExp('^(?<major>\\\\d+)\\\\.(?<minor>\\\\d+)\\\\.(?<patch>\\\\d+)(-(?<compatibility>.*))?$')\n // * matches the versioning approach used by the Python images on DockerHub:\n // RegExp('^(?<major>\\\\d+)\\\\.(?<minor>\\\\d+)\\\\.(?<patch>\\\\d+)(?<prerelease>[^.-]+)?(-(?<compatibility>.*))?$');\n // * matches the versioning approach used by the Bitnami images on DockerHub:\n // RegExp('^(?<major>\\\\d+)\\\\.(?<minor>\\\\d+)\\\\.(?<patch>\\\\d+)(:?-(?<compatibility>.*-r)(?<build>\\\\d+))?$');\n protected readonly _config: RegExp;\n\n constructor(_new_config: string | undefined) {\n super();\n const new_config = _new_config ?? '^(?<major>\\\\d+)?$';\n\n // without at least one of {major, minor, patch} specified in the regex,\n // this versioner will not work properly\n if (\n !new_config.includes('<major>') &&\n !new_config.includes('<minor>') &&\n !new_config.includes('<patch>')\n ) {\n const error = new Error(CONFIG_VALIDATION);\n error.validationSource = new_config;\n error.validationError =\n 'regex versioning needs at least one major, minor or patch group defined';\n throw error;\n }\n\n // TODO: should we validate the user has not added extra unsupported\n // capture groups? (#9717)\n this._config = regEx(new_config);\n }\n\n // convenience method for passing a string into a Version given current config.\n protected _parse(version: string): RegExpVersion | null {\n const groups = this._config?.exec(version)?.groups;\n if (!groups) {\n return null;\n }\n\n const { major, minor, patch, build, revision, prerelease, compatibility } =\n groups;\n const release = [\n isUndefined(major) ? 0 : Number.parseInt(major, 10),\n isUndefined(minor) ? 0 : Number.parseInt(minor, 10),\n isUndefined(patch) ? 0 : Number.parseInt(patch, 10),\n ];\n\n if (build) {\n release.push(Number.parseInt(build, 10));\n if (revision) {\n release.push(Number.parseInt(revision, 10));\n }\n }\n\n return {\n release,\n prerelease,\n compatibility,\n };\n }\n\n override isCompatible(version: string, current: string): boolean {\n const parsedVersion = this._parse(version);\n const parsedCurrent = this._parse(current);\n return !!(\n parsedVersion &&\n parsedVersion.compatibility === parsedCurrent?.compatibility\n );\n }\n}\n\nexport const api: VersioningApiConstructor = RegExpVersioningApi;\n\nexport default api;\n"],"mappings":";;;;;AAOA,MAAa,KAAK;AAalB,IAAa,sBAAb,cAAyC,qBAAoC;CAY3E;CAEA,YAAY,aAAiC;EAC3C,MAAM;EACN,MAAM,aAAa,eAAe;EAIlC,IACE,CAAC,WAAW,SAAS,SAAS,KAC9B,CAAC,WAAW,SAAS,SAAS,KAC9B,CAAC,WAAW,SAAS,SAAS,GAC9B;GACA,MAAM,QAAQ,IAAI,MAAM,iBAAiB;GACzC,MAAM,mBAAmB;GACzB,MAAM,kBACJ;GACF,MAAM;EACR;EAIA,KAAK,UAAU,MAAM,UAAU;CACjC;CAGA,OAAiB,SAAuC;EACtD,MAAM,SAAS,KAAK,SAAS,KAAK,OAAO,CAAC,EAAE;EAC5C,IAAI,CAAC,QACH,OAAO;EAGT,MAAM,EAAE,OAAO,OAAO,OAAO,OAAO,UAAU,YAAY,kBACxD;EACF,MAAM,UAAU;GACd,YAAY,KAAK,IAAI,IAAI,OAAO,SAAS,OAAO,EAAE;GAClD,YAAY,KAAK,IAAI,IAAI,OAAO,SAAS,OAAO,EAAE;GAClD,YAAY,KAAK,IAAI,IAAI,OAAO,SAAS,OAAO,EAAE;EACpD;EAEA,IAAI,OAAO;GACT,QAAQ,KAAK,OAAO,SAAS,OAAO,EAAE,CAAC;GACvC,IAAI,UACF,QAAQ,KAAK,OAAO,SAAS,UAAU,EAAE,CAAC;EAE9C;EAEA,OAAO;GACL;GACA;GACA;EACF;CACF;CAEA,aAAsB,SAAiB,SAA0B;EAC/D,MAAM,gBAAgB,KAAK,OAAO,OAAO;EACzC,MAAM,gBAAgB,KAAK,OAAO,OAAO;EACzC,OAAO,CAAC,EACN,iBACA,cAAc,kBAAkB,eAAe;CAEnD;AACF;AAEA,MAAa,MAAgC"}
package/dist/proxy.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { addSecretForSanitizing } from "./util/sanitize.js";
2
2
  import { logger } from "./logger/index.js";
3
3
  import { parseUrl } from "./util/url.js";
4
- import { isNonEmptyString } from "@sindresorhus/is";
4
+ import { isNonEmptyString, isUndefined } from "@sindresorhus/is";
5
5
  import { createGlobalProxyAgent } from "global-agent";
6
6
  //#region lib/proxy.ts
7
7
  const envVars = [
@@ -18,7 +18,7 @@ function sanitizeProxyCredentials(envVar) {
18
18
  function bootstrap() {
19
19
  envVars.forEach((envVar) => {
20
20
  /* v8 ignore next -- env is case-insensitive on windows */
21
- if (typeof process.env[envVar] === "undefined" && typeof process.env[envVar.toLowerCase()] !== "undefined") process.env[envVar] = process.env[envVar.toLowerCase()];
21
+ if (isUndefined(process.env[envVar]) && !isUndefined(process.env[envVar.toLowerCase()])) process.env[envVar] = process.env[envVar.toLowerCase()];
22
22
  if (process.env[envVar]) {
23
23
  logger.debug(`Detected ${envVar} value in env`);
24
24
  process.env[envVar.toLowerCase()] = process.env[envVar];
package/dist/proxy.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"proxy.js","names":[],"sources":["../lib/proxy.ts"],"sourcesContent":["import { isNonEmptyString } from '@sindresorhus/is';\nimport { createGlobalProxyAgent } from 'global-agent';\nimport { logger } from './logger/index.ts';\nimport { addSecretForSanitizing } from './util/sanitize.ts';\nimport { parseUrl } from './util/url.ts';\n\nconst envVars = ['HTTP_PROXY', 'HTTPS_PROXY', 'NO_PROXY'];\nconst proxyEnvVarsWithCredentials = ['HTTP_PROXY', 'HTTPS_PROXY'];\n\nlet agent = false;\n\nfunction sanitizeProxyCredentials(envVar: string): void {\n const uri = parseUrl(process.env[envVar]);\n if (uri?.password) {\n addSecretForSanitizing(uri.password, 'global');\n }\n}\n\nexport function bootstrap(): void {\n envVars.forEach((envVar) => {\n /* v8 ignore next -- env is case-insensitive on windows */\n if (\n typeof process.env[envVar] === 'undefined' &&\n typeof process.env[envVar.toLowerCase()] !== 'undefined'\n ) {\n process.env[envVar] = process.env[envVar.toLowerCase()];\n }\n\n if (process.env[envVar]) {\n logger.debug(`Detected ${envVar} value in env`);\n process.env[envVar.toLowerCase()] = process.env[envVar];\n }\n });\n\n proxyEnvVarsWithCredentials.forEach(sanitizeProxyCredentials);\n\n if (\n isNonEmptyString(process.env.HTTP_PROXY) ||\n isNonEmptyString(process.env.HTTPS_PROXY)\n ) {\n createGlobalProxyAgent({\n environmentVariableNamespace: '',\n });\n agent = true;\n } else {\n // for testing only, does not reset global agent\n agent = false;\n }\n}\n\n// will be used by our http layer later\nexport function hasProxy(): boolean {\n return agent === true;\n}\n"],"mappings":";;;;;;AAMA,MAAM,UAAU;CAAC;CAAc;CAAe;AAAU;AACxD,MAAM,8BAA8B,CAAC,cAAc,aAAa;AAEhE,IAAI,QAAQ;AAEZ,SAAS,yBAAyB,QAAsB;CACtD,MAAM,MAAM,SAAS,QAAQ,IAAI,OAAO;CACxC,IAAI,KAAK,UACP,uBAAuB,IAAI,UAAU,QAAQ;AAEjD;AAEA,SAAgB,YAAkB;CAChC,QAAQ,SAAS,WAAW;;EAE1B,IACE,OAAO,QAAQ,IAAI,YAAY,eAC/B,OAAO,QAAQ,IAAI,OAAO,YAAY,OAAO,aAE7C,QAAQ,IAAI,UAAU,QAAQ,IAAI,OAAO,YAAY;EAGvD,IAAI,QAAQ,IAAI,SAAS;GACvB,OAAO,MAAM,YAAY,OAAO,cAAc;GAC9C,QAAQ,IAAI,OAAO,YAAY,KAAK,QAAQ,IAAI;EAClD;CACF,CAAC;CAED,4BAA4B,QAAQ,wBAAwB;CAE5D,IACE,iBAAiB,QAAQ,IAAI,UAAU,KACvC,iBAAiB,QAAQ,IAAI,WAAW,GACxC;EACA,uBAAuB,EACrB,8BAA8B,GAChC,CAAC;EACD,QAAQ;CACV,OAEE,QAAQ;AAEZ;AAGA,SAAgB,WAAoB;CAClC,OAAO,UAAU;AACnB"}
1
+ {"version":3,"file":"proxy.js","names":[],"sources":["../lib/proxy.ts"],"sourcesContent":["import { isNonEmptyString, isUndefined } from '@sindresorhus/is';\nimport { createGlobalProxyAgent } from 'global-agent';\nimport { logger } from './logger/index.ts';\nimport { addSecretForSanitizing } from './util/sanitize.ts';\nimport { parseUrl } from './util/url.ts';\n\nconst envVars = ['HTTP_PROXY', 'HTTPS_PROXY', 'NO_PROXY'];\nconst proxyEnvVarsWithCredentials = ['HTTP_PROXY', 'HTTPS_PROXY'];\n\nlet agent = false;\n\nfunction sanitizeProxyCredentials(envVar: string): void {\n const uri = parseUrl(process.env[envVar]);\n if (uri?.password) {\n addSecretForSanitizing(uri.password, 'global');\n }\n}\n\nexport function bootstrap(): void {\n envVars.forEach((envVar) => {\n /* v8 ignore next -- env is case-insensitive on windows */\n if (\n isUndefined(process.env[envVar]) &&\n !isUndefined(process.env[envVar.toLowerCase()])\n ) {\n process.env[envVar] = process.env[envVar.toLowerCase()];\n }\n\n if (process.env[envVar]) {\n logger.debug(`Detected ${envVar} value in env`);\n process.env[envVar.toLowerCase()] = process.env[envVar];\n }\n });\n\n proxyEnvVarsWithCredentials.forEach(sanitizeProxyCredentials);\n\n if (\n isNonEmptyString(process.env.HTTP_PROXY) ||\n isNonEmptyString(process.env.HTTPS_PROXY)\n ) {\n createGlobalProxyAgent({\n environmentVariableNamespace: '',\n });\n agent = true;\n } else {\n // for testing only, does not reset global agent\n agent = false;\n }\n}\n\n// will be used by our http layer later\nexport function hasProxy(): boolean {\n return agent === true;\n}\n"],"mappings":";;;;;;AAMA,MAAM,UAAU;CAAC;CAAc;CAAe;AAAU;AACxD,MAAM,8BAA8B,CAAC,cAAc,aAAa;AAEhE,IAAI,QAAQ;AAEZ,SAAS,yBAAyB,QAAsB;CACtD,MAAM,MAAM,SAAS,QAAQ,IAAI,OAAO;CACxC,IAAI,KAAK,UACP,uBAAuB,IAAI,UAAU,QAAQ;AAEjD;AAEA,SAAgB,YAAkB;CAChC,QAAQ,SAAS,WAAW;;EAE1B,IACE,YAAY,QAAQ,IAAI,OAAO,KAC/B,CAAC,YAAY,QAAQ,IAAI,OAAO,YAAY,EAAE,GAE9C,QAAQ,IAAI,UAAU,QAAQ,IAAI,OAAO,YAAY;EAGvD,IAAI,QAAQ,IAAI,SAAS;GACvB,OAAO,MAAM,YAAY,OAAO,cAAc;GAC9C,QAAQ,IAAI,OAAO,YAAY,KAAK,QAAQ,IAAI;EAClD;CACF,CAAC;CAED,4BAA4B,QAAQ,wBAAwB;CAE5D,IACE,iBAAiB,QAAQ,IAAI,UAAU,KACvC,iBAAiB,QAAQ,IAAI,WAAW,GACxC;EACA,uBAAuB,EACrB,8BAA8B,GAChC,CAAC;EACD,QAAQ;CACV,OAEE,QAAQ;AAEZ;AAGA,SAAgB,WAAoB;CAClC,OAAO,UAAU;AACnB"}
@@ -1,5 +1,6 @@
1
1
  import { regEx } from "../regex.js";
2
2
  import { GlobalConfig } from "../../config/global.js";
3
+ import { isUndefined } from "@sindresorhus/is";
3
4
  //#region lib/util/exec/env.ts
4
5
  const basicEnvVars = [
5
6
  "HTTP_PROXY",
@@ -49,7 +50,7 @@ function getChildProcessEnv(customEnvVars = []) {
49
50
  ...hardcodedProcessEnv
50
51
  };
51
52
  [...basicEnvVars, ...customEnvVars].forEach((envVar) => {
52
- if (typeof process.env[envVar] !== "undefined") env[envVar] = process.env[envVar];
53
+ if (!isUndefined(process.env[envVar])) env[envVar] = process.env[envVar];
53
54
  });
54
55
  for (const key of Object.keys(process.env)) if (regEx(/^URL_REPLACE_\d+_(?:FROM|TO)$/).test(key)) env[key] = process.env[key];
55
56
  for (const [key, value] of Object.entries(hardcodedProcessEnv)) env[key] = value;
@@ -1 +1 @@
1
- {"version":3,"file":"env.js","names":[],"sources":["../../../lib/util/exec/env.ts"],"sourcesContent":["import { GlobalConfig } from '../../config/global.ts';\nimport { regEx } from '../regex.ts';\n\nexport const basicEnvVars = [\n 'HTTP_PROXY',\n 'HTTPS_PROXY',\n 'NO_PROXY',\n 'http_proxy',\n 'https_proxy',\n 'no_proxy',\n 'HOME',\n 'PATH',\n 'LC_ALL',\n 'LANG',\n 'DOCKER_HOST',\n 'DOCKER_TLS_VERIFY',\n 'DOCKER_CERT_PATH',\n // Custom certificate variables\n // https://github.com/containerbase/base/blob/main/docs/custom-root-ca.md\n 'SSL_CERT_DIR',\n 'SSL_CERT_FILE',\n 'NODE_EXTRA_CA_CERTS',\n 'GIT_SSL_CAPATH',\n 'GIT_SSL_CAINFO',\n // Required for NuGet to work on Windows.\n 'PROGRAMFILES',\n 'PROGRAMFILES(X86)',\n 'APPDATA',\n 'LOCALAPPDATA',\n // Required for .NET dotnet-install.ps1 to work on Windows.\n 'PROCESSOR_ARCHITECTURE',\n 'PATHEXT',\n // Corepack: https://github.com/nodejs/corepack\n 'COREPACK_DEFAULT_TO_LATEST',\n 'COREPACK_ENABLE_NETWORK',\n 'COREPACK_ENABLE_STRICT',\n 'COREPACK_ENABLE_PROJECT_SPEC',\n 'COREPACK_ENABLE_UNSAFE_CUSTOM_URLS',\n 'COREPACK_HOME',\n 'COREPACK_INTEGRITY_KEYS',\n 'COREPACK_NPM_REGISTRY',\n 'COREPACK_NPM_TOKEN',\n 'COREPACK_NPM_USERNAME',\n 'COREPACK_NPM_PASSWORD',\n 'COREPACK_ROOT',\n // pnpm specific variables\n 'PNPM_WORKERS',\n 'PNPM_MAX_WORKERS',\n] as const;\n\nexport const hardcodedProcessEnv: Readonly<NodeJS.ProcessEnv> = {\n CI: 'true',\n} as const;\n\nexport function getChildProcessEnv(\n customEnvVars: string[] = [],\n): NodeJS.ProcessEnv {\n const env: NodeJS.ProcessEnv = {};\n if (GlobalConfig.get('exposeAllEnv')) {\n return { ...process.env, ...hardcodedProcessEnv };\n }\n const envVars = [...basicEnvVars, ...customEnvVars];\n envVars.forEach((envVar) => {\n if (typeof process.env[envVar] !== 'undefined') {\n env[envVar] = process.env[envVar];\n }\n });\n\n // Copy containerbase url replacements\n for (const key of Object.keys(process.env)) {\n if (regEx(/^URL_REPLACE_\\d+_(?:FROM|TO)$/).test(key)) {\n env[key] = process.env[key];\n }\n }\n\n for (const [key, value] of Object.entries(hardcodedProcessEnv)) {\n env[key] = value;\n }\n\n return env;\n}\n"],"mappings":";;;AAGA,MAAa,eAAe;CAC1B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAGA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CAEA;CACA;CAEA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;AACF;AAEA,MAAa,sBAAmD,EAC9D,IAAI,OACN;AAEA,SAAgB,mBACd,gBAA0B,CAAC,GACR;CACnB,MAAM,MAAyB,CAAC;CAChC,IAAI,aAAa,IAAI,cAAc,GACjC,OAAO;EAAE,GAAG,QAAQ;EAAK,GAAG;CAAoB;CAGlD,CADiB,GAAG,cAAc,GAAG,aAC/B,CAAC,CAAC,SAAS,WAAW;EAC1B,IAAI,OAAO,QAAQ,IAAI,YAAY,aACjC,IAAI,UAAU,QAAQ,IAAI;CAE9B,CAAC;CAGD,KAAK,MAAM,OAAO,OAAO,KAAK,QAAQ,GAAG,GACvC,IAAI,MAAM,+BAA+B,CAAC,CAAC,KAAK,GAAG,GACjD,IAAI,OAAO,QAAQ,IAAI;CAI3B,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,mBAAmB,GAC3D,IAAI,OAAO;CAGb,OAAO;AACT"}
1
+ {"version":3,"file":"env.js","names":[],"sources":["../../../lib/util/exec/env.ts"],"sourcesContent":["import { isUndefined } from '@sindresorhus/is';\nimport { GlobalConfig } from '../../config/global.ts';\nimport { regEx } from '../regex.ts';\n\nexport const basicEnvVars = [\n 'HTTP_PROXY',\n 'HTTPS_PROXY',\n 'NO_PROXY',\n 'http_proxy',\n 'https_proxy',\n 'no_proxy',\n 'HOME',\n 'PATH',\n 'LC_ALL',\n 'LANG',\n 'DOCKER_HOST',\n 'DOCKER_TLS_VERIFY',\n 'DOCKER_CERT_PATH',\n // Custom certificate variables\n // https://github.com/containerbase/base/blob/main/docs/custom-root-ca.md\n 'SSL_CERT_DIR',\n 'SSL_CERT_FILE',\n 'NODE_EXTRA_CA_CERTS',\n 'GIT_SSL_CAPATH',\n 'GIT_SSL_CAINFO',\n // Required for NuGet to work on Windows.\n 'PROGRAMFILES',\n 'PROGRAMFILES(X86)',\n 'APPDATA',\n 'LOCALAPPDATA',\n // Required for .NET dotnet-install.ps1 to work on Windows.\n 'PROCESSOR_ARCHITECTURE',\n 'PATHEXT',\n // Corepack: https://github.com/nodejs/corepack\n 'COREPACK_DEFAULT_TO_LATEST',\n 'COREPACK_ENABLE_NETWORK',\n 'COREPACK_ENABLE_STRICT',\n 'COREPACK_ENABLE_PROJECT_SPEC',\n 'COREPACK_ENABLE_UNSAFE_CUSTOM_URLS',\n 'COREPACK_HOME',\n 'COREPACK_INTEGRITY_KEYS',\n 'COREPACK_NPM_REGISTRY',\n 'COREPACK_NPM_TOKEN',\n 'COREPACK_NPM_USERNAME',\n 'COREPACK_NPM_PASSWORD',\n 'COREPACK_ROOT',\n // pnpm specific variables\n 'PNPM_WORKERS',\n 'PNPM_MAX_WORKERS',\n] as const;\n\nexport const hardcodedProcessEnv: Readonly<NodeJS.ProcessEnv> = {\n CI: 'true',\n} as const;\n\nexport function getChildProcessEnv(\n customEnvVars: string[] = [],\n): NodeJS.ProcessEnv {\n const env: NodeJS.ProcessEnv = {};\n if (GlobalConfig.get('exposeAllEnv')) {\n return { ...process.env, ...hardcodedProcessEnv };\n }\n const envVars = [...basicEnvVars, ...customEnvVars];\n envVars.forEach((envVar) => {\n if (!isUndefined(process.env[envVar])) {\n env[envVar] = process.env[envVar];\n }\n });\n\n // Copy containerbase url replacements\n for (const key of Object.keys(process.env)) {\n if (regEx(/^URL_REPLACE_\\d+_(?:FROM|TO)$/).test(key)) {\n env[key] = process.env[key];\n }\n }\n\n for (const [key, value] of Object.entries(hardcodedProcessEnv)) {\n env[key] = value;\n }\n\n return env;\n}\n"],"mappings":";;;;AAIA,MAAa,eAAe;CAC1B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAGA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CAEA;CACA;CAEA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;AACF;AAEA,MAAa,sBAAmD,EAC9D,IAAI,OACN;AAEA,SAAgB,mBACd,gBAA0B,CAAC,GACR;CACnB,MAAM,MAAyB,CAAC;CAChC,IAAI,aAAa,IAAI,cAAc,GACjC,OAAO;EAAE,GAAG,QAAQ;EAAK,GAAG;CAAoB;CAGlD,CADiB,GAAG,cAAc,GAAG,aAC/B,CAAC,CAAC,SAAS,WAAW;EAC1B,IAAI,CAAC,YAAY,QAAQ,IAAI,OAAO,GAClC,IAAI,UAAU,QAAQ,IAAI;CAE9B,CAAC;CAGD,KAAK,MAAM,OAAO,OAAO,KAAK,QAAQ,GAAG,GACvC,IAAI,MAAM,+BAA+B,CAAC,CAAC,KAAK,GAAG,GACjD,IAAI,OAAO,QAAQ,IAAI;CAI3B,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,mBAAmB,GAC3D,IAAI,OAAO;CAGb,OAAO;AACT"}
@@ -1,12 +1,13 @@
1
+ import { isFunction, isSymbol } from "@sindresorhus/is";
1
2
  import { createHash } from "node:crypto";
2
3
  //#region lib/util/fingerprint.ts
3
4
  function isEmittable(value, cache) {
4
- if (value === void 0 || typeof value === "function" || typeof value === "symbol") return false;
5
+ if (value === void 0 || isFunction(value) || isSymbol(value)) return false;
5
6
  if (value === null || typeof value !== "object") return true;
6
7
  const cached = cache.get(value);
7
8
  if (cached !== void 0) return cached;
8
9
  const obj = value;
9
- const result = typeof obj.toJSON === "function" ? isEmittable(obj.toJSON(), cache) : true;
10
+ const result = isFunction(obj.toJSON) ? isEmittable(obj.toJSON(), cache) : true;
10
11
  cache.set(value, result);
11
12
  return result;
12
13
  }
@@ -16,7 +17,7 @@ function fingerprintInto(h, value, seen, emittableCache) {
16
17
  return;
17
18
  }
18
19
  const obj = value;
19
- if (typeof obj.toJSON === "function") {
20
+ if (isFunction(obj.toJSON)) {
20
21
  fingerprintInto(h, obj.toJSON(), seen, emittableCache);
21
22
  return;
22
23
  }
@@ -1 +1 @@
1
- {"version":3,"file":"fingerprint.js","names":[],"sources":["../../lib/util/fingerprint.ts"],"sourcesContent":["import { type Hash, createHash } from 'node:crypto';\n\n// Returns true when `value` would appear in the canonical JSON produced by\n// `safe-stable-stringify`. We pre-check before emitting because objects must\n// drop keys whose value resolves to nothing (incl. via toJSON → undefined),\n// and incremental hashing can't roll back already-emitted bytes.\n//\n// `cache` memoizes the result per object reference so callers that invoke\n// isEmittable just before recursing don't re-walk the toJSON chain twice.\nfunction isEmittable(value: unknown, cache: WeakMap<object, boolean>): boolean {\n if (\n value === undefined ||\n typeof value === 'function' ||\n typeof value === 'symbol'\n ) {\n return false;\n }\n // oxlint-disable-next-line renovate/prefer-is-object -- byte-exact JSON canonicalization: functions are handled explicitly above and must not take the object path\n if (value === null || typeof value !== 'object') {\n return true;\n }\n const cached = cache.get(value);\n if (cached !== undefined) {\n return cached;\n }\n const obj = value as { toJSON?: () => unknown };\n const result =\n typeof obj.toJSON === 'function' ? isEmittable(obj.toJSON(), cache) : true;\n cache.set(value, result);\n return result;\n}\n\n// Walks `value` and emits canonical JSON chunks directly into `h`,\n// matching `safe-stable-stringify` (deterministic mode) byte-for-byte\n// without materializing the full string. Required to avoid V8's max\n// string length when the input is large (e.g. a PR carrying upgrades\n// across hundreds of manifest files).\nfunction fingerprintInto(\n h: Hash,\n value: unknown,\n seen: WeakSet<object>,\n emittableCache: WeakMap<object, boolean>,\n): void {\n // oxlint-disable-next-line renovate/prefer-is-object -- byte-exact JSON canonicalization: functions must take the JSON.stringify primitive path, but isObject() matches them\n if (value === null || typeof value !== 'object') {\n h.update(JSON.stringify(value));\n return;\n }\n\n const obj = value as { toJSON?: () => unknown };\n if (typeof obj.toJSON === 'function') {\n fingerprintInto(h, obj.toJSON(), seen, emittableCache);\n return;\n }\n\n if (seen.has(value)) {\n h.update('\"[Circular]\"');\n return;\n }\n seen.add(value);\n\n if (Array.isArray(value)) {\n h.update('[');\n for (let i = 0; i < value.length; i++) {\n if (i > 0) {\n h.update(',');\n }\n const item: unknown = value[i];\n if (isEmittable(item, emittableCache)) {\n fingerprintInto(h, item, seen, emittableCache);\n } else {\n h.update('null');\n }\n }\n h.update(']');\n } else {\n const entries = value as Record<string, unknown>;\n const keys = Object.keys(entries).sort();\n h.update('{');\n let first = true;\n for (const k of keys) {\n const v = entries[k];\n if (!isEmittable(v, emittableCache)) {\n continue;\n }\n if (!first) {\n h.update(',');\n }\n first = false;\n h.update(JSON.stringify(k));\n h.update(':');\n fingerprintInto(h, v, seen, emittableCache);\n }\n h.update('}');\n }\n seen.delete(value);\n}\n\nexport function fingerprint(input: unknown): string {\n const emittableCache = new WeakMap<object, boolean>();\n if (!isEmittable(input, emittableCache)) {\n return '';\n }\n const h = createHash('sha512');\n fingerprintInto(h, input, new WeakSet(), emittableCache);\n return h.digest('hex');\n}\n"],"mappings":";;AASA,SAAS,YAAY,OAAgB,OAA0C;CAC7E,IACE,UAAU,KAAA,KACV,OAAO,UAAU,cACjB,OAAO,UAAU,UAEjB,OAAO;CAGT,IAAI,UAAU,QAAQ,OAAO,UAAU,UACrC,OAAO;CAET,MAAM,SAAS,MAAM,IAAI,KAAK;CAC9B,IAAI,WAAW,KAAA,GACb,OAAO;CAET,MAAM,MAAM;CACZ,MAAM,SACJ,OAAO,IAAI,WAAW,aAAa,YAAY,IAAI,OAAO,GAAG,KAAK,IAAI;CACxE,MAAM,IAAI,OAAO,MAAM;CACvB,OAAO;AACT;AAOA,SAAS,gBACP,GACA,OACA,MACA,gBACM;CAEN,IAAI,UAAU,QAAQ,OAAO,UAAU,UAAU;EAC/C,EAAE,OAAO,KAAK,UAAU,KAAK,CAAC;EAC9B;CACF;CAEA,MAAM,MAAM;CACZ,IAAI,OAAO,IAAI,WAAW,YAAY;EACpC,gBAAgB,GAAG,IAAI,OAAO,GAAG,MAAM,cAAc;EACrD;CACF;CAEA,IAAI,KAAK,IAAI,KAAK,GAAG;EACnB,EAAE,OAAO,gBAAc;EACvB;CACF;CACA,KAAK,IAAI,KAAK;CAEd,IAAI,MAAM,QAAQ,KAAK,GAAG;EACxB,EAAE,OAAO,GAAG;EACZ,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;GACrC,IAAI,IAAI,GACN,EAAE,OAAO,GAAG;GAEd,MAAM,OAAgB,MAAM;GAC5B,IAAI,YAAY,MAAM,cAAc,GAClC,gBAAgB,GAAG,MAAM,MAAM,cAAc;QAE7C,EAAE,OAAO,MAAM;EAEnB;EACA,EAAE,OAAO,GAAG;CACd,OAAO;EACL,MAAM,UAAU;EAChB,MAAM,OAAO,OAAO,KAAK,OAAO,CAAC,CAAC,KAAK;EACvC,EAAE,OAAO,GAAG;EACZ,IAAI,QAAQ;EACZ,KAAK,MAAM,KAAK,MAAM;GACpB,MAAM,IAAI,QAAQ;GAClB,IAAI,CAAC,YAAY,GAAG,cAAc,GAChC;GAEF,IAAI,CAAC,OACH,EAAE,OAAO,GAAG;GAEd,QAAQ;GACR,EAAE,OAAO,KAAK,UAAU,CAAC,CAAC;GAC1B,EAAE,OAAO,GAAG;GACZ,gBAAgB,GAAG,GAAG,MAAM,cAAc;EAC5C;EACA,EAAE,OAAO,GAAG;CACd;CACA,KAAK,OAAO,KAAK;AACnB;AAEA,SAAgB,YAAY,OAAwB;CAClD,MAAM,iCAAiB,IAAI,QAAyB;CACpD,IAAI,CAAC,YAAY,OAAO,cAAc,GACpC,OAAO;CAET,MAAM,IAAI,WAAW,QAAQ;CAC7B,gBAAgB,GAAG,uBAAO,IAAI,QAAQ,GAAG,cAAc;CACvD,OAAO,EAAE,OAAO,KAAK;AACvB"}
1
+ {"version":3,"file":"fingerprint.js","names":[],"sources":["../../lib/util/fingerprint.ts"],"sourcesContent":["import { type Hash, createHash } from 'node:crypto';\nimport { isFunction, isSymbol } from '@sindresorhus/is';\n\n// Returns true when `value` would appear in the canonical JSON produced by\n// `safe-stable-stringify`. We pre-check before emitting because objects must\n// drop keys whose value resolves to nothing (incl. via toJSON → undefined),\n// and incremental hashing can't roll back already-emitted bytes.\n//\n// `cache` memoizes the result per object reference so callers that invoke\n// isEmittable just before recursing don't re-walk the toJSON chain twice.\nfunction isEmittable(value: unknown, cache: WeakMap<object, boolean>): boolean {\n if (value === undefined || isFunction(value) || isSymbol(value)) {\n return false;\n }\n // oxlint-disable-next-line renovate/prefer-is-object -- byte-exact JSON canonicalization: functions are handled explicitly above and must not take the object path\n if (value === null || typeof value !== 'object') {\n return true;\n }\n const cached = cache.get(value);\n if (cached !== undefined) {\n return cached;\n }\n const obj = value as { toJSON?: () => unknown };\n const result = isFunction(obj.toJSON)\n ? isEmittable(obj.toJSON(), cache)\n : true;\n cache.set(value, result);\n return result;\n}\n\n// Walks `value` and emits canonical JSON chunks directly into `h`,\n// matching `safe-stable-stringify` (deterministic mode) byte-for-byte\n// without materializing the full string. Required to avoid V8's max\n// string length when the input is large (e.g. a PR carrying upgrades\n// across hundreds of manifest files).\nfunction fingerprintInto(\n h: Hash,\n value: unknown,\n seen: WeakSet<object>,\n emittableCache: WeakMap<object, boolean>,\n): void {\n // oxlint-disable-next-line renovate/prefer-is-object -- byte-exact JSON canonicalization: functions must take the JSON.stringify primitive path, but isObject() matches them\n if (value === null || typeof value !== 'object') {\n h.update(JSON.stringify(value));\n return;\n }\n\n const obj = value as { toJSON?: () => unknown };\n if (isFunction(obj.toJSON)) {\n fingerprintInto(h, obj.toJSON(), seen, emittableCache);\n return;\n }\n\n if (seen.has(value)) {\n h.update('\"[Circular]\"');\n return;\n }\n seen.add(value);\n\n if (Array.isArray(value)) {\n h.update('[');\n for (let i = 0; i < value.length; i++) {\n if (i > 0) {\n h.update(',');\n }\n const item: unknown = value[i];\n if (isEmittable(item, emittableCache)) {\n fingerprintInto(h, item, seen, emittableCache);\n } else {\n h.update('null');\n }\n }\n h.update(']');\n } else {\n const entries = value as Record<string, unknown>;\n const keys = Object.keys(entries).sort();\n h.update('{');\n let first = true;\n for (const k of keys) {\n const v = entries[k];\n if (!isEmittable(v, emittableCache)) {\n continue;\n }\n if (!first) {\n h.update(',');\n }\n first = false;\n h.update(JSON.stringify(k));\n h.update(':');\n fingerprintInto(h, v, seen, emittableCache);\n }\n h.update('}');\n }\n seen.delete(value);\n}\n\nexport function fingerprint(input: unknown): string {\n const emittableCache = new WeakMap<object, boolean>();\n if (!isEmittable(input, emittableCache)) {\n return '';\n }\n const h = createHash('sha512');\n fingerprintInto(h, input, new WeakSet(), emittableCache);\n return h.digest('hex');\n}\n"],"mappings":";;;AAUA,SAAS,YAAY,OAAgB,OAA0C;CAC7E,IAAI,UAAU,KAAA,KAAa,WAAW,KAAK,KAAK,SAAS,KAAK,GAC5D,OAAO;CAGT,IAAI,UAAU,QAAQ,OAAO,UAAU,UACrC,OAAO;CAET,MAAM,SAAS,MAAM,IAAI,KAAK;CAC9B,IAAI,WAAW,KAAA,GACb,OAAO;CAET,MAAM,MAAM;CACZ,MAAM,SAAS,WAAW,IAAI,MAAM,IAChC,YAAY,IAAI,OAAO,GAAG,KAAK,IAC/B;CACJ,MAAM,IAAI,OAAO,MAAM;CACvB,OAAO;AACT;AAOA,SAAS,gBACP,GACA,OACA,MACA,gBACM;CAEN,IAAI,UAAU,QAAQ,OAAO,UAAU,UAAU;EAC/C,EAAE,OAAO,KAAK,UAAU,KAAK,CAAC;EAC9B;CACF;CAEA,MAAM,MAAM;CACZ,IAAI,WAAW,IAAI,MAAM,GAAG;EAC1B,gBAAgB,GAAG,IAAI,OAAO,GAAG,MAAM,cAAc;EACrD;CACF;CAEA,IAAI,KAAK,IAAI,KAAK,GAAG;EACnB,EAAE,OAAO,gBAAc;EACvB;CACF;CACA,KAAK,IAAI,KAAK;CAEd,IAAI,MAAM,QAAQ,KAAK,GAAG;EACxB,EAAE,OAAO,GAAG;EACZ,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;GACrC,IAAI,IAAI,GACN,EAAE,OAAO,GAAG;GAEd,MAAM,OAAgB,MAAM;GAC5B,IAAI,YAAY,MAAM,cAAc,GAClC,gBAAgB,GAAG,MAAM,MAAM,cAAc;QAE7C,EAAE,OAAO,MAAM;EAEnB;EACA,EAAE,OAAO,GAAG;CACd,OAAO;EACL,MAAM,UAAU;EAChB,MAAM,OAAO,OAAO,KAAK,OAAO,CAAC,CAAC,KAAK;EACvC,EAAE,OAAO,GAAG;EACZ,IAAI,QAAQ;EACZ,KAAK,MAAM,KAAK,MAAM;GACpB,MAAM,IAAI,QAAQ;GAClB,IAAI,CAAC,YAAY,GAAG,cAAc,GAChC;GAEF,IAAI,CAAC,OACH,EAAE,OAAO,GAAG;GAEd,QAAQ;GACR,EAAE,OAAO,KAAK,UAAU,CAAC,CAAC;GAC1B,EAAE,OAAO,GAAG;GACZ,gBAAgB,GAAG,GAAG,MAAM,cAAc;EAC5C;EACA,EAAE,OAAO,GAAG;CACd;CACA,KAAK,OAAO,KAAK;AACnB;AAEA,SAAgB,YAAY,OAAwB;CAClD,MAAM,iCAAiB,IAAI,QAAyB;CACpD,IAAI,CAAC,YAAY,OAAO,cAAc,GACpC,OAAO;CAET,MAAM,IAAI,WAAW,QAAQ;CAC7B,gBAAgB,GAAG,uBAAO,IAAI,QAAQ,GAAG,cAAc;CACvD,OAAO,EAAE,OAAO,KAAK;AACvB"}
package/dist/util/html.js CHANGED
@@ -1,7 +1,8 @@
1
+ import { isUndefined } from "@sindresorhus/is";
1
2
  import { parse } from "node-html-parser";
2
3
  //#region lib/util/html.ts
3
4
  function parse$1(html, config) {
4
- if (typeof config !== "undefined") return parse(html, config);
5
+ if (!isUndefined(config)) return parse(html, config);
5
6
  return parse(html);
6
7
  }
7
8
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"html.js","names":["parse","_parse"],"sources":["../../lib/util/html.ts"],"sourcesContent":["import type { HTMLElement, Options } from 'node-html-parser';\nimport { parse as _parse } from 'node-html-parser';\n\nexport type { HTMLElement, Options };\n\nexport function parse(html: string, config?: Partial<Options>): HTMLElement {\n if (typeof config !== 'undefined') {\n return _parse(html, config);\n }\n\n return _parse(html);\n}\n"],"mappings":";;AAKA,SAAgBA,QAAM,MAAc,QAAwC;CAC1E,IAAI,OAAO,WAAW,aACpB,OAAOC,MAAO,MAAM,MAAM;CAG5B,OAAOA,MAAO,IAAI;AACpB"}
1
+ {"version":3,"file":"html.js","names":["parse","_parse"],"sources":["../../lib/util/html.ts"],"sourcesContent":["import { isUndefined } from '@sindresorhus/is';\nimport type { HTMLElement, Options } from 'node-html-parser';\nimport { parse as _parse } from 'node-html-parser';\n\nexport type { HTMLElement, Options };\n\nexport function parse(html: string, config?: Partial<Options>): HTMLElement {\n if (!isUndefined(config)) {\n return _parse(html, config);\n }\n\n return _parse(html);\n}\n"],"mappings":";;;AAMA,SAAgBA,QAAM,MAAc,QAAwC;CAC1E,IAAI,CAAC,YAAY,MAAM,GACrB,OAAOC,MAAO,MAAM,MAAM;CAG5B,OAAOA,MAAO,IAAI;AACpB"}
@@ -1,9 +1,10 @@
1
1
  import { logger } from "../logger/index.js";
2
+ import { isBoolean, isUndefined } from "@sindresorhus/is";
2
3
  import { NEVER } from "zod/v4";
3
4
  //#region lib/util/result.ts
4
5
  function isZodResult(input) {
5
- if (typeof input !== "object" || input === null || Object.keys(input).length !== 2 || !("success" in input) || typeof input.success !== "boolean") return false;
6
- if (input.success) return "data" in input && typeof input.data !== "undefined" && input.data !== null;
6
+ if (typeof input !== "object" || input === null || Object.keys(input).length !== 2 || !("success" in input) || !isBoolean(input.success)) return false;
7
+ if (input.success) return "data" in input && !isUndefined(input.data) && input.data !== null;
7
8
  return "error" in input;
8
9
  }
9
10
  function fromZodResult(input) {
@@ -1 +1 @@
1
- {"version":3,"file":"result.js","names":[],"sources":["../../lib/util/result.ts"],"sourcesContent":["import type { ZodError, output as ZodOutput, ZodType } from 'zod/v4';\nimport { NEVER } from 'zod/v4';\nimport { logger } from '../logger/index.ts';\nimport type { Nullish } from '../types/index.ts';\n\ntype Val = NonNullable<unknown>;\n\n// ZodSafeParseResult is not exported from zod/v4 public API, derive from safeParse return type\ntype ZodSafeParseResult<T> = ReturnType<ZodType<T>['safeParse']>;\n\ninterface Ok<T extends Val> {\n readonly ok: true;\n readonly val: T;\n readonly err?: never;\n}\n\ninterface Err<E extends Val> {\n readonly ok: false;\n readonly err: E;\n readonly val?: never;\n\n /**\n * Internal flag to indicate that the error was thrown during `.transform()`\n * and will be re-thrown on `.unwrap()`.\n */\n readonly _uncaught?: true;\n}\n\ntype Res<T extends Val, E extends Val> = Ok<T> | Err<E>;\n\nfunction isZodResult<Output extends Val>(\n input: unknown,\n): input is ZodSafeParseResult<Output> {\n if (\n // oxlint-disable-next-line renovate/prefer-is-object -- guards arbitrary callback results; isObject() matches functions, which must never be classified as zod results\n typeof input !== 'object' ||\n input === null ||\n Object.keys(input).length !== 2 ||\n !('success' in input) ||\n typeof input.success !== 'boolean'\n ) {\n return false;\n }\n\n if (input.success) {\n return (\n 'data' in input &&\n typeof input.data !== 'undefined' &&\n input.data !== null\n );\n }\n return 'error' in input;\n}\n\nfunction fromZodResult<ZodOutput extends Val>(\n input: ZodSafeParseResult<ZodOutput>,\n): Result<ZodOutput, ZodError> {\n return input.success ? Result.ok(input.data) : Result.err(input.error);\n}\n\n/**\n * All non-nullable values that also are not Promises nor Zod results.\n * It's useful for restricting Zod results to not return `null` or `undefined`.\n */\ntype RawValue<T extends Val> = Exclude<\n T,\n ZodSafeParseResult<T> | Promise<unknown>\n>;\n\nfunction fromNullable<\n T extends Val,\n ErrForNull extends Val,\n ErrForUndefined extends Val,\n>(\n input: Nullish<T>,\n errForNull: ErrForNull,\n errForUndefined: ErrForUndefined,\n): Result<T, ErrForNull | ErrForUndefined> {\n if (input === null) {\n return Result.err(errForNull);\n }\n\n if (input === undefined) {\n return Result.err(errForUndefined);\n }\n\n return Result.ok(input);\n}\n\n/**\n * Class for representing a result that can fail.\n *\n * The mental model:\n * - `.wrap()` and `.wrapNullable()` are sinks\n * - `.transform()` are pipes which can be chained\n * - `.unwrap()` is the point of consumption\n */\nexport class Result<T extends Val, E extends Val = Error> {\n private readonly res: Res<T, E>;\n\n private constructor(res: Res<T, E>) {\n this.res = res;\n }\n\n static ok<T extends Val>(val: T): Result<T, never> {\n return new Result({ ok: true, val });\n }\n\n static err<E extends Val>(err: E): Result<never, E> {\n return new Result({ ok: false, err });\n }\n\n static _uncaught<E extends Val>(err: E): Result<never, E> {\n return new Result({ ok: false, err, _uncaught: true });\n }\n\n /**\n * Wrap a callback or promise in a Result in such a way that any thrown errors\n * are caught and wrapped with `Result.err()` (and hence never re-thrown).\n *\n * In case of a promise, the `AsyncResult` is returned.\n * Use `.unwrap()` to get the `Promise<Result<T, E>>` from `AsyncResult`.\n *\n * ```ts\n *\n * // SYNC\n * const parse = (json: string) => Result.wrap(() => JSON.parse(json));\n *\n * const { val, err } = parse('{\"foo\": \"bar\"}').unwrap();\n * expect(val).toEqual({ foo: 'bar' });\n * expect(err).toBeUndefined();\n *\n * const { val, err } = parse('!!!').unwrap();\n * expect(val).toBeUndefined();\n * expect(err).toBeInstanceOf(SyntaxError);\n *\n * // ASYNC\n * const request = (url: string) => Result.wrap(http.get(url));\n *\n * const { val, err } = await request('https://example.com').unwrap();\n * expect(val).toBeString();\n * expect(err).toBeUndefined();\n *\n * ```\n */\n static wrap<T extends Val>(\n zodResult: ZodSafeParseResult<T>,\n ): Result<T, ZodError>;\n static wrap<T extends Val, E extends Val = Error>(\n callback: () => RawValue<T>,\n ): Result<T, E>;\n static wrap<T extends Val, E extends Val = Error>(\n callback: () => Promise<RawValue<T>>,\n ): AsyncResult<T, E>;\n static wrap<T extends Val, E extends Val = Error, EE extends Val = never>(\n promise: Promise<Result<T, EE>>,\n ): AsyncResult<T, E | EE>;\n static wrap<T extends Val, E extends Val = Error>(\n promise: Promise<RawValue<T>>,\n ): AsyncResult<T, E>;\n static wrap<T extends Val, E extends Val = Error, EE extends Val = never>(\n input:\n | ZodSafeParseResult<T>\n | (() => RawValue<T>)\n | (() => Promise<RawValue<T>>)\n | Promise<Result<T, EE>>\n | Promise<RawValue<T>>,\n ): Result<T, ZodError> | Result<T, E | EE> | AsyncResult<T, E | EE> {\n if (isZodResult<T>(input)) {\n return fromZodResult<T>(input);\n }\n\n if (input instanceof Promise) {\n return AsyncResult.wrap(input);\n }\n\n try {\n const result = input();\n\n if (result instanceof Promise) {\n return AsyncResult.wrap(result);\n }\n\n return Result.ok(result);\n } catch (error) {\n return Result.err(error);\n }\n }\n\n /**\n * Similar to `Result.wrap()`, but helps to undo the billion dollar mistake by\n * replacing `null` or `undefined` with an error of provided type.\n *\n * Errors thrown inside the callback or promise are caught and wrapped with `Result.err()`,\n * hence never re-thrown.\n *\n * Since functions and promises returning nullable can't be wrapped with `Result.wrap()`\n * because `val` is constrained by being `NonNullable`, `null` and `undefined`\n * must be converted to some sort of `err` value.\n *\n * This method does exactly this, i.g. it is the feature-rich shorthand for:\n *\n * ```ts\n * const { val, err } = Result.wrap(() => {\n * const result = callback();\n * return result === null || result === undefined\n * ? Result.err('oops')\n * : Result.ok(result);\n * }).unwrap();\n * ```\n *\n * In case of a promise, the `AsyncResult` is returned.\n *\n * ```ts\n *\n * // SYNC\n * const getHostname = (url: string) =>\n * Result.wrapNullable(\n * () => parseUrl(url)?.hostname,\n * 'invalid-url' as const\n * );\n * const { val, err } = getHostname('foobar').unwrap();\n * expect(val).toBeUndefined();\n * expect(err).toBe('invalid-url');\n *\n * // ASYNC\n * const { val, err } = await Result.wrapNullable(\n * readLocalFile('yarn.lock'),\n * 'file-read-error' as const\n * ).unwrap();\n *\n * ```\n */\n static wrapNullable<\n T extends Val,\n E extends Val = Error,\n ErrForNullable extends Val = Error,\n >(\n callback: () => Nullish<T>,\n errForNullable: ErrForNullable,\n ): Result<T, E | ErrForNullable>;\n static wrapNullable<\n T extends Val,\n E extends Val = Error,\n ErrForNull extends Val = Error,\n ErrForUndefined extends Val = Error,\n >(\n callback: () => Nullish<T>,\n errForNull: ErrForNull,\n errForUndefined: ErrForUndefined,\n ): Result<T, E | ErrForNull | ErrForUndefined>;\n static wrapNullable<\n T extends Val,\n E extends Val = Error,\n ErrForNullable extends Val = Error,\n >(\n promise: Promise<Nullish<T>>,\n errForNullable: ErrForNullable,\n ): AsyncResult<T, E | ErrForNullable>;\n static wrapNullable<\n T extends Val,\n E extends Val = Error,\n ErrForNull extends Val = Error,\n ErrForUndefined extends Val = Error,\n >(\n promise: Promise<Nullish<T>>,\n errForNull: ErrForNull,\n errForUndefined: ErrForUndefined,\n ): AsyncResult<T, E | ErrForNull | ErrForUndefined>;\n static wrapNullable<\n T extends Val,\n E extends Val = Error,\n ErrForNullable extends Val = Error,\n >(\n value: Nullish<T>,\n errForNullable: ErrForNullable,\n ): Result<T, E | ErrForNullable>;\n static wrapNullable<\n T extends Val,\n E extends Val = Error,\n ErrForNull extends Val = Error,\n ErrForUndefined extends Val = Error,\n >(\n value: Nullish<T>,\n errForNull: ErrForNull,\n errForUndefined: ErrForUndefined,\n ): Result<T, E | ErrForNull | ErrForUndefined>;\n static wrapNullable<\n T extends Val,\n E extends Val = Error,\n ErrForNull extends Val = Error,\n ErrForUndefined extends Val = Error,\n >(\n input: (() => Nullish<T>) | Promise<Nullish<T>> | Nullish<T>,\n arg2: ErrForNull,\n arg3?: ErrForUndefined,\n ):\n | Result<T, E | ErrForNull | ErrForUndefined>\n | AsyncResult<T, E | ErrForNull | ErrForUndefined> {\n const errForNull = arg2;\n const errForUndefined = arg3 ?? arg2;\n\n if (input instanceof Promise) {\n return AsyncResult.wrapNullable(input, errForNull, errForUndefined);\n }\n\n if (input instanceof Function) {\n try {\n const result = input();\n return fromNullable(result, errForNull, errForUndefined);\n } catch (error) {\n return Result.err(error);\n }\n }\n\n return fromNullable(input, errForNull, errForUndefined);\n }\n\n /**\n * Returns a discriminated union for type-safe consumption of the result.\n * When error was uncaught during transformation, it's being re-thrown here.\n *\n * ```ts\n *\n * const { val, err } = Result.ok('foo').unwrap();\n * expect(val).toBe('foo');\n * expect(err).toBeUndefined();\n *\n * ```\n */\n unwrap(): Res<T, E> {\n if (this.res.ok) {\n return this.res;\n }\n\n if (this.res._uncaught) {\n // TODO: fix, should only allow `Error` type\n // oxlint-disable-next-line typescript/only-throw-error\n throw this.res.err;\n }\n\n return this.res;\n }\n\n /**\n * Returns a success value or a fallback value.\n * When error was uncaught during transformation, it's being re-thrown here.\n *\n * ```ts\n *\n * const value = Result.err('bar').unwrapOr('foo');\n * expect(val).toBe('foo');\n *\n * ```\n */\n unwrapOr(fallback: T): T {\n if (this.res.ok) {\n return this.res.val;\n }\n\n if (this.res._uncaught) {\n // TODO: fix, should only allow `Error` type\n // oxlint-disable-next-line typescript/only-throw-error\n throw this.res.err;\n }\n\n return fallback;\n }\n\n /**\n * Returns the ok-value or throw the error.\n */\n unwrapOrThrow(): T {\n if (this.res.ok) {\n return this.res.val;\n }\n\n // TODO: fix, should only allow `Error` type\n // oxlint-disable-next-line typescript/only-throw-error\n throw this.res.err;\n }\n\n /**\n * Returns the ok-value or `null`.\n * When error was uncaught during transformation, it's being re-thrown here.\n */\n unwrapOrNull(): T | null {\n if (this.res.ok) {\n return this.res.val;\n }\n\n if (this.res._uncaught) {\n // TODO: fix, should only allow `Error` type\n // oxlint-disable-next-line typescript/only-throw-error\n throw this.res.err;\n }\n\n return null;\n }\n\n /**\n * Transforms the ok-value, sync or async way.\n *\n * Transform functions SHOULD NOT throw.\n * Uncaught errors are logged and wrapped to `Result._uncaught()`,\n * which leads to re-throwing them in `unwrap()`.\n *\n * Zod `.safeParse()` results are converted automatically.\n *\n * ```ts\n *\n * // SYNC\n * const { val, err } = Result.ok('foo')\n * .transform((x) => x.length)\n * .unwrap();\n * expect(val).toBe(3);\n *\n * // ASYNC\n * const { val, err } = await Result.wrap(\n * http.getJson('https://api.example.com/data.json')\n * )\n * .transform(({ body }) => body)\n * .unwrap();\n *\n * ```\n */\n transform<U extends Val, EE extends Val>(\n fn: (value: T) => Result<U, E | EE>,\n ): Result<U, E | EE>;\n transform<U extends Val, EE extends Val>(\n fn: (value: T) => AsyncResult<U, E | EE>,\n ): AsyncResult<U, E | EE>;\n transform<U extends Val>(\n fn: (value: T) => ZodSafeParseResult<NonNullable<U>>,\n ): Result<U, E | ZodError>;\n transform<U extends Val>(\n fn: (value: T) => Promise<ZodSafeParseResult<NonNullable<U>>>,\n ): AsyncResult<U, E | ZodError>;\n transform<U extends Val, EE extends Val>(\n fn: (value: T) => Promise<Result<U, E | EE>>,\n ): AsyncResult<U, E | EE>;\n transform<U extends Val>(\n fn: (value: T) => Promise<RawValue<U>>,\n ): AsyncResult<U, E>;\n transform<U extends Val>(fn: (value: T) => RawValue<U>): Result<U, E>;\n transform<U extends Val, EE extends Val>(\n fn: (\n value: T,\n ) =>\n | Result<U, E | EE>\n | AsyncResult<U, E | EE>\n | ZodSafeParseResult<NonNullable<U>>\n | Promise<ZodSafeParseResult<NonNullable<U>>>\n | Promise<Result<U, E | EE>>\n | Promise<RawValue<U>>\n | RawValue<U>,\n ): Result<U, E | EE | ZodError> | AsyncResult<U, E | EE | ZodError> {\n if (!this.res.ok) {\n return Result.err(this.res.err);\n }\n\n try {\n const result = fn(this.res.val);\n\n if (result instanceof Result) {\n return result;\n }\n\n if (result instanceof AsyncResult) {\n return result;\n }\n\n if (isZodResult<U>(result)) {\n return fromZodResult<U>(result);\n }\n\n if (result instanceof Promise) {\n return AsyncResult.wrap(result, (err) => {\n logger.warn({ err }, 'Result: unhandled async transform error');\n return Result._uncaught(err);\n });\n }\n\n return Result.ok(result);\n } catch (err) {\n logger.warn({ err }, 'Result: unhandled transform error');\n return Result._uncaught(err);\n }\n }\n\n catch<U extends Val = T, EE extends Val = E>(\n fn: (err: E) => Result<U, EE>,\n ): Result<T | U, EE>;\n catch<U extends Val = T, EE extends Val = E>(\n fn: (err: E) => AsyncResult<U, EE>,\n ): AsyncResult<T | U, EE>;\n catch<U extends Val = T, EE extends Val = E>(\n fn: (err: E) => Promise<Result<U, EE>>,\n ): AsyncResult<T | U, EE>;\n catch<U extends Val = T, EE extends Val = E>(\n fn: (err: E) => Result<U, EE> | AsyncResult<U, EE> | Promise<Result<U, EE>>,\n ): Result<T | U, EE> | AsyncResult<T | U, EE> {\n if (this.res.ok) {\n return this as never;\n }\n\n if (this.res._uncaught) {\n return this as never;\n }\n\n try {\n const result = fn(this.res.err);\n\n if (result instanceof Promise) {\n return AsyncResult.wrap(result, (err) => {\n logger.warn(\n { err },\n 'Result: unexpected error in async catch handler',\n );\n return Result._uncaught(err);\n });\n }\n\n return result;\n } catch (err) {\n logger.warn({ err }, 'Result: unexpected error in catch handler');\n return Result._uncaught(err);\n }\n }\n\n /**\n * Given a `schema` and `input`, returns a `Result` with `val` being the parsed value.\n * Additionally, `null` and `undefined` values are converted into Zod error.\n */\n static parse<Schema extends ZodType<any, any, any>>(\n input: unknown,\n schema: Schema,\n ): Result<NonNullable<ZodOutput<Schema>>, ZodError> {\n const parseResult = schema\n .transform((result, ctx): NonNullable<ZodOutput<Schema>> => {\n if (result === undefined) {\n ctx.addIssue({\n code: 'custom',\n message: `Result can't accept nullish values, but input was parsed by Zod schema to undefined`,\n });\n return NEVER;\n }\n\n if (result === null) {\n ctx.addIssue({\n code: 'custom',\n message: `Result can't accept nullish values, but input was parsed by Zod schema to null`,\n });\n return NEVER;\n }\n\n return result;\n })\n .safeParse(input);\n\n return fromZodResult<NonNullable<ZodOutput<Schema>>>(parseResult);\n }\n\n /**\n * Given a `schema`, returns a `Result` with `val` being the parsed value.\n * Additionally, `null` and `undefined` values are converted into Zod error.\n */\n parse<Schema extends ZodType<any, any, any>>(\n schema: Schema,\n ): Result<NonNullable<ZodOutput<Schema>>, E | ZodError> {\n if (this.res.ok) {\n return Result.parse(this.res.val, schema);\n }\n\n const err = this.res.err;\n\n if (this.res._uncaught) {\n return Result._uncaught(err);\n }\n\n return Result.err(err);\n }\n\n /**\n * Call `fn` on the `val` if the result is ok.\n */\n onValue(fn: (value: T) => void): Result<T, E> {\n if (this.res.ok) {\n try {\n fn(this.res.val);\n } catch (err) {\n return Result._uncaught(err);\n }\n }\n\n return this;\n }\n\n /**\n * Call `fn` on the `err` if the result is err.\n */\n onError(fn: (err: E) => void): Result<T, E> {\n if (!this.res.ok) {\n try {\n fn(this.res.err);\n } catch (err) {\n return Result._uncaught(err);\n }\n }\n\n return this;\n }\n}\n\n/**\n * This class is being used when `Result` methods encounter async code.\n * It isn't meant to be used directly, but exported for usage in type annotations.\n *\n * All the methods resemble `Result` methods, but work asynchronously.\n */\nexport class AsyncResult<T extends Val, E extends Val> implements PromiseLike<\n Result<T, E>\n> {\n private asyncResult: Promise<Result<T, E>>;\n\n private constructor(asyncResult: Promise<Result<T, E>>) {\n this.asyncResult = asyncResult;\n }\n\n // oxlint-disable-next-line unicorn/no-thenable -- required to implement PromiseLike\n then<TResult1 = Result<T, E>>(\n onfulfilled?:\n | ((value: Result<T, E>) => TResult1 | PromiseLike<TResult1>)\n | null,\n ): PromiseLike<TResult1> {\n return this.asyncResult.then(onfulfilled);\n }\n\n static ok<T extends Val>(val: T): AsyncResult<T, never> {\n return new AsyncResult(Promise.resolve(Result.ok(val)));\n }\n\n static err<E extends Val>(err: NonNullable<E>): AsyncResult<never, E> {\n return new AsyncResult(Promise.resolve(Result.err(err)));\n }\n\n static wrap<T extends Val, E extends Val = Error, EE extends Val = never>(\n promise:\n | Promise<ZodSafeParseResult<T>>\n | Promise<Result<T, EE>>\n | Promise<RawValue<T>>,\n onErr?: (err: NonNullable<E>) => Result<T, E>,\n ): AsyncResult<T, E | EE> {\n return new AsyncResult(\n promise\n .then((value) => {\n if (value instanceof Result) {\n return value;\n }\n\n if (isZodResult<T>(value)) {\n return fromZodResult<T>(value);\n }\n\n return Result.ok(value);\n })\n .catch((err) => {\n if (onErr) {\n return onErr(err);\n }\n return Result.err(err);\n }),\n );\n }\n\n static wrapNullable<\n T extends Val,\n E extends Val,\n ErrForNull extends Val,\n ErrForUndefined extends Val,\n >(\n promise: Promise<Nullish<T>>,\n errForNull: NonNullable<ErrForNull>,\n errForUndefined: NonNullable<ErrForUndefined>,\n ): AsyncResult<T, E | ErrForNull | ErrForUndefined> {\n return new AsyncResult(\n promise\n .then((value) => fromNullable(value, errForNull, errForUndefined))\n .catch((err) => Result.err(err)),\n );\n }\n\n /**\n * Returns a discriminated union for type-safe consumption of the result.\n *\n * ```ts\n *\n * const { val, err } = await Result.wrap(readFile('foo.txt')).unwrap();\n * expect(val).toBe('foo');\n * expect(err).toBeUndefined();\n *\n * ```\n */\n unwrap(): Promise<Res<T, E>> {\n return this.asyncResult.then<Res<T, E>>((res) => res.unwrap());\n }\n\n /**\n * Returns a success value or a fallback value.\n *\n * ```ts\n *\n * const val = await Result.wrap(readFile('foo.txt')).unwrapOr('bar');\n * expect(val).toBe('bar');\n * expect(err).toBeUndefined();\n *\n * ```\n */\n unwrapOr(fallback: T): Promise<T> {\n return this.asyncResult.then<T>((res) => res.unwrapOr(fallback));\n }\n\n /**\n * Returns the ok-value or throw the error.\n */\n async unwrapOrThrow(): Promise<T> {\n const result = await this.asyncResult;\n return result.unwrapOrThrow();\n }\n\n /**\n * Returns the ok-value or `null`.\n */\n unwrapOrNull(): Promise<T | null> {\n return this.asyncResult.then<T | null>((res) => res.unwrapOrNull());\n }\n\n /**\n * Transforms the ok-value, sync or async way.\n *\n * Transform functions SHOULD NOT throw.\n * Uncaught errors are logged and wrapped to `Result._uncaught()`,\n * which leads to re-throwing them in `unwrap()`.\n *\n * Zod `.safeParse()` results are converted automatically.\n *\n * ```ts\n *\n * const { val, err } = await Result.wrap(\n * http.getJson('https://api.example.com/data.json')\n * )\n * .transform(({ body }) => body)\n * .unwrap();\n *\n * ```\n */\n transform<U extends Val, EE extends Val>(\n fn: (value: T) => Result<U, E | EE>,\n ): AsyncResult<U, E | EE>;\n transform<U extends Val, EE extends Val>(\n fn: (value: T) => AsyncResult<U, E | EE>,\n ): AsyncResult<U, E | EE>;\n transform<U extends Val>(\n fn: (value: T) => ZodSafeParseResult<NonNullable<U>>,\n ): AsyncResult<U, E | ZodError>;\n transform<U extends Val>(\n fn: (value: T) => Promise<ZodSafeParseResult<NonNullable<U>>>,\n ): AsyncResult<U, E | ZodError>;\n transform<U extends Val, EE extends Val>(\n fn: (value: T) => Promise<Result<U, E | EE>>,\n ): AsyncResult<U, E | EE>;\n transform<U extends Val>(\n fn: (value: T) => Promise<RawValue<U>>,\n ): AsyncResult<U, E>;\n transform<U extends Val>(fn: (value: T) => RawValue<U>): AsyncResult<U, E>;\n transform<U extends Val, EE extends Val>(\n fn: (\n value: T,\n ) =>\n | Result<U, E | EE>\n | AsyncResult<U, E | EE>\n | ZodSafeParseResult<NonNullable<U>>\n | Promise<ZodSafeParseResult<NonNullable<U>>>\n | Promise<Result<U, E | EE>>\n | Promise<RawValue<U>>\n | RawValue<U>,\n ): AsyncResult<U, E | EE | ZodError> {\n return new AsyncResult(\n this.asyncResult\n .then((oldResult) => {\n const { ok, val: value, err: error } = oldResult.unwrap();\n if (!ok) {\n return Result.err(error);\n }\n\n try {\n const result = fn(value);\n\n if (result instanceof Result) {\n return result;\n }\n\n if (result instanceof AsyncResult) {\n return result;\n }\n\n if (isZodResult<U>(result)) {\n return fromZodResult<U>(result);\n }\n\n if (result instanceof Promise) {\n return AsyncResult.wrap(result, (err) => {\n logger.warn(\n { err },\n 'AsyncResult: unhandled async transform error',\n );\n return Result._uncaught(err);\n });\n }\n\n return Result.ok(result);\n } catch (err) {\n logger.warn({ err }, 'AsyncResult: unhandled transform error');\n return Result._uncaught(err);\n }\n })\n .catch((err) => {\n // Happens when `.unwrap()` of `oldResult` throws\n return Result._uncaught(err);\n }),\n );\n }\n\n catch<U extends Val = T, EE extends Val = E>(\n fn: (err: NonNullable<E>) => Result<U, EE>,\n ): AsyncResult<T | U, EE>;\n catch<U extends Val = T, EE extends Val = E>(\n fn: (err: NonNullable<E>) => AsyncResult<U, EE>,\n ): AsyncResult<T | U, EE>;\n catch<U extends Val = T, EE extends Val = E>(\n fn: (err: NonNullable<E>) => Promise<Result<U, EE>>,\n ): AsyncResult<T | U, EE>;\n catch<U extends Val = T, EE extends Val = E>(\n fn: (\n err: NonNullable<E>,\n ) => Result<U, EE> | AsyncResult<U, EE> | Promise<Result<U, EE>>,\n ): AsyncResult<T | U, EE> {\n const caughtAsyncResult: Promise<Result<T, EE>> = this.asyncResult.then(\n (result) => result.catch(fn as never),\n );\n return AsyncResult.wrap(caughtAsyncResult);\n }\n\n /**\n * Given a `schema`, returns a `Result` with `val` being the parsed value.\n * Additionally, `null` and `undefined` values are converted into Zod error.\n */\n parse<Schema extends ZodType<any, any, any>>(\n schema: Schema,\n ): AsyncResult<NonNullable<ZodOutput<Schema>>, E | ZodError> {\n return new AsyncResult(\n this.asyncResult\n .then((oldResult) => oldResult.parse(schema))\n .catch(\n /* istanbul ignore next: should never happen */\n (err) => Result._uncaught(err),\n ),\n );\n }\n\n onValue(fn: (value: T) => void): AsyncResult<T, E> {\n return new AsyncResult(\n this.asyncResult\n .then((result) => result.onValue(fn))\n .catch(\n /* istanbul ignore next: should never happen */\n (err) => Result._uncaught(err),\n ),\n );\n }\n\n onError(fn: (err: E) => void): AsyncResult<T, E> {\n return new AsyncResult(\n this.asyncResult\n .then((result) => result.onError(fn))\n .catch(\n /* istanbul ignore next: should never happen */\n (err) => Result._uncaught(err),\n ),\n );\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"result.js","names":[],"sources":["../../lib/util/result.ts"],"sourcesContent":["import { isBoolean, isUndefined } from '@sindresorhus/is';\nimport type { ZodError, output as ZodOutput, ZodType } from 'zod/v4';\nimport { NEVER } from 'zod/v4';\nimport { logger } from '../logger/index.ts';\nimport type { Nullish } from '../types/index.ts';\n\ntype Val = NonNullable<unknown>;\n\n// ZodSafeParseResult is not exported from zod/v4 public API, derive from safeParse return type\ntype ZodSafeParseResult<T> = ReturnType<ZodType<T>['safeParse']>;\n\ninterface Ok<T extends Val> {\n readonly ok: true;\n readonly val: T;\n readonly err?: never;\n}\n\ninterface Err<E extends Val> {\n readonly ok: false;\n readonly err: E;\n readonly val?: never;\n\n /**\n * Internal flag to indicate that the error was thrown during `.transform()`\n * and will be re-thrown on `.unwrap()`.\n */\n readonly _uncaught?: true;\n}\n\ntype Res<T extends Val, E extends Val> = Ok<T> | Err<E>;\n\nfunction isZodResult<Output extends Val>(\n input: unknown,\n): input is ZodSafeParseResult<Output> {\n if (\n // oxlint-disable-next-line renovate/prefer-is-object -- guards arbitrary callback results; isObject() matches functions, which must never be classified as zod results\n typeof input !== 'object' ||\n input === null ||\n Object.keys(input).length !== 2 ||\n !('success' in input) ||\n !isBoolean(input.success)\n ) {\n return false;\n }\n\n if (input.success) {\n return 'data' in input && !isUndefined(input.data) && input.data !== null;\n }\n return 'error' in input;\n}\n\nfunction fromZodResult<ZodOutput extends Val>(\n input: ZodSafeParseResult<ZodOutput>,\n): Result<ZodOutput, ZodError> {\n return input.success ? Result.ok(input.data) : Result.err(input.error);\n}\n\n/**\n * All non-nullable values that also are not Promises nor Zod results.\n * It's useful for restricting Zod results to not return `null` or `undefined`.\n */\ntype RawValue<T extends Val> = Exclude<\n T,\n ZodSafeParseResult<T> | Promise<unknown>\n>;\n\nfunction fromNullable<\n T extends Val,\n ErrForNull extends Val,\n ErrForUndefined extends Val,\n>(\n input: Nullish<T>,\n errForNull: ErrForNull,\n errForUndefined: ErrForUndefined,\n): Result<T, ErrForNull | ErrForUndefined> {\n if (input === null) {\n return Result.err(errForNull);\n }\n\n if (input === undefined) {\n return Result.err(errForUndefined);\n }\n\n return Result.ok(input);\n}\n\n/**\n * Class for representing a result that can fail.\n *\n * The mental model:\n * - `.wrap()` and `.wrapNullable()` are sinks\n * - `.transform()` are pipes which can be chained\n * - `.unwrap()` is the point of consumption\n */\nexport class Result<T extends Val, E extends Val = Error> {\n private readonly res: Res<T, E>;\n\n private constructor(res: Res<T, E>) {\n this.res = res;\n }\n\n static ok<T extends Val>(val: T): Result<T, never> {\n return new Result({ ok: true, val });\n }\n\n static err<E extends Val>(err: E): Result<never, E> {\n return new Result({ ok: false, err });\n }\n\n static _uncaught<E extends Val>(err: E): Result<never, E> {\n return new Result({ ok: false, err, _uncaught: true });\n }\n\n /**\n * Wrap a callback or promise in a Result in such a way that any thrown errors\n * are caught and wrapped with `Result.err()` (and hence never re-thrown).\n *\n * In case of a promise, the `AsyncResult` is returned.\n * Use `.unwrap()` to get the `Promise<Result<T, E>>` from `AsyncResult`.\n *\n * ```ts\n *\n * // SYNC\n * const parse = (json: string) => Result.wrap(() => JSON.parse(json));\n *\n * const { val, err } = parse('{\"foo\": \"bar\"}').unwrap();\n * expect(val).toEqual({ foo: 'bar' });\n * expect(err).toBeUndefined();\n *\n * const { val, err } = parse('!!!').unwrap();\n * expect(val).toBeUndefined();\n * expect(err).toBeInstanceOf(SyntaxError);\n *\n * // ASYNC\n * const request = (url: string) => Result.wrap(http.get(url));\n *\n * const { val, err } = await request('https://example.com').unwrap();\n * expect(val).toBeString();\n * expect(err).toBeUndefined();\n *\n * ```\n */\n static wrap<T extends Val>(\n zodResult: ZodSafeParseResult<T>,\n ): Result<T, ZodError>;\n static wrap<T extends Val, E extends Val = Error>(\n callback: () => RawValue<T>,\n ): Result<T, E>;\n static wrap<T extends Val, E extends Val = Error>(\n callback: () => Promise<RawValue<T>>,\n ): AsyncResult<T, E>;\n static wrap<T extends Val, E extends Val = Error, EE extends Val = never>(\n promise: Promise<Result<T, EE>>,\n ): AsyncResult<T, E | EE>;\n static wrap<T extends Val, E extends Val = Error>(\n promise: Promise<RawValue<T>>,\n ): AsyncResult<T, E>;\n static wrap<T extends Val, E extends Val = Error, EE extends Val = never>(\n input:\n | ZodSafeParseResult<T>\n | (() => RawValue<T>)\n | (() => Promise<RawValue<T>>)\n | Promise<Result<T, EE>>\n | Promise<RawValue<T>>,\n ): Result<T, ZodError> | Result<T, E | EE> | AsyncResult<T, E | EE> {\n if (isZodResult<T>(input)) {\n return fromZodResult<T>(input);\n }\n\n if (input instanceof Promise) {\n return AsyncResult.wrap(input);\n }\n\n try {\n const result = input();\n\n if (result instanceof Promise) {\n return AsyncResult.wrap(result);\n }\n\n return Result.ok(result);\n } catch (error) {\n return Result.err(error);\n }\n }\n\n /**\n * Similar to `Result.wrap()`, but helps to undo the billion dollar mistake by\n * replacing `null` or `undefined` with an error of provided type.\n *\n * Errors thrown inside the callback or promise are caught and wrapped with `Result.err()`,\n * hence never re-thrown.\n *\n * Since functions and promises returning nullable can't be wrapped with `Result.wrap()`\n * because `val` is constrained by being `NonNullable`, `null` and `undefined`\n * must be converted to some sort of `err` value.\n *\n * This method does exactly this, i.g. it is the feature-rich shorthand for:\n *\n * ```ts\n * const { val, err } = Result.wrap(() => {\n * const result = callback();\n * return result === null || result === undefined\n * ? Result.err('oops')\n * : Result.ok(result);\n * }).unwrap();\n * ```\n *\n * In case of a promise, the `AsyncResult` is returned.\n *\n * ```ts\n *\n * // SYNC\n * const getHostname = (url: string) =>\n * Result.wrapNullable(\n * () => parseUrl(url)?.hostname,\n * 'invalid-url' as const\n * );\n * const { val, err } = getHostname('foobar').unwrap();\n * expect(val).toBeUndefined();\n * expect(err).toBe('invalid-url');\n *\n * // ASYNC\n * const { val, err } = await Result.wrapNullable(\n * readLocalFile('yarn.lock'),\n * 'file-read-error' as const\n * ).unwrap();\n *\n * ```\n */\n static wrapNullable<\n T extends Val,\n E extends Val = Error,\n ErrForNullable extends Val = Error,\n >(\n callback: () => Nullish<T>,\n errForNullable: ErrForNullable,\n ): Result<T, E | ErrForNullable>;\n static wrapNullable<\n T extends Val,\n E extends Val = Error,\n ErrForNull extends Val = Error,\n ErrForUndefined extends Val = Error,\n >(\n callback: () => Nullish<T>,\n errForNull: ErrForNull,\n errForUndefined: ErrForUndefined,\n ): Result<T, E | ErrForNull | ErrForUndefined>;\n static wrapNullable<\n T extends Val,\n E extends Val = Error,\n ErrForNullable extends Val = Error,\n >(\n promise: Promise<Nullish<T>>,\n errForNullable: ErrForNullable,\n ): AsyncResult<T, E | ErrForNullable>;\n static wrapNullable<\n T extends Val,\n E extends Val = Error,\n ErrForNull extends Val = Error,\n ErrForUndefined extends Val = Error,\n >(\n promise: Promise<Nullish<T>>,\n errForNull: ErrForNull,\n errForUndefined: ErrForUndefined,\n ): AsyncResult<T, E | ErrForNull | ErrForUndefined>;\n static wrapNullable<\n T extends Val,\n E extends Val = Error,\n ErrForNullable extends Val = Error,\n >(\n value: Nullish<T>,\n errForNullable: ErrForNullable,\n ): Result<T, E | ErrForNullable>;\n static wrapNullable<\n T extends Val,\n E extends Val = Error,\n ErrForNull extends Val = Error,\n ErrForUndefined extends Val = Error,\n >(\n value: Nullish<T>,\n errForNull: ErrForNull,\n errForUndefined: ErrForUndefined,\n ): Result<T, E | ErrForNull | ErrForUndefined>;\n static wrapNullable<\n T extends Val,\n E extends Val = Error,\n ErrForNull extends Val = Error,\n ErrForUndefined extends Val = Error,\n >(\n input: (() => Nullish<T>) | Promise<Nullish<T>> | Nullish<T>,\n arg2: ErrForNull,\n arg3?: ErrForUndefined,\n ):\n | Result<T, E | ErrForNull | ErrForUndefined>\n | AsyncResult<T, E | ErrForNull | ErrForUndefined> {\n const errForNull = arg2;\n const errForUndefined = arg3 ?? arg2;\n\n if (input instanceof Promise) {\n return AsyncResult.wrapNullable(input, errForNull, errForUndefined);\n }\n\n if (input instanceof Function) {\n try {\n const result = input();\n return fromNullable(result, errForNull, errForUndefined);\n } catch (error) {\n return Result.err(error);\n }\n }\n\n return fromNullable(input, errForNull, errForUndefined);\n }\n\n /**\n * Returns a discriminated union for type-safe consumption of the result.\n * When error was uncaught during transformation, it's being re-thrown here.\n *\n * ```ts\n *\n * const { val, err } = Result.ok('foo').unwrap();\n * expect(val).toBe('foo');\n * expect(err).toBeUndefined();\n *\n * ```\n */\n unwrap(): Res<T, E> {\n if (this.res.ok) {\n return this.res;\n }\n\n if (this.res._uncaught) {\n // TODO: fix, should only allow `Error` type\n // oxlint-disable-next-line typescript/only-throw-error\n throw this.res.err;\n }\n\n return this.res;\n }\n\n /**\n * Returns a success value or a fallback value.\n * When error was uncaught during transformation, it's being re-thrown here.\n *\n * ```ts\n *\n * const value = Result.err('bar').unwrapOr('foo');\n * expect(val).toBe('foo');\n *\n * ```\n */\n unwrapOr(fallback: T): T {\n if (this.res.ok) {\n return this.res.val;\n }\n\n if (this.res._uncaught) {\n // TODO: fix, should only allow `Error` type\n // oxlint-disable-next-line typescript/only-throw-error\n throw this.res.err;\n }\n\n return fallback;\n }\n\n /**\n * Returns the ok-value or throw the error.\n */\n unwrapOrThrow(): T {\n if (this.res.ok) {\n return this.res.val;\n }\n\n // TODO: fix, should only allow `Error` type\n // oxlint-disable-next-line typescript/only-throw-error\n throw this.res.err;\n }\n\n /**\n * Returns the ok-value or `null`.\n * When error was uncaught during transformation, it's being re-thrown here.\n */\n unwrapOrNull(): T | null {\n if (this.res.ok) {\n return this.res.val;\n }\n\n if (this.res._uncaught) {\n // TODO: fix, should only allow `Error` type\n // oxlint-disable-next-line typescript/only-throw-error\n throw this.res.err;\n }\n\n return null;\n }\n\n /**\n * Transforms the ok-value, sync or async way.\n *\n * Transform functions SHOULD NOT throw.\n * Uncaught errors are logged and wrapped to `Result._uncaught()`,\n * which leads to re-throwing them in `unwrap()`.\n *\n * Zod `.safeParse()` results are converted automatically.\n *\n * ```ts\n *\n * // SYNC\n * const { val, err } = Result.ok('foo')\n * .transform((x) => x.length)\n * .unwrap();\n * expect(val).toBe(3);\n *\n * // ASYNC\n * const { val, err } = await Result.wrap(\n * http.getJson('https://api.example.com/data.json')\n * )\n * .transform(({ body }) => body)\n * .unwrap();\n *\n * ```\n */\n transform<U extends Val, EE extends Val>(\n fn: (value: T) => Result<U, E | EE>,\n ): Result<U, E | EE>;\n transform<U extends Val, EE extends Val>(\n fn: (value: T) => AsyncResult<U, E | EE>,\n ): AsyncResult<U, E | EE>;\n transform<U extends Val>(\n fn: (value: T) => ZodSafeParseResult<NonNullable<U>>,\n ): Result<U, E | ZodError>;\n transform<U extends Val>(\n fn: (value: T) => Promise<ZodSafeParseResult<NonNullable<U>>>,\n ): AsyncResult<U, E | ZodError>;\n transform<U extends Val, EE extends Val>(\n fn: (value: T) => Promise<Result<U, E | EE>>,\n ): AsyncResult<U, E | EE>;\n transform<U extends Val>(\n fn: (value: T) => Promise<RawValue<U>>,\n ): AsyncResult<U, E>;\n transform<U extends Val>(fn: (value: T) => RawValue<U>): Result<U, E>;\n transform<U extends Val, EE extends Val>(\n fn: (\n value: T,\n ) =>\n | Result<U, E | EE>\n | AsyncResult<U, E | EE>\n | ZodSafeParseResult<NonNullable<U>>\n | Promise<ZodSafeParseResult<NonNullable<U>>>\n | Promise<Result<U, E | EE>>\n | Promise<RawValue<U>>\n | RawValue<U>,\n ): Result<U, E | EE | ZodError> | AsyncResult<U, E | EE | ZodError> {\n if (!this.res.ok) {\n return Result.err(this.res.err);\n }\n\n try {\n const result = fn(this.res.val);\n\n if (result instanceof Result) {\n return result;\n }\n\n if (result instanceof AsyncResult) {\n return result;\n }\n\n if (isZodResult<U>(result)) {\n return fromZodResult<U>(result);\n }\n\n if (result instanceof Promise) {\n return AsyncResult.wrap(result, (err) => {\n logger.warn({ err }, 'Result: unhandled async transform error');\n return Result._uncaught(err);\n });\n }\n\n return Result.ok(result);\n } catch (err) {\n logger.warn({ err }, 'Result: unhandled transform error');\n return Result._uncaught(err);\n }\n }\n\n catch<U extends Val = T, EE extends Val = E>(\n fn: (err: E) => Result<U, EE>,\n ): Result<T | U, EE>;\n catch<U extends Val = T, EE extends Val = E>(\n fn: (err: E) => AsyncResult<U, EE>,\n ): AsyncResult<T | U, EE>;\n catch<U extends Val = T, EE extends Val = E>(\n fn: (err: E) => Promise<Result<U, EE>>,\n ): AsyncResult<T | U, EE>;\n catch<U extends Val = T, EE extends Val = E>(\n fn: (err: E) => Result<U, EE> | AsyncResult<U, EE> | Promise<Result<U, EE>>,\n ): Result<T | U, EE> | AsyncResult<T | U, EE> {\n if (this.res.ok) {\n return this as never;\n }\n\n if (this.res._uncaught) {\n return this as never;\n }\n\n try {\n const result = fn(this.res.err);\n\n if (result instanceof Promise) {\n return AsyncResult.wrap(result, (err) => {\n logger.warn(\n { err },\n 'Result: unexpected error in async catch handler',\n );\n return Result._uncaught(err);\n });\n }\n\n return result;\n } catch (err) {\n logger.warn({ err }, 'Result: unexpected error in catch handler');\n return Result._uncaught(err);\n }\n }\n\n /**\n * Given a `schema` and `input`, returns a `Result` with `val` being the parsed value.\n * Additionally, `null` and `undefined` values are converted into Zod error.\n */\n static parse<Schema extends ZodType<any, any, any>>(\n input: unknown,\n schema: Schema,\n ): Result<NonNullable<ZodOutput<Schema>>, ZodError> {\n const parseResult = schema\n .transform((result, ctx): NonNullable<ZodOutput<Schema>> => {\n if (result === undefined) {\n ctx.addIssue({\n code: 'custom',\n message: `Result can't accept nullish values, but input was parsed by Zod schema to undefined`,\n });\n return NEVER;\n }\n\n if (result === null) {\n ctx.addIssue({\n code: 'custom',\n message: `Result can't accept nullish values, but input was parsed by Zod schema to null`,\n });\n return NEVER;\n }\n\n return result;\n })\n .safeParse(input);\n\n return fromZodResult<NonNullable<ZodOutput<Schema>>>(parseResult);\n }\n\n /**\n * Given a `schema`, returns a `Result` with `val` being the parsed value.\n * Additionally, `null` and `undefined` values are converted into Zod error.\n */\n parse<Schema extends ZodType<any, any, any>>(\n schema: Schema,\n ): Result<NonNullable<ZodOutput<Schema>>, E | ZodError> {\n if (this.res.ok) {\n return Result.parse(this.res.val, schema);\n }\n\n const err = this.res.err;\n\n if (this.res._uncaught) {\n return Result._uncaught(err);\n }\n\n return Result.err(err);\n }\n\n /**\n * Call `fn` on the `val` if the result is ok.\n */\n onValue(fn: (value: T) => void): Result<T, E> {\n if (this.res.ok) {\n try {\n fn(this.res.val);\n } catch (err) {\n return Result._uncaught(err);\n }\n }\n\n return this;\n }\n\n /**\n * Call `fn` on the `err` if the result is err.\n */\n onError(fn: (err: E) => void): Result<T, E> {\n if (!this.res.ok) {\n try {\n fn(this.res.err);\n } catch (err) {\n return Result._uncaught(err);\n }\n }\n\n return this;\n }\n}\n\n/**\n * This class is being used when `Result` methods encounter async code.\n * It isn't meant to be used directly, but exported for usage in type annotations.\n *\n * All the methods resemble `Result` methods, but work asynchronously.\n */\nexport class AsyncResult<T extends Val, E extends Val> implements PromiseLike<\n Result<T, E>\n> {\n private asyncResult: Promise<Result<T, E>>;\n\n private constructor(asyncResult: Promise<Result<T, E>>) {\n this.asyncResult = asyncResult;\n }\n\n // oxlint-disable-next-line unicorn/no-thenable -- required to implement PromiseLike\n then<TResult1 = Result<T, E>>(\n onfulfilled?:\n | ((value: Result<T, E>) => TResult1 | PromiseLike<TResult1>)\n | null,\n ): PromiseLike<TResult1> {\n return this.asyncResult.then(onfulfilled);\n }\n\n static ok<T extends Val>(val: T): AsyncResult<T, never> {\n return new AsyncResult(Promise.resolve(Result.ok(val)));\n }\n\n static err<E extends Val>(err: NonNullable<E>): AsyncResult<never, E> {\n return new AsyncResult(Promise.resolve(Result.err(err)));\n }\n\n static wrap<T extends Val, E extends Val = Error, EE extends Val = never>(\n promise:\n | Promise<ZodSafeParseResult<T>>\n | Promise<Result<T, EE>>\n | Promise<RawValue<T>>,\n onErr?: (err: NonNullable<E>) => Result<T, E>,\n ): AsyncResult<T, E | EE> {\n return new AsyncResult(\n promise\n .then((value) => {\n if (value instanceof Result) {\n return value;\n }\n\n if (isZodResult<T>(value)) {\n return fromZodResult<T>(value);\n }\n\n return Result.ok(value);\n })\n .catch((err) => {\n if (onErr) {\n return onErr(err);\n }\n return Result.err(err);\n }),\n );\n }\n\n static wrapNullable<\n T extends Val,\n E extends Val,\n ErrForNull extends Val,\n ErrForUndefined extends Val,\n >(\n promise: Promise<Nullish<T>>,\n errForNull: NonNullable<ErrForNull>,\n errForUndefined: NonNullable<ErrForUndefined>,\n ): AsyncResult<T, E | ErrForNull | ErrForUndefined> {\n return new AsyncResult(\n promise\n .then((value) => fromNullable(value, errForNull, errForUndefined))\n .catch((err) => Result.err(err)),\n );\n }\n\n /**\n * Returns a discriminated union for type-safe consumption of the result.\n *\n * ```ts\n *\n * const { val, err } = await Result.wrap(readFile('foo.txt')).unwrap();\n * expect(val).toBe('foo');\n * expect(err).toBeUndefined();\n *\n * ```\n */\n unwrap(): Promise<Res<T, E>> {\n return this.asyncResult.then<Res<T, E>>((res) => res.unwrap());\n }\n\n /**\n * Returns a success value or a fallback value.\n *\n * ```ts\n *\n * const val = await Result.wrap(readFile('foo.txt')).unwrapOr('bar');\n * expect(val).toBe('bar');\n * expect(err).toBeUndefined();\n *\n * ```\n */\n unwrapOr(fallback: T): Promise<T> {\n return this.asyncResult.then<T>((res) => res.unwrapOr(fallback));\n }\n\n /**\n * Returns the ok-value or throw the error.\n */\n async unwrapOrThrow(): Promise<T> {\n const result = await this.asyncResult;\n return result.unwrapOrThrow();\n }\n\n /**\n * Returns the ok-value or `null`.\n */\n unwrapOrNull(): Promise<T | null> {\n return this.asyncResult.then<T | null>((res) => res.unwrapOrNull());\n }\n\n /**\n * Transforms the ok-value, sync or async way.\n *\n * Transform functions SHOULD NOT throw.\n * Uncaught errors are logged and wrapped to `Result._uncaught()`,\n * which leads to re-throwing them in `unwrap()`.\n *\n * Zod `.safeParse()` results are converted automatically.\n *\n * ```ts\n *\n * const { val, err } = await Result.wrap(\n * http.getJson('https://api.example.com/data.json')\n * )\n * .transform(({ body }) => body)\n * .unwrap();\n *\n * ```\n */\n transform<U extends Val, EE extends Val>(\n fn: (value: T) => Result<U, E | EE>,\n ): AsyncResult<U, E | EE>;\n transform<U extends Val, EE extends Val>(\n fn: (value: T) => AsyncResult<U, E | EE>,\n ): AsyncResult<U, E | EE>;\n transform<U extends Val>(\n fn: (value: T) => ZodSafeParseResult<NonNullable<U>>,\n ): AsyncResult<U, E | ZodError>;\n transform<U extends Val>(\n fn: (value: T) => Promise<ZodSafeParseResult<NonNullable<U>>>,\n ): AsyncResult<U, E | ZodError>;\n transform<U extends Val, EE extends Val>(\n fn: (value: T) => Promise<Result<U, E | EE>>,\n ): AsyncResult<U, E | EE>;\n transform<U extends Val>(\n fn: (value: T) => Promise<RawValue<U>>,\n ): AsyncResult<U, E>;\n transform<U extends Val>(fn: (value: T) => RawValue<U>): AsyncResult<U, E>;\n transform<U extends Val, EE extends Val>(\n fn: (\n value: T,\n ) =>\n | Result<U, E | EE>\n | AsyncResult<U, E | EE>\n | ZodSafeParseResult<NonNullable<U>>\n | Promise<ZodSafeParseResult<NonNullable<U>>>\n | Promise<Result<U, E | EE>>\n | Promise<RawValue<U>>\n | RawValue<U>,\n ): AsyncResult<U, E | EE | ZodError> {\n return new AsyncResult(\n this.asyncResult\n .then((oldResult) => {\n const { ok, val: value, err: error } = oldResult.unwrap();\n if (!ok) {\n return Result.err(error);\n }\n\n try {\n const result = fn(value);\n\n if (result instanceof Result) {\n return result;\n }\n\n if (result instanceof AsyncResult) {\n return result;\n }\n\n if (isZodResult<U>(result)) {\n return fromZodResult<U>(result);\n }\n\n if (result instanceof Promise) {\n return AsyncResult.wrap(result, (err) => {\n logger.warn(\n { err },\n 'AsyncResult: unhandled async transform error',\n );\n return Result._uncaught(err);\n });\n }\n\n return Result.ok(result);\n } catch (err) {\n logger.warn({ err }, 'AsyncResult: unhandled transform error');\n return Result._uncaught(err);\n }\n })\n .catch((err) => {\n // Happens when `.unwrap()` of `oldResult` throws\n return Result._uncaught(err);\n }),\n );\n }\n\n catch<U extends Val = T, EE extends Val = E>(\n fn: (err: NonNullable<E>) => Result<U, EE>,\n ): AsyncResult<T | U, EE>;\n catch<U extends Val = T, EE extends Val = E>(\n fn: (err: NonNullable<E>) => AsyncResult<U, EE>,\n ): AsyncResult<T | U, EE>;\n catch<U extends Val = T, EE extends Val = E>(\n fn: (err: NonNullable<E>) => Promise<Result<U, EE>>,\n ): AsyncResult<T | U, EE>;\n catch<U extends Val = T, EE extends Val = E>(\n fn: (\n err: NonNullable<E>,\n ) => Result<U, EE> | AsyncResult<U, EE> | Promise<Result<U, EE>>,\n ): AsyncResult<T | U, EE> {\n const caughtAsyncResult: Promise<Result<T, EE>> = this.asyncResult.then(\n (result) => result.catch(fn as never),\n );\n return AsyncResult.wrap(caughtAsyncResult);\n }\n\n /**\n * Given a `schema`, returns a `Result` with `val` being the parsed value.\n * Additionally, `null` and `undefined` values are converted into Zod error.\n */\n parse<Schema extends ZodType<any, any, any>>(\n schema: Schema,\n ): AsyncResult<NonNullable<ZodOutput<Schema>>, E | ZodError> {\n return new AsyncResult(\n this.asyncResult\n .then((oldResult) => oldResult.parse(schema))\n .catch(\n /* istanbul ignore next: should never happen */\n (err) => Result._uncaught(err),\n ),\n );\n }\n\n onValue(fn: (value: T) => void): AsyncResult<T, E> {\n return new AsyncResult(\n this.asyncResult\n .then((result) => result.onValue(fn))\n .catch(\n /* istanbul ignore next: should never happen */\n (err) => Result._uncaught(err),\n ),\n );\n }\n\n onError(fn: (err: E) => void): AsyncResult<T, E> {\n return new AsyncResult(\n this.asyncResult\n .then((result) => result.onError(fn))\n .catch(\n /* istanbul ignore next: should never happen */\n (err) => Result._uncaught(err),\n ),\n );\n }\n}\n"],"mappings":"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"}
@@ -21,7 +21,7 @@ import { getChangedLabels, prepareLabels, shouldUpdateLabels } from "./labels.js
21
21
  import { addParticipants } from "./participants.js";
22
22
  import { generatePrBodyFingerprintConfig, validatePrCache } from "./pr-fingerprint.js";
23
23
  import { tryReuseAutoclosedPr } from "./pr-reuse.js";
24
- import { isArray, isNonEmptyArray, isNumber } from "@sindresorhus/is";
24
+ import { isArray, isNonEmptyArray, isNumber, isUndefined } from "@sindresorhus/is";
25
25
  //#region lib/workers/repository/update/pr/index.ts
26
26
  function getPlatformPrOptions(config) {
27
27
  const usePlatformAutomerge = Boolean(config.automerge && (config.automergeType === "pr" || config.automergeType === "branch") && config.platformAutomerge);
@@ -163,7 +163,7 @@ async function ensurePr(prConfig) {
163
163
  processedUpgrades.push(upgradeKey);
164
164
  const logJSON = upgrade.logJSON;
165
165
  if (logJSON) {
166
- if (typeof logJSON.error === "undefined") {
166
+ if (isUndefined(logJSON.error)) {
167
167
  if (logJSON.project) upgrade.repoName = logJSON.project.repository;
168
168
  upgrade.hasReleaseNotes = false;
169
169
  upgrade.releases = [];
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../../lib/workers/repository/update/pr/index.ts"],"sourcesContent":["import { isArray, isNonEmptyArray, isNumber } from '@sindresorhus/is';\nimport { GlobalConfig } from '../../../../config/global.ts';\nimport type { RenovateConfig } from '../../../../config/types.ts';\nimport {\n PLATFORM_INTEGRATION_UNAUTHORIZED,\n PLATFORM_RATE_LIMIT_EXCEEDED,\n REPOSITORY_CHANGED,\n} from '../../../../constants/error-messages.ts';\nimport { pkg } from '../../../../expose.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport { ensureComment } from '../../../../modules/platform/comment.ts';\nimport type {\n PlatformPrOptions,\n Pr,\n PrDebugData,\n UpdatePrConfig,\n} from '../../../../modules/platform/index.ts';\nimport { platform } from '../../../../modules/platform/index.ts';\nimport {\n getPrBodyStruct,\n hashBody,\n} from '../../../../modules/platform/pr-body.ts';\nimport { scm } from '../../../../modules/platform/scm.ts';\nimport { ExternalHostError } from '../../../../types/errors/external-host-error.ts';\nimport { getElapsedHours } from '../../../../util/date.ts';\nimport { stripEmojis } from '../../../../util/emoji.ts';\nimport { fingerprint } from '../../../../util/fingerprint.ts';\nimport { getBranchLastCommitTime } from '../../../../util/git/index.ts';\nimport { memoize } from '../../../../util/memoize.ts';\nimport { incCountValue, isLimitReached } from '../../../global/limits.ts';\nimport type {\n BranchConfig,\n BranchUpgradeConfig,\n PrBlockedBy,\n} from '../../../types.ts';\nimport { embedChangelogs } from '../../changelog/index.ts';\nimport { resolveBranchStatus } from '../branch/status-checks.ts';\nimport { getPrBody } from './body/index.ts';\nimport {\n getChangedLabels,\n prepareLabels,\n shouldUpdateLabels,\n} from './labels.ts';\nimport { addParticipants } from './participants.ts';\nimport { getPrCache, setPrCache } from './pr-cache.ts';\nimport {\n generatePrBodyFingerprintConfig,\n validatePrCache,\n} from './pr-fingerprint.ts';\nimport { tryReuseAutoclosedPr } from './pr-reuse.ts';\n\nexport function getPlatformPrOptions(\n config: RenovateConfig & PlatformPrOptions,\n): PlatformPrOptions {\n const usePlatformAutomerge = Boolean(\n config.automerge &&\n (config.automergeType === 'pr' || config.automergeType === 'branch') &&\n config.platformAutomerge,\n );\n\n return {\n autoApprove: !!config.autoApprove,\n automergeCommitMessage: config.commitMessage,\n automergeStrategy: config.automergeStrategy,\n azureWorkItemId: config.azureWorkItemId ?? 0,\n bbAutoResolvePrTasks: !!config.bbAutoResolvePrTasks,\n bbUseDefaultReviewers: !!config.bbUseDefaultReviewers,\n gitLabIgnoreApprovals: !!config.gitLabIgnoreApprovals,\n forkModeDisallowMaintainerEdits: !!config.forkModeDisallowMaintainerEdits,\n usePlatformAutomerge,\n };\n}\n\nexport interface ResultWithPr {\n type: 'with-pr';\n pr: Pr;\n}\n\nexport interface ResultWithoutPr {\n type: 'without-pr';\n prBlockedBy: PrBlockedBy;\n}\n\nexport type EnsurePrResult = ResultWithPr | ResultWithoutPr;\n\nexport function updatePrDebugData(\n targetBranch: string,\n labels: string[],\n debugData: PrDebugData | undefined,\n): PrDebugData {\n const createdByRenovateVersion = debugData?.createdInVer ?? pkg.version;\n const updatedByRenovateVersion = pkg.version;\n\n const updatedPrDebugData: PrDebugData = {\n createdInVer: createdByRenovateVersion,\n updatedInVer: updatedByRenovateVersion,\n targetBranch,\n };\n\n // Add labels to the debug data object.\n // When to add:\n // 1. Add it when a new PR is created, i.e., when debugData is undefined.\n // 2. Add it if an existing PR already has labels in the debug data, confirming that we can update its labels.\n if (!debugData || isArray(debugData.labels)) {\n updatedPrDebugData.labels = labels;\n }\n\n return updatedPrDebugData;\n}\n\nfunction hasNotIgnoredReviewers(pr: Pr, config: BranchConfig): boolean {\n if (\n isNonEmptyArray(config.ignoreReviewers) &&\n isNonEmptyArray(pr.reviewers)\n ) {\n const ignoreReviewers = new Set(config.ignoreReviewers);\n return (\n pr.reviewers.filter((reviewer) => !ignoreReviewers.has(reviewer)).length >\n 0\n );\n }\n return isNonEmptyArray(pr.reviewers);\n}\n\nfunction addPullRequestNoteIfAttestationHasBeenLost(\n upgrade: BranchUpgradeConfig,\n currentReleaseHasAttestation: boolean | undefined,\n): void {\n const { packageName, depName, currentVersion, newVersion } = upgrade;\n const name = packageName ?? depName;\n\n const newRelease = upgrade.releases?.find(\n (release) => release.version === newVersion,\n );\n\n if (\n newRelease &&\n currentReleaseHasAttestation === true &&\n newRelease.attestation !== true\n ) {\n upgrade.prBodyNotes ??= [];\n upgrade.prBodyNotes.push(\n [\n '> :stop_sign: **Caution**',\n '>',\n `> ${name} ${currentVersion} was released with an attestation, but ${newVersion} has no attestation.`,\n `> Verify that release ${newVersion} was published by the expected author.`,\n '\\n',\n ].join('\\n'),\n );\n }\n}\n\n// Ensures that PR exists with matching title/body\nexport async function ensurePr(\n prConfig: BranchConfig,\n): Promise<EnsurePrResult> {\n const config: BranchConfig = { ...prConfig };\n const filteredPrConfig = generatePrBodyFingerprintConfig(config);\n const prBodyFingerprint = fingerprint(filteredPrConfig);\n logger.trace({ config }, 'ensurePr');\n // If there is a group, it will use the config of the first upgrade in the array\n const {\n branchName,\n ignoreTests,\n internalChecksAsSuccess,\n prTitle = '',\n upgrades,\n hasAttestation: currentReleaseHasAttestation,\n } = config;\n const getBranchStatus = memoize(() =>\n resolveBranchStatus(branchName, !!internalChecksAsSuccess, ignoreTests),\n );\n const dependencyDashboardCheck =\n config.dependencyDashboardChecks?.[config.branchName];\n // Check if PR already exists\n const existingPr =\n (await platform.getBranchPr(branchName, config.baseBranch)) ??\n (await tryReuseAutoclosedPr(branchName, prTitle));\n const prCache = getPrCache(branchName);\n if (existingPr) {\n logger.debug('Found existing PR');\n if (existingPr.bodyStruct?.rebaseRequested) {\n logger.debug('PR rebase requested, so skipping cache check');\n } else if (prCache) {\n logger.trace({ prCache }, 'Found existing PR cache');\n // return if pr cache is valid and pr was not changed in the past 24hrs\n // skip cache when autoApprove is set, since new commits may have\n // reset platform approvals (e.g. GitLab's \"Remove all approvals\" setting)\n if (validatePrCache(prCache, prBodyFingerprint) && !config.autoApprove) {\n return { type: 'with-pr', pr: existingPr };\n }\n } else if (config.repositoryCache === 'enabled') {\n logger.debug('PR cache not found');\n }\n }\n config.upgrades = [];\n\n if (config.artifactErrors?.length) {\n logger.debug('Forcing PR because of artifact errors');\n config.forcePr = true;\n }\n\n if (dependencyDashboardCheck === 'approvePr') {\n logger.debug('Forcing PR because of dependency dashboard approval');\n config.forcePr = true;\n }\n\n if (!existingPr) {\n // Only create a PR if a branch automerge has failed\n if (\n config.automerge === true &&\n config.automergeType?.startsWith('branch') &&\n !config.forcePr\n ) {\n logger.debug(`Branch automerge is enabled`);\n if (\n config.stabilityStatus !== 'yellow' &&\n (await getBranchStatus()) === 'yellow' &&\n isNumber(config.prNotPendingHours)\n ) {\n logger.debug('Checking how long this branch has been pending');\n const lastCommitTime = await getBranchLastCommitTime(branchName);\n if (getElapsedHours(lastCommitTime) >= config.prNotPendingHours) {\n logger.debug(\n `Branch exceeds prNotPending=${config.prNotPendingHours}, hours - forcing PR creation`,\n );\n config.forcePr = true;\n }\n }\n if (config.forcePr || (await getBranchStatus()) === 'red') {\n logger.debug(`Branch tests failed, so will create PR`);\n } else {\n // Branch should be automerged, so we don't want to create a PR\n return { type: 'without-pr', prBlockedBy: 'BranchAutomerge' };\n }\n }\n if (config.prCreation === 'status-success') {\n logger.debug('Checking branch combined status');\n if ((await getBranchStatus()) !== 'green') {\n logger.debug(`Branch status isn't green - not creating PR`);\n return { type: 'without-pr', prBlockedBy: 'AwaitingTests' };\n }\n logger.debug('Branch status success');\n } else if (\n config.prCreation === 'approval' &&\n dependencyDashboardCheck !== 'approvePr'\n ) {\n return { type: 'without-pr', prBlockedBy: 'NeedsApproval' };\n } else if (config.prCreation === 'not-pending' && !config.forcePr) {\n logger.debug('Checking branch combined status');\n if ((await getBranchStatus()) === 'yellow') {\n logger.debug(`Branch status is yellow - checking timeout`);\n const lastCommitTime = await getBranchLastCommitTime(branchName);\n const elapsedHours = getElapsedHours(lastCommitTime);\n if (\n !dependencyDashboardCheck &&\n ((config.stabilityStatus && config.stabilityStatus !== 'yellow') ||\n (isNumber(config.prNotPendingHours) &&\n elapsedHours < config.prNotPendingHours))\n ) {\n logger.debug(\n `Branch is ${elapsedHours} hours old - skipping PR creation as prNotPendingHours is set to ${config.prNotPendingHours}`,\n );\n return {\n type: 'without-pr',\n prBlockedBy: 'AwaitingTests',\n };\n }\n const prNotPendingHours = String(config.prNotPendingHours);\n logger.debug(\n `prNotPendingHours=${prNotPendingHours} threshold hit - creating PR`,\n );\n }\n logger.debug('Branch status success');\n }\n }\n\n const processedUpgrades: string[] = [];\n const commitRepos: string[] = [];\n\n function getRepoNameWithSourceDirectory(\n upgrade: BranchUpgradeConfig,\n ): string {\n // TODO: types (#22198)\n return `${upgrade.repoName!}${\n upgrade.sourceDirectory ? `:${upgrade.sourceDirectory}` : ''\n }`;\n }\n\n // fetch changelogs for matching upgrades.\n await embedChangelogs({\n upgrades: upgrades,\n stage: 'pr',\n });\n\n // Get changelog and then generate template strings\n for (const upgrade of upgrades) {\n // TODO: types (#22198)\n const upgradeKey = `${upgrade.depType!}-${upgrade.depName!}-${upgrade.manager}-${upgrade.currentVersion ?? ''}-${upgrade.currentValue ?? ''}-${upgrade.newVersion ?? ''}-${upgrade.newValue ?? ''}`;\n if (processedUpgrades.includes(upgradeKey)) {\n continue;\n }\n processedUpgrades.push(upgradeKey);\n\n const logJSON = upgrade.logJSON;\n\n if (logJSON) {\n if (typeof logJSON.error === 'undefined') {\n if (logJSON.project) {\n upgrade.repoName = logJSON.project.repository;\n }\n upgrade.hasReleaseNotes = false;\n upgrade.releases = [];\n if (\n logJSON.hasReleaseNotes &&\n upgrade.repoName &&\n !commitRepos.includes(getRepoNameWithSourceDirectory(upgrade))\n ) {\n commitRepos.push(getRepoNameWithSourceDirectory(upgrade));\n upgrade.hasReleaseNotes = logJSON.hasReleaseNotes;\n if (logJSON.versions) {\n for (const version of logJSON.versions) {\n const release = { ...version };\n upgrade.releases.push(release);\n }\n }\n }\n } else if (logJSON.error === 'MissingGithubToken') {\n upgrade.prBodyNotes ??= [];\n upgrade.prBodyNotes.push(\n [\n '> :exclamation: **Important**',\n '> ',\n '> Release Notes retrieval for this PR were skipped because no github.com credentials were available. ',\n '> If you are self-hosted, please see [this instruction](https://github.com/renovatebot/renovate/blob/master/docs/usage/examples/self-hosting.md#githubcom-token-for-release-notes).',\n '\\n',\n ].join('\\n'),\n );\n }\n }\n\n addPullRequestNoteIfAttestationHasBeenLost(\n upgrade,\n currentReleaseHasAttestation,\n );\n\n config.upgrades.push(upgrade);\n }\n\n config.hasReleaseNotes = config.upgrades.some((upg) => upg.hasReleaseNotes);\n\n const releaseNotesSources: string[] = [];\n for (const upgrade of config.upgrades) {\n let notesSourceUrl = upgrade.releases?.[0]?.releaseNotes?.notesSourceUrl;\n // TODO: types (#22198)\n notesSourceUrl ??= `${upgrade.sourceUrl!}${\n upgrade.sourceDirectory ? `:${upgrade.sourceDirectory}` : ''\n }`;\n\n if (upgrade.hasReleaseNotes && notesSourceUrl) {\n if (releaseNotesSources.includes(notesSourceUrl)) {\n logger.debug(\n { depName: upgrade.depName },\n 'Removing duplicate release notes',\n );\n upgrade.hasReleaseNotes = false;\n } else {\n releaseNotesSources.push(notesSourceUrl);\n }\n }\n }\n\n const prBody = getPrBody(\n config,\n {\n debugData: updatePrDebugData(\n config.baseBranch,\n prepareLabels(config), // include labels in debug data\n existingPr?.bodyStruct?.debugData,\n ),\n },\n config,\n );\n\n try {\n if (existingPr) {\n logger.debug('Processing existing PR');\n\n if (\n !existingPr.hasAssignees &&\n !hasNotIgnoredReviewers(existingPr, config) &&\n config.automerge &&\n !config.assignAutomerge &&\n (await getBranchStatus()) === 'red'\n ) {\n logger.debug(`Setting assignees and reviewers as status checks failed`);\n await addParticipants(config, existingPr);\n }\n // Check if existing PR needs updating\n const existingPrTitle = stripEmojis(existingPr.title);\n const existingPrBodyHash = existingPr.bodyStruct?.hash;\n const newPrTitle = stripEmojis(prTitle);\n const newPrBodyHash = hashBody(prBody);\n\n const prInitialLabels = existingPr.bodyStruct?.debugData?.labels;\n const prCurrentLabels = existingPr.labels;\n const configuredLabels = prepareLabels(config);\n\n const labelsNeedUpdate = shouldUpdateLabels(\n prInitialLabels,\n prCurrentLabels,\n configuredLabels,\n );\n\n if (\n existingPr?.targetBranch === config.baseBranch &&\n existingPrTitle === newPrTitle &&\n existingPrBodyHash === newPrBodyHash &&\n !labelsNeedUpdate &&\n !config.autoApprove\n ) {\n // adds or-cache for existing PRs\n setPrCache(branchName, prBodyFingerprint, false);\n logger.debug(\n `Pull Request #${existingPr.number} does not need updating`,\n );\n return { type: 'with-pr', pr: existingPr };\n }\n\n const updatePrConfig: UpdatePrConfig = {\n number: existingPr.number,\n prTitle,\n prBody,\n platformPrOptions: getPlatformPrOptions(config),\n };\n // PR must need updating\n if (existingPr?.targetBranch !== config.baseBranch) {\n logger.debug(\n {\n branchName,\n oldBaseBranch: existingPr?.targetBranch,\n newBaseBranch: config.baseBranch,\n },\n 'PR base branch has changed',\n );\n updatePrConfig.targetBranch = config.baseBranch;\n }\n\n if (labelsNeedUpdate) {\n logger.debug(\n {\n branchName,\n prCurrentLabels,\n configuredLabels,\n },\n 'PR labels have changed',\n );\n\n // Divide labels into three categories:\n // i) addLabels: Labels that need to be added\n // ii) removeLabels: Labels that need to be removed\n // iii) labels: New labels for the PR, replacing the old labels array entirely.\n // This distinction is necessary because different platforms update labels differently\n // For more details, refer to the updatePr function of each platform.\n\n const [addLabels, removeLabels] = getChangedLabels(\n prCurrentLabels,\n configuredLabels,\n );\n\n // for Gitea\n updatePrConfig.labels = configuredLabels;\n\n // for GitHub, GitLab\n updatePrConfig.addLabels = addLabels;\n updatePrConfig.removeLabels = removeLabels;\n }\n if (existingPrTitle !== newPrTitle) {\n logger.debug(\n {\n branchName,\n oldPrTitle: existingPr.title,\n newPrTitle: prTitle,\n },\n 'PR title changed',\n );\n } else if (config.autoApprove) {\n logger.debug({ prTitle }, 'PR approval required');\n } else if (!config.committedFiles && !config.rebaseRequested) {\n logger.debug(\n {\n prTitle,\n },\n 'PR body changed',\n );\n }\n\n if (GlobalConfig.get('dryRun')) {\n logger.info(`DRY-RUN: Would update PR #${existingPr.number}`);\n return { type: 'with-pr', pr: existingPr };\n }\n await platform.updatePr(updatePrConfig);\n logger.info({ pr: existingPr.number, prTitle }, `PR updated`);\n setPrCache(branchName, prBodyFingerprint, true);\n\n return {\n type: 'with-pr',\n pr: {\n ...existingPr,\n bodyStruct: getPrBodyStruct(prBody),\n title: prTitle,\n targetBranch: config.baseBranch,\n },\n };\n }\n logger.debug({ branch: branchName, prTitle }, `Creating PR`);\n if (config.updateType === 'rollback') {\n logger.info('Creating Rollback PR');\n }\n let pr: Pr | null;\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n { labels: prepareLabels(config) },\n `DRY-RUN: Would create PR: ${prTitle}`,\n );\n pr = { number: 0 } as never;\n } else {\n try {\n if (\n !dependencyDashboardCheck &&\n isLimitReached('ConcurrentPRs', prConfig) &&\n !config.isVulnerabilityAlert\n ) {\n logger.debug('Skipping PR - limit reached');\n return { type: 'without-pr', prBlockedBy: 'RateLimited' };\n }\n pr = await platform.createPr({\n sourceBranch: branchName,\n targetBranch: config.baseBranch,\n prTitle,\n prBody,\n labels: prepareLabels(config),\n platformPrOptions: getPlatformPrOptions(config),\n draftPR: !!config.draftPR,\n milestone: config.milestone,\n });\n\n incCountValue('ConcurrentPRs');\n incCountValue('HourlyPRs');\n logger.info(\n { pr: pr?.number, prTitle, labels: pr?.labels },\n 'PR created',\n );\n } catch (err) {\n logger.debug({ err }, 'Pull request creation error');\n if (\n err.body?.message === 'Validation failed' &&\n err.body.errors?.length &&\n err.body.errors.some((error: { message?: string }) =>\n error.message?.startsWith('A pull request already exists'),\n )\n ) {\n logger.warn('A pull requests already exists');\n return { type: 'without-pr', prBlockedBy: 'Error' };\n }\n if (err.statusCode === 502) {\n logger.warn(\n { branch: branchName },\n 'Deleting branch due to server error',\n );\n await scm.deleteBranch(branchName);\n }\n return { type: 'without-pr', prBlockedBy: 'Error' };\n }\n }\n if (\n pr &&\n config.branchAutomergeFailureMessage &&\n !config.suppressNotifications?.includes('branchAutomergeFailure')\n ) {\n const topic = 'Branch automerge failure';\n let content =\n 'This PR was configured for branch automerge. However, this is not possible, so it has been raised as a PR instead.';\n if (config.branchAutomergeFailureMessage === 'branch status error') {\n content += '\\n___\\n * Branch has one or more failed status checks';\n }\n content = platform.massageMarkdown(content, config.rebaseLabel);\n logger.debug('Adding branch automerge failure message to PR');\n if (GlobalConfig.get('dryRun')) {\n logger.info(`DRY-RUN: Would add comment to PR #${pr.number}`);\n } else {\n await ensureComment({\n number: pr.number,\n topic,\n content,\n });\n }\n }\n // Skip assign and review if automerging PR\n if (pr) {\n if (\n config.automerge &&\n !config.assignAutomerge &&\n (await getBranchStatus()) !== 'red'\n ) {\n logger.debug(\n `Skipping assignees and reviewers as automerge=${config.automerge}`,\n );\n } else {\n await addParticipants(config, pr);\n }\n setPrCache(branchName, prBodyFingerprint, true);\n logger.debug(`Created Pull Request #${pr.number}`);\n return { type: 'with-pr', pr };\n }\n } catch (err) {\n if (\n // oxlint-disable-next-line typescript/prefer-optional-chain -- instanceof is not a null guard\n err instanceof ExternalHostError ||\n err.message === REPOSITORY_CHANGED ||\n err.message === PLATFORM_RATE_LIMIT_EXCEEDED ||\n err.message === PLATFORM_INTEGRATION_UNAUTHORIZED\n ) {\n logger.debug('Passing error up');\n throw err;\n }\n logger.warn({ err, prTitle }, 'Failed to ensure PR');\n }\n if (existingPr) {\n return { type: 'with-pr', pr: existingPr };\n }\n return { type: 'without-pr', prBlockedBy: 'Error' };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../../lib/workers/repository/update/pr/index.ts"],"sourcesContent":["import {\n isArray,\n isNonEmptyArray,\n isNumber,\n isUndefined,\n} from '@sindresorhus/is';\nimport { GlobalConfig } from '../../../../config/global.ts';\nimport type { RenovateConfig } from '../../../../config/types.ts';\nimport {\n PLATFORM_INTEGRATION_UNAUTHORIZED,\n PLATFORM_RATE_LIMIT_EXCEEDED,\n REPOSITORY_CHANGED,\n} from '../../../../constants/error-messages.ts';\nimport { pkg } from '../../../../expose.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport { ensureComment } from '../../../../modules/platform/comment.ts';\nimport type {\n PlatformPrOptions,\n Pr,\n PrDebugData,\n UpdatePrConfig,\n} from '../../../../modules/platform/index.ts';\nimport { platform } from '../../../../modules/platform/index.ts';\nimport {\n getPrBodyStruct,\n hashBody,\n} from '../../../../modules/platform/pr-body.ts';\nimport { scm } from '../../../../modules/platform/scm.ts';\nimport { ExternalHostError } from '../../../../types/errors/external-host-error.ts';\nimport { getElapsedHours } from '../../../../util/date.ts';\nimport { stripEmojis } from '../../../../util/emoji.ts';\nimport { fingerprint } from '../../../../util/fingerprint.ts';\nimport { getBranchLastCommitTime } from '../../../../util/git/index.ts';\nimport { memoize } from '../../../../util/memoize.ts';\nimport { incCountValue, isLimitReached } from '../../../global/limits.ts';\nimport type {\n BranchConfig,\n BranchUpgradeConfig,\n PrBlockedBy,\n} from '../../../types.ts';\nimport { embedChangelogs } from '../../changelog/index.ts';\nimport { resolveBranchStatus } from '../branch/status-checks.ts';\nimport { getPrBody } from './body/index.ts';\nimport {\n getChangedLabels,\n prepareLabels,\n shouldUpdateLabels,\n} from './labels.ts';\nimport { addParticipants } from './participants.ts';\nimport { getPrCache, setPrCache } from './pr-cache.ts';\nimport {\n generatePrBodyFingerprintConfig,\n validatePrCache,\n} from './pr-fingerprint.ts';\nimport { tryReuseAutoclosedPr } from './pr-reuse.ts';\n\nexport function getPlatformPrOptions(\n config: RenovateConfig & PlatformPrOptions,\n): PlatformPrOptions {\n const usePlatformAutomerge = Boolean(\n config.automerge &&\n (config.automergeType === 'pr' || config.automergeType === 'branch') &&\n config.platformAutomerge,\n );\n\n return {\n autoApprove: !!config.autoApprove,\n automergeCommitMessage: config.commitMessage,\n automergeStrategy: config.automergeStrategy,\n azureWorkItemId: config.azureWorkItemId ?? 0,\n bbAutoResolvePrTasks: !!config.bbAutoResolvePrTasks,\n bbUseDefaultReviewers: !!config.bbUseDefaultReviewers,\n gitLabIgnoreApprovals: !!config.gitLabIgnoreApprovals,\n forkModeDisallowMaintainerEdits: !!config.forkModeDisallowMaintainerEdits,\n usePlatformAutomerge,\n };\n}\n\nexport interface ResultWithPr {\n type: 'with-pr';\n pr: Pr;\n}\n\nexport interface ResultWithoutPr {\n type: 'without-pr';\n prBlockedBy: PrBlockedBy;\n}\n\nexport type EnsurePrResult = ResultWithPr | ResultWithoutPr;\n\nexport function updatePrDebugData(\n targetBranch: string,\n labels: string[],\n debugData: PrDebugData | undefined,\n): PrDebugData {\n const createdByRenovateVersion = debugData?.createdInVer ?? pkg.version;\n const updatedByRenovateVersion = pkg.version;\n\n const updatedPrDebugData: PrDebugData = {\n createdInVer: createdByRenovateVersion,\n updatedInVer: updatedByRenovateVersion,\n targetBranch,\n };\n\n // Add labels to the debug data object.\n // When to add:\n // 1. Add it when a new PR is created, i.e., when debugData is undefined.\n // 2. Add it if an existing PR already has labels in the debug data, confirming that we can update its labels.\n if (!debugData || isArray(debugData.labels)) {\n updatedPrDebugData.labels = labels;\n }\n\n return updatedPrDebugData;\n}\n\nfunction hasNotIgnoredReviewers(pr: Pr, config: BranchConfig): boolean {\n if (\n isNonEmptyArray(config.ignoreReviewers) &&\n isNonEmptyArray(pr.reviewers)\n ) {\n const ignoreReviewers = new Set(config.ignoreReviewers);\n return (\n pr.reviewers.filter((reviewer) => !ignoreReviewers.has(reviewer)).length >\n 0\n );\n }\n return isNonEmptyArray(pr.reviewers);\n}\n\nfunction addPullRequestNoteIfAttestationHasBeenLost(\n upgrade: BranchUpgradeConfig,\n currentReleaseHasAttestation: boolean | undefined,\n): void {\n const { packageName, depName, currentVersion, newVersion } = upgrade;\n const name = packageName ?? depName;\n\n const newRelease = upgrade.releases?.find(\n (release) => release.version === newVersion,\n );\n\n if (\n newRelease &&\n currentReleaseHasAttestation === true &&\n newRelease.attestation !== true\n ) {\n upgrade.prBodyNotes ??= [];\n upgrade.prBodyNotes.push(\n [\n '> :stop_sign: **Caution**',\n '>',\n `> ${name} ${currentVersion} was released with an attestation, but ${newVersion} has no attestation.`,\n `> Verify that release ${newVersion} was published by the expected author.`,\n '\\n',\n ].join('\\n'),\n );\n }\n}\n\n// Ensures that PR exists with matching title/body\nexport async function ensurePr(\n prConfig: BranchConfig,\n): Promise<EnsurePrResult> {\n const config: BranchConfig = { ...prConfig };\n const filteredPrConfig = generatePrBodyFingerprintConfig(config);\n const prBodyFingerprint = fingerprint(filteredPrConfig);\n logger.trace({ config }, 'ensurePr');\n // If there is a group, it will use the config of the first upgrade in the array\n const {\n branchName,\n ignoreTests,\n internalChecksAsSuccess,\n prTitle = '',\n upgrades,\n hasAttestation: currentReleaseHasAttestation,\n } = config;\n const getBranchStatus = memoize(() =>\n resolveBranchStatus(branchName, !!internalChecksAsSuccess, ignoreTests),\n );\n const dependencyDashboardCheck =\n config.dependencyDashboardChecks?.[config.branchName];\n // Check if PR already exists\n const existingPr =\n (await platform.getBranchPr(branchName, config.baseBranch)) ??\n (await tryReuseAutoclosedPr(branchName, prTitle));\n const prCache = getPrCache(branchName);\n if (existingPr) {\n logger.debug('Found existing PR');\n if (existingPr.bodyStruct?.rebaseRequested) {\n logger.debug('PR rebase requested, so skipping cache check');\n } else if (prCache) {\n logger.trace({ prCache }, 'Found existing PR cache');\n // return if pr cache is valid and pr was not changed in the past 24hrs\n // skip cache when autoApprove is set, since new commits may have\n // reset platform approvals (e.g. GitLab's \"Remove all approvals\" setting)\n if (validatePrCache(prCache, prBodyFingerprint) && !config.autoApprove) {\n return { type: 'with-pr', pr: existingPr };\n }\n } else if (config.repositoryCache === 'enabled') {\n logger.debug('PR cache not found');\n }\n }\n config.upgrades = [];\n\n if (config.artifactErrors?.length) {\n logger.debug('Forcing PR because of artifact errors');\n config.forcePr = true;\n }\n\n if (dependencyDashboardCheck === 'approvePr') {\n logger.debug('Forcing PR because of dependency dashboard approval');\n config.forcePr = true;\n }\n\n if (!existingPr) {\n // Only create a PR if a branch automerge has failed\n if (\n config.automerge === true &&\n config.automergeType?.startsWith('branch') &&\n !config.forcePr\n ) {\n logger.debug(`Branch automerge is enabled`);\n if (\n config.stabilityStatus !== 'yellow' &&\n (await getBranchStatus()) === 'yellow' &&\n isNumber(config.prNotPendingHours)\n ) {\n logger.debug('Checking how long this branch has been pending');\n const lastCommitTime = await getBranchLastCommitTime(branchName);\n if (getElapsedHours(lastCommitTime) >= config.prNotPendingHours) {\n logger.debug(\n `Branch exceeds prNotPending=${config.prNotPendingHours}, hours - forcing PR creation`,\n );\n config.forcePr = true;\n }\n }\n if (config.forcePr || (await getBranchStatus()) === 'red') {\n logger.debug(`Branch tests failed, so will create PR`);\n } else {\n // Branch should be automerged, so we don't want to create a PR\n return { type: 'without-pr', prBlockedBy: 'BranchAutomerge' };\n }\n }\n if (config.prCreation === 'status-success') {\n logger.debug('Checking branch combined status');\n if ((await getBranchStatus()) !== 'green') {\n logger.debug(`Branch status isn't green - not creating PR`);\n return { type: 'without-pr', prBlockedBy: 'AwaitingTests' };\n }\n logger.debug('Branch status success');\n } else if (\n config.prCreation === 'approval' &&\n dependencyDashboardCheck !== 'approvePr'\n ) {\n return { type: 'without-pr', prBlockedBy: 'NeedsApproval' };\n } else if (config.prCreation === 'not-pending' && !config.forcePr) {\n logger.debug('Checking branch combined status');\n if ((await getBranchStatus()) === 'yellow') {\n logger.debug(`Branch status is yellow - checking timeout`);\n const lastCommitTime = await getBranchLastCommitTime(branchName);\n const elapsedHours = getElapsedHours(lastCommitTime);\n if (\n !dependencyDashboardCheck &&\n ((config.stabilityStatus && config.stabilityStatus !== 'yellow') ||\n (isNumber(config.prNotPendingHours) &&\n elapsedHours < config.prNotPendingHours))\n ) {\n logger.debug(\n `Branch is ${elapsedHours} hours old - skipping PR creation as prNotPendingHours is set to ${config.prNotPendingHours}`,\n );\n return {\n type: 'without-pr',\n prBlockedBy: 'AwaitingTests',\n };\n }\n const prNotPendingHours = String(config.prNotPendingHours);\n logger.debug(\n `prNotPendingHours=${prNotPendingHours} threshold hit - creating PR`,\n );\n }\n logger.debug('Branch status success');\n }\n }\n\n const processedUpgrades: string[] = [];\n const commitRepos: string[] = [];\n\n function getRepoNameWithSourceDirectory(\n upgrade: BranchUpgradeConfig,\n ): string {\n // TODO: types (#22198)\n return `${upgrade.repoName!}${\n upgrade.sourceDirectory ? `:${upgrade.sourceDirectory}` : ''\n }`;\n }\n\n // fetch changelogs for matching upgrades.\n await embedChangelogs({\n upgrades: upgrades,\n stage: 'pr',\n });\n\n // Get changelog and then generate template strings\n for (const upgrade of upgrades) {\n // TODO: types (#22198)\n const upgradeKey = `${upgrade.depType!}-${upgrade.depName!}-${upgrade.manager}-${upgrade.currentVersion ?? ''}-${upgrade.currentValue ?? ''}-${upgrade.newVersion ?? ''}-${upgrade.newValue ?? ''}`;\n if (processedUpgrades.includes(upgradeKey)) {\n continue;\n }\n processedUpgrades.push(upgradeKey);\n\n const logJSON = upgrade.logJSON;\n\n if (logJSON) {\n if (isUndefined(logJSON.error)) {\n if (logJSON.project) {\n upgrade.repoName = logJSON.project.repository;\n }\n upgrade.hasReleaseNotes = false;\n upgrade.releases = [];\n if (\n logJSON.hasReleaseNotes &&\n upgrade.repoName &&\n !commitRepos.includes(getRepoNameWithSourceDirectory(upgrade))\n ) {\n commitRepos.push(getRepoNameWithSourceDirectory(upgrade));\n upgrade.hasReleaseNotes = logJSON.hasReleaseNotes;\n if (logJSON.versions) {\n for (const version of logJSON.versions) {\n const release = { ...version };\n upgrade.releases.push(release);\n }\n }\n }\n } else if (logJSON.error === 'MissingGithubToken') {\n upgrade.prBodyNotes ??= [];\n upgrade.prBodyNotes.push(\n [\n '> :exclamation: **Important**',\n '> ',\n '> Release Notes retrieval for this PR were skipped because no github.com credentials were available. ',\n '> If you are self-hosted, please see [this instruction](https://github.com/renovatebot/renovate/blob/master/docs/usage/examples/self-hosting.md#githubcom-token-for-release-notes).',\n '\\n',\n ].join('\\n'),\n );\n }\n }\n\n addPullRequestNoteIfAttestationHasBeenLost(\n upgrade,\n currentReleaseHasAttestation,\n );\n\n config.upgrades.push(upgrade);\n }\n\n config.hasReleaseNotes = config.upgrades.some((upg) => upg.hasReleaseNotes);\n\n const releaseNotesSources: string[] = [];\n for (const upgrade of config.upgrades) {\n let notesSourceUrl = upgrade.releases?.[0]?.releaseNotes?.notesSourceUrl;\n // TODO: types (#22198)\n notesSourceUrl ??= `${upgrade.sourceUrl!}${\n upgrade.sourceDirectory ? `:${upgrade.sourceDirectory}` : ''\n }`;\n\n if (upgrade.hasReleaseNotes && notesSourceUrl) {\n if (releaseNotesSources.includes(notesSourceUrl)) {\n logger.debug(\n { depName: upgrade.depName },\n 'Removing duplicate release notes',\n );\n upgrade.hasReleaseNotes = false;\n } else {\n releaseNotesSources.push(notesSourceUrl);\n }\n }\n }\n\n const prBody = getPrBody(\n config,\n {\n debugData: updatePrDebugData(\n config.baseBranch,\n prepareLabels(config), // include labels in debug data\n existingPr?.bodyStruct?.debugData,\n ),\n },\n config,\n );\n\n try {\n if (existingPr) {\n logger.debug('Processing existing PR');\n\n if (\n !existingPr.hasAssignees &&\n !hasNotIgnoredReviewers(existingPr, config) &&\n config.automerge &&\n !config.assignAutomerge &&\n (await getBranchStatus()) === 'red'\n ) {\n logger.debug(`Setting assignees and reviewers as status checks failed`);\n await addParticipants(config, existingPr);\n }\n // Check if existing PR needs updating\n const existingPrTitle = stripEmojis(existingPr.title);\n const existingPrBodyHash = existingPr.bodyStruct?.hash;\n const newPrTitle = stripEmojis(prTitle);\n const newPrBodyHash = hashBody(prBody);\n\n const prInitialLabels = existingPr.bodyStruct?.debugData?.labels;\n const prCurrentLabels = existingPr.labels;\n const configuredLabels = prepareLabels(config);\n\n const labelsNeedUpdate = shouldUpdateLabels(\n prInitialLabels,\n prCurrentLabels,\n configuredLabels,\n );\n\n if (\n existingPr?.targetBranch === config.baseBranch &&\n existingPrTitle === newPrTitle &&\n existingPrBodyHash === newPrBodyHash &&\n !labelsNeedUpdate &&\n !config.autoApprove\n ) {\n // adds or-cache for existing PRs\n setPrCache(branchName, prBodyFingerprint, false);\n logger.debug(\n `Pull Request #${existingPr.number} does not need updating`,\n );\n return { type: 'with-pr', pr: existingPr };\n }\n\n const updatePrConfig: UpdatePrConfig = {\n number: existingPr.number,\n prTitle,\n prBody,\n platformPrOptions: getPlatformPrOptions(config),\n };\n // PR must need updating\n if (existingPr?.targetBranch !== config.baseBranch) {\n logger.debug(\n {\n branchName,\n oldBaseBranch: existingPr?.targetBranch,\n newBaseBranch: config.baseBranch,\n },\n 'PR base branch has changed',\n );\n updatePrConfig.targetBranch = config.baseBranch;\n }\n\n if (labelsNeedUpdate) {\n logger.debug(\n {\n branchName,\n prCurrentLabels,\n configuredLabels,\n },\n 'PR labels have changed',\n );\n\n // Divide labels into three categories:\n // i) addLabels: Labels that need to be added\n // ii) removeLabels: Labels that need to be removed\n // iii) labels: New labels for the PR, replacing the old labels array entirely.\n // This distinction is necessary because different platforms update labels differently\n // For more details, refer to the updatePr function of each platform.\n\n const [addLabels, removeLabels] = getChangedLabels(\n prCurrentLabels,\n configuredLabels,\n );\n\n // for Gitea\n updatePrConfig.labels = configuredLabels;\n\n // for GitHub, GitLab\n updatePrConfig.addLabels = addLabels;\n updatePrConfig.removeLabels = removeLabels;\n }\n if (existingPrTitle !== newPrTitle) {\n logger.debug(\n {\n branchName,\n oldPrTitle: existingPr.title,\n newPrTitle: prTitle,\n },\n 'PR title changed',\n );\n } else if (config.autoApprove) {\n logger.debug({ prTitle }, 'PR approval required');\n } else if (!config.committedFiles && !config.rebaseRequested) {\n logger.debug(\n {\n prTitle,\n },\n 'PR body changed',\n );\n }\n\n if (GlobalConfig.get('dryRun')) {\n logger.info(`DRY-RUN: Would update PR #${existingPr.number}`);\n return { type: 'with-pr', pr: existingPr };\n }\n await platform.updatePr(updatePrConfig);\n logger.info({ pr: existingPr.number, prTitle }, `PR updated`);\n setPrCache(branchName, prBodyFingerprint, true);\n\n return {\n type: 'with-pr',\n pr: {\n ...existingPr,\n bodyStruct: getPrBodyStruct(prBody),\n title: prTitle,\n targetBranch: config.baseBranch,\n },\n };\n }\n logger.debug({ branch: branchName, prTitle }, `Creating PR`);\n if (config.updateType === 'rollback') {\n logger.info('Creating Rollback PR');\n }\n let pr: Pr | null;\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n { labels: prepareLabels(config) },\n `DRY-RUN: Would create PR: ${prTitle}`,\n );\n pr = { number: 0 } as never;\n } else {\n try {\n if (\n !dependencyDashboardCheck &&\n isLimitReached('ConcurrentPRs', prConfig) &&\n !config.isVulnerabilityAlert\n ) {\n logger.debug('Skipping PR - limit reached');\n return { type: 'without-pr', prBlockedBy: 'RateLimited' };\n }\n pr = await platform.createPr({\n sourceBranch: branchName,\n targetBranch: config.baseBranch,\n prTitle,\n prBody,\n labels: prepareLabels(config),\n platformPrOptions: getPlatformPrOptions(config),\n draftPR: !!config.draftPR,\n milestone: config.milestone,\n });\n\n incCountValue('ConcurrentPRs');\n incCountValue('HourlyPRs');\n logger.info(\n { pr: pr?.number, prTitle, labels: pr?.labels },\n 'PR created',\n );\n } catch (err) {\n logger.debug({ err }, 'Pull request creation error');\n if (\n err.body?.message === 'Validation failed' &&\n err.body.errors?.length &&\n err.body.errors.some((error: { message?: string }) =>\n error.message?.startsWith('A pull request already exists'),\n )\n ) {\n logger.warn('A pull requests already exists');\n return { type: 'without-pr', prBlockedBy: 'Error' };\n }\n if (err.statusCode === 502) {\n logger.warn(\n { branch: branchName },\n 'Deleting branch due to server error',\n );\n await scm.deleteBranch(branchName);\n }\n return { type: 'without-pr', prBlockedBy: 'Error' };\n }\n }\n if (\n pr &&\n config.branchAutomergeFailureMessage &&\n !config.suppressNotifications?.includes('branchAutomergeFailure')\n ) {\n const topic = 'Branch automerge failure';\n let content =\n 'This PR was configured for branch automerge. However, this is not possible, so it has been raised as a PR instead.';\n if (config.branchAutomergeFailureMessage === 'branch status error') {\n content += '\\n___\\n * Branch has one or more failed status checks';\n }\n content = platform.massageMarkdown(content, config.rebaseLabel);\n logger.debug('Adding branch automerge failure message to PR');\n if (GlobalConfig.get('dryRun')) {\n logger.info(`DRY-RUN: Would add comment to PR #${pr.number}`);\n } else {\n await ensureComment({\n number: pr.number,\n topic,\n content,\n });\n }\n }\n // Skip assign and review if automerging PR\n if (pr) {\n if (\n config.automerge &&\n !config.assignAutomerge &&\n (await getBranchStatus()) !== 'red'\n ) {\n logger.debug(\n `Skipping assignees and reviewers as automerge=${config.automerge}`,\n );\n } else {\n await addParticipants(config, pr);\n }\n setPrCache(branchName, prBodyFingerprint, true);\n logger.debug(`Created Pull Request #${pr.number}`);\n return { type: 'with-pr', pr };\n }\n } catch (err) {\n if (\n // oxlint-disable-next-line typescript/prefer-optional-chain -- instanceof is not a null guard\n err instanceof ExternalHostError ||\n err.message === REPOSITORY_CHANGED ||\n err.message === PLATFORM_RATE_LIMIT_EXCEEDED ||\n err.message === PLATFORM_INTEGRATION_UNAUTHORIZED\n ) {\n logger.debug('Passing error up');\n throw err;\n }\n logger.warn({ err, prTitle }, 'Failed to ensure PR');\n }\n if (existingPr) {\n return { type: 'with-pr', pr: existingPr };\n }\n return { type: 'without-pr', prBlockedBy: 'Error' };\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": "44.46.1",
4
+ "version": "44.46.2",
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 44.46.1 config files (https://renovatebot.com/)",
3
+ "title": "JSON schema for Renovate 44.46.2 config files (https://renovatebot.com/)",
4
4
  "$schema": "http://json-schema.org/draft-07/schema#",
5
- "x-renovate-version": "44.46.1",
5
+ "x-renovate-version": "44.46.2",
6
6
  "allowComments": true,
7
7
  "type": "object",
8
8
  "definitions": {