renovate 44.210.2 → 44.211.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/options/index.js +1 -1
- package/dist/config/options/index.js.map +1 -1
- package/dist/config/utils.js +2 -1
- package/dist/config/utils.js.map +1 -1
- package/dist/config/validation-helpers/regex-glob-matchers.js.map +1 -1
- package/dist/config/validation-helpers/utils.js +5 -1
- package/dist/config/validation-helpers/utils.js.map +1 -1
- package/dist/config/validation.js +8 -2
- package/dist/config/validation.js.map +1 -1
- package/dist/config-validator.js +1 -1
- package/dist/config-validator.js.map +1 -1
- package/dist/global-config-option-defaults.generated.js +1 -1
- package/dist/global-config-option-defaults.generated.js.map +1 -1
- package/dist/instrumentation/index.js +3 -2
- package/dist/instrumentation/index.js.map +1 -1
- package/dist/logger/bunyan.js +3 -2
- package/dist/logger/bunyan.js.map +1 -1
- package/dist/logger/pretty-stdout.js +2 -1
- package/dist/logger/pretty-stdout.js.map +1 -1
- package/dist/modules/datasource/apk/index.js +2 -2
- package/dist/modules/datasource/apk/index.js.map +1 -1
- package/dist/modules/datasource/artifactory/index.js +2 -3
- package/dist/modules/datasource/artifactory/index.js.map +1 -1
- package/dist/modules/datasource/bazel/index.js +2 -1
- package/dist/modules/datasource/bazel/index.js.map +1 -1
- package/dist/modules/datasource/cdnjs/index.js +2 -1
- package/dist/modules/datasource/cdnjs/index.js.map +1 -1
- package/dist/modules/datasource/conda/index.js +2 -1
- package/dist/modules/datasource/conda/index.js.map +1 -1
- package/dist/modules/datasource/crate/index.js +2 -1
- package/dist/modules/datasource/crate/index.js.map +1 -1
- package/dist/modules/datasource/dart-version/index.js +2 -1
- package/dist/modules/datasource/dart-version/index.js.map +1 -1
- package/dist/modules/datasource/datasource.js +2 -2
- package/dist/modules/datasource/datasource.js.map +1 -1
- package/dist/modules/datasource/deb/url.js +3 -1
- package/dist/modules/datasource/deb/url.js.map +1 -1
- package/dist/modules/datasource/devbox/index.js +2 -1
- package/dist/modules/datasource/devbox/index.js.map +1 -1
- package/dist/modules/datasource/docker/common.js +10 -8
- package/dist/modules/datasource/docker/common.js.map +1 -1
- package/dist/modules/datasource/docker/ecr.js +2 -1
- package/dist/modules/datasource/docker/ecr.js.map +1 -1
- package/dist/modules/datasource/docker/index.js +20 -17
- package/dist/modules/datasource/docker/index.js.map +1 -1
- package/dist/modules/datasource/gitea-tags/base.js +2 -3
- package/dist/modules/datasource/gitea-tags/base.js.map +1 -1
- package/dist/modules/datasource/github-tags/index.js +2 -1
- package/dist/modules/datasource/github-tags/index.js.map +1 -1
- package/dist/modules/datasource/gitlab-tags/index.js +2 -3
- package/dist/modules/datasource/gitlab-tags/index.js.map +1 -1
- package/dist/modules/datasource/go/base.js +1 -1
- package/dist/modules/datasource/go/base.js.map +1 -1
- package/dist/modules/datasource/go/common.js +8 -2
- package/dist/modules/datasource/go/common.js.map +1 -1
- package/dist/modules/datasource/go/env.js +2 -1
- package/dist/modules/datasource/go/env.js.map +1 -1
- package/dist/modules/datasource/go/releases-goproxy.js +7 -5
- package/dist/modules/datasource/go/releases-goproxy.js.map +1 -1
- package/dist/modules/datasource/helm/index.js +2 -1
- package/dist/modules/datasource/helm/index.js.map +1 -1
- package/dist/modules/datasource/hexpm-bob/index.js +2 -1
- package/dist/modules/datasource/hexpm-bob/index.js.map +1 -1
- package/dist/modules/datasource/index.js +4 -3
- package/dist/modules/datasource/index.js.map +1 -1
- package/dist/modules/datasource/java-version/adoptium.js +3 -2
- package/dist/modules/datasource/java-version/adoptium.js.map +1 -1
- package/dist/modules/datasource/java-version/graalvm.js +2 -1
- package/dist/modules/datasource/java-version/graalvm.js.map +1 -1
- package/dist/modules/datasource/maven/index.js.map +1 -1
- package/dist/modules/datasource/maven/util.js +7 -10
- package/dist/modules/datasource/maven/util.js.map +1 -1
- package/dist/modules/datasource/npm/npmrc.js +2 -2
- package/dist/modules/datasource/npm/npmrc.js.map +1 -1
- package/dist/modules/datasource/nuget/v3.js +3 -5
- package/dist/modules/datasource/nuget/v3.js.map +1 -1
- package/dist/modules/datasource/packagist/index.js +4 -5
- package/dist/modules/datasource/packagist/index.js.map +1 -1
- package/dist/modules/datasource/pod/index.js +4 -4
- package/dist/modules/datasource/pod/index.js.map +1 -1
- package/dist/modules/datasource/pypi/index.js +19 -11
- package/dist/modules/datasource/pypi/index.js.map +1 -1
- package/dist/modules/datasource/python-version/index.js +2 -3
- package/dist/modules/datasource/python-version/index.js.map +1 -1
- package/dist/modules/datasource/repology/index.js +4 -3
- package/dist/modules/datasource/repology/index.js.map +1 -1
- package/dist/modules/datasource/rpm/providers/common.js +3 -1
- package/dist/modules/datasource/rpm/providers/common.js.map +1 -1
- package/dist/modules/datasource/rubygems/index.js +2 -5
- package/dist/modules/datasource/rubygems/index.js.map +1 -1
- package/dist/modules/datasource/rubygems/versions-endpoint-cache.js +13 -18
- package/dist/modules/datasource/rubygems/versions-endpoint-cache.js.map +1 -1
- package/dist/modules/datasource/terraform-module/base.js +2 -1
- package/dist/modules/datasource/terraform-module/base.js.map +1 -1
- package/dist/modules/datasource/terraform-provider/index.js +2 -3
- package/dist/modules/datasource/terraform-provider/index.js.map +1 -1
- package/dist/modules/manager/bazel-module/parser/context.js +0 -1
- package/dist/modules/manager/bazel-module/parser/context.js.map +1 -1
- package/dist/modules/manager/bundler/host-rules.js +4 -1
- package/dist/modules/manager/bundler/host-rules.js.map +1 -1
- package/dist/modules/manager/composer/range.js +1 -1
- package/dist/modules/manager/composer/range.js.map +1 -1
- package/dist/modules/manager/custom/utils.js +3 -1
- package/dist/modules/manager/custom/utils.js.map +1 -1
- package/dist/modules/manager/devbox/schema.js +2 -1
- package/dist/modules/manager/devbox/schema.js.map +1 -1
- package/dist/modules/manager/dockerfile/extract.js +10 -2
- package/dist/modules/manager/dockerfile/extract.js.map +1 -1
- package/dist/modules/manager/fingerprint.generated.js +1 -1
- package/dist/modules/manager/fingerprint.generated.js.map +1 -1
- package/dist/modules/manager/github-actions/parse.js +2 -1
- package/dist/modules/manager/github-actions/parse.js.map +1 -1
- package/dist/modules/manager/gomod/artifacts.js +5 -2
- package/dist/modules/manager/gomod/artifacts.js.map +1 -1
- package/dist/modules/manager/gradle/artifacts.js +5 -2
- package/dist/modules/manager/gradle/artifacts.js.map +1 -1
- package/dist/modules/manager/gradle/utils.js +2 -1
- package/dist/modules/manager/gradle/utils.js.map +1 -1
- package/dist/modules/manager/gradle-wrapper/utils.js +9 -5
- package/dist/modules/manager/gradle-wrapper/utils.js.map +1 -1
- package/dist/modules/manager/helm-values/util.js +1 -1
- package/dist/modules/manager/helm-values/util.js.map +1 -1
- package/dist/modules/manager/helmfile/artifacts.js +1 -1
- package/dist/modules/manager/helmfile/artifacts.js.map +1 -1
- package/dist/modules/manager/helmv3/artifacts.js +1 -1
- package/dist/modules/manager/helmv3/artifacts.js.map +1 -1
- package/dist/modules/manager/maven/extract.js +5 -2
- package/dist/modules/manager/maven/extract.js.map +1 -1
- package/dist/modules/manager/maven-wrapper/artifacts.js +3 -2
- package/dist/modules/manager/maven-wrapper/artifacts.js.map +1 -1
- package/dist/modules/manager/mise/artifacts.js +2 -1
- package/dist/modules/manager/mise/artifacts.js.map +1 -1
- package/dist/modules/manager/mise/extract.js.map +1 -1
- package/dist/modules/manager/npm/artifacts.js +3 -1
- package/dist/modules/manager/npm/artifacts.js.map +1 -1
- package/dist/modules/manager/npm/extract/common/dependency.js +4 -1
- package/dist/modules/manager/npm/extract/common/dependency.js.map +1 -1
- package/dist/modules/manager/npm/extract/common/package-file.js +2 -1
- package/dist/modules/manager/npm/extract/common/package-file.js.map +1 -1
- package/dist/modules/manager/npm/extract/index.js.map +1 -1
- package/dist/modules/manager/npm/extract/post/locked-versions.js.map +1 -1
- package/dist/modules/manager/npm/npmrc.js +2 -1
- package/dist/modules/manager/npm/npmrc.js.map +1 -1
- package/dist/modules/manager/npm/post-update/index.js +2 -1
- package/dist/modules/manager/npm/post-update/index.js.map +1 -1
- package/dist/modules/manager/npm/post-update/npm.js +2 -3
- package/dist/modules/manager/npm/post-update/npm.js.map +1 -1
- package/dist/modules/manager/npm/post-update/yarn.js.map +1 -1
- package/dist/modules/manager/npm/schema.js +6 -2
- package/dist/modules/manager/npm/schema.js.map +1 -1
- package/dist/modules/manager/npm/update/dependency/index.js +3 -2
- package/dist/modules/manager/npm/update/dependency/index.js.map +1 -1
- package/dist/modules/manager/npm/update/locked-dependency/common/parent-version.js +6 -2
- package/dist/modules/manager/npm/update/locked-dependency/common/parent-version.js.map +1 -1
- package/dist/modules/manager/npm/update/locked-dependency/package-lock/get-locked.js +2 -1
- package/dist/modules/manager/npm/update/locked-dependency/package-lock/get-locked.js.map +1 -1
- package/dist/modules/manager/nuget/package-tree.js +2 -1
- package/dist/modules/manager/nuget/package-tree.js.map +1 -1
- package/dist/modules/manager/paket/update-locked.js +4 -1
- package/dist/modules/manager/paket/update-locked.js.map +1 -1
- package/dist/modules/manager/pipenv/extract.js +4 -1
- package/dist/modules/manager/pipenv/extract.js.map +1 -1
- package/dist/modules/platform/azure/azure-helper.js +2 -1
- package/dist/modules/platform/azure/azure-helper.js.map +1 -1
- package/dist/modules/platform/azure/index.js +7 -3
- package/dist/modules/platform/azure/index.js.map +1 -1
- package/dist/modules/platform/bitbucket/index.js +13 -6
- package/dist/modules/platform/bitbucket/index.js.map +1 -1
- package/dist/modules/platform/bitbucket-server/index.js +13 -9
- package/dist/modules/platform/bitbucket-server/index.js.map +1 -1
- package/dist/modules/platform/codecommit/index.js +2 -2
- package/dist/modules/platform/codecommit/index.js.map +1 -1
- package/dist/modules/platform/gerrit/client.js +4 -1
- package/dist/modules/platform/gerrit/client.js.map +1 -1
- package/dist/modules/platform/gerrit/index.js +3 -2
- package/dist/modules/platform/gerrit/index.js.map +1 -1
- package/dist/modules/platform/gitea/gitea-helper.js +5 -4
- package/dist/modules/platform/gitea/gitea-helper.js.map +1 -1
- package/dist/modules/platform/gitea/index.js +11 -4
- package/dist/modules/platform/gitea/index.js.map +1 -1
- package/dist/modules/platform/github/index.js +36 -23
- package/dist/modules/platform/github/index.js.map +1 -1
- package/dist/modules/platform/gitlab/index.js +16 -9
- package/dist/modules/platform/gitlab/index.js.map +1 -1
- package/dist/modules/platform/scm-manager/index.js +4 -1
- package/dist/modules/platform/scm-manager/index.js.map +1 -1
- package/dist/modules/platform/scm-manager/utils.js +2 -1
- package/dist/modules/platform/scm-manager/utils.js.map +1 -1
- package/dist/modules/versioning/cargo/index.js.map +1 -1
- package/dist/modules/versioning/composer/index.js +2 -1
- package/dist/modules/versioning/composer/index.js.map +1 -1
- package/dist/modules/versioning/conan/common.js +4 -1
- package/dist/modules/versioning/conan/common.js.map +1 -1
- package/dist/modules/versioning/debian/index.js +2 -1
- package/dist/modules/versioning/debian/index.js.map +1 -1
- package/dist/modules/versioning/gradle/compare.js +2 -1
- package/dist/modules/versioning/gradle/compare.js.map +1 -1
- package/dist/modules/versioning/hex/index.js +2 -1
- package/dist/modules/versioning/hex/index.js.map +1 -1
- package/dist/modules/versioning/julia/index.js.map +1 -1
- package/dist/modules/versioning/maven/compare.js +17 -7
- package/dist/modules/versioning/maven/compare.js.map +1 -1
- package/dist/modules/versioning/npm/index.js +2 -1
- package/dist/modules/versioning/npm/index.js.map +1 -1
- package/dist/modules/versioning/npm/range.js.map +1 -1
- package/dist/modules/versioning/paket/index.js +2 -1
- package/dist/modules/versioning/paket/index.js.map +1 -1
- package/dist/modules/versioning/paket/range.js +7 -3
- package/dist/modules/versioning/paket/range.js.map +1 -1
- package/dist/modules/versioning/pep440/index.js +2 -1
- package/dist/modules/versioning/pep440/index.js.map +1 -1
- package/dist/modules/versioning/poetry/index.js +2 -1
- package/dist/modules/versioning/poetry/index.js.map +1 -1
- package/dist/modules/versioning/regex/index.js +1 -1
- package/dist/modules/versioning/regex/index.js.map +1 -1
- package/dist/modules/versioning/rez/index.js +2 -1
- package/dist/modules/versioning/rez/index.js.map +1 -1
- package/dist/modules/versioning/vcpkg/index.js +2 -1
- package/dist/modules/versioning/vcpkg/index.js.map +1 -1
- package/dist/util/cache/package/impl/base.js +2 -1
- package/dist/util/cache/package/impl/base.js.map +1 -1
- package/dist/util/cache/package/with-cache.js +2 -1
- package/dist/util/cache/package/with-cache.js.map +1 -1
- package/dist/util/check-token.js +7 -4
- package/dist/util/check-token.js.map +1 -1
- package/dist/util/exec/utils.js +4 -1
- package/dist/util/exec/utils.js.map +1 -1
- package/dist/util/git/auth.js +5 -1
- package/dist/util/git/auth.js.map +1 -1
- package/dist/util/git/error.js.map +1 -1
- package/dist/util/host-rules.js +5 -3
- package/dist/util/host-rules.js.map +1 -1
- package/dist/util/http/cache/abstract-http-cache-provider.js +3 -2
- package/dist/util/http/cache/abstract-http-cache-provider.js.map +1 -1
- package/dist/util/http/cache/package-http-cache-provider.js +2 -1
- package/dist/util/http/cache/package-http-cache-provider.js.map +1 -1
- package/dist/util/http/github.js +15 -11
- package/dist/util/http/github.js.map +1 -1
- package/dist/util/http/gitlab.js +5 -4
- package/dist/util/http/gitlab.js.map +1 -1
- package/dist/util/http/http.js +2 -1
- package/dist/util/http/http.js.map +1 -1
- package/dist/util/http/jwt.js +2 -1
- package/dist/util/http/jwt.js.map +1 -1
- package/dist/util/http/retry-after.js +2 -1
- package/dist/util/http/retry-after.js.map +1 -1
- package/dist/util/http/status.js +95 -0
- package/dist/util/http/status.js.map +1 -0
- package/dist/util/merge-confidence/index.js +3 -2
- package/dist/util/merge-confidence/index.js.map +1 -1
- package/dist/util/package-rules/current-version.js +4 -1
- package/dist/util/package-rules/current-version.js.map +1 -1
- package/dist/util/package-rules/index.js +7 -3
- package/dist/util/package-rules/index.js.map +1 -1
- package/dist/util/schema-utils/index.js +5 -0
- package/dist/util/schema-utils/index.js.map +1 -1
- package/dist/workers/global/config/parse/host-rules-from-env.js +2 -1
- package/dist/workers/global/config/parse/host-rules-from-env.js.map +1 -1
- package/dist/workers/repository/common.js +4 -1
- package/dist/workers/repository/common.js.map +1 -1
- package/dist/workers/repository/config-migration/branch/index.js +2 -1
- package/dist/workers/repository/config-migration/branch/index.js.map +1 -1
- package/dist/workers/repository/dependency-dashboard.js +6 -2
- package/dist/workers/repository/dependency-dashboard.js.map +1 -1
- package/dist/workers/repository/finalize/repository-statistics.js +4 -1
- package/dist/workers/repository/finalize/repository-statistics.js.map +1 -1
- package/dist/workers/repository/init/merge.js +13 -3
- package/dist/workers/repository/init/merge.js.map +1 -1
- package/dist/workers/repository/onboarding/branch/check.js +2 -1
- package/dist/workers/repository/onboarding/branch/check.js.map +1 -1
- package/dist/workers/repository/onboarding/pr/pr-list.js +4 -2
- package/dist/workers/repository/onboarding/pr/pr-list.js.map +1 -1
- package/dist/workers/repository/process/extract-update.js +4 -1
- package/dist/workers/repository/process/extract-update.js.map +1 -1
- package/dist/workers/repository/process/lookup/digest.js +2 -1
- package/dist/workers/repository/process/lookup/digest.js.map +1 -1
- package/dist/workers/repository/process/lookup/generate.js +1 -1
- package/dist/workers/repository/process/lookup/generate.js.map +1 -1
- package/dist/workers/repository/process/lookup/index.js +4 -1
- package/dist/workers/repository/process/lookup/index.js.map +1 -1
- package/dist/workers/repository/process/lookup/utils.js +7 -1
- package/dist/workers/repository/process/lookup/utils.js.map +1 -1
- package/dist/workers/repository/process/vulnerabilities.js +10 -3
- package/dist/workers/repository/process/vulnerabilities.js.map +1 -1
- package/dist/workers/repository/reconfigure/index.js +2 -1
- package/dist/workers/repository/reconfigure/index.js.map +1 -1
- package/dist/workers/repository/update/branch/auto-replace.js +6 -2
- package/dist/workers/repository/update/branch/auto-replace.js.map +1 -1
- package/dist/workers/repository/update/branch/errors.js +2 -1
- package/dist/workers/repository/update/branch/errors.js.map +1 -1
- package/dist/workers/repository/update/branch/execute-post-upgrade-commands.js +2 -2
- package/dist/workers/repository/update/branch/execute-post-upgrade-commands.js.map +1 -1
- package/dist/workers/repository/update/branch/get-updated.js +1 -2
- package/dist/workers/repository/update/branch/get-updated.js.map +1 -1
- package/dist/workers/repository/update/branch/index.js +2 -1
- package/dist/workers/repository/update/branch/index.js.map +1 -1
- package/dist/workers/repository/update/branch/status-checks.js +2 -1
- package/dist/workers/repository/update/branch/status-checks.js.map +1 -1
- package/dist/workers/repository/update/pr/body/index.js.map +1 -1
- package/dist/workers/repository/update/pr/changelog/release-notes.js +3 -2
- package/dist/workers/repository/update/pr/changelog/release-notes.js.map +1 -1
- package/dist/workers/repository/update/pr/index.js +7 -3
- package/dist/workers/repository/update/pr/index.js.map +1 -1
- package/dist/workers/repository/updates/generate.js +6 -3
- package/dist/workers/repository/updates/generate.js.map +1 -1
- package/package.json +2 -2
- package/renovate-schema.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../lib/util/package-rules/index.ts"],"sourcesContent":["import {\n isNonEmptyArray,\n isNullOrUndefined,\n isString,\n isTruthy,\n} from '@sindresorhus/is';\nimport _slugify from 'slugify';\nimport type {\n PackageRule,\n PackageRuleInputConfig,\n} from '../../config/types.ts';\nimport { mergeChildConfig } from '../../config/utils.ts';\nimport { logger } from '../../logger/index.ts';\nimport type { StageName } from '../../types/skip-reason.ts';\nimport { coerceArray } from '../array.ts';\nimport { compile } from '../template/index.ts';\nimport matchers from './matchers.ts';\n\nconst slugify = _slugify;\n\nasync function matchesRule(\n inputConfig: PackageRuleInputConfig,\n packageRule: PackageRule,\n): Promise<boolean> {\n for (const matcher of matchers) {\n const isMatch = await matcher.matches(inputConfig, packageRule);\n\n // no rules are defined\n if (isNullOrUndefined(isMatch)) {\n continue;\n }\n\n if (!isTruthy(isMatch)) {\n return false;\n }\n }\n\n return true;\n}\n\nexport async function applyPackageRules<T extends PackageRuleInputConfig>(\n inputConfig: T,\n stageName?: StageName,\n): Promise<T> {\n let config = { ...inputConfig };\n const packageRules = coerceArray(config.packageRules);\n // The `packageRules` array is invariant while rules are being applied, and\n // can be very large (e.g. vulnerability alerts append rules embedding full\n // advisory texts). Remove it from the working config so mergeChildConfig()\n // does not deep-clone the whole array once per matched rule, then restore\n // it afterwards.\n delete config.packageRules;\n logger.trace(\n { dependency: config.depName, packageRules },\n `Checking against ${packageRules.length} packageRules`,\n );\n for (const packageRule of packageRules) {\n // This rule is considered matched if there was at least one positive match and no negative matches\n if (await matchesRule(config, packageRule)) {\n // Package rule config overrides any existing config\n const toApply = removeMatchers({ ...packageRule });\n if (config.groupSlug && packageRule.groupName && !packageRule.groupSlug) {\n // Need to apply groupSlug otherwise the existing one will take precedence\n toApply.groupSlug = slugify(packageRule.groupName, {\n lower: true,\n });\n }\n\n
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../lib/util/package-rules/index.ts"],"sourcesContent":["import {\n isNonEmptyArray,\n isNullOrUndefined,\n isString,\n isTruthy,\n} from '@sindresorhus/is';\nimport _slugify from 'slugify';\nimport type {\n PackageRule,\n PackageRuleInputConfig,\n} from '../../config/types.ts';\nimport { mergeChildConfig } from '../../config/utils.ts';\nimport { logger } from '../../logger/index.ts';\nimport type { StageName } from '../../types/skip-reason.ts';\nimport { coerceArray } from '../array.ts';\nimport { compile } from '../template/index.ts';\nimport matchers from './matchers.ts';\n\nconst slugify = _slugify;\n\nfunction hasRegistryUrls(config: PackageRuleInputConfig): boolean {\n return (\n isNonEmptyArray(config.registryUrls) ||\n isNonEmptyArray(config.defaultRegistryUrls)\n );\n}\n\nasync function matchesRule(\n inputConfig: PackageRuleInputConfig,\n packageRule: PackageRule,\n): Promise<boolean> {\n for (const matcher of matchers) {\n const isMatch = await matcher.matches(inputConfig, packageRule);\n\n // no rules are defined\n if (isNullOrUndefined(isMatch)) {\n continue;\n }\n\n if (!isTruthy(isMatch)) {\n return false;\n }\n }\n\n return true;\n}\n\nexport async function applyPackageRules<T extends PackageRuleInputConfig>(\n inputConfig: T,\n stageName?: StageName,\n): Promise<T> {\n let config = { ...inputConfig };\n const packageRules = coerceArray(config.packageRules);\n // The `packageRules` array is invariant while rules are being applied, and\n // can be very large (e.g. vulnerability alerts append rules embedding full\n // advisory texts). Remove it from the working config so mergeChildConfig()\n // does not deep-clone the whole array once per matched rule, then restore\n // it afterwards.\n delete config.packageRules;\n logger.trace(\n { dependency: config.depName, packageRules },\n `Checking against ${packageRules.length} packageRules`,\n );\n for (const packageRule of packageRules) {\n // This rule is considered matched if there was at least one positive match and no negative matches\n if (await matchesRule(config, packageRule)) {\n // Package rule config overrides any existing config\n const toApply = removeMatchers({ ...packageRule });\n if (config.groupSlug && packageRule.groupName && !packageRule.groupSlug) {\n // Need to apply groupSlug otherwise the existing one will take precedence\n toApply.groupSlug = slugify(packageRule.groupName, {\n lower: true,\n });\n }\n\n // unless a force'd config option wins, record it even if the\n // dependency is already disabled, so a user's rule can be told apart\n // from a manager disabling it by default\n const isDisabledWithoutForce =\n toApply.enabled === false && config.force?.enabled !== true;\n if (\n // if it's got higher precedence, as it's a force'd config option\n // multiple force'd config options are \"last defined wins\"\n toApply.force?.enabled === false ||\n isDisabledWithoutForce\n ) {\n config.skipReason = 'package-rules';\n if (stageName) {\n config.skipStage = stageName;\n }\n }\n\n const isEnabled = !!toApply.force?.enabled || !!toApply.enabled;\n if (\n isEnabled &&\n // `unknown-registry` is not about whether the user wants the dependency\n // updated, but about Renovate having nowhere to look it up, so a\n // registry clears it rather than `enabled` - see below\n config.skipReason !== 'unknown-registry'\n ) {\n delete config.skipReason;\n delete config.skipStage;\n }\n if (\n isString(toApply.overrideDatasource) &&\n toApply.overrideDatasource !== config.datasource\n ) {\n logger.debug(\n `Overriding datasource from ${config.datasource} to ${toApply.overrideDatasource} for ${config.depName}`,\n );\n config.datasource = toApply.overrideDatasource;\n }\n if (\n isString(toApply.overrideDepName) &&\n toApply.overrideDepName !== config.depName\n ) {\n logger.debug(\n `Overriding depName from ${config.depName} to ${toApply.overrideDepName}`,\n );\n config.depName = compile(toApply.overrideDepName, config);\n }\n if (\n isString(toApply.overridePackageName) &&\n toApply.overridePackageName !== config.packageName\n ) {\n logger.debug(\n `Overriding packageName from ${config.packageName} to ${toApply.overridePackageName} for ${config.depName}`,\n );\n config.packageName = compile(toApply.overridePackageName, config);\n }\n if (isString(toApply.sourceUrl)) {\n toApply.sourceUrl = compile(toApply.sourceUrl, config);\n }\n delete toApply.overrideDatasource;\n delete toApply.overrideDepName;\n delete toApply.overridePackageName;\n config = mergeChildConfig(config, toApply);\n }\n }\n // A manager which could not work out where to look leaves `unknown-registry`\n // behind. Config can still answer that, from a rule applied above or from the\n // repository config the rules were applied to, so the dependency is no longer\n // skipped once it has a registry to be looked up in.\n if (config.skipReason === 'unknown-registry' && hasRegistryUrls(config)) {\n delete config.skipReason;\n delete config.skipStage;\n }\n\n // Restore the rules. If any applied rule carried nested `packageRules`\n // (e.g. from a resolved preset), preserve the concat-merge semantics that\n // mergeChildConfig() would previously have applied.\n if (config.packageRules) {\n config.packageRules = packageRules.concat(config.packageRules);\n } else if ('packageRules' in inputConfig) {\n config.packageRules = inputConfig.packageRules;\n }\n return config;\n}\n\nfunction removeMatchers<T extends Record<string, unknown>>(\n packageRule: T,\n): Record<string, unknown> & {\n force?: Record<string, unknown>;\n} {\n for (const key of Object.keys(packageRule)) {\n if (key.startsWith('match') || key.startsWith('exclude')) {\n delete packageRule[key];\n }\n }\n\n return packageRule;\n}\n"],"mappings":";;;;;;;;AAkBA,MAAM,UAAU;AAEhB,SAAS,gBAAgB,QAAyC;CAChE,OACE,gBAAgB,OAAO,YAAY,KACnC,gBAAgB,OAAO,mBAAmB;AAE9C;AAEA,eAAe,YACb,aACA,aACkB;CAClB,KAAK,MAAM,WAAW,UAAU;EAC9B,MAAM,UAAU,MAAM,QAAQ,QAAQ,aAAa,WAAW;EAG9D,IAAI,kBAAkB,OAAO,GAC3B;EAGF,IAAI,CAAC,SAAS,OAAO,GACnB,OAAO;CAEX;CAEA,OAAO;AACT;AAEA,eAAsB,kBACpB,aACA,WACY;CACZ,IAAI,SAAS,EAAE,GAAG,YAAY;CAC9B,MAAM,eAAe,YAAY,OAAO,YAAY;CAMpD,OAAO,OAAO;CACd,OAAO,MACL;EAAE,YAAY,OAAO;EAAS;CAAa,GAC3C,oBAAoB,aAAa,OAAO,cAC1C;CACA,KAAK,MAAM,eAAe,cAExB,IAAI,MAAM,YAAY,QAAQ,WAAW,GAAG;EAE1C,MAAM,UAAU,eAAe,EAAE,GAAG,YAAY,CAAC;EACjD,IAAI,OAAO,aAAa,YAAY,aAAa,CAAC,YAAY,WAE5D,QAAQ,YAAY,QAAQ,YAAY,WAAW,EACjD,OAAO,KACT,CAAC;EAMH,MAAM,yBACJ,QAAQ,YAAY,SAAS,OAAO,OAAO,YAAY;EACzD,IAGE,QAAQ,OAAO,YAAY,SAC3B,wBACA;GACA,OAAO,aAAa;GACpB,IAAI,WACF,OAAO,YAAY;EAEvB;EAGA,KADkB,CAAC,CAAC,QAAQ,OAAO,WAAW,CAAC,CAAC,QAAQ,YAMtD,OAAO,eAAe,oBACtB;GACA,OAAO,OAAO;GACd,OAAO,OAAO;EAChB;EACA,IACE,SAAS,QAAQ,kBAAkB,KACnC,QAAQ,uBAAuB,OAAO,YACtC;GACA,OAAO,MACL,8BAA8B,OAAO,WAAW,MAAM,QAAQ,mBAAmB,OAAO,OAAO,SACjG;GACA,OAAO,aAAa,QAAQ;EAC9B;EACA,IACE,SAAS,QAAQ,eAAe,KAChC,QAAQ,oBAAoB,OAAO,SACnC;GACA,OAAO,MACL,2BAA2B,OAAO,QAAQ,MAAM,QAAQ,iBAC1D;GACA,OAAO,UAAU,QAAQ,QAAQ,iBAAiB,MAAM;EAC1D;EACA,IACE,SAAS,QAAQ,mBAAmB,KACpC,QAAQ,wBAAwB,OAAO,aACvC;GACA,OAAO,MACL,+BAA+B,OAAO,YAAY,MAAM,QAAQ,oBAAoB,OAAO,OAAO,SACpG;GACA,OAAO,cAAc,QAAQ,QAAQ,qBAAqB,MAAM;EAClE;EACA,IAAI,SAAS,QAAQ,SAAS,GAC5B,QAAQ,YAAY,QAAQ,QAAQ,WAAW,MAAM;EAEvD,OAAO,QAAQ;EACf,OAAO,QAAQ;EACf,OAAO,QAAQ;EACf,SAAS,iBAAiB,QAAQ,OAAO;CAC3C;CAMF,IAAI,OAAO,eAAe,sBAAsB,gBAAgB,MAAM,GAAG;EACvE,OAAO,OAAO;EACd,OAAO,OAAO;CAChB;CAKA,IAAI,OAAO,cACT,OAAO,eAAe,aAAa,OAAO,OAAO,YAAY;MACxD,IAAI,kBAAkB,aAC3B,OAAO,eAAe,YAAY;CAEpC,OAAO;AACT;AAEA,SAAS,eACP,aAGA;CACA,KAAK,MAAM,OAAO,OAAO,KAAK,WAAW,GACvC,IAAI,IAAI,WAAW,OAAO,KAAK,IAAI,WAAW,SAAS,GACrD,OAAO,YAAY;CAIvB,OAAO;AACT"}
|
|
@@ -295,6 +295,11 @@ const EmailAddress = z.string().refine((value) => StandardEmail.safeParse(value.
|
|
|
295
295
|
function isEmailAdress(value) {
|
|
296
296
|
return EmailAddress.safeParse(value).success;
|
|
297
297
|
}
|
|
298
|
+
z.union([z.string(), z.array(z.string())]);
|
|
299
|
+
z.union([z.object({ type: z.literal("string") }), z.object({
|
|
300
|
+
type: z.literal("array"),
|
|
301
|
+
subType: z.literal("string")
|
|
302
|
+
})]);
|
|
298
303
|
export { DeepNullish, EmailAddress, Ini, Json, Json5, Jsonc, LooseArray, LooseRecord, NotCircular, Nullish, Toml, UtcDate, Yaml, isEmailAdress, multidocYaml, withDebugMessage, withDepType };
|
|
299
304
|
|
|
300
305
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["parseToml"],"sources":["../../../lib/util/schema-utils/index.ts"],"sourcesContent":["import ini from 'ini';\nimport JSON5 from 'json5';\nimport { DateTime } from 'luxon';\nimport type { JsonArray } from 'type-fest';\nimport { z } from 'zod/v4';\nimport { logger } from '../../logger/index.ts';\nimport type { PackageDependency } from '../../modules/manager/types.ts';\nimport { parseJsonc } from '../common.ts';\nimport { parse as parseToml } from '../toml.ts';\nimport type { YamlOptions } from '../yaml.ts';\nimport { parseSingleYaml, parseYaml } from '../yaml.ts';\n\ninterface ErrorContext<T> {\n error: z.ZodError;\n input: T;\n}\n\ninterface LooseOpts<T> {\n onError?: (err: ErrorContext<T>) => void;\n}\n\n/**\n * Works like `z.array()`, but drops wrong elements instead of invalidating the whole array.\n *\n * **Important**: non-array inputs are still invalid.\n * Use `LooseArray(...).catch([])` to handle it.\n *\n * @param Elem Schema for array elements\n * @param onError Callback for errors\n * @returns Schema for array\n */\nexport function LooseArray<Schema extends z.ZodTypeAny>(\n Elem: Schema,\n { onError }: LooseOpts<unknown[]> = {},\n): z.ZodType<z.TypeOf<Schema>[], any> {\n if (!onError) {\n // Avoid error-related computations inside the loop\n return z.array(z.any()).transform((input) => {\n const output: z.infer<Schema>[] = [];\n for (const x of input) {\n const parsed = Elem.safeParse(x);\n if (parsed.success) {\n output.push(parsed.data);\n }\n }\n return output;\n });\n }\n\n return z.array(z.any()).transform((input) => {\n const output: z.infer<Schema>[] = [];\n const issues: z.ZodIssue[] = [];\n\n for (let idx = 0; idx < input.length; idx += 1) {\n const x = input[idx];\n const parsed = Elem.safeParse(x);\n\n if (parsed.success) {\n output.push(parsed.data);\n continue;\n }\n\n for (const issue of parsed.error.issues) {\n issues.push({ ...issue, path: [idx, ...issue.path] });\n }\n }\n\n if (issues.length) {\n const error = new z.ZodError(issues);\n onError({ error, input });\n }\n\n return output;\n });\n}\n\ntype LooseRecordResult<ValueSchema extends z.ZodTypeAny> = z.ZodType<\n Record<string, z.TypeOf<ValueSchema>>,\n any\n>;\n\ntype LooseRecordOpts = LooseOpts<Record<string, unknown>>;\n\n/**\n * Works like `z.record()`, but drops wrong elements instead of invalidating the whole record.\n *\n * **Important**: non-record inputs other are still invalid.\n * Use `LooseRecord(...).catch({})` to handle it.\n *\n * @param KeyValue Schema for record keys\n * @param ValueValue Schema for record values\n * @param onError Callback for errors\n * @returns Schema for record\n */\nexport function LooseRecord<ValueSchema extends z.ZodTypeAny>(\n Value: ValueSchema,\n): LooseRecordResult<ValueSchema>;\nexport function LooseRecord<\n KeySchema extends z.ZodTypeAny,\n ValueSchema extends z.ZodTypeAny,\n>(Key: KeySchema, Value: ValueSchema): LooseRecordResult<ValueSchema>;\nexport function LooseRecord<ValueSchema extends z.ZodTypeAny>(\n Value: ValueSchema,\n { onError }: LooseRecordOpts,\n): LooseRecordResult<ValueSchema>;\nexport function LooseRecord<\n KeySchema extends z.ZodTypeAny,\n ValueSchema extends z.ZodTypeAny,\n>(\n Key: KeySchema,\n Value: ValueSchema,\n { onError }: LooseRecordOpts,\n): LooseRecordResult<ValueSchema>;\nexport function LooseRecord<\n KeySchema extends z.ZodTypeAny,\n ValueSchema extends z.ZodTypeAny,\n>(\n arg1: ValueSchema | KeySchema,\n arg2?: ValueSchema | LooseOpts<Record<string, unknown>>,\n arg3?: LooseRecordOpts,\n): LooseRecordResult<ValueSchema> {\n let Key: z.ZodType = z.any();\n let Value: ValueSchema;\n let opts: LooseRecordOpts = {};\n if (arg2 && arg3) {\n Key = arg1 as KeySchema;\n Value = arg2 as ValueSchema;\n opts = arg3;\n } else if (arg2) {\n if (arg2 instanceof z.ZodType) {\n Key = arg1 as KeySchema;\n Value = arg2;\n } else {\n Value = arg1 as ValueSchema;\n opts = arg2;\n }\n } else {\n Value = arg1 as ValueSchema;\n }\n\n const { onError } = opts;\n if (!onError) {\n // Avoid error-related computations inside the loop\n return z.record(z.string(), z.any()).transform((input) => {\n const output: Record<string, z.infer<ValueSchema>> = {};\n for (const [inputKey, inputVal] of Object.entries(input)) {\n const parsedKey = Key.safeParse(inputKey);\n const parsedValue = Value.safeParse(inputVal);\n if (parsedKey.success && parsedValue.success) {\n output[parsedKey.data as string] = parsedValue.data;\n }\n }\n return output;\n });\n }\n\n return z.record(z.string(), z.any()).transform((input) => {\n const output: Record<string, z.infer<ValueSchema>> = {};\n const issues: z.ZodIssue[] = [];\n\n for (const [inputKey, inputVal] of Object.entries(input)) {\n const parsedKey = Key.safeParse(inputKey);\n if (!parsedKey.success) {\n for (const issue of parsedKey.error.issues) {\n issues.push({ ...issue, path: [inputKey, ...issue.path] });\n }\n continue;\n }\n\n const parsedValue = Value.safeParse(inputVal);\n if (!parsedValue.success) {\n for (const issue of parsedValue.error.issues) {\n issues.push({ ...issue, path: [inputKey, ...issue.path] });\n }\n continue;\n }\n\n output[parsedKey.data as string] = parsedValue.data;\n }\n\n if (issues.length) {\n const error = new z.ZodError(issues);\n onError({ error, input });\n }\n\n return output;\n });\n}\n\n/**\n * Accepts `null`, `undefined`, or an absent key and normalizes all to\n * `undefined`. Keeps the output type as `T | undefined` (never `null`), so\n * assignment into non-nullable targets needs no `?? undefined` coalescing.\n */\nexport function Nullish<Schema extends z.ZodTypeAny>(\n schema: Schema,\n): z.ZodOptional<z.ZodType<z.output<Schema> | undefined>> {\n return schema\n .nullable()\n .transform((value) => value ?? undefined)\n .optional();\n}\n\nfunction deepNullishRewrite(node: z.ZodTypeAny): z.ZodTypeAny {\n if (node instanceof z.ZodOptional) {\n return Nullish(deepNullishRewrite(node.unwrap() as z.ZodTypeAny));\n }\n if (node instanceof z.ZodObject) {\n const shape: Record<string, z.ZodTypeAny> = {};\n for (const [key, value] of Object.entries(node.shape)) {\n shape[key] = deepNullishRewrite(value as z.ZodTypeAny);\n }\n return z.object(shape);\n }\n if (node instanceof z.ZodArray) {\n return z.array(deepNullishRewrite(node.element as z.ZodTypeAny));\n }\n if (node instanceof z.ZodRecord) {\n return z.record(\n node.keyType,\n deepNullishRewrite(node.valueType as z.ZodTypeAny),\n );\n }\n if (node instanceof z.ZodUnion) {\n const options = node.options as z.ZodTypeAny[];\n return z.union(\n options.map(deepNullishRewrite) as [\n z.ZodTypeAny,\n z.ZodTypeAny,\n ...z.ZodTypeAny[],\n ],\n );\n }\n if (node instanceof z.ZodDefault) {\n return deepNullishRewrite(node.unwrap() as z.ZodTypeAny).default(\n node.def.defaultValue,\n );\n }\n if (node instanceof z.ZodNullable) {\n return z.nullable(deepNullishRewrite(node.unwrap() as z.ZodTypeAny));\n }\n if (node instanceof z.ZodPipe) {\n return z.pipe(\n node.def.in as z.ZodTypeAny,\n deepNullishRewrite(node.def.out as z.ZodTypeAny),\n );\n }\n return node;\n}\n\n/**\n * Walks `schema` at build time and replaces every `.optional()` position with\n * `Nullish` semantics — accepting `null`/`undefined`/absent and normalizing all\n * to `undefined`. Recurses through `object`, `array`, `record`, `union`,\n * `default`, `nullable`, and the **output side** of `pipe`/transform nodes\n * (e.g. `Json.pipe(…)`).\n *\n * Intentional `.nullable()` fields are preserved (null kept), distinguishing\n * this from a blunt null-stripping preprocessor.\n *\n * The pipe **input** side (the decoder, e.g. `Json`) is left untouched.\n * **`LooseArray`/`LooseRecord` remain opaque** because their element schema is\n * captured in a closure — wrap the inner schema directly for those\n * (e.g. `LooseArray(DeepNullish(Inner))`).\n *\n * Object modifiers (`.strict()`/`.catchall()`/`.passthrough()`/object-level\n * `.refine()`) are dropped by the `z.object(shape)` rebuild.\n */\nexport function DeepNullish<Schema extends z.ZodTypeAny>(\n schema: Schema,\n): z.ZodType<z.output<Schema>> {\n return deepNullishRewrite(schema) as z.ZodType<z.output<Schema>>;\n}\n\nexport const Json = z.string().transform((str, ctx): unknown => {\n try {\n return JSON.parse(str);\n } catch {\n ctx.addIssue({ code: 'custom', message: 'Invalid JSON' });\n return z.NEVER;\n }\n});\n\nexport const Json5 = z.string().transform((str, ctx): unknown => {\n try {\n return JSON5.parse(str);\n } catch {\n ctx.addIssue({ code: 'custom', message: 'Invalid JSON5' });\n return z.NEVER;\n }\n});\n\nexport const Jsonc = z.string().transform((str, ctx): unknown => {\n try {\n return parseJsonc(str);\n } catch {\n ctx.addIssue({ code: 'custom', message: 'Invalid JSONC' });\n return z.NEVER;\n }\n});\n\nexport const UtcDate = z\n .string()\n .describe('ISO 8601 string')\n .transform((str, ctx): DateTime => {\n const date = DateTime.fromISO(str, { zone: 'utc' });\n if (!date.isValid) {\n ctx.addIssue({ code: 'custom', message: 'Invalid date' });\n return z.NEVER;\n }\n return date;\n });\n\nexport const Yaml = z.string().transform((str, ctx): unknown => {\n try {\n return parseSingleYaml(str);\n } catch {\n ctx.addIssue({ code: 'custom', message: 'Invalid YAML' });\n return z.NEVER;\n }\n});\n\nexport const MultidocYaml = z.string().transform((str, ctx): unknown => {\n try {\n return parseYaml(str);\n } catch {\n ctx.addIssue({ code: 'custom', message: 'Invalid YAML' });\n return z.NEVER;\n }\n});\n\nexport function multidocYaml(\n opts?: Omit<YamlOptions, 'customSchema'>,\n): z.ZodType<JsonArray> {\n return z.string().transform((str, ctx): JsonArray => {\n try {\n return parseYaml(str, opts) as JsonArray;\n } catch {\n ctx.addIssue({ code: 'custom', message: 'Invalid YAML' });\n return z.NEVER;\n }\n });\n}\n\nexport const Toml = z.string().transform((str, ctx) => {\n try {\n return parseToml(str);\n } catch {\n ctx.addIssue({ code: 'custom', message: 'Invalid TOML' });\n return z.NEVER;\n }\n});\n\nexport const Ini = z.string().transform((str, ctx): Record<string, unknown> => {\n try {\n return ini.parse(str);\n } catch /* v8 ignore next -- TODO: add test #40625 */ {\n ctx.addIssue({ code: 'custom', message: 'Invalid INI' });\n return z.NEVER;\n }\n});\n\nexport function withDepType<Output extends PackageDependency[]>(\n schema: z.ZodType<Output>,\n depType: string,\n force = true,\n): z.ZodType<Output> {\n return schema.transform((deps) => {\n for (const dep of deps) {\n if (!dep.depType || force) {\n dep.depType = depType;\n }\n }\n return deps;\n });\n}\n\nexport function withDebugMessage<Output>(\n value: Output,\n msg: string,\n): (ctx: { error: unknown; input: unknown }) => Output {\n return ({ error: err }) => {\n logger.debug({ err }, msg);\n return value;\n };\n}\n\nexport function withTraceMessage<Output>(\n value: Output,\n msg: string,\n): (ctx: { error: unknown; input: unknown }) => Output {\n return ({ error: err }) => {\n logger.trace({ err }, msg);\n return value;\n };\n}\n\nfunction isCircular(value: unknown, visited = new Set<unknown>()): boolean {\n // oxlint-disable-next-line renovate/prefer-is-object -- functions must stay non-circular leaves; isObject() matches functions and would send them into the property walk\n if (value === null || typeof value !== 'object') {\n return false;\n }\n\n if (visited.has(value)) {\n return true;\n }\n\n const downstreamVisited = new Set(visited);\n downstreamVisited.add(value);\n\n if (Array.isArray(value)) {\n for (const childValue of value) {\n if (isCircular(childValue, downstreamVisited)) {\n return true;\n }\n }\n\n return false;\n }\n\n const values = Object.values(value);\n for (const ov of values) {\n if (isCircular(ov, downstreamVisited)) {\n return true;\n }\n }\n\n return false;\n}\n\nexport const NotCircular = z.unknown().superRefine((val, ctx) => {\n if (isCircular(val)) {\n ctx.addIssue({\n code: 'custom',\n message: 'values cannot be circular data structures',\n fatal: true,\n });\n\n return z.NEVER;\n }\n});\n\nconst StandardEmail = z.email();\n\n// GitHub/Forgejo apps use addresses like `1234+name[bot]@users.noreply.github.com`.\n// The `[bot]` marker is not valid in the local part per RFC 5322, so we strip it before\nexport const EmailAddress = z\n .string()\n .refine(\n (value) => StandardEmail.safeParse(value.replace('[bot]@', '@')).success,\n 'Invalid email address',\n );\nexport type EmailAddress = z.infer<typeof EmailAddress>;\n\nexport function isEmailAdress(value: string): boolean {\n return EmailAddress.safeParse(value).success;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AA+BA,SAAgB,WACd,MACA,EAAE,YAAkC,CAAC,GACD;CACpC,IAAI,CAAC,SAEH,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,WAAW,UAAU;EAC3C,MAAM,SAA4B,CAAC;EACnC,KAAK,MAAM,KAAK,OAAO;GACrB,MAAM,SAAS,KAAK,UAAU,CAAC;GAC/B,IAAI,OAAO,SACT,OAAO,KAAK,OAAO,IAAI;EAE3B;EACA,OAAO;CACT,CAAC;CAGH,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,WAAW,UAAU;EAC3C,MAAM,SAA4B,CAAC;EACnC,MAAM,SAAuB,CAAC;EAE9B,KAAK,IAAI,MAAM,GAAG,MAAM,MAAM,QAAQ,OAAO,GAAG;GAC9C,MAAM,IAAI,MAAM;GAChB,MAAM,SAAS,KAAK,UAAU,CAAC;GAE/B,IAAI,OAAO,SAAS;IAClB,OAAO,KAAK,OAAO,IAAI;IACvB;GACF;GAEA,KAAK,MAAM,SAAS,OAAO,MAAM,QAC/B,OAAO,KAAK;IAAE,GAAG;IAAO,MAAM,CAAC,KAAK,GAAG,MAAM,IAAI;GAAE,CAAC;EAExD;EAEA,IAAI,OAAO,QAET,QAAQ;GAAE,OAAA,IADQ,EAAE,SAAS,MACf;GAAG;EAAM,CAAC;EAG1B,OAAO;CACT,CAAC;AACH;AAuCA,SAAgB,YAId,MACA,MACA,MACgC;CAChC,IAAI,MAAiB,EAAE,IAAI;CAC3B,IAAI;CACJ,IAAI,OAAwB,CAAC;CAC7B,IAAI,QAAQ,MAAM;EAChB,MAAM;EACN,QAAQ;EACR,OAAO;CACT,OAAO,IAAI,MAAM;EACf,IAAI,gBAAgB,EAAE,SAAS;GAC7B,MAAM;GACN,QAAQ;EACV,OAAO;GACL,QAAQ;GACR,OAAO;EACT;CACF,OACE,QAAQ;CAGV,MAAM,EAAE,YAAY;CACpB,IAAI,CAAC,SAEH,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,WAAW,UAAU;EACxD,MAAM,SAA+C,CAAC;EACtD,KAAK,MAAM,CAAC,UAAU,aAAa,OAAO,QAAQ,KAAK,GAAG;GACxD,MAAM,YAAY,IAAI,UAAU,QAAQ;GACxC,MAAM,cAAc,MAAM,UAAU,QAAQ;GAC5C,IAAI,UAAU,WAAW,YAAY,SACnC,OAAO,UAAU,QAAkB,YAAY;EAEnD;EACA,OAAO;CACT,CAAC;CAGH,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,WAAW,UAAU;EACxD,MAAM,SAA+C,CAAC;EACtD,MAAM,SAAuB,CAAC;EAE9B,KAAK,MAAM,CAAC,UAAU,aAAa,OAAO,QAAQ,KAAK,GAAG;GACxD,MAAM,YAAY,IAAI,UAAU,QAAQ;GACxC,IAAI,CAAC,UAAU,SAAS;IACtB,KAAK,MAAM,SAAS,UAAU,MAAM,QAClC,OAAO,KAAK;KAAE,GAAG;KAAO,MAAM,CAAC,UAAU,GAAG,MAAM,IAAI;IAAE,CAAC;IAE3D;GACF;GAEA,MAAM,cAAc,MAAM,UAAU,QAAQ;GAC5C,IAAI,CAAC,YAAY,SAAS;IACxB,KAAK,MAAM,SAAS,YAAY,MAAM,QACpC,OAAO,KAAK;KAAE,GAAG;KAAO,MAAM,CAAC,UAAU,GAAG,MAAM,IAAI;IAAE,CAAC;IAE3D;GACF;GAEA,OAAO,UAAU,QAAkB,YAAY;EACjD;EAEA,IAAI,OAAO,QAAQ;GACjB,MAAM,QAAQ,IAAI,EAAE,SAAS,MAAM;GACnC,QAAQ;IAAE;IAAO;GAAM,CAAC;EAC1B;EAEA,OAAO;CACT,CAAC;AACH;;;;;;AAOA,SAAgB,QACd,QACwD;CACxD,OAAO,OACJ,SAAS,CAAC,CACV,WAAW,UAAU,SAAS,KAAA,CAAS,CAAC,CACxC,SAAS;AACd;AAEA,SAAS,mBAAmB,MAAkC;CAC5D,IAAI,gBAAgB,EAAE,aACpB,OAAO,QAAQ,mBAAmB,KAAK,OAAO,CAAiB,CAAC;CAElE,IAAI,gBAAgB,EAAE,WAAW;EAC/B,MAAM,QAAsC,CAAC;EAC7C,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,KAAK,GAClD,MAAM,OAAO,mBAAmB,KAAqB;EAEvD,OAAO,EAAE,OAAO,KAAK;CACvB;CACA,IAAI,gBAAgB,EAAE,UACpB,OAAO,EAAE,MAAM,mBAAmB,KAAK,OAAuB,CAAC;CAEjE,IAAI,gBAAgB,EAAE,WACpB,OAAO,EAAE,OACP,KAAK,SACL,mBAAmB,KAAK,SAAyB,CACnD;CAEF,IAAI,gBAAgB,EAAE,UAAU;EAC9B,MAAM,UAAU,KAAK;EACrB,OAAO,EAAE,MACP,QAAQ,IAAI,kBAAkB,CAKhC;CACF;CACA,IAAI,gBAAgB,EAAE,YACpB,OAAO,mBAAmB,KAAK,OAAO,CAAiB,CAAC,CAAC,QACvD,KAAK,IAAI,YACX;CAEF,IAAI,gBAAgB,EAAE,aACpB,OAAO,EAAE,SAAS,mBAAmB,KAAK,OAAO,CAAiB,CAAC;CAErE,IAAI,gBAAgB,EAAE,SACpB,OAAO,EAAE,KACP,KAAK,IAAI,IACT,mBAAmB,KAAK,IAAI,GAAmB,CACjD;CAEF,OAAO;AACT;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,YACd,QAC6B;CAC7B,OAAO,mBAAmB,MAAM;AAClC;AAEA,MAAa,OAAO,EAAE,OAAO,CAAC,CAAC,WAAW,KAAK,QAAiB;CAC9D,IAAI;EACF,OAAO,KAAK,MAAM,GAAG;CACvB,QAAQ;EACN,IAAI,SAAS;GAAE,MAAM;GAAU,SAAS;EAAe,CAAC;EACxD,OAAO,EAAE;CACX;AACF,CAAC;AAED,MAAa,QAAQ,EAAE,OAAO,CAAC,CAAC,WAAW,KAAK,QAAiB;CAC/D,IAAI;EACF,OAAO,MAAM,MAAM,GAAG;CACxB,QAAQ;EACN,IAAI,SAAS;GAAE,MAAM;GAAU,SAAS;EAAgB,CAAC;EACzD,OAAO,EAAE;CACX;AACF,CAAC;AAED,MAAa,QAAQ,EAAE,OAAO,CAAC,CAAC,WAAW,KAAK,QAAiB;CAC/D,IAAI;EACF,OAAO,WAAW,GAAG;CACvB,QAAQ;EACN,IAAI,SAAS;GAAE,MAAM;GAAU,SAAS;EAAgB,CAAC;EACzD,OAAO,EAAE;CACX;AACF,CAAC;AAED,MAAa,UAAU,EACpB,OAAO,CAAC,CACR,SAAS,iBAAiB,CAAC,CAC3B,WAAW,KAAK,QAAkB;CACjC,MAAM,OAAO,SAAS,QAAQ,KAAK,EAAE,MAAM,MAAM,CAAC;CAClD,IAAI,CAAC,KAAK,SAAS;EACjB,IAAI,SAAS;GAAE,MAAM;GAAU,SAAS;EAAe,CAAC;EACxD,OAAO,EAAE;CACX;CACA,OAAO;AACT,CAAC;AAEH,MAAa,OAAO,EAAE,OAAO,CAAC,CAAC,WAAW,KAAK,QAAiB;CAC9D,IAAI;EACF,OAAO,gBAAgB,GAAG;CAC5B,QAAQ;EACN,IAAI,SAAS;GAAE,MAAM;GAAU,SAAS;EAAe,CAAC;EACxD,OAAO,EAAE;CACX;AACF,CAAC;AAE2B,EAAE,OAAO,CAAC,CAAC,WAAW,KAAK,QAAiB;CACtE,IAAI;EACF,OAAO,UAAU,GAAG;CACtB,QAAQ;EACN,IAAI,SAAS;GAAE,MAAM;GAAU,SAAS;EAAe,CAAC;EACxD,OAAO,EAAE;CACX;AACF,CAAC;AAED,SAAgB,aACd,MACsB;CACtB,OAAO,EAAE,OAAO,CAAC,CAAC,WAAW,KAAK,QAAmB;EACnD,IAAI;GACF,OAAO,UAAU,KAAK,IAAI;EAC5B,QAAQ;GACN,IAAI,SAAS;IAAE,MAAM;IAAU,SAAS;GAAe,CAAC;GACxD,OAAO,EAAE;EACX;CACF,CAAC;AACH;AAEA,MAAa,OAAO,EAAE,OAAO,CAAC,CAAC,WAAW,KAAK,QAAQ;CACrD,IAAI;EACF,OAAOA,MAAU,GAAG;CACtB,QAAQ;EACN,IAAI,SAAS;GAAE,MAAM;GAAU,SAAS;EAAe,CAAC;EACxD,OAAO,EAAE;CACX;AACF,CAAC;AAED,MAAa,MAAM,EAAE,OAAO,CAAC,CAAC,WAAW,KAAK,QAAiC;CAC7E,IAAI;EACF,OAAO,IAAI,MAAM,GAAG;CACtB,sDAAsD;EACpD,IAAI,SAAS;GAAE,MAAM;GAAU,SAAS;EAAc,CAAC;EACvD,OAAO,EAAE;CACX;AACF,CAAC;AAED,SAAgB,YACd,QACA,SACA,QAAQ,MACW;CACnB,OAAO,OAAO,WAAW,SAAS;EAChC,KAAK,MAAM,OAAO,MAChB,IAAI,CAAC,IAAI,WAAW,OAClB,IAAI,UAAU;EAGlB,OAAO;CACT,CAAC;AACH;AAEA,SAAgB,iBACd,OACA,KACqD;CACrD,QAAQ,EAAE,OAAO,UAAU;EACzB,OAAO,MAAM,EAAE,IAAI,GAAG,GAAG;EACzB,OAAO;CACT;AACF;AAYA,SAAS,WAAW,OAAgB,0BAAU,IAAI,IAAa,GAAY;CAEzE,IAAI,UAAU,QAAQ,OAAO,UAAU,UACrC,OAAO;CAGT,IAAI,QAAQ,IAAI,KAAK,GACnB,OAAO;CAGT,MAAM,oBAAoB,IAAI,IAAI,OAAO;CACzC,kBAAkB,IAAI,KAAK;CAE3B,IAAI,MAAM,QAAQ,KAAK,GAAG;EACxB,KAAK,MAAM,cAAc,OACvB,IAAI,WAAW,YAAY,iBAAiB,GAC1C,OAAO;EAIX,OAAO;CACT;CAEA,MAAM,SAAS,OAAO,OAAO,KAAK;CAClC,KAAK,MAAM,MAAM,QACf,IAAI,WAAW,IAAI,iBAAiB,GAClC,OAAO;CAIX,OAAO;AACT;AAEA,MAAa,cAAc,EAAE,QAAQ,CAAC,CAAC,aAAa,KAAK,QAAQ;CAC/D,IAAI,WAAW,GAAG,GAAG;EACnB,IAAI,SAAS;GACX,MAAM;GACN,SAAS;GACT,OAAO;EACT,CAAC;EAED,OAAO,EAAE;CACX;AACF,CAAC;AAED,MAAM,gBAAgB,EAAE,MAAM;AAI9B,MAAa,eAAe,EACzB,OAAO,CAAC,CACR,QACE,UAAU,cAAc,UAAU,MAAM,QAAQ,UAAU,GAAG,CAAC,CAAC,CAAC,SACjE,uBACF;AAGF,SAAgB,cAAc,OAAwB;CACpD,OAAO,aAAa,UAAU,KAAK,CAAC,CAAC;AACvC"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["parseToml"],"sources":["../../../lib/util/schema-utils/index.ts"],"sourcesContent":["import ini from 'ini';\nimport JSON5 from 'json5';\nimport { DateTime } from 'luxon';\nimport type { JsonArray } from 'type-fest';\nimport { z } from 'zod/v4';\nimport { logger } from '../../logger/index.ts';\nimport type { PackageDependency } from '../../modules/manager/types.ts';\nimport { parseJsonc } from '../common.ts';\nimport { parse as parseToml } from '../toml.ts';\nimport type { YamlOptions } from '../yaml.ts';\nimport { parseSingleYaml, parseYaml } from '../yaml.ts';\n\ninterface ErrorContext<T> {\n error: z.ZodError;\n input: T;\n}\n\ninterface LooseOpts<T> {\n onError?: (err: ErrorContext<T>) => void;\n}\n\n/**\n * Works like `z.array()`, but drops wrong elements instead of invalidating the whole array.\n *\n * **Important**: non-array inputs are still invalid.\n * Use `LooseArray(...).catch([])` to handle it.\n *\n * @param Elem Schema for array elements\n * @param onError Callback for errors\n * @returns Schema for array\n */\nexport function LooseArray<Schema extends z.ZodTypeAny>(\n Elem: Schema,\n { onError }: LooseOpts<unknown[]> = {},\n): z.ZodType<z.TypeOf<Schema>[], any> {\n if (!onError) {\n // Avoid error-related computations inside the loop\n return z.array(z.any()).transform((input) => {\n const output: z.infer<Schema>[] = [];\n for (const x of input) {\n const parsed = Elem.safeParse(x);\n if (parsed.success) {\n output.push(parsed.data);\n }\n }\n return output;\n });\n }\n\n return z.array(z.any()).transform((input) => {\n const output: z.infer<Schema>[] = [];\n const issues: z.ZodIssue[] = [];\n\n for (let idx = 0; idx < input.length; idx += 1) {\n const x = input[idx];\n const parsed = Elem.safeParse(x);\n\n if (parsed.success) {\n output.push(parsed.data);\n continue;\n }\n\n for (const issue of parsed.error.issues) {\n issues.push({ ...issue, path: [idx, ...issue.path] });\n }\n }\n\n if (issues.length) {\n const error = new z.ZodError(issues);\n onError({ error, input });\n }\n\n return output;\n });\n}\n\ntype LooseRecordResult<ValueSchema extends z.ZodTypeAny> = z.ZodType<\n Record<string, z.TypeOf<ValueSchema>>,\n any\n>;\n\ntype LooseRecordOpts = LooseOpts<Record<string, unknown>>;\n\n/**\n * Works like `z.record()`, but drops wrong elements instead of invalidating the whole record.\n *\n * **Important**: non-record inputs other are still invalid.\n * Use `LooseRecord(...).catch({})` to handle it.\n *\n * @param KeyValue Schema for record keys\n * @param ValueValue Schema for record values\n * @param onError Callback for errors\n * @returns Schema for record\n */\nexport function LooseRecord<ValueSchema extends z.ZodTypeAny>(\n Value: ValueSchema,\n): LooseRecordResult<ValueSchema>;\nexport function LooseRecord<\n KeySchema extends z.ZodTypeAny,\n ValueSchema extends z.ZodTypeAny,\n>(Key: KeySchema, Value: ValueSchema): LooseRecordResult<ValueSchema>;\nexport function LooseRecord<ValueSchema extends z.ZodTypeAny>(\n Value: ValueSchema,\n { onError }: LooseRecordOpts,\n): LooseRecordResult<ValueSchema>;\nexport function LooseRecord<\n KeySchema extends z.ZodTypeAny,\n ValueSchema extends z.ZodTypeAny,\n>(\n Key: KeySchema,\n Value: ValueSchema,\n { onError }: LooseRecordOpts,\n): LooseRecordResult<ValueSchema>;\nexport function LooseRecord<\n KeySchema extends z.ZodTypeAny,\n ValueSchema extends z.ZodTypeAny,\n>(\n arg1: ValueSchema | KeySchema,\n arg2?: ValueSchema | LooseOpts<Record<string, unknown>>,\n arg3?: LooseRecordOpts,\n): LooseRecordResult<ValueSchema> {\n let Key: z.ZodType = z.any();\n let Value: ValueSchema;\n let opts: LooseRecordOpts = {};\n if (arg2 && arg3) {\n Key = arg1 as KeySchema;\n Value = arg2 as ValueSchema;\n opts = arg3;\n } else if (arg2) {\n if (arg2 instanceof z.ZodType) {\n Key = arg1 as KeySchema;\n Value = arg2;\n } else {\n Value = arg1 as ValueSchema;\n opts = arg2;\n }\n } else {\n Value = arg1 as ValueSchema;\n }\n\n const { onError } = opts;\n if (!onError) {\n // Avoid error-related computations inside the loop\n return z.record(z.string(), z.any()).transform((input) => {\n const output: Record<string, z.infer<ValueSchema>> = {};\n for (const [inputKey, inputVal] of Object.entries(input)) {\n const parsedKey = Key.safeParse(inputKey);\n const parsedValue = Value.safeParse(inputVal);\n if (parsedKey.success && parsedValue.success) {\n output[parsedKey.data as string] = parsedValue.data;\n }\n }\n return output;\n });\n }\n\n return z.record(z.string(), z.any()).transform((input) => {\n const output: Record<string, z.infer<ValueSchema>> = {};\n const issues: z.ZodIssue[] = [];\n\n for (const [inputKey, inputVal] of Object.entries(input)) {\n const parsedKey = Key.safeParse(inputKey);\n if (!parsedKey.success) {\n for (const issue of parsedKey.error.issues) {\n issues.push({ ...issue, path: [inputKey, ...issue.path] });\n }\n continue;\n }\n\n const parsedValue = Value.safeParse(inputVal);\n if (!parsedValue.success) {\n for (const issue of parsedValue.error.issues) {\n issues.push({ ...issue, path: [inputKey, ...issue.path] });\n }\n continue;\n }\n\n output[parsedKey.data as string] = parsedValue.data;\n }\n\n if (issues.length) {\n const error = new z.ZodError(issues);\n onError({ error, input });\n }\n\n return output;\n });\n}\n\n/**\n * Accepts `null`, `undefined`, or an absent key and normalizes all to\n * `undefined`. Keeps the output type as `T | undefined` (never `null`), so\n * assignment into non-nullable targets needs no `?? undefined` coalescing.\n */\nexport function Nullish<Schema extends z.ZodTypeAny>(\n schema: Schema,\n): z.ZodOptional<z.ZodType<z.output<Schema> | undefined>> {\n return schema\n .nullable()\n .transform((value) => value ?? undefined)\n .optional();\n}\n\nfunction deepNullishRewrite(node: z.ZodTypeAny): z.ZodTypeAny {\n if (node instanceof z.ZodOptional) {\n return Nullish(deepNullishRewrite(node.unwrap() as z.ZodTypeAny));\n }\n if (node instanceof z.ZodObject) {\n const shape: Record<string, z.ZodTypeAny> = {};\n for (const [key, value] of Object.entries(node.shape)) {\n shape[key] = deepNullishRewrite(value as z.ZodTypeAny);\n }\n return z.object(shape);\n }\n if (node instanceof z.ZodArray) {\n return z.array(deepNullishRewrite(node.element as z.ZodTypeAny));\n }\n if (node instanceof z.ZodRecord) {\n return z.record(\n node.keyType,\n deepNullishRewrite(node.valueType as z.ZodTypeAny),\n );\n }\n if (node instanceof z.ZodUnion) {\n const options = node.options as z.ZodTypeAny[];\n return z.union(\n options.map(deepNullishRewrite) as [\n z.ZodTypeAny,\n z.ZodTypeAny,\n ...z.ZodTypeAny[],\n ],\n );\n }\n if (node instanceof z.ZodDefault) {\n return deepNullishRewrite(node.unwrap() as z.ZodTypeAny).default(\n node.def.defaultValue,\n );\n }\n if (node instanceof z.ZodNullable) {\n return z.nullable(deepNullishRewrite(node.unwrap() as z.ZodTypeAny));\n }\n if (node instanceof z.ZodPipe) {\n return z.pipe(\n node.def.in as z.ZodTypeAny,\n deepNullishRewrite(node.def.out as z.ZodTypeAny),\n );\n }\n return node;\n}\n\n/**\n * Walks `schema` at build time and replaces every `.optional()` position with\n * `Nullish` semantics — accepting `null`/`undefined`/absent and normalizing all\n * to `undefined`. Recurses through `object`, `array`, `record`, `union`,\n * `default`, `nullable`, and the **output side** of `pipe`/transform nodes\n * (e.g. `Json.pipe(…)`).\n *\n * Intentional `.nullable()` fields are preserved (null kept), distinguishing\n * this from a blunt null-stripping preprocessor.\n *\n * The pipe **input** side (the decoder, e.g. `Json`) is left untouched.\n * **`LooseArray`/`LooseRecord` remain opaque** because their element schema is\n * captured in a closure — wrap the inner schema directly for those\n * (e.g. `LooseArray(DeepNullish(Inner))`).\n *\n * Object modifiers (`.strict()`/`.catchall()`/`.passthrough()`/object-level\n * `.refine()`) are dropped by the `z.object(shape)` rebuild.\n */\nexport function DeepNullish<Schema extends z.ZodTypeAny>(\n schema: Schema,\n): z.ZodType<z.output<Schema>> {\n return deepNullishRewrite(schema) as z.ZodType<z.output<Schema>>;\n}\n\nexport const Json = z.string().transform((str, ctx): unknown => {\n try {\n return JSON.parse(str);\n } catch {\n ctx.addIssue({ code: 'custom', message: 'Invalid JSON' });\n return z.NEVER;\n }\n});\n\nexport const Json5 = z.string().transform((str, ctx): unknown => {\n try {\n return JSON5.parse(str);\n } catch {\n ctx.addIssue({ code: 'custom', message: 'Invalid JSON5' });\n return z.NEVER;\n }\n});\n\nexport const Jsonc = z.string().transform((str, ctx): unknown => {\n try {\n return parseJsonc(str);\n } catch {\n ctx.addIssue({ code: 'custom', message: 'Invalid JSONC' });\n return z.NEVER;\n }\n});\n\nexport const UtcDate = z\n .string()\n .describe('ISO 8601 string')\n .transform((str, ctx): DateTime => {\n const date = DateTime.fromISO(str, { zone: 'utc' });\n if (!date.isValid) {\n ctx.addIssue({ code: 'custom', message: 'Invalid date' });\n return z.NEVER;\n }\n return date;\n });\n\nexport const Yaml = z.string().transform((str, ctx): unknown => {\n try {\n return parseSingleYaml(str);\n } catch {\n ctx.addIssue({ code: 'custom', message: 'Invalid YAML' });\n return z.NEVER;\n }\n});\n\nexport const MultidocYaml = z.string().transform((str, ctx): unknown => {\n try {\n return parseYaml(str);\n } catch {\n ctx.addIssue({ code: 'custom', message: 'Invalid YAML' });\n return z.NEVER;\n }\n});\n\nexport function multidocYaml(\n opts?: Omit<YamlOptions, 'customSchema'>,\n): z.ZodType<JsonArray> {\n return z.string().transform((str, ctx): JsonArray => {\n try {\n return parseYaml(str, opts) as JsonArray;\n } catch {\n ctx.addIssue({ code: 'custom', message: 'Invalid YAML' });\n return z.NEVER;\n }\n });\n}\n\nexport const Toml = z.string().transform((str, ctx) => {\n try {\n return parseToml(str);\n } catch {\n ctx.addIssue({ code: 'custom', message: 'Invalid TOML' });\n return z.NEVER;\n }\n});\n\nexport const Ini = z.string().transform((str, ctx): Record<string, unknown> => {\n try {\n // oxlint-disable-next-line renovate/prefer-parser-pipe -- this is the Ini helper itself\n return ini.parse(str);\n } catch /* v8 ignore next -- TODO: add test #40625 */ {\n ctx.addIssue({ code: 'custom', message: 'Invalid INI' });\n return z.NEVER;\n }\n});\n\nexport function withDepType<Output extends PackageDependency[]>(\n schema: z.ZodType<Output>,\n depType: string,\n force = true,\n): z.ZodType<Output> {\n return schema.transform((deps) => {\n for (const dep of deps) {\n if (!dep.depType || force) {\n dep.depType = depType;\n }\n }\n return deps;\n });\n}\n\nexport function withDebugMessage<Output>(\n value: Output,\n msg: string,\n): (ctx: { error: unknown; input: unknown }) => Output {\n return ({ error: err }) => {\n logger.debug({ err }, msg);\n return value;\n };\n}\n\nexport function withTraceMessage<Output>(\n value: Output,\n msg: string,\n): (ctx: { error: unknown; input: unknown }) => Output {\n return ({ error: err }) => {\n logger.trace({ err }, msg);\n return value;\n };\n}\n\nfunction isCircular(value: unknown, visited = new Set<unknown>()): boolean {\n // oxlint-disable-next-line renovate/prefer-is-object -- functions must stay non-circular leaves; isObject() matches functions and would send them into the property walk\n if (value === null || typeof value !== 'object') {\n return false;\n }\n\n if (visited.has(value)) {\n return true;\n }\n\n const downstreamVisited = new Set(visited);\n downstreamVisited.add(value);\n\n if (Array.isArray(value)) {\n for (const childValue of value) {\n if (isCircular(childValue, downstreamVisited)) {\n return true;\n }\n }\n\n return false;\n }\n\n const values = Object.values(value);\n for (const ov of values) {\n if (isCircular(ov, downstreamVisited)) {\n return true;\n }\n }\n\n return false;\n}\n\nexport const NotCircular = z.unknown().superRefine((val, ctx) => {\n if (isCircular(val)) {\n ctx.addIssue({\n code: 'custom',\n message: 'values cannot be circular data structures',\n fatal: true,\n });\n\n return z.NEVER;\n }\n});\n\nconst StandardEmail = z.email();\n\n// GitHub/Forgejo apps use addresses like `1234+name[bot]@users.noreply.github.com`.\n// The `[bot]` marker is not valid in the local part per RFC 5322, so we strip it before\nexport const EmailAddress = z\n .string()\n .refine(\n (value) => StandardEmail.safeParse(value.replace('[bot]@', '@')).success,\n 'Invalid email address',\n );\nexport type EmailAddress = z.infer<typeof EmailAddress>;\n\nexport function isEmailAdress(value: string): boolean {\n return EmailAddress.safeParse(value).success;\n}\n\nexport const StringOrStringArray = z.union([z.string(), z.array(z.string())]);\n\n/**\n * A config option definition whose value is a string or an array of strings.\n */\nexport const StringOrStringArrayOption = z.union([\n z.object({ type: z.literal('string') }),\n z.object({ type: z.literal('array'), subType: z.literal('string') }),\n]);\n"],"mappings":"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"}
|
|
@@ -43,7 +43,8 @@ function hostRulesFromEnv(env) {
|
|
|
43
43
|
}
|
|
44
44
|
const splitEnv = envName.replace(regEx(/^RENOVATE_/), "").toLowerCase().replace(regEx(/__/g), "-").split("_");
|
|
45
45
|
const hostType = splitEnv.shift();
|
|
46
|
-
|
|
46
|
+
const isPlatformWithHost = platforms.has(hostType) && splitEnv.length > 1;
|
|
47
|
+
if (datasources.has(hostType) || isPlatformWithHost) {
|
|
47
48
|
let suffix = splitEnv.pop();
|
|
48
49
|
if (isAuthField(suffix) || isHttpsAuthField(suffix)) {
|
|
49
50
|
suffix = restoreHttpsAuthField(suffix);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host-rules-from-env.js","names":[],"sources":["../../../../../lib/workers/global/config/parse/host-rules-from-env.ts"],"sourcesContent":["import { logger } from '../../../../logger/index.ts';\nimport { getDatasourceList } from '../../../../modules/datasource/index.ts';\nimport type { HostRule } from '../../../../types/index.ts';\nimport { regEx } from '../../../../util/regex.ts';\n\ntype AuthField = 'token' | 'username' | 'password';\n\ntype HttpsAuthField =\n 'httpscertificate' | 'httpsprivatekey' | 'httpscertificateauthority';\n\nfunction isAuthField(x: unknown): x is AuthField {\n return x === 'token' || x === 'username' || x === 'password';\n}\n\nfunction isHttpsAuthField(x: unknown): x is HttpsAuthField {\n return (\n x === 'httpscertificate' ||\n x === 'httpsprivatekey' ||\n x === 'httpscertificateauthority'\n );\n}\n\nfunction restoreHttpsAuthField(x: HttpsAuthField | AuthField): string {\n switch (x) {\n case 'httpsprivatekey':\n return 'httpsPrivateKey';\n case 'httpscertificate':\n return 'httpsCertificate';\n case 'httpscertificateauthority':\n return 'httpsCertificateAuthority';\n }\n\n return x;\n}\n\nfunction setHostRuleValue(\n rule: HostRule,\n key: string,\n value: string | undefined,\n): void {\n if (value !== undefined) {\n switch (key) {\n case 'token':\n case 'username':\n case 'password':\n case 'httpsCertificateAuthority':\n case 'httpsCertificate':\n case 'httpsPrivateKey':\n rule[key] = value;\n }\n }\n}\n\nexport function hostRulesFromEnv(env: NodeJS.ProcessEnv): HostRule[] {\n const datasources = new Set(getDatasourceList());\n const platforms = new Set(['github']);\n\n const hostRules: HostRule[] = [];\n\n const npmEnvPrefixes = ['npm_config_', 'npm_lifecycle_', 'npm_package_'];\n\n for (const envName of Object.keys(env).sort()) {\n if (['GITHUB_COM_TOKEN', 'RENOVATE_GITHUB_COM_TOKEN'].includes(envName)) {\n continue;\n }\n if (npmEnvPrefixes.some((prefix) => envName.startsWith(prefix))) {\n logger.trace(`Ignoring npm env: ${envName}`);\n continue;\n }\n // Double underscore __ is used in place of hyphen -\n const splitEnv = envName\n .replace(regEx(/^RENOVATE_/), '')\n .toLowerCase()\n .replace(regEx(/__/g), '-')\n .split('_');\n const hostType = splitEnv.shift()!;\n
|
|
1
|
+
{"version":3,"file":"host-rules-from-env.js","names":[],"sources":["../../../../../lib/workers/global/config/parse/host-rules-from-env.ts"],"sourcesContent":["import { logger } from '../../../../logger/index.ts';\nimport { getDatasourceList } from '../../../../modules/datasource/index.ts';\nimport type { HostRule } from '../../../../types/index.ts';\nimport { regEx } from '../../../../util/regex.ts';\n\ntype AuthField = 'token' | 'username' | 'password';\n\ntype HttpsAuthField =\n 'httpscertificate' | 'httpsprivatekey' | 'httpscertificateauthority';\n\nfunction isAuthField(x: unknown): x is AuthField {\n return x === 'token' || x === 'username' || x === 'password';\n}\n\nfunction isHttpsAuthField(x: unknown): x is HttpsAuthField {\n return (\n x === 'httpscertificate' ||\n x === 'httpsprivatekey' ||\n x === 'httpscertificateauthority'\n );\n}\n\nfunction restoreHttpsAuthField(x: HttpsAuthField | AuthField): string {\n switch (x) {\n case 'httpsprivatekey':\n return 'httpsPrivateKey';\n case 'httpscertificate':\n return 'httpsCertificate';\n case 'httpscertificateauthority':\n return 'httpsCertificateAuthority';\n }\n\n return x;\n}\n\nfunction setHostRuleValue(\n rule: HostRule,\n key: string,\n value: string | undefined,\n): void {\n if (value !== undefined) {\n switch (key) {\n case 'token':\n case 'username':\n case 'password':\n case 'httpsCertificateAuthority':\n case 'httpsCertificate':\n case 'httpsPrivateKey':\n rule[key] = value;\n }\n }\n}\n\nexport function hostRulesFromEnv(env: NodeJS.ProcessEnv): HostRule[] {\n const datasources = new Set(getDatasourceList());\n const platforms = new Set(['github']);\n\n const hostRules: HostRule[] = [];\n\n const npmEnvPrefixes = ['npm_config_', 'npm_lifecycle_', 'npm_package_'];\n\n for (const envName of Object.keys(env).sort()) {\n if (['GITHUB_COM_TOKEN', 'RENOVATE_GITHUB_COM_TOKEN'].includes(envName)) {\n continue;\n }\n if (npmEnvPrefixes.some((prefix) => envName.startsWith(prefix))) {\n logger.trace(`Ignoring npm env: ${envName}`);\n continue;\n }\n // Double underscore __ is used in place of hyphen -\n const splitEnv = envName\n .replace(regEx(/^RENOVATE_/), '')\n .toLowerCase()\n .replace(regEx(/__/g), '-')\n .split('_');\n const hostType = splitEnv.shift()!;\n const isPlatformWithHost = platforms.has(hostType) && splitEnv.length > 1;\n if (datasources.has(hostType) || isPlatformWithHost) {\n let suffix = splitEnv.pop()!;\n if (isAuthField(suffix) || isHttpsAuthField(suffix)) {\n suffix = restoreHttpsAuthField(suffix);\n\n let matchHost: string | undefined = undefined;\n const rule: HostRule = {};\n setHostRuleValue(rule, suffix, env[envName]);\n if (splitEnv.length === 0) {\n // host-less rule\n } else if (splitEnv.length === 1) {\n logger.warn({ env: envName }, 'Cannot parse env');\n continue;\n } else {\n matchHost = splitEnv.join('.');\n }\n const existingRule = hostRules.find(\n (hr) => hr.hostType === hostType && hr.matchHost === matchHost,\n );\n logger.debug(`Converting ${envName} into a global host rule`);\n if (existingRule) {\n // Add current field to existing rule\n setHostRuleValue(existingRule, suffix, env[envName]);\n } else {\n // Create a new rule\n const newRule: HostRule = {\n hostType,\n };\n if (matchHost) {\n newRule.matchHost = matchHost;\n }\n setHostRuleValue(newRule, suffix, env[envName]);\n hostRules.push(newRule);\n }\n }\n }\n }\n return hostRules;\n}\n"],"mappings":";;;;AAUA,SAAS,YAAY,GAA4B;CAC/C,OAAO,MAAM,WAAW,MAAM,cAAc,MAAM;AACpD;AAEA,SAAS,iBAAiB,GAAiC;CACzD,OACE,MAAM,sBACN,MAAM,qBACN,MAAM;AAEV;AAEA,SAAS,sBAAsB,GAAuC;CACpE,QAAQ,GAAR;EACE,KAAK,mBACH,OAAO;EACT,KAAK,oBACH,OAAO;EACT,KAAK,6BACH,OAAO;CACX;CAEA,OAAO;AACT;AAEA,SAAS,iBACP,MACA,KACA,OACM;CACN,IAAI,UAAU,KAAA,GACZ,QAAQ,KAAR;EACE,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,mBACH,KAAK,OAAO;CAChB;AAEJ;AAEA,SAAgB,iBAAiB,KAAoC;CACnE,MAAM,cAAc,IAAI,IAAI,kBAAkB,CAAC;CAC/C,MAAM,4BAAY,IAAI,IAAI,CAAC,QAAQ,CAAC;CAEpC,MAAM,YAAwB,CAAC;CAE/B,MAAM,iBAAiB;EAAC;EAAe;EAAkB;CAAc;CAEvE,KAAK,MAAM,WAAW,OAAO,KAAK,GAAG,CAAC,CAAC,KAAK,GAAG;EAC7C,IAAI,CAAC,oBAAoB,2BAA2B,CAAC,CAAC,SAAS,OAAO,GACpE;EAEF,IAAI,eAAe,MAAM,WAAW,QAAQ,WAAW,MAAM,CAAC,GAAG;GAC/D,OAAO,MAAM,qBAAqB,SAAS;GAC3C;EACF;EAEA,MAAM,WAAW,QACd,QAAQ,MAAM,YAAY,GAAG,EAAE,CAAC,CAChC,YAAY,CAAC,CACb,QAAQ,MAAM,KAAK,GAAG,GAAG,CAAC,CAC1B,MAAM,GAAG;EACZ,MAAM,WAAW,SAAS,MAAM;EAChC,MAAM,qBAAqB,UAAU,IAAI,QAAQ,KAAK,SAAS,SAAS;EACxE,IAAI,YAAY,IAAI,QAAQ,KAAK,oBAAoB;GACnD,IAAI,SAAS,SAAS,IAAI;GAC1B,IAAI,YAAY,MAAM,KAAK,iBAAiB,MAAM,GAAG;IACnD,SAAS,sBAAsB,MAAM;IAErC,IAAI,YAAgC,KAAA;IAEpC,iBAAiB,CAAG,GAAG,QAAQ,IAAI,QAAQ;IAC3C,IAAI,SAAS,WAAW,GAAG,CAE3B,OAAO,IAAI,SAAS,WAAW,GAAG;KAChC,OAAO,KAAK,EAAE,KAAK,QAAQ,GAAG,kBAAkB;KAChD;IACF,OACE,YAAY,SAAS,KAAK,GAAG;IAE/B,MAAM,eAAe,UAAU,MAC5B,OAAO,GAAG,aAAa,YAAY,GAAG,cAAc,SACvD;IACA,OAAO,MAAM,cAAc,QAAQ,yBAAyB;IAC5D,IAAI,cAEF,iBAAiB,cAAc,QAAQ,IAAI,QAAQ;SAC9C;KAEL,MAAM,UAAoB,EACxB,SACF;KACA,IAAI,WACF,QAAQ,YAAY;KAEtB,iBAAiB,SAAS,QAAQ,IAAI,QAAQ;KAC9C,UAAU,KAAK,OAAO;IACxB;GACF;EACF;CACF;CACA,OAAO;AACT"}
|
|
@@ -7,7 +7,10 @@ import { DEBUG, ERROR, FATAL, INFO, TRACE, WARN, nameFromLevel } from "bunyan";
|
|
|
7
7
|
* in the same package file.
|
|
8
8
|
*/
|
|
9
9
|
function replacementAlreadyExists(deps, currentDep, newName) {
|
|
10
|
-
return deps.some((sibling) =>
|
|
10
|
+
return deps.some((sibling) => {
|
|
11
|
+
if (sibling === currentDep) return false;
|
|
12
|
+
return sibling.depName === newName || sibling.packageName === newName;
|
|
13
|
+
});
|
|
11
14
|
}
|
|
12
15
|
function extractRepoProblems(repository) {
|
|
13
16
|
return new Set(getProblems().filter((problem) => problem.repository === repository && !problem.artifactErrors).map((problem) => `${formatProblemLevel(problem.level)}: ${problem.msg}`));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.js","names":[],"sources":["../../../lib/workers/repository/common.ts"],"sourcesContent":["import { DEBUG, ERROR, FATAL, INFO, TRACE, WARN, nameFromLevel } from 'bunyan';\nimport { getProblems } from '../../logger/index.ts';\nimport type { PackageDependency } from '../../modules/manager/types.ts';\nimport { emojify } from '../../util/emoji.ts';\n\n/**\n * Checks whether a replacement target already exists as a sibling dependency\n * in the same package file.\n */\nexport function replacementAlreadyExists(\n deps: PackageDependency[],\n currentDep: PackageDependency,\n newName: string,\n): boolean {\n return deps.some(
|
|
1
|
+
{"version":3,"file":"common.js","names":[],"sources":["../../../lib/workers/repository/common.ts"],"sourcesContent":["import { DEBUG, ERROR, FATAL, INFO, TRACE, WARN, nameFromLevel } from 'bunyan';\nimport { getProblems } from '../../logger/index.ts';\nimport type { PackageDependency } from '../../modules/manager/types.ts';\nimport { emojify } from '../../util/emoji.ts';\n\n/**\n * Checks whether a replacement target already exists as a sibling dependency\n * in the same package file.\n */\nexport function replacementAlreadyExists(\n deps: PackageDependency[],\n currentDep: PackageDependency,\n newName: string,\n): boolean {\n return deps.some((sibling) => {\n if (sibling === currentDep) {\n return false;\n }\n return sibling.depName === newName || sibling.packageName === newName;\n });\n}\n\nexport function extractRepoProblems(\n repository: string | undefined,\n): Set<string> {\n return new Set(\n getProblems()\n .filter(\n (problem) =>\n problem.repository === repository && !problem.artifactErrors,\n )\n .map((problem) => `${formatProblemLevel(problem.level)}: ${problem.msg}`),\n );\n}\n\ntype EmojiLogLevelMapping = Record<number, string>;\n\nconst logLevelEmojis: EmojiLogLevelMapping = {\n [TRACE]: ':microscope:',\n [DEBUG]: ':mag:',\n [INFO]: ':information_source:',\n [WARN]: ':warning:',\n [ERROR]: ':x:',\n [FATAL]: ':skull:',\n};\n\nexport function formatProblemLevel(level: number): string {\n const name = nameFromLevel[level].toUpperCase();\n const emojiName = logLevelEmojis[level];\n\n return `${emojify(emojiName)} ${name}`;\n}\n"],"mappings":";;;;;;;;AASA,SAAgB,yBACd,MACA,YACA,SACS;CACT,OAAO,KAAK,MAAM,YAAY;EAC5B,IAAI,YAAY,YACd,OAAO;EAET,OAAO,QAAQ,YAAY,WAAW,QAAQ,gBAAgB;CAChE,CAAC;AACH;AAEA,SAAgB,oBACd,YACa;CACb,OAAO,IAAI,IACT,YAAY,CAAC,CACV,QACE,YACC,QAAQ,eAAe,cAAc,CAAC,QAAQ,cAClD,CAAC,CACA,KAAK,YAAY,GAAG,mBAAmB,QAAQ,KAAK,EAAE,IAAI,QAAQ,KAAK,CAC5E;AACF;AAIA,MAAM,iBAAuC;EAC1C,QAAQ;EACR,QAAQ;EACR,OAAO;EACP,OAAO;EACP,QAAQ;EACR,QAAQ;AACX;AAEA,SAAgB,mBAAmB,OAAuB;CACxD,MAAM,OAAO,cAAc,MAAM,CAAC,YAAY;CAC9C,MAAM,YAAY,eAAe;CAEjC,OAAO,GAAG,QAAQ,SAAS,EAAE,GAAG;AAClC"}
|
|
@@ -11,7 +11,8 @@ import { isUndefined } from "@sindresorhus/is";
|
|
|
11
11
|
async function checkConfigMigrationBranch(config, migratedConfigData) {
|
|
12
12
|
logger.debug("checkConfigMigrationBranch()");
|
|
13
13
|
const configMigrationCheckboxState = config.dependencyDashboardChecks?.configMigrationCheckboxState;
|
|
14
|
-
|
|
14
|
+
const isCheckboxNotChecked = isUndefined(configMigrationCheckboxState) || configMigrationCheckboxState === "no-checkbox" || configMigrationCheckboxState === "unchecked";
|
|
15
|
+
if (!config.configMigration && isCheckboxNotChecked) {
|
|
15
16
|
logger.debug("Config migration needed but config migration is disabled and checkbox not checked or not present.");
|
|
16
17
|
return { result: "no-migration-branch" };
|
|
17
18
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../../../lib/workers/repository/config-migration/branch/index.ts"],"sourcesContent":["import { isUndefined } from '@sindresorhus/is';\nimport { GlobalConfig } from '../../../../config/global.ts';\nimport type { RenovateConfig } from '../../../../config/types.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport type { FindPRConfig, Pr } from '../../../../modules/platform/index.ts';\nimport { platform } from '../../../../modules/platform/index.ts';\nimport { scm } from '../../../../modules/platform/scm.ts';\nimport { getMigrationBranchName } from '../common.ts';\nimport { ConfigMigrationCommitMessageFactory } from './commit-message.ts';\nimport { createConfigMigrationBranch } from './create.ts';\nimport type { MigratedData } from './migrated-data.ts';\nimport { rebaseMigrationBranch } from './rebase.ts';\n\nexport type CheckConfigMigrationBranchResult =\n | { result: 'no-migration-branch' }\n | {\n result: 'migration-branch-exists' | 'migration-branch-modified';\n migrationBranch: string;\n };\n\nexport async function checkConfigMigrationBranch(\n config: RenovateConfig,\n migratedConfigData: MigratedData,\n): Promise<CheckConfigMigrationBranchResult> {\n logger.debug('checkConfigMigrationBranch()');\n const configMigrationCheckboxState =\n config.dependencyDashboardChecks?.configMigrationCheckboxState;\n\n
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../../lib/workers/repository/config-migration/branch/index.ts"],"sourcesContent":["import { isUndefined } from '@sindresorhus/is';\nimport { GlobalConfig } from '../../../../config/global.ts';\nimport type { RenovateConfig } from '../../../../config/types.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport type { FindPRConfig, Pr } from '../../../../modules/platform/index.ts';\nimport { platform } from '../../../../modules/platform/index.ts';\nimport { scm } from '../../../../modules/platform/scm.ts';\nimport { getMigrationBranchName } from '../common.ts';\nimport { ConfigMigrationCommitMessageFactory } from './commit-message.ts';\nimport { createConfigMigrationBranch } from './create.ts';\nimport type { MigratedData } from './migrated-data.ts';\nimport { rebaseMigrationBranch } from './rebase.ts';\n\nexport type CheckConfigMigrationBranchResult =\n | { result: 'no-migration-branch' }\n | {\n result: 'migration-branch-exists' | 'migration-branch-modified';\n migrationBranch: string;\n };\n\nexport async function checkConfigMigrationBranch(\n config: RenovateConfig,\n migratedConfigData: MigratedData,\n): Promise<CheckConfigMigrationBranchResult> {\n logger.debug('checkConfigMigrationBranch()');\n const configMigrationCheckboxState =\n config.dependencyDashboardChecks?.configMigrationCheckboxState;\n\n const isCheckboxNotChecked =\n isUndefined(configMigrationCheckboxState) ||\n configMigrationCheckboxState === 'no-checkbox' ||\n configMigrationCheckboxState === 'unchecked';\n if (!config.configMigration && isCheckboxNotChecked) {\n logger.debug(\n 'Config migration needed but config migration is disabled and checkbox not checked or not present.',\n );\n return { result: 'no-migration-branch' };\n }\n\n const configMigrationBranch = getMigrationBranchName(config);\n\n const branchPr = await migrationPrExists(\n configMigrationBranch,\n config.baseBranch,\n ); // handles open/autoclosed PRs\n\n if (!branchPr) {\n const commitMessageFactory = new ConfigMigrationCommitMessageFactory(\n config,\n migratedConfigData.filename,\n );\n const prTitle = commitMessageFactory.getPrTitle();\n const closedPrConfig: FindPRConfig = {\n branchName: configMigrationBranch,\n prTitle,\n state: 'closed',\n targetBranch: config.baseBranch,\n };\n\n // handles closed PR\n const closedPr = await platform.findPr(closedPrConfig);\n\n // found closed migration PR\n if (closedPr) {\n logger.debug('Closed config migration PR found.');\n\n // if a closed pr exists and the checkbox for config migration is not checked\n // return no-migration-branch result so that the checkbox gets added again\n // we only want to create a config migration pr if the checkbox is checked\n if (configMigrationCheckboxState !== 'checked') {\n logger.debug(\n 'Config migration is enabled and needed. But a closed pr exists and checkbox is not checked. Skipping migration branch creation.',\n );\n return { result: 'no-migration-branch' };\n }\n\n logger.debug(\n 'Closed migration PR found and checkbox is checked. Try to delete this old branch and create a new one.',\n );\n await handlePr(config, closedPr);\n }\n }\n\n let result: CheckConfigMigrationBranchResult['result'];\n\n if (branchPr) {\n logger.debug('Config Migration PR already exists');\n\n if (await isMigrationBranchModified(config, configMigrationBranch)) {\n logger.debug(\n 'Config Migration branch has been modified. Skipping branch rebase.',\n );\n result = 'migration-branch-modified';\n } else {\n await rebaseMigrationBranch(config, migratedConfigData);\n if (platform.refreshPr) {\n const configMigrationPr = await platform.getBranchPr(\n configMigrationBranch,\n config.baseBranch,\n );\n if (configMigrationPr) {\n await platform.refreshPr(configMigrationPr.number);\n }\n }\n result = 'migration-branch-exists';\n }\n } else {\n logger.debug('Config Migration PR does not exist');\n logger.debug('Need to create migration PR');\n await createConfigMigrationBranch(config, migratedConfigData);\n result = 'migration-branch-exists';\n }\n if (!GlobalConfig.get('dryRun')) {\n await scm.checkoutBranch(configMigrationBranch);\n }\n return {\n migrationBranch: configMigrationBranch,\n result,\n };\n}\n\nexport async function migrationPrExists(\n branchName: string,\n targetBranch?: string,\n): Promise<Pr | null> {\n return await platform.getBranchPr(branchName, targetBranch);\n}\n\nasync function handlePr(config: RenovateConfig, pr: Pr): Promise<void> {\n if (await scm.branchExists(pr.sourceBranch)) {\n if (GlobalConfig.get('dryRun')) {\n logger.info(`DRY-RUN: Would delete branch ${pr.sourceBranch}`);\n } else {\n await scm.deleteBranch(pr.sourceBranch);\n }\n }\n}\n\nasync function isMigrationBranchModified(\n config: RenovateConfig,\n configMigrationBranch: string,\n): Promise<boolean> {\n const baseBranch = config.defaultBranch!;\n return await scm.isBranchModified(configMigrationBranch, baseBranch);\n}\n"],"mappings":";;;;;;;;;;AAoBA,eAAsB,2BACpB,QACA,oBAC2C;CAC3C,OAAO,MAAM,8BAA8B;CAC3C,MAAM,+BACJ,OAAO,2BAA2B;CAEpC,MAAM,uBACJ,YAAY,4BAA4B,KACxC,iCAAiC,iBACjC,iCAAiC;CACnC,IAAI,CAAC,OAAO,mBAAmB,sBAAsB;EACnD,OAAO,MACL,mGACF;EACA,OAAO,EAAE,QAAQ,sBAAsB;CACzC;CAEA,MAAM,wBAAwB,uBAAuB,MAAM;CAE3D,MAAM,WAAW,MAAM,kBACrB,uBACA,OAAO,UACT;CAEA,IAAI,CAAC,UAAU;EAMb,MAAM,iBAA+B;GACnC,YAAY;GACZ,SAHc,IAJiB,oCAC/B,QACA,mBAAmB,QAEc,CAAC,CAAC,WAG7B;GACN,OAAO;GACP,cAAc,OAAO;EACvB;EAGA,MAAM,WAAW,MAAM,SAAS,OAAO,cAAc;EAGrD,IAAI,UAAU;GACZ,OAAO,MAAM,mCAAmC;GAKhD,IAAI,iCAAiC,WAAW;IAC9C,OAAO,MACL,iIACF;IACA,OAAO,EAAE,QAAQ,sBAAsB;GACzC;GAEA,OAAO,MACL,wGACF;GACA,MAAM,SAAS,QAAQ,QAAQ;EACjC;CACF;CAEA,IAAI;CAEJ,IAAI,UAAU;EACZ,OAAO,MAAM,oCAAoC;EAEjD,IAAI,MAAM,0BAA0B,QAAQ,qBAAqB,GAAG;GAClE,OAAO,MACL,oEACF;GACA,SAAS;EACX,OAAO;GACL,MAAM,sBAAsB,QAAQ,kBAAkB;GACtD,IAAI,SAAS,WAAW;IACtB,MAAM,oBAAoB,MAAM,SAAS,YACvC,uBACA,OAAO,UACT;IACA,IAAI,mBACF,MAAM,SAAS,UAAU,kBAAkB,MAAM;GAErD;GACA,SAAS;EACX;CACF,OAAO;EACL,OAAO,MAAM,oCAAoC;EACjD,OAAO,MAAM,6BAA6B;EAC1C,MAAM,4BAA4B,QAAQ,kBAAkB;EAC5D,SAAS;CACX;CACA,IAAI,CAAC,aAAa,IAAI,QAAQ,GAC5B,MAAM,IAAI,eAAe,qBAAqB;CAEhD,OAAO;EACL,iBAAiB;EACjB;CACF;AACF;AAEA,eAAsB,kBACpB,YACA,cACoB;CACpB,OAAO,MAAM,SAAS,YAAY,YAAY,YAAY;AAC5D;AAEA,eAAe,SAAS,QAAwB,IAAuB;CACrE,IAAI,MAAM,IAAI,aAAa,GAAG,YAAY,GAAG;EAC3C,IAAI,aAAa,IAAI,QAAQ,GAC3B,OAAO,KAAK,gCAAgC,GAAG,cAAc;OAE7D,MAAM,IAAI,aAAa,GAAG,YAAY;CAE1C;AACF;AAEA,eAAe,0BACb,QACA,uBACkB;CAClB,MAAM,aAAa,OAAO;CAC1B,OAAO,MAAM,IAAI,iBAAiB,uBAAuB,UAAU;AACrE"}
|
|
@@ -119,6 +119,9 @@ async function readDashboardBody(config) {
|
|
|
119
119
|
if (GlobalConfig.get("rebaseAllOpenBranches")) dashboardChecks.dependencyDashboardRebaseAllOpen = true;
|
|
120
120
|
Object.assign(config, dashboardChecks);
|
|
121
121
|
}
|
|
122
|
+
function needsDashboardApproval(branch) {
|
|
123
|
+
return !!branch.dependencyDashboardApproval || !!branch.dependencyDashboardPrApproval;
|
|
124
|
+
}
|
|
122
125
|
function formatAsMarkdownLink(name, url) {
|
|
123
126
|
return url ? `[${name}](${url})` : `\`${name}\``;
|
|
124
127
|
}
|
|
@@ -203,7 +206,7 @@ async function ensureDependencyDashboard(config, allBranches, packageFiles = {},
|
|
|
203
206
|
}
|
|
204
207
|
const reuseTitle = "Update Dependencies (Renovate Bot)";
|
|
205
208
|
const branches = allBranches.filter((branch) => branch.result !== "automerged" && !branch.upgrades?.every((upgrade) => upgrade.remediationNotPossible));
|
|
206
|
-
if (!(config.dependencyDashboard === true || config.dependencyDashboardApproval === true || config.packageRules?.some((rule) => rule.dependencyDashboardApproval) === true || branches.some(
|
|
209
|
+
if (!(config.dependencyDashboard === true || config.dependencyDashboardApproval === true || config.packageRules?.some((rule) => rule.dependencyDashboardApproval) === true || branches.some(needsDashboardApproval))) {
|
|
207
210
|
if (GlobalConfig.get("dryRun")) logger.info({ title: config.dependencyDashboardTitle }, "DRY-RUN: Would close Dependency Dashboard");
|
|
208
211
|
else {
|
|
209
212
|
logger.debug("Closing Dependency Dashboard");
|
|
@@ -226,7 +229,8 @@ async function ensureDependencyDashboard(config, allBranches, packageFiles = {},
|
|
|
226
229
|
const replacementUpdate = dep.updates?.find((update) => update.updateType === "replacement");
|
|
227
230
|
const hasAnyReplacement = !!replacementUpdate;
|
|
228
231
|
const hasActionableReplacement = hasAnyReplacement && !(replacementUpdate.newName && replacementAlreadyExists(fileName.deps, dep, replacementUpdate.newName));
|
|
229
|
-
|
|
232
|
+
const deprecationOrReplacement = dep.deprecationMessage ?? hasAnyReplacement;
|
|
233
|
+
if (name && deprecationOrReplacement) {
|
|
230
234
|
hasDeprecationsOrReplacements = true;
|
|
231
235
|
deprecatedPackages[manager] ??= {};
|
|
232
236
|
deprecatedPackages[manager][name] ??= {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dependency-dashboard.js","names":["template.compile"],"sources":["../../../lib/workers/repository/dependency-dashboard.ts"],"sourcesContent":["import {\n isNonEmptyArray,\n isNonEmptyObject,\n isNonEmptyString,\n isNullOrUndefined,\n isTruthy,\n} from '@sindresorhus/is';\nimport { DateTime } from 'luxon';\nimport { GlobalConfig } from '../../config/global.ts';\nimport type { RenovateConfig } from '../../config/types.ts';\nimport { logger } from '../../logger/index.ts';\nimport type { PackageFile } from '../../modules/manager/types.ts';\nimport { platform } from '../../modules/platform/index.ts';\nimport { coerceArray } from '../../util/array.ts';\nimport { emojify } from '../../util/emoji.ts';\nimport { regEx } from '../../util/regex.ts';\nimport { coerceString } from '../../util/string.ts';\nimport * as template from '../../util/template/index.ts';\nimport type { BranchConfig, SelectAllConfig } from '../types.ts';\nimport { extractRepoProblems, replacementAlreadyExists } from './common.ts';\nimport type { ConfigMigrationResult } from './config-migration/index.ts';\nimport { getDepWarningsDashboard } from './errors-warnings.ts';\nimport { PackageFiles } from './package-files.ts';\nimport type { Vulnerability } from './process/types.ts';\nimport { Vulnerabilities } from './process/vulnerabilities.ts';\nimport type {\n DependencyDashboardCheck,\n DependencyDashboardListItemType,\n} from './types.ts';\n\ninterface DependencyDashboard {\n dependencyDashboardChecks: Record<string, string>;\n dependencyDashboardRebaseAllOpen: boolean;\n dependencyDashboardAllPending: boolean;\n dependencyDashboardAllRateLimited: boolean;\n dependencyDashboardAllAwaitingSchedule: boolean;\n}\n\nconst rateLimitedRe = regEx(\n ` - \\\\[ \\\\] ${getMarkdownComment('unlimit-branch=([^\\\\s]+)')}`,\n 'g',\n);\nconst pendingApprovalRe = regEx(\n ` - \\\\[ \\\\] ${getMarkdownComment('approve-branch=([^\\\\s]+)')}`,\n 'g',\n);\nconst awaitingScheduleRe = regEx(\n ` - \\\\[ \\\\] ${getMarkdownComment('unschedule-branch=([^\\\\s]+)')}`,\n 'g',\n);\nconst generalBranchRe = regEx(\n ` ${getMarkdownComment('([a-zA-Z]+)-branch=([^\\\\s]+)')}`,\n);\nconst markedBranchesRe = regEx(\n ` - \\\\[x\\\\] ${getMarkdownComment('([a-zA-Z]+)-branch=([^\\\\s]+)')}`,\n 'g',\n);\n\nconst approveAllPendingPrs = 'approve-all-pending-prs';\nconst createAllRateLimitedPrs = 'create-all-rate-limited-prs';\nconst createAllAwaitingSchedulePrs = 'create-all-awaiting-schedule-prs';\nconst createConfigMigrationPr = 'create-config-migration-pr';\nconst configMigrationPrInfo = 'config-migration-pr-info';\nconst rebaseAllOpenPrs = 'rebase-all-open-prs';\n\nfunction getMarkdownComment(comment: string): string {\n return `<!-- ${comment} -->`;\n}\n\nfunction isBoxChecked(issueBody: string, type: string): boolean {\n return issueBody.includes(getCheckbox(type, true));\n}\n\nfunction isBoxUnchecked(issueBody: string, type: string): boolean {\n return issueBody.includes(getCheckbox(type));\n}\n\nfunction getCheckbox(type: string, checked = false): string {\n return ` - [${checked ? 'x' : ' '}] ${getMarkdownComment(type)}`;\n}\n\nfunction checkOpenAllRateLimitedPR(issueBody: string): boolean {\n return isBoxChecked(issueBody, createAllRateLimitedPrs);\n}\n\nfunction checkOpenAllAwaitingSchedulePR(issueBody: string): boolean {\n return isBoxChecked(issueBody, createAllAwaitingSchedulePrs);\n}\n\nfunction checkApproveAllPendingPR(issueBody: string): boolean {\n return isBoxChecked(issueBody, approveAllPendingPrs);\n}\n\nfunction checkRebaseAll(issueBody: string): boolean {\n return isBoxChecked(issueBody, rebaseAllOpenPrs);\n}\n\nfunction getConfigMigrationCheckboxState(\n issueBody: string,\n): 'no-checkbox' | 'checked' | 'unchecked' | 'migration-pr-exists' {\n if (issueBody.includes(getMarkdownComment(configMigrationPrInfo))) {\n return 'migration-pr-exists';\n }\n\n if (isBoxChecked(issueBody, createConfigMigrationPr)) {\n return 'checked';\n }\n\n if (isBoxUnchecked(issueBody, createConfigMigrationPr)) {\n return 'unchecked';\n }\n\n return 'no-checkbox';\n}\n\nfunction selectAllRelevantBranches(issueBody: string): string[] {\n const checkedBranches = [];\n if (checkOpenAllRateLimitedPR(issueBody)) {\n for (const match of issueBody.matchAll(rateLimitedRe)) {\n checkedBranches.push(match[0]);\n }\n }\n if (checkOpenAllAwaitingSchedulePR(issueBody)) {\n for (const match of issueBody.matchAll(awaitingScheduleRe)) {\n checkedBranches.push(match[0]);\n }\n }\n if (checkApproveAllPendingPR(issueBody)) {\n for (const match of issueBody.matchAll(pendingApprovalRe)) {\n checkedBranches.push(match[0]);\n }\n }\n return checkedBranches;\n}\n\nfunction getAllSelectedBranches(\n issueBody: string,\n dependencyDashboardChecks: Record<string, string>,\n): Record<string, string> {\n const allRelevantBranches = selectAllRelevantBranches(issueBody);\n for (const branch of allRelevantBranches) {\n const [, type, branchName] = generalBranchRe.exec(branch)!;\n dependencyDashboardChecks[branchName] = type;\n }\n return dependencyDashboardChecks;\n}\n\nfunction getCheckedBranches(issueBody: string): Record<string, string> {\n let dependencyDashboardChecks: Record<string, string> = {};\n for (const [, type, branchName] of issueBody.matchAll(markedBranchesRe)) {\n dependencyDashboardChecks[branchName] = type;\n }\n dependencyDashboardChecks = getAllSelectedBranches(\n issueBody,\n dependencyDashboardChecks,\n );\n return dependencyDashboardChecks;\n}\n\nfunction parseDashboardIssue(issueBody: string): DependencyDashboard {\n const dependencyDashboardChecks = getCheckedBranches(issueBody);\n const dependencyDashboardRebaseAllOpen = checkRebaseAll(issueBody);\n const dependencyDashboardAllAwaitingSchedule =\n checkOpenAllAwaitingSchedulePR(issueBody);\n const dependencyDashboardAllPending = checkApproveAllPendingPR(issueBody);\n const dependencyDashboardAllRateLimited =\n checkOpenAllRateLimitedPR(issueBody);\n dependencyDashboardChecks.configMigrationCheckboxState =\n getConfigMigrationCheckboxState(issueBody);\n return {\n dependencyDashboardChecks,\n dependencyDashboardRebaseAllOpen,\n dependencyDashboardAllAwaitingSchedule,\n dependencyDashboardAllPending,\n dependencyDashboardAllRateLimited,\n };\n}\n\nexport async function readDashboardBody(\n config: SelectAllConfig,\n): Promise<void> {\n let dashboardChecks: DependencyDashboard = {\n dependencyDashboardChecks: {},\n dependencyDashboardRebaseAllOpen: false,\n dependencyDashboardAllAwaitingSchedule: false,\n dependencyDashboardAllPending: false,\n dependencyDashboardAllRateLimited: false,\n };\n const stringifiedConfig = JSON.stringify(config);\n // mode=silent never updates the dashboard, so checkboxes left on an existing one would never be cleared\n if (config.mode === 'silent') {\n logger.debug('Ignoring Dependency Dashboard checkboxes when mode=silent');\n } else if (\n config.dependencyDashboard === true ||\n stringifiedConfig.includes('\"dependencyDashboardApproval\":true') ||\n stringifiedConfig.includes('\"prCreation\":\"approval\"')\n ) {\n config.dependencyDashboardTitle =\n config.dependencyDashboardTitle ?? `Dependency Dashboard`;\n const issue = await platform.findIssue(config.dependencyDashboardTitle);\n if (issue) {\n config.dependencyDashboardIssue = issue.number;\n dashboardChecks = parseDashboardIssue(issue.body ?? '');\n }\n }\n\n const checkedBranches = GlobalConfig.get('checkedBranches');\n if (isNonEmptyArray(checkedBranches)) {\n const checkedBranchesRec: Record<string, DependencyDashboardCheck> =\n Object.fromEntries(\n checkedBranches.map((branchName) => [branchName, 'global-config']),\n );\n dashboardChecks.dependencyDashboardChecks = {\n ...dashboardChecks.dependencyDashboardChecks,\n ...checkedBranchesRec,\n };\n }\n\n if (GlobalConfig.get('rebaseAllOpenBranches')) {\n dashboardChecks.dependencyDashboardRebaseAllOpen = true;\n }\n\n Object.assign(config, dashboardChecks);\n}\n\nfunction formatAsMarkdownLink(name: string, url?: string | null): string {\n return url ? `[${name}](${url})` : `\\`${name}\\``;\n}\n\nfunction getListItem(\n branch: BranchConfig,\n type: DependencyDashboardListItemType,\n): string {\n let item = getCheckbox(`${type}-branch=${branch.branchName}`);\n if (branch.prNo) {\n // TODO: types (#22198)\n item += `[${branch.prTitle!}](../pull/${branch.prNo})`;\n } else {\n item += branch.prTitle;\n }\n const uniquePackages = [\n // TODO: types (#22198)\n ...new Set(branch.upgrades.map((upgrade) => `\\`${upgrade.depName!}\\``)),\n ];\n if (uniquePackages.length < 2) {\n return `${item}\\n`;\n }\n return `${item} (${uniquePackages.join(', ')})\\n`;\n}\n\nfunction splitBranchesByCategory(filteredBranches: BranchConfig[]): {\n categories: Record<string, BranchConfig[]>;\n uncategorized: BranchConfig[];\n hasCategorized: boolean;\n hasUncategorized: boolean;\n} {\n const categories: Record<string, BranchConfig[]> = {};\n const uncategorized: BranchConfig[] = [];\n let hasCategorized = false;\n let hasUncategorized = false;\n for (const branch of filteredBranches) {\n if (branch.dependencyDashboardCategory) {\n categories[branch.dependencyDashboardCategory] ??= [];\n categories[branch.dependencyDashboardCategory].push(branch);\n hasCategorized = true;\n continue;\n }\n uncategorized.push(branch);\n hasUncategorized = true;\n }\n return { categories, uncategorized, hasCategorized, hasUncategorized };\n}\n\nfunction getBranchList(\n branches: BranchConfig[],\n listItemType: DependencyDashboardListItemType,\n): string {\n return branches\n .map((branch: BranchConfig): string => getListItem(branch, listItemType))\n .join('');\n}\n\nfunction getBranchesListMd(\n branches: BranchConfig[],\n predicate: (\n value: BranchConfig,\n index: number,\n array: BranchConfig[],\n ) => unknown,\n title: string,\n description: string,\n listItemType: DependencyDashboardListItemType = 'approvePr',\n bulkComment?: string,\n bulkMessage?: string,\n bulkIcon?: '🔐',\n): string {\n const filteredBranches = branches.filter(predicate);\n if (filteredBranches.length === 0) {\n return '';\n }\n let result = `## ${title}\\n\\n${description}\\n\\n`;\n const { categories, uncategorized, hasCategorized, hasUncategorized } =\n splitBranchesByCategory(filteredBranches);\n if (hasCategorized) {\n for (const [category, branches] of Object.entries(categories).sort(\n ([keyA], [keyB]) =>\n keyA.localeCompare(keyB, undefined, { numeric: true }),\n )) {\n result = `${result.trimEnd()}\\n\\n`;\n result += `### ${category}\\n\\n`;\n result += getBranchList(branches, listItemType);\n }\n if (hasUncategorized) {\n result = `${result.trimEnd()}\\n\\n`;\n result += `### Others`;\n }\n }\n result = `${result.trimEnd()}\\n\\n`;\n result += getBranchList(uncategorized, listItemType);\n\n if (bulkComment && bulkMessage && filteredBranches.length > 1) {\n if (hasCategorized) {\n result = `${result.trimEnd()}\\n\\n`;\n result += '### All\\n\\n';\n }\n result += getCheckbox(bulkComment);\n result += `${bulkIcon ? `${bulkIcon} ` : ''}**${bulkMessage}**${bulkIcon ? ` ${bulkIcon}` : ''}`;\n }\n return `${result.trimEnd()}\\n\\n`;\n}\n\nfunction appendRepoProblems(config: RenovateConfig, issueBody: string): string {\n let newIssueBody = issueBody;\n const repoProblems = extractRepoProblems(config.repository);\n if (repoProblems.size) {\n newIssueBody += '## Repository Problems\\n\\n';\n const repoProblemsHeader =\n config.customizeDashboard?.repoProblemsHeader ??\n 'Renovate tried to run on this repository, but found these problems.';\n newIssueBody += `${template.compile(repoProblemsHeader, config)}\\n\\n`;\n\n for (const repoProblem of repoProblems) {\n newIssueBody += ` - ${repoProblem}\\n`;\n }\n newIssueBody += '\\n';\n }\n return newIssueBody;\n}\n\nexport async function ensureDependencyDashboard(\n config: SelectAllConfig,\n allBranches: BranchConfig[],\n packageFiles: Record<string, PackageFile[]> = {},\n configMigrationRes: ConfigMigrationResult,\n): Promise<void> {\n logger.debug('ensureDependencyDashboard()');\n if (config.mode === 'silent') {\n logger.debug(\n 'Dependency Dashboard issue is not created, updated or closed when mode=silent',\n );\n return;\n }\n // legacy/migrated issue\n const reuseTitle = 'Update Dependencies (Renovate Bot)';\n const branches = allBranches.filter(\n (branch) =>\n branch.result !== 'automerged' &&\n !branch.upgrades?.every((upgrade) => upgrade.remediationNotPossible),\n );\n if (!(\n config.dependencyDashboard === true ||\n config.dependencyDashboardApproval === true ||\n config.packageRules?.some((rule) => rule.dependencyDashboardApproval) ===\n true ||\n branches.some(\n (branch) =>\n !!branch.dependencyDashboardApproval ||\n !!branch.dependencyDashboardPrApproval,\n )\n )) {\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n { title: config.dependencyDashboardTitle },\n 'DRY-RUN: Would close Dependency Dashboard',\n );\n } else {\n logger.debug('Closing Dependency Dashboard');\n await platform.ensureIssueClosing(config.dependencyDashboardTitle!);\n delete config.dependencyDashboardIssue;\n }\n return;\n }\n // istanbul ignore if\n if (config.repoIsOnboarded === false) {\n logger.debug('Repo is onboarding - skipping dependency dashboard');\n return;\n }\n logger.debug('Ensuring Dependency Dashboard');\n\n // Check packageFiles for any deprecations or replacements\n let hasDeprecationsOrReplacements = false;\n const deprecatedPackages: Record<\n string,\n Record<\n string,\n { hasActionableReplacement: boolean; sourceUrl?: string | null }\n >\n > = {};\n logger.debug('Checking packageFiles for deprecated or replacement packages');\n if (isNonEmptyObject(packageFiles)) {\n for (const [manager, fileNames] of Object.entries(packageFiles)) {\n for (const fileName of fileNames) {\n for (const dep of fileName.deps) {\n const name = dep.packageName;\n const replacementUpdate = dep.updates?.find(\n (update) => update.updateType === 'replacement',\n );\n const hasAnyReplacement = !!replacementUpdate;\n const hasActionableReplacement =\n hasAnyReplacement &&\n !(\n replacementUpdate.newName &&\n replacementAlreadyExists(\n fileName.deps,\n dep,\n replacementUpdate.newName,\n )\n );\n if (name && (dep.deprecationMessage ?? hasAnyReplacement)) {\n hasDeprecationsOrReplacements = true;\n deprecatedPackages[manager] ??= {};\n deprecatedPackages[manager][name] ??= {\n hasActionableReplacement,\n sourceUrl: dep.sourceUrl,\n };\n }\n }\n }\n }\n }\n\n const hasBranches = isNonEmptyArray(branches);\n if (\n config.dependencyDashboardAutoclose &&\n !hasBranches &&\n !hasDeprecationsOrReplacements\n ) {\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n { title: config.dependencyDashboardTitle },\n 'DRY-RUN: Would close Dependency Dashboard',\n );\n } else {\n logger.debug('Closing Dependency Dashboard');\n await platform.ensureIssueClosing(config.dependencyDashboardTitle!);\n delete config.dependencyDashboardIssue;\n }\n return;\n }\n let issueBody = '';\n\n if (config.dependencyDashboardHeader?.length) {\n issueBody += `${template.compile(config.dependencyDashboardHeader, config)}\\n\\n`;\n }\n\n if (configMigrationRes.result === 'pr-exists') {\n issueBody += `## Config Migration Needed\\n\\n${getMarkdownComment(configMigrationPrInfo)} See Config Migration PR: #${configMigrationRes.prNumber}.\\n\\n`;\n } else if (configMigrationRes?.result === 'pr-modified') {\n issueBody += `## Config Migration Needed (Blocked)\\n\\n${getMarkdownComment(configMigrationPrInfo)} The Config Migration branch exists but has been modified by another user. Renovate will not push to this branch unless it is first deleted. \\n\\n See Config Migration PR: #${configMigrationRes.prNumber}.\\n\\n`;\n } else if (configMigrationRes?.result === 'add-checkbox') {\n issueBody += `## Config Migration Needed\\n\\n${getCheckbox(createConfigMigrationPr)} Select this checkbox to let Renovate create an automated Config Migration PR.\\n\\n`;\n }\n\n issueBody = appendRepoProblems(config, issueBody);\n\n if (hasDeprecationsOrReplacements) {\n issueBody += '## Deprecations / Replacements\\n';\n issueBody += emojify('> :warning: **Warning**\\n> \\n');\n issueBody +=\n '> The following dependencies are either deprecated or have replacements available.\\n\\n';\n issueBody += '| Datasource | Package | Replacement PR? |\\n';\n issueBody += '|------------|------|--------------|\\n';\n for (const manager of Object.keys(deprecatedPackages).sort()) {\n const deps = deprecatedPackages[manager];\n for (const depName of Object.keys(deps).sort()) {\n const { hasActionableReplacement, sourceUrl } = deps[depName];\n const packageName = formatAsMarkdownLink(depName, sourceUrl);\n\n issueBody += `| ${manager} | ${packageName} | ${\n hasActionableReplacement\n ? ''\n : ''\n } |\\n`;\n }\n }\n issueBody += '\\n';\n }\n\n if (config.dependencyDashboardReportAbandonment) {\n issueBody += getAbandonedPackagesMd(config, packageFiles);\n }\n\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'needs-approval',\n 'Pending Approval',\n 'The following branches are pending approval. To create them, click on a checkbox below.',\n 'approve',\n approveAllPendingPrs,\n 'Create all pending approval PRs at once',\n '🔐',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'minimum-group-size-not-met',\n 'Group Size Not Met',\n 'The following branches have not met their minimum group size. To create them, click on a checkbox below.',\n 'approveGroup',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'not-scheduled',\n 'Awaiting Schedule',\n 'The following updates are awaiting their schedule. To get an update now, click on a checkbox below.',\n 'unschedule',\n createAllAwaitingSchedulePrs,\n 'Create all awaiting schedule PRs at once',\n '🔐',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) =>\n branch.result === 'branch-limit-reached' ||\n branch.result === 'pr-limit-reached' ||\n branch.result === 'commit-per-run-limit-reached' ||\n branch.result === 'commit-hourly-limit-reached',\n 'Rate-Limited',\n 'The following updates are currently rate-limited. To force their creation now, click on a checkbox below.',\n 'unlimit',\n createAllRateLimitedPrs,\n 'Create all rate-limited PRs at once',\n '🔐',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'error',\n 'Errored',\n 'The following updates encountered an error and will be retried. To force a retry now, click on a checkbox below.',\n 'retry',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'needs-pr-approval',\n 'PR Creation Approval Required',\n 'The following branches exist but PR creation requires approval. To approve PR creation, click on a checkbox below.',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'pr-edited',\n 'PR Edited (Blocked)',\n 'The following updates have been manually edited so Renovate will no longer make changes. To discard all commits and start over, click on a checkbox below.',\n 'rebase',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'pending',\n 'Pending Status Checks',\n 'The following updates await pending status checks. To force their creation now, click on a checkbox below.',\n 'unpend',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.prBlockedBy === 'BranchAutomerge',\n 'Pending Branch Automerge',\n 'The following updates await pending status checks before automerging. To abort the branch automerge and create a PR instead, click on a checkbox below.',\n );\n\n const warn = getDepWarningsDashboard(packageFiles, config);\n if (warn) {\n issueBody += warn;\n issueBody += '\\n';\n }\n\n const otherRes = [\n 'pending',\n 'needs-approval',\n 'needs-pr-approval',\n 'not-scheduled',\n 'pr-limit-reached',\n 'commit-per-run-limit-reached',\n 'commit-hourly-limit-reached',\n 'branch-limit-reached',\n 'already-existed',\n 'error',\n 'automerged',\n 'pr-edited',\n 'minimum-group-size-not-met',\n ];\n const inProgress = branches.filter(\n (branch) =>\n !otherRes.includes(branch.result!) &&\n branch.prBlockedBy !== 'BranchAutomerge',\n );\n issueBody += getBranchesListMd(\n inProgress,\n (branch) => !!branch.prBlockedBy || !branch.prNo,\n 'Other Branches',\n 'The following updates are pending. To force the creation of a PR, click on a checkbox below.',\n 'other',\n );\n issueBody += getBranchesListMd(\n inProgress,\n (branch) => branch.prNo && !branch.prBlockedBy,\n 'Open',\n 'The following updates have all been created. To force a retry/rebase of any, click on a checkbox below.',\n 'rebase',\n rebaseAllOpenPrs,\n 'Click on this checkbox to rebase all open PRs at once',\n );\n\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'already-existed',\n 'PR Closed (Blocked)',\n 'The following updates are blocked by an existing closed PR. To recreate the PR, click on a checkbox below.',\n 'recreate',\n );\n\n if (!hasBranches) {\n issueBody +=\n 'This repository currently has no open or pending branches.\\n\\n';\n }\n\n // add CVE section\n issueBody += await getDashboardMarkdownVulnerabilities(config, packageFiles);\n\n // fit the detected dependencies section\n const footer = getFooter(config);\n issueBody += PackageFiles.getDashboardMarkdown(\n platform.maxBodyLength() - issueBody.length - footer.length,\n );\n\n issueBody += footer;\n\n if (config.dependencyDashboardIssue) {\n // If we're not changing the dashboard issue, then we can skip checking if the user changed it.\n // The cached issue we get back here will reflect its state at the _start_ of our run\n const cachedIssue = await platform.getIssue?.(\n config.dependencyDashboardIssue,\n );\n if (cachedIssue?.body === issueBody) {\n logger.debug('No changes to dependency dashboard issue needed');\n return;\n }\n\n // Skip cache when getting the issue to ensure we get the latest body,\n // including any updates the user made after we started the run\n const updatedIssue = await platform.getIssue?.(\n config.dependencyDashboardIssue,\n false,\n );\n if (updatedIssue) {\n const { dependencyDashboardChecks } = parseDashboardIssue(\n coerceString(updatedIssue.body),\n );\n for (const branchName of Object.keys(config.dependencyDashboardChecks!)) {\n delete dependencyDashboardChecks[branchName];\n }\n for (const branchName of Object.keys(dependencyDashboardChecks)) {\n const checkText = getCheckbox(\n `${dependencyDashboardChecks[branchName]}-branch=${branchName}`,\n );\n issueBody = issueBody.replace(\n checkText,\n checkText.replace('[ ]', '[x]'),\n );\n }\n }\n }\n\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n { title: config.dependencyDashboardTitle },\n 'DRY-RUN: Would ensure Dependency Dashboard',\n );\n } else {\n const result = await platform.ensureIssue({\n title: config.dependencyDashboardTitle!,\n reuseTitle,\n body: platform.massageMarkdown(issueBody, config.rebaseLabel),\n labels: config.dependencyDashboardLabels,\n confidential: config.confidential,\n });\n // ensureIssue doesn't return the issue, so a newly created (or renamed)\n // dashboard needs a lookup to record its number\n if (result && !config.dependencyDashboardIssue) {\n const issue = await platform.findIssue(config.dependencyDashboardTitle!);\n config.dependencyDashboardIssue = issue?.number;\n }\n }\n}\n\nexport function getAbandonedPackagesMd(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n): string {\n const abandonedPackages: Record<\n string,\n Record<\n string,\n { mostRecentTimestamp?: string | null; sourceUrl?: string | null }\n >\n > = {};\n let abandonedCount = 0;\n\n for (const [manager, managerPackageFiles] of Object.entries(packageFiles)) {\n for (const packageFile of managerPackageFiles) {\n for (const dep of coerceArray(packageFile.deps)) {\n if (dep.depName && dep.isAbandoned) {\n abandonedCount++;\n abandonedPackages[manager] = abandonedPackages[manager] || {};\n abandonedPackages[manager][dep.depName] = {\n mostRecentTimestamp: dep.mostRecentTimestamp,\n sourceUrl: dep.sourceUrl,\n };\n }\n }\n }\n }\n\n if (abandonedCount === 0) {\n return '';\n }\n\n let abandonedMd = '## Abandoned Dependencies\\n\\n';\n abandonedMd +=\n 'The following dependencies have not received updates for an extended period and may be unmaintained.\\n\\n';\n\n // Keep the note outside the `<details>` block: GitHub only renders alert\n // callouts at the top level of a body, not inside collapsible sections.\n abandonedMd += emojify('> :information_source: **Note**\\n> \\n');\n abandonedMd += `> Packages are marked as abandoned when they exceed the [\\`abandonmentThreshold\\`](${GlobalConfig.get('productLinks').documentation}configuration-options/#abandonmentthreshold) since their last release. `;\n abandonedMd +=\n 'Unlike deprecated packages with official notices, abandonment is detected by release inactivity.\\n> \\n';\n\n abandonedMd += '<details>\\n';\n abandonedMd += `<summary>View abandoned dependencies (${abandonedCount})</summary>\\n\\n`;\n\n abandonedMd += '| Datasource | Package | Last Updated |\\n';\n abandonedMd += '|------------|------|-------------|\\n';\n\n for (const manager of Object.keys(abandonedPackages).sort()) {\n const deps = abandonedPackages[manager];\n for (const depName of Object.keys(deps).sort()) {\n const { mostRecentTimestamp, sourceUrl } = deps[depName];\n const formattedDate = mostRecentTimestamp\n ? DateTime.fromISO(mostRecentTimestamp).toFormat('yyyy-MM-dd')\n : 'unknown';\n const packageName = formatAsMarkdownLink(depName, sourceUrl);\n abandonedMd += `| ${manager} | ${packageName} | \\`${formattedDate}\\` |\\n`;\n }\n }\n\n abandonedMd += '\\n</details>\\n\\n\\n';\n\n return abandonedMd;\n}\n\nfunction getFooter(config: RenovateConfig): string {\n let footer = '';\n if (config.dependencyDashboardFooter?.length) {\n footer += `---\\n${template.compile(config.dependencyDashboardFooter, config)}\\n`;\n }\n\n return footer;\n}\n\nexport async function getDashboardMarkdownVulnerabilities(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n): Promise<string> {\n let result = '';\n\n if (\n isNullOrUndefined(config.dependencyDashboardOSVVulnerabilitySummary) ||\n config.dependencyDashboardOSVVulnerabilitySummary === 'none'\n ) {\n return result;\n }\n\n result += '## Vulnerabilities\\n\\n';\n\n let vulnerabilities: Vulnerability[];\n try {\n const vulnerabilityFetcher = await Vulnerabilities.create();\n vulnerabilities = await vulnerabilityFetcher.fetchVulnerabilities(\n config,\n packageFiles,\n );\n } catch (err) {\n logger.warn({ err }, 'Unable to read vulnerability information');\n result +=\n 'Renovate was unable to fetch CVE information from [osv.dev](https://osv.dev) this run.\\n\\n';\n return result;\n }\n\n if (vulnerabilities.length === 0) {\n result +=\n 'Renovate has not found any CVEs on [osv.dev](https://osv.dev).\\n\\n';\n return result;\n }\n\n const unresolvedVulnerabilities = vulnerabilities.filter((value) =>\n isNullOrUndefined(value.fixedVersion),\n );\n const resolvedVulnerabilitiesLength =\n vulnerabilities.length - unresolvedVulnerabilities.length;\n\n result += emojify('> :exclamation: **Important**\\n> \\n');\n result += `> \\`${resolvedVulnerabilitiesLength}\\`/\\`${vulnerabilities.length}\\``;\n if (isTruthy(config.osvVulnerabilityAlerts)) {\n result += ' CVEs have Renovate fixes.\\n\\n';\n } else {\n result += ` CVEs have possible Renovate fixes.\\n> See [\\`osvVulnerabilityAlerts\\`](${GlobalConfig.get('productLinks').documentation}configuration-options/#osvvulnerabilityalerts) to allow Renovate to supply fixes.\\n\\n`;\n }\n\n let renderedVulnerabilities: Vulnerability[];\n switch (config.dependencyDashboardOSVVulnerabilitySummary) {\n // filter vulnerabilities to display based on configuration\n case 'unresolved':\n renderedVulnerabilities = unresolvedVulnerabilities;\n break;\n default:\n renderedVulnerabilities = vulnerabilities;\n }\n\n const managerRecords: Record<\n string,\n Record<string, Record<string, Vulnerability[]>>\n > = {};\n for (const vulnerability of renderedVulnerabilities) {\n const { manager, packageFile } = vulnerability.packageFileConfig;\n if (isNullOrUndefined(managerRecords[manager!])) {\n managerRecords[manager!] = {};\n }\n if (isNullOrUndefined(managerRecords[manager!][packageFile])) {\n managerRecords[manager!][packageFile] = {};\n }\n if (\n isNullOrUndefined(\n managerRecords[manager!][packageFile][vulnerability.packageName],\n )\n ) {\n managerRecords[manager!][packageFile][vulnerability.packageName] = [];\n }\n managerRecords[manager!][packageFile][vulnerability.packageName].push(\n vulnerability,\n );\n }\n\n for (const [manager, packageFileRecords] of Object.entries(managerRecords)) {\n result += `<details><summary>${manager}</summary>\\n<blockquote>\\n\\n`;\n for (const [packageFile, packageNameRecords] of Object.entries(\n packageFileRecords,\n )) {\n result += `<details><summary>${packageFile}</summary>\\n<blockquote>\\n\\n`;\n for (const [packageName, cves] of Object.entries(packageNameRecords)) {\n result += `<details><summary>${packageName}</summary>\\n<blockquote>\\n\\n`;\n for (const vul of cves) {\n const id = vul.vulnerability.id;\n const suffix = isNonEmptyString(vul.fixedVersion)\n ? ` (fixed in ${vul.fixedVersion})`\n : '';\n result += `- [${id}](https://osv.dev/vulnerability/${id})${suffix}\\n`;\n }\n result += `</blockquote>\\n</details>\\n\\n`;\n }\n result += `</blockquote>\\n</details>\\n\\n`;\n }\n result += `</blockquote>\\n</details>\\n\\n`;\n }\n\n return result;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dependency-dashboard.js","names":["template.compile"],"sources":["../../../lib/workers/repository/dependency-dashboard.ts"],"sourcesContent":["import {\n isNonEmptyArray,\n isNonEmptyObject,\n isNonEmptyString,\n isNullOrUndefined,\n isTruthy,\n} from '@sindresorhus/is';\nimport { DateTime } from 'luxon';\nimport { GlobalConfig } from '../../config/global.ts';\nimport type { RenovateConfig } from '../../config/types.ts';\nimport { logger } from '../../logger/index.ts';\nimport type { PackageFile } from '../../modules/manager/types.ts';\nimport { platform } from '../../modules/platform/index.ts';\nimport { coerceArray } from '../../util/array.ts';\nimport { emojify } from '../../util/emoji.ts';\nimport { regEx } from '../../util/regex.ts';\nimport { coerceString } from '../../util/string.ts';\nimport * as template from '../../util/template/index.ts';\nimport type { BranchConfig, SelectAllConfig } from '../types.ts';\nimport { extractRepoProblems, replacementAlreadyExists } from './common.ts';\nimport type { ConfigMigrationResult } from './config-migration/index.ts';\nimport { getDepWarningsDashboard } from './errors-warnings.ts';\nimport { PackageFiles } from './package-files.ts';\nimport type { Vulnerability } from './process/types.ts';\nimport { Vulnerabilities } from './process/vulnerabilities.ts';\nimport type {\n DependencyDashboardCheck,\n DependencyDashboardListItemType,\n} from './types.ts';\n\ninterface DependencyDashboard {\n dependencyDashboardChecks: Record<string, string>;\n dependencyDashboardRebaseAllOpen: boolean;\n dependencyDashboardAllPending: boolean;\n dependencyDashboardAllRateLimited: boolean;\n dependencyDashboardAllAwaitingSchedule: boolean;\n}\n\nconst rateLimitedRe = regEx(\n ` - \\\\[ \\\\] ${getMarkdownComment('unlimit-branch=([^\\\\s]+)')}`,\n 'g',\n);\nconst pendingApprovalRe = regEx(\n ` - \\\\[ \\\\] ${getMarkdownComment('approve-branch=([^\\\\s]+)')}`,\n 'g',\n);\nconst awaitingScheduleRe = regEx(\n ` - \\\\[ \\\\] ${getMarkdownComment('unschedule-branch=([^\\\\s]+)')}`,\n 'g',\n);\nconst generalBranchRe = regEx(\n ` ${getMarkdownComment('([a-zA-Z]+)-branch=([^\\\\s]+)')}`,\n);\nconst markedBranchesRe = regEx(\n ` - \\\\[x\\\\] ${getMarkdownComment('([a-zA-Z]+)-branch=([^\\\\s]+)')}`,\n 'g',\n);\n\nconst approveAllPendingPrs = 'approve-all-pending-prs';\nconst createAllRateLimitedPrs = 'create-all-rate-limited-prs';\nconst createAllAwaitingSchedulePrs = 'create-all-awaiting-schedule-prs';\nconst createConfigMigrationPr = 'create-config-migration-pr';\nconst configMigrationPrInfo = 'config-migration-pr-info';\nconst rebaseAllOpenPrs = 'rebase-all-open-prs';\n\nfunction getMarkdownComment(comment: string): string {\n return `<!-- ${comment} -->`;\n}\n\nfunction isBoxChecked(issueBody: string, type: string): boolean {\n return issueBody.includes(getCheckbox(type, true));\n}\n\nfunction isBoxUnchecked(issueBody: string, type: string): boolean {\n return issueBody.includes(getCheckbox(type));\n}\n\nfunction getCheckbox(type: string, checked = false): string {\n return ` - [${checked ? 'x' : ' '}] ${getMarkdownComment(type)}`;\n}\n\nfunction checkOpenAllRateLimitedPR(issueBody: string): boolean {\n return isBoxChecked(issueBody, createAllRateLimitedPrs);\n}\n\nfunction checkOpenAllAwaitingSchedulePR(issueBody: string): boolean {\n return isBoxChecked(issueBody, createAllAwaitingSchedulePrs);\n}\n\nfunction checkApproveAllPendingPR(issueBody: string): boolean {\n return isBoxChecked(issueBody, approveAllPendingPrs);\n}\n\nfunction checkRebaseAll(issueBody: string): boolean {\n return isBoxChecked(issueBody, rebaseAllOpenPrs);\n}\n\nfunction getConfigMigrationCheckboxState(\n issueBody: string,\n): 'no-checkbox' | 'checked' | 'unchecked' | 'migration-pr-exists' {\n if (issueBody.includes(getMarkdownComment(configMigrationPrInfo))) {\n return 'migration-pr-exists';\n }\n\n if (isBoxChecked(issueBody, createConfigMigrationPr)) {\n return 'checked';\n }\n\n if (isBoxUnchecked(issueBody, createConfigMigrationPr)) {\n return 'unchecked';\n }\n\n return 'no-checkbox';\n}\n\nfunction selectAllRelevantBranches(issueBody: string): string[] {\n const checkedBranches = [];\n if (checkOpenAllRateLimitedPR(issueBody)) {\n for (const match of issueBody.matchAll(rateLimitedRe)) {\n checkedBranches.push(match[0]);\n }\n }\n if (checkOpenAllAwaitingSchedulePR(issueBody)) {\n for (const match of issueBody.matchAll(awaitingScheduleRe)) {\n checkedBranches.push(match[0]);\n }\n }\n if (checkApproveAllPendingPR(issueBody)) {\n for (const match of issueBody.matchAll(pendingApprovalRe)) {\n checkedBranches.push(match[0]);\n }\n }\n return checkedBranches;\n}\n\nfunction getAllSelectedBranches(\n issueBody: string,\n dependencyDashboardChecks: Record<string, string>,\n): Record<string, string> {\n const allRelevantBranches = selectAllRelevantBranches(issueBody);\n for (const branch of allRelevantBranches) {\n const [, type, branchName] = generalBranchRe.exec(branch)!;\n dependencyDashboardChecks[branchName] = type;\n }\n return dependencyDashboardChecks;\n}\n\nfunction getCheckedBranches(issueBody: string): Record<string, string> {\n let dependencyDashboardChecks: Record<string, string> = {};\n for (const [, type, branchName] of issueBody.matchAll(markedBranchesRe)) {\n dependencyDashboardChecks[branchName] = type;\n }\n dependencyDashboardChecks = getAllSelectedBranches(\n issueBody,\n dependencyDashboardChecks,\n );\n return dependencyDashboardChecks;\n}\n\nfunction parseDashboardIssue(issueBody: string): DependencyDashboard {\n const dependencyDashboardChecks = getCheckedBranches(issueBody);\n const dependencyDashboardRebaseAllOpen = checkRebaseAll(issueBody);\n const dependencyDashboardAllAwaitingSchedule =\n checkOpenAllAwaitingSchedulePR(issueBody);\n const dependencyDashboardAllPending = checkApproveAllPendingPR(issueBody);\n const dependencyDashboardAllRateLimited =\n checkOpenAllRateLimitedPR(issueBody);\n dependencyDashboardChecks.configMigrationCheckboxState =\n getConfigMigrationCheckboxState(issueBody);\n return {\n dependencyDashboardChecks,\n dependencyDashboardRebaseAllOpen,\n dependencyDashboardAllAwaitingSchedule,\n dependencyDashboardAllPending,\n dependencyDashboardAllRateLimited,\n };\n}\n\nexport async function readDashboardBody(\n config: SelectAllConfig,\n): Promise<void> {\n let dashboardChecks: DependencyDashboard = {\n dependencyDashboardChecks: {},\n dependencyDashboardRebaseAllOpen: false,\n dependencyDashboardAllAwaitingSchedule: false,\n dependencyDashboardAllPending: false,\n dependencyDashboardAllRateLimited: false,\n };\n const stringifiedConfig = JSON.stringify(config);\n // mode=silent never updates the dashboard, so checkboxes left on an existing one would never be cleared\n if (config.mode === 'silent') {\n logger.debug('Ignoring Dependency Dashboard checkboxes when mode=silent');\n } else if (\n config.dependencyDashboard === true ||\n stringifiedConfig.includes('\"dependencyDashboardApproval\":true') ||\n stringifiedConfig.includes('\"prCreation\":\"approval\"')\n ) {\n config.dependencyDashboardTitle =\n config.dependencyDashboardTitle ?? `Dependency Dashboard`;\n const issue = await platform.findIssue(config.dependencyDashboardTitle);\n if (issue) {\n config.dependencyDashboardIssue = issue.number;\n dashboardChecks = parseDashboardIssue(issue.body ?? '');\n }\n }\n\n const checkedBranches = GlobalConfig.get('checkedBranches');\n if (isNonEmptyArray(checkedBranches)) {\n const checkedBranchesRec: Record<string, DependencyDashboardCheck> =\n Object.fromEntries(\n checkedBranches.map((branchName) => [branchName, 'global-config']),\n );\n dashboardChecks.dependencyDashboardChecks = {\n ...dashboardChecks.dependencyDashboardChecks,\n ...checkedBranchesRec,\n };\n }\n\n if (GlobalConfig.get('rebaseAllOpenBranches')) {\n dashboardChecks.dependencyDashboardRebaseAllOpen = true;\n }\n\n Object.assign(config, dashboardChecks);\n}\n\nfunction needsDashboardApproval(branch: BranchConfig): boolean {\n return (\n !!branch.dependencyDashboardApproval ||\n !!branch.dependencyDashboardPrApproval\n );\n}\n\nfunction formatAsMarkdownLink(name: string, url?: string | null): string {\n return url ? `[${name}](${url})` : `\\`${name}\\``;\n}\n\nfunction getListItem(\n branch: BranchConfig,\n type: DependencyDashboardListItemType,\n): string {\n let item = getCheckbox(`${type}-branch=${branch.branchName}`);\n if (branch.prNo) {\n // TODO: types (#22198)\n item += `[${branch.prTitle!}](../pull/${branch.prNo})`;\n } else {\n item += branch.prTitle;\n }\n const uniquePackages = [\n // TODO: types (#22198)\n ...new Set(branch.upgrades.map((upgrade) => `\\`${upgrade.depName!}\\``)),\n ];\n if (uniquePackages.length < 2) {\n return `${item}\\n`;\n }\n return `${item} (${uniquePackages.join(', ')})\\n`;\n}\n\nfunction splitBranchesByCategory(filteredBranches: BranchConfig[]): {\n categories: Record<string, BranchConfig[]>;\n uncategorized: BranchConfig[];\n hasCategorized: boolean;\n hasUncategorized: boolean;\n} {\n const categories: Record<string, BranchConfig[]> = {};\n const uncategorized: BranchConfig[] = [];\n let hasCategorized = false;\n let hasUncategorized = false;\n for (const branch of filteredBranches) {\n if (branch.dependencyDashboardCategory) {\n categories[branch.dependencyDashboardCategory] ??= [];\n categories[branch.dependencyDashboardCategory].push(branch);\n hasCategorized = true;\n continue;\n }\n uncategorized.push(branch);\n hasUncategorized = true;\n }\n return { categories, uncategorized, hasCategorized, hasUncategorized };\n}\n\nfunction getBranchList(\n branches: BranchConfig[],\n listItemType: DependencyDashboardListItemType,\n): string {\n return branches\n .map((branch: BranchConfig): string => getListItem(branch, listItemType))\n .join('');\n}\n\nfunction getBranchesListMd(\n branches: BranchConfig[],\n predicate: (\n value: BranchConfig,\n index: number,\n array: BranchConfig[],\n ) => unknown,\n title: string,\n description: string,\n listItemType: DependencyDashboardListItemType = 'approvePr',\n bulkComment?: string,\n bulkMessage?: string,\n bulkIcon?: '🔐',\n): string {\n const filteredBranches = branches.filter(predicate);\n if (filteredBranches.length === 0) {\n return '';\n }\n let result = `## ${title}\\n\\n${description}\\n\\n`;\n const { categories, uncategorized, hasCategorized, hasUncategorized } =\n splitBranchesByCategory(filteredBranches);\n if (hasCategorized) {\n for (const [category, branches] of Object.entries(categories).sort(\n ([keyA], [keyB]) =>\n keyA.localeCompare(keyB, undefined, { numeric: true }),\n )) {\n result = `${result.trimEnd()}\\n\\n`;\n result += `### ${category}\\n\\n`;\n result += getBranchList(branches, listItemType);\n }\n if (hasUncategorized) {\n result = `${result.trimEnd()}\\n\\n`;\n result += `### Others`;\n }\n }\n result = `${result.trimEnd()}\\n\\n`;\n result += getBranchList(uncategorized, listItemType);\n\n if (bulkComment && bulkMessage && filteredBranches.length > 1) {\n if (hasCategorized) {\n result = `${result.trimEnd()}\\n\\n`;\n result += '### All\\n\\n';\n }\n result += getCheckbox(bulkComment);\n result += `${bulkIcon ? `${bulkIcon} ` : ''}**${bulkMessage}**${bulkIcon ? ` ${bulkIcon}` : ''}`;\n }\n return `${result.trimEnd()}\\n\\n`;\n}\n\nfunction appendRepoProblems(config: RenovateConfig, issueBody: string): string {\n let newIssueBody = issueBody;\n const repoProblems = extractRepoProblems(config.repository);\n if (repoProblems.size) {\n newIssueBody += '## Repository Problems\\n\\n';\n const repoProblemsHeader =\n config.customizeDashboard?.repoProblemsHeader ??\n 'Renovate tried to run on this repository, but found these problems.';\n newIssueBody += `${template.compile(repoProblemsHeader, config)}\\n\\n`;\n\n for (const repoProblem of repoProblems) {\n newIssueBody += ` - ${repoProblem}\\n`;\n }\n newIssueBody += '\\n';\n }\n return newIssueBody;\n}\n\nexport async function ensureDependencyDashboard(\n config: SelectAllConfig,\n allBranches: BranchConfig[],\n packageFiles: Record<string, PackageFile[]> = {},\n configMigrationRes: ConfigMigrationResult,\n): Promise<void> {\n logger.debug('ensureDependencyDashboard()');\n if (config.mode === 'silent') {\n logger.debug(\n 'Dependency Dashboard issue is not created, updated or closed when mode=silent',\n );\n return;\n }\n // legacy/migrated issue\n const reuseTitle = 'Update Dependencies (Renovate Bot)';\n const branches = allBranches.filter(\n (branch) =>\n branch.result !== 'automerged' &&\n !branch.upgrades?.every((upgrade) => upgrade.remediationNotPossible),\n );\n if (!(\n config.dependencyDashboard === true ||\n config.dependencyDashboardApproval === true ||\n config.packageRules?.some((rule) => rule.dependencyDashboardApproval) ===\n true ||\n branches.some(needsDashboardApproval)\n )) {\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n { title: config.dependencyDashboardTitle },\n 'DRY-RUN: Would close Dependency Dashboard',\n );\n } else {\n logger.debug('Closing Dependency Dashboard');\n await platform.ensureIssueClosing(config.dependencyDashboardTitle!);\n delete config.dependencyDashboardIssue;\n }\n return;\n }\n // istanbul ignore if\n if (config.repoIsOnboarded === false) {\n logger.debug('Repo is onboarding - skipping dependency dashboard');\n return;\n }\n logger.debug('Ensuring Dependency Dashboard');\n\n // Check packageFiles for any deprecations or replacements\n let hasDeprecationsOrReplacements = false;\n const deprecatedPackages: Record<\n string,\n Record<\n string,\n { hasActionableReplacement: boolean; sourceUrl?: string | null }\n >\n > = {};\n logger.debug('Checking packageFiles for deprecated or replacement packages');\n if (isNonEmptyObject(packageFiles)) {\n for (const [manager, fileNames] of Object.entries(packageFiles)) {\n for (const fileName of fileNames) {\n for (const dep of fileName.deps) {\n const name = dep.packageName;\n const replacementUpdate = dep.updates?.find(\n (update) => update.updateType === 'replacement',\n );\n const hasAnyReplacement = !!replacementUpdate;\n const hasActionableReplacement =\n hasAnyReplacement &&\n !(\n replacementUpdate.newName &&\n replacementAlreadyExists(\n fileName.deps,\n dep,\n replacementUpdate.newName,\n )\n );\n const deprecationOrReplacement =\n dep.deprecationMessage ?? hasAnyReplacement;\n if (name && deprecationOrReplacement) {\n hasDeprecationsOrReplacements = true;\n deprecatedPackages[manager] ??= {};\n deprecatedPackages[manager][name] ??= {\n hasActionableReplacement,\n sourceUrl: dep.sourceUrl,\n };\n }\n }\n }\n }\n }\n\n const hasBranches = isNonEmptyArray(branches);\n if (\n config.dependencyDashboardAutoclose &&\n !hasBranches &&\n !hasDeprecationsOrReplacements\n ) {\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n { title: config.dependencyDashboardTitle },\n 'DRY-RUN: Would close Dependency Dashboard',\n );\n } else {\n logger.debug('Closing Dependency Dashboard');\n await platform.ensureIssueClosing(config.dependencyDashboardTitle!);\n delete config.dependencyDashboardIssue;\n }\n return;\n }\n let issueBody = '';\n\n if (config.dependencyDashboardHeader?.length) {\n issueBody += `${template.compile(config.dependencyDashboardHeader, config)}\\n\\n`;\n }\n\n if (configMigrationRes.result === 'pr-exists') {\n issueBody += `## Config Migration Needed\\n\\n${getMarkdownComment(configMigrationPrInfo)} See Config Migration PR: #${configMigrationRes.prNumber}.\\n\\n`;\n } else if (configMigrationRes?.result === 'pr-modified') {\n issueBody += `## Config Migration Needed (Blocked)\\n\\n${getMarkdownComment(configMigrationPrInfo)} The Config Migration branch exists but has been modified by another user. Renovate will not push to this branch unless it is first deleted. \\n\\n See Config Migration PR: #${configMigrationRes.prNumber}.\\n\\n`;\n } else if (configMigrationRes?.result === 'add-checkbox') {\n issueBody += `## Config Migration Needed\\n\\n${getCheckbox(createConfigMigrationPr)} Select this checkbox to let Renovate create an automated Config Migration PR.\\n\\n`;\n }\n\n issueBody = appendRepoProblems(config, issueBody);\n\n if (hasDeprecationsOrReplacements) {\n issueBody += '## Deprecations / Replacements\\n';\n issueBody += emojify('> :warning: **Warning**\\n> \\n');\n issueBody +=\n '> The following dependencies are either deprecated or have replacements available.\\n\\n';\n issueBody += '| Datasource | Package | Replacement PR? |\\n';\n issueBody += '|------------|------|--------------|\\n';\n for (const manager of Object.keys(deprecatedPackages).sort()) {\n const deps = deprecatedPackages[manager];\n for (const depName of Object.keys(deps).sort()) {\n const { hasActionableReplacement, sourceUrl } = deps[depName];\n const packageName = formatAsMarkdownLink(depName, sourceUrl);\n\n issueBody += `| ${manager} | ${packageName} | ${\n hasActionableReplacement\n ? ''\n : ''\n } |\\n`;\n }\n }\n issueBody += '\\n';\n }\n\n if (config.dependencyDashboardReportAbandonment) {\n issueBody += getAbandonedPackagesMd(config, packageFiles);\n }\n\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'needs-approval',\n 'Pending Approval',\n 'The following branches are pending approval. To create them, click on a checkbox below.',\n 'approve',\n approveAllPendingPrs,\n 'Create all pending approval PRs at once',\n '🔐',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'minimum-group-size-not-met',\n 'Group Size Not Met',\n 'The following branches have not met their minimum group size. To create them, click on a checkbox below.',\n 'approveGroup',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'not-scheduled',\n 'Awaiting Schedule',\n 'The following updates are awaiting their schedule. To get an update now, click on a checkbox below.',\n 'unschedule',\n createAllAwaitingSchedulePrs,\n 'Create all awaiting schedule PRs at once',\n '🔐',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) =>\n branch.result === 'branch-limit-reached' ||\n branch.result === 'pr-limit-reached' ||\n branch.result === 'commit-per-run-limit-reached' ||\n branch.result === 'commit-hourly-limit-reached',\n 'Rate-Limited',\n 'The following updates are currently rate-limited. To force their creation now, click on a checkbox below.',\n 'unlimit',\n createAllRateLimitedPrs,\n 'Create all rate-limited PRs at once',\n '🔐',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'error',\n 'Errored',\n 'The following updates encountered an error and will be retried. To force a retry now, click on a checkbox below.',\n 'retry',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'needs-pr-approval',\n 'PR Creation Approval Required',\n 'The following branches exist but PR creation requires approval. To approve PR creation, click on a checkbox below.',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'pr-edited',\n 'PR Edited (Blocked)',\n 'The following updates have been manually edited so Renovate will no longer make changes. To discard all commits and start over, click on a checkbox below.',\n 'rebase',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'pending',\n 'Pending Status Checks',\n 'The following updates await pending status checks. To force their creation now, click on a checkbox below.',\n 'unpend',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.prBlockedBy === 'BranchAutomerge',\n 'Pending Branch Automerge',\n 'The following updates await pending status checks before automerging. To abort the branch automerge and create a PR instead, click on a checkbox below.',\n );\n\n const warn = getDepWarningsDashboard(packageFiles, config);\n if (warn) {\n issueBody += warn;\n issueBody += '\\n';\n }\n\n const otherRes = [\n 'pending',\n 'needs-approval',\n 'needs-pr-approval',\n 'not-scheduled',\n 'pr-limit-reached',\n 'commit-per-run-limit-reached',\n 'commit-hourly-limit-reached',\n 'branch-limit-reached',\n 'already-existed',\n 'error',\n 'automerged',\n 'pr-edited',\n 'minimum-group-size-not-met',\n ];\n const inProgress = branches.filter(\n (branch) =>\n !otherRes.includes(branch.result!) &&\n branch.prBlockedBy !== 'BranchAutomerge',\n );\n issueBody += getBranchesListMd(\n inProgress,\n (branch) => !!branch.prBlockedBy || !branch.prNo,\n 'Other Branches',\n 'The following updates are pending. To force the creation of a PR, click on a checkbox below.',\n 'other',\n );\n issueBody += getBranchesListMd(\n inProgress,\n (branch) => branch.prNo && !branch.prBlockedBy,\n 'Open',\n 'The following updates have all been created. To force a retry/rebase of any, click on a checkbox below.',\n 'rebase',\n rebaseAllOpenPrs,\n 'Click on this checkbox to rebase all open PRs at once',\n );\n\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'already-existed',\n 'PR Closed (Blocked)',\n 'The following updates are blocked by an existing closed PR. To recreate the PR, click on a checkbox below.',\n 'recreate',\n );\n\n if (!hasBranches) {\n issueBody +=\n 'This repository currently has no open or pending branches.\\n\\n';\n }\n\n // add CVE section\n issueBody += await getDashboardMarkdownVulnerabilities(config, packageFiles);\n\n // fit the detected dependencies section\n const footer = getFooter(config);\n issueBody += PackageFiles.getDashboardMarkdown(\n platform.maxBodyLength() - issueBody.length - footer.length,\n );\n\n issueBody += footer;\n\n if (config.dependencyDashboardIssue) {\n // If we're not changing the dashboard issue, then we can skip checking if the user changed it.\n // The cached issue we get back here will reflect its state at the _start_ of our run\n const cachedIssue = await platform.getIssue?.(\n config.dependencyDashboardIssue,\n );\n if (cachedIssue?.body === issueBody) {\n logger.debug('No changes to dependency dashboard issue needed');\n return;\n }\n\n // Skip cache when getting the issue to ensure we get the latest body,\n // including any updates the user made after we started the run\n const updatedIssue = await platform.getIssue?.(\n config.dependencyDashboardIssue,\n false,\n );\n if (updatedIssue) {\n const { dependencyDashboardChecks } = parseDashboardIssue(\n coerceString(updatedIssue.body),\n );\n for (const branchName of Object.keys(config.dependencyDashboardChecks!)) {\n delete dependencyDashboardChecks[branchName];\n }\n for (const branchName of Object.keys(dependencyDashboardChecks)) {\n const checkText = getCheckbox(\n `${dependencyDashboardChecks[branchName]}-branch=${branchName}`,\n );\n issueBody = issueBody.replace(\n checkText,\n checkText.replace('[ ]', '[x]'),\n );\n }\n }\n }\n\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n { title: config.dependencyDashboardTitle },\n 'DRY-RUN: Would ensure Dependency Dashboard',\n );\n } else {\n const result = await platform.ensureIssue({\n title: config.dependencyDashboardTitle!,\n reuseTitle,\n body: platform.massageMarkdown(issueBody, config.rebaseLabel),\n labels: config.dependencyDashboardLabels,\n confidential: config.confidential,\n });\n // ensureIssue doesn't return the issue, so a newly created (or renamed)\n // dashboard needs a lookup to record its number\n if (result && !config.dependencyDashboardIssue) {\n const issue = await platform.findIssue(config.dependencyDashboardTitle!);\n config.dependencyDashboardIssue = issue?.number;\n }\n }\n}\n\nexport function getAbandonedPackagesMd(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n): string {\n const abandonedPackages: Record<\n string,\n Record<\n string,\n { mostRecentTimestamp?: string | null; sourceUrl?: string | null }\n >\n > = {};\n let abandonedCount = 0;\n\n for (const [manager, managerPackageFiles] of Object.entries(packageFiles)) {\n for (const packageFile of managerPackageFiles) {\n for (const dep of coerceArray(packageFile.deps)) {\n if (dep.depName && dep.isAbandoned) {\n abandonedCount++;\n abandonedPackages[manager] = abandonedPackages[manager] || {};\n abandonedPackages[manager][dep.depName] = {\n mostRecentTimestamp: dep.mostRecentTimestamp,\n sourceUrl: dep.sourceUrl,\n };\n }\n }\n }\n }\n\n if (abandonedCount === 0) {\n return '';\n }\n\n let abandonedMd = '## Abandoned Dependencies\\n\\n';\n abandonedMd +=\n 'The following dependencies have not received updates for an extended period and may be unmaintained.\\n\\n';\n\n // Keep the note outside the `<details>` block: GitHub only renders alert\n // callouts at the top level of a body, not inside collapsible sections.\n abandonedMd += emojify('> :information_source: **Note**\\n> \\n');\n abandonedMd += `> Packages are marked as abandoned when they exceed the [\\`abandonmentThreshold\\`](${GlobalConfig.get('productLinks').documentation}configuration-options/#abandonmentthreshold) since their last release. `;\n abandonedMd +=\n 'Unlike deprecated packages with official notices, abandonment is detected by release inactivity.\\n> \\n';\n\n abandonedMd += '<details>\\n';\n abandonedMd += `<summary>View abandoned dependencies (${abandonedCount})</summary>\\n\\n`;\n\n abandonedMd += '| Datasource | Package | Last Updated |\\n';\n abandonedMd += '|------------|------|-------------|\\n';\n\n for (const manager of Object.keys(abandonedPackages).sort()) {\n const deps = abandonedPackages[manager];\n for (const depName of Object.keys(deps).sort()) {\n const { mostRecentTimestamp, sourceUrl } = deps[depName];\n const formattedDate = mostRecentTimestamp\n ? DateTime.fromISO(mostRecentTimestamp).toFormat('yyyy-MM-dd')\n : 'unknown';\n const packageName = formatAsMarkdownLink(depName, sourceUrl);\n abandonedMd += `| ${manager} | ${packageName} | \\`${formattedDate}\\` |\\n`;\n }\n }\n\n abandonedMd += '\\n</details>\\n\\n\\n';\n\n return abandonedMd;\n}\n\nfunction getFooter(config: RenovateConfig): string {\n let footer = '';\n if (config.dependencyDashboardFooter?.length) {\n footer += `---\\n${template.compile(config.dependencyDashboardFooter, config)}\\n`;\n }\n\n return footer;\n}\n\nexport async function getDashboardMarkdownVulnerabilities(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n): Promise<string> {\n let result = '';\n\n if (\n isNullOrUndefined(config.dependencyDashboardOSVVulnerabilitySummary) ||\n config.dependencyDashboardOSVVulnerabilitySummary === 'none'\n ) {\n return result;\n }\n\n result += '## Vulnerabilities\\n\\n';\n\n let vulnerabilities: Vulnerability[];\n try {\n const vulnerabilityFetcher = await Vulnerabilities.create();\n vulnerabilities = await vulnerabilityFetcher.fetchVulnerabilities(\n config,\n packageFiles,\n );\n } catch (err) {\n logger.warn({ err }, 'Unable to read vulnerability information');\n result +=\n 'Renovate was unable to fetch CVE information from [osv.dev](https://osv.dev) this run.\\n\\n';\n return result;\n }\n\n if (vulnerabilities.length === 0) {\n result +=\n 'Renovate has not found any CVEs on [osv.dev](https://osv.dev).\\n\\n';\n return result;\n }\n\n const unresolvedVulnerabilities = vulnerabilities.filter((value) =>\n isNullOrUndefined(value.fixedVersion),\n );\n const resolvedVulnerabilitiesLength =\n vulnerabilities.length - unresolvedVulnerabilities.length;\n\n result += emojify('> :exclamation: **Important**\\n> \\n');\n result += `> \\`${resolvedVulnerabilitiesLength}\\`/\\`${vulnerabilities.length}\\``;\n if (isTruthy(config.osvVulnerabilityAlerts)) {\n result += ' CVEs have Renovate fixes.\\n\\n';\n } else {\n result += ` CVEs have possible Renovate fixes.\\n> See [\\`osvVulnerabilityAlerts\\`](${GlobalConfig.get('productLinks').documentation}configuration-options/#osvvulnerabilityalerts) to allow Renovate to supply fixes.\\n\\n`;\n }\n\n let renderedVulnerabilities: Vulnerability[];\n switch (config.dependencyDashboardOSVVulnerabilitySummary) {\n // filter vulnerabilities to display based on configuration\n case 'unresolved':\n renderedVulnerabilities = unresolvedVulnerabilities;\n break;\n default:\n renderedVulnerabilities = vulnerabilities;\n }\n\n const managerRecords: Record<\n string,\n Record<string, Record<string, Vulnerability[]>>\n > = {};\n for (const vulnerability of renderedVulnerabilities) {\n const { manager, packageFile } = vulnerability.packageFileConfig;\n if (isNullOrUndefined(managerRecords[manager!])) {\n managerRecords[manager!] = {};\n }\n if (isNullOrUndefined(managerRecords[manager!][packageFile])) {\n managerRecords[manager!][packageFile] = {};\n }\n if (\n isNullOrUndefined(\n managerRecords[manager!][packageFile][vulnerability.packageName],\n )\n ) {\n managerRecords[manager!][packageFile][vulnerability.packageName] = [];\n }\n managerRecords[manager!][packageFile][vulnerability.packageName].push(\n vulnerability,\n );\n }\n\n for (const [manager, packageFileRecords] of Object.entries(managerRecords)) {\n result += `<details><summary>${manager}</summary>\\n<blockquote>\\n\\n`;\n for (const [packageFile, packageNameRecords] of Object.entries(\n packageFileRecords,\n )) {\n result += `<details><summary>${packageFile}</summary>\\n<blockquote>\\n\\n`;\n for (const [packageName, cves] of Object.entries(packageNameRecords)) {\n result += `<details><summary>${packageName}</summary>\\n<blockquote>\\n\\n`;\n for (const vul of cves) {\n const id = vul.vulnerability.id;\n const suffix = isNonEmptyString(vul.fixedVersion)\n ? ` (fixed in ${vul.fixedVersion})`\n : '';\n result += `- [${id}](https://osv.dev/vulnerability/${id})${suffix}\\n`;\n }\n result += `</blockquote>\\n</details>\\n\\n`;\n }\n result += `</blockquote>\\n</details>\\n\\n`;\n }\n result += `</blockquote>\\n</details>\\n\\n`;\n }\n\n return result;\n}\n"],"mappings":"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"}
|
|
@@ -5,6 +5,9 @@ import { getInheritedOrGlobal } from "../../../util/common.js";
|
|
|
5
5
|
import { getCache, isCacheModified } from "../../../util/cache/repository/index.js";
|
|
6
6
|
import { addBranchStats } from "../../../instrumentation/reporting.js";
|
|
7
7
|
// lib/workers/repository/finalize/repository-statistics.ts
|
|
8
|
+
function isLaterThan(date, previous) {
|
|
9
|
+
return !previous || date > previous;
|
|
10
|
+
}
|
|
8
11
|
function runRenovateRepoStats(config, prList) {
|
|
9
12
|
const prStats = {
|
|
10
13
|
total: 0,
|
|
@@ -19,7 +22,7 @@ function runRenovateRepoStats(config, prList) {
|
|
|
19
22
|
switch (pr.state) {
|
|
20
23
|
case "merged":
|
|
21
24
|
prStats.merged += 1;
|
|
22
|
-
if (pr.closedAt && (
|
|
25
|
+
if (pr.closedAt && isLaterThan(pr.closedAt, lastPRMergedAt)) lastPRMergedAt = pr.closedAt;
|
|
23
26
|
break;
|
|
24
27
|
case "closed":
|
|
25
28
|
prStats.closed += 1;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repository-statistics.js","names":[],"sources":["../../../../lib/workers/repository/finalize/repository-statistics.ts"],"sourcesContent":["import type { RenovateConfig } from '../../../config/types.ts';\nimport { addBranchStats } from '../../../instrumentation/reporting.ts';\nimport { logger } from '../../../logger/index.ts';\nimport type { Pr } from '../../../modules/platform/index.ts';\nimport { coerceArray } from '../../../util/array.ts';\nimport {\n getCache,\n isCacheModified,\n} from '../../../util/cache/repository/index.ts';\nimport type {\n BranchCache,\n BranchUpgradeCache,\n} from '../../../util/cache/repository/types.ts';\nimport { getInheritedOrGlobal } from '../../../util/common.ts';\nimport { coerceObject } from '../../../util/object.ts';\nimport type {\n BaseBranchMetadata,\n BaseBranchUpdateSummary,\n BranchMetadata,\n BranchSummary,\n ManagerUpdateSummary,\n UpdateSummary,\n} from '../../types.ts';\n\nexport function runRenovateRepoStats(\n config: RenovateConfig,\n prList: Pr[],\n): void {\n const prStats = { total: 0, open: 0, closed: 0, merged: 0 };\n let lastPRMergedAt: string | undefined;\n\n for (const pr of prList) {\n if (\n pr.title === 'Configure Renovate' ||\n pr.title === getInheritedOrGlobal('onboardingPrTitle')\n ) {\n continue;\n }\n prStats.total += 1;\n switch (pr.state) {\n case 'merged':\n prStats.merged += 1;\n if (pr.closedAt && (
|
|
1
|
+
{"version":3,"file":"repository-statistics.js","names":[],"sources":["../../../../lib/workers/repository/finalize/repository-statistics.ts"],"sourcesContent":["import type { RenovateConfig } from '../../../config/types.ts';\nimport { addBranchStats } from '../../../instrumentation/reporting.ts';\nimport { logger } from '../../../logger/index.ts';\nimport type { Pr } from '../../../modules/platform/index.ts';\nimport { coerceArray } from '../../../util/array.ts';\nimport {\n getCache,\n isCacheModified,\n} from '../../../util/cache/repository/index.ts';\nimport type {\n BranchCache,\n BranchUpgradeCache,\n} from '../../../util/cache/repository/types.ts';\nimport { getInheritedOrGlobal } from '../../../util/common.ts';\nimport { coerceObject } from '../../../util/object.ts';\nimport type {\n BaseBranchMetadata,\n BaseBranchUpdateSummary,\n BranchMetadata,\n BranchSummary,\n ManagerUpdateSummary,\n UpdateSummary,\n} from '../../types.ts';\n\nfunction isLaterThan(date: string, previous: string | undefined): boolean {\n return !previous || date > previous;\n}\n\nexport function runRenovateRepoStats(\n config: RenovateConfig,\n prList: Pr[],\n): void {\n const prStats = { total: 0, open: 0, closed: 0, merged: 0 };\n let lastPRMergedAt: string | undefined;\n\n for (const pr of prList) {\n if (\n pr.title === 'Configure Renovate' ||\n pr.title === getInheritedOrGlobal('onboardingPrTitle')\n ) {\n continue;\n }\n prStats.total += 1;\n switch (pr.state) {\n case 'merged':\n prStats.merged += 1;\n if (pr.closedAt && isLaterThan(pr.closedAt, lastPRMergedAt)) {\n lastPRMergedAt = pr.closedAt;\n }\n break;\n case 'closed':\n prStats.closed += 1;\n break;\n case 'open':\n prStats.open += 1;\n break;\n default:\n break;\n }\n }\n logger.debug(\n { stats: prStats, lastPRMergedAt },\n `Renovate repository PR statistics`,\n );\n}\n\nfunction branchCacheToMetadata({\n automerge,\n baseBranch,\n baseBranchSha,\n branchName,\n isModified,\n pristine: isPristine,\n sha: branchSha,\n}: BranchCache): BranchMetadata {\n return {\n automerge,\n baseBranch,\n baseBranchSha,\n branchName,\n branchSha,\n isModified,\n isPristine,\n };\n}\n\nfunction filterDependencyDashboardData(\n branches: BranchCache[],\n): Partial<BranchCache>[] {\n const branchesFiltered: Partial<BranchCache>[] = [];\n for (const branch of branches) {\n const upgradesFiltered: Partial<BranchUpgradeCache>[] = [];\n const {\n baseBranch,\n branchName,\n prNo,\n prTitle,\n result,\n upgrades,\n prBlockedBy,\n } = branch;\n\n for (const upgrade of coerceArray(upgrades)) {\n const {\n datasource,\n depName,\n displayPending,\n fixedVersion,\n currentVersion,\n currentValue,\n currentDigest,\n newValue,\n newVersion,\n newDigest,\n packageFile,\n updateType,\n packageName,\n } = upgrade;\n\n const filteredUpgrade: Partial<BranchUpgradeCache> = {\n datasource,\n depName,\n displayPending,\n fixedVersion,\n currentVersion,\n currentValue,\n currentDigest,\n newValue,\n newVersion,\n newDigest,\n packageFile,\n updateType,\n packageName,\n };\n upgradesFiltered.push(filteredUpgrade);\n }\n\n const filteredBranch: Partial<BranchCache> = {\n baseBranch,\n branchName,\n prNo,\n prTitle,\n result,\n prBlockedBy,\n upgrades: upgradesFiltered,\n };\n branchesFiltered.push(filteredBranch);\n }\n\n return branchesFiltered;\n}\n\nexport function runBranchSummary(config: RenovateConfig): void {\n const defaultBranch = config.defaultBranch;\n const { scan, branches } = getCache();\n\n const baseMetadata: BaseBranchMetadata[] = [];\n for (const [branchName, cached] of Object.entries(coerceObject(scan))) {\n baseMetadata.push({ branchName, sha: cached.sha });\n }\n\n const branchMetadata: BranchMetadata[] = [];\n const inactiveBranches: string[] = [];\n\n for (const branch of coerceArray(branches)) {\n if (branch.sha) {\n branchMetadata.push(branchCacheToMetadata(branch));\n } else {\n inactiveBranches.push(branch.branchName);\n }\n }\n\n const res: BranchSummary = {\n cacheModified: isCacheModified(),\n baseBranches: baseMetadata,\n branches: branchMetadata,\n defaultBranch,\n inactiveBranches,\n };\n\n logger.debug(res, 'Branch summary');\n\n if (branches?.length) {\n const branchesInformation = filterDependencyDashboardData(branches);\n addBranchStats(config, branchesInformation);\n logger.debug({ branchesInformation }, 'branches info extended');\n\n const updateSummary = getUpdateSummary(branches);\n logger.debug({ updateSummary }, 'Updates summary');\n }\n}\n\nexport function getUpdateSummary(branches: BranchCache[]): UpdateSummary {\n const summaryByBase = new Map<string, BaseBranchUpdateSummary>();\n\n for (const branch of branches) {\n const baseBranch = branch.baseBranch ?? '';\n let entry = summaryByBase.get(baseBranch);\n if (!entry) {\n entry = {\n baseBranch,\n total: 0,\n vulnerabilityAlert: 0,\n updates: {},\n managers: {},\n };\n summaryByBase.set(baseBranch, entry);\n }\n for (const upgrade of coerceArray(branch.upgrades)) {\n const { updateType } = upgrade;\n if (updateType) {\n entry.total += 1;\n if (upgrade.isVulnerabilityAlert) {\n entry.vulnerabilityAlert += 1;\n }\n\n entry.updates[updateType] = (entry.updates[updateType] ?? 0) + 1;\n\n const manager = upgrade.manager ?? '';\n let managerEntry: ManagerUpdateSummary | undefined =\n entry.managers[manager];\n if (!managerEntry) {\n managerEntry = { total: 0, vulnerabilityAlert: 0, updates: {} };\n entry.managers[manager] = managerEntry;\n }\n managerEntry.total += 1;\n if (upgrade.isVulnerabilityAlert) {\n managerEntry.vulnerabilityAlert += 1;\n }\n managerEntry.updates[updateType] =\n (managerEntry.updates[updateType] ?? 0) + 1;\n } else {\n logger.debug(\n { upgrade },\n 'Found an upgrade without an updateType, which should not be possible',\n );\n }\n }\n }\n\n return Array.from(summaryByBase.values());\n}\n"],"mappings":"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"}
|