renovate 44.30.0 → 44.30.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (199) hide show
  1. package/dist/config/migration.js +3 -3
  2. package/dist/config/migration.js.map +1 -1
  3. package/dist/config/migrations/custom/azure-gitlab-automerge-migration.js.map +1 -1
  4. package/dist/config/migrations/custom/dep-types-migration.js.map +1 -1
  5. package/dist/config/options/env.js +2 -1
  6. package/dist/config/options/env.js.map +1 -1
  7. package/dist/logger/utils.js +3 -3
  8. package/dist/logger/utils.js.map +1 -1
  9. package/dist/modules/datasource/crate/index.js +3 -3
  10. package/dist/modules/datasource/crate/index.js.map +1 -1
  11. package/dist/modules/datasource/go/base.js +1 -1
  12. package/dist/modules/datasource/go/base.js.map +1 -1
  13. package/dist/modules/datasource/go/goproxy-parser.js +1 -1
  14. package/dist/modules/datasource/go/goproxy-parser.js.map +1 -1
  15. package/dist/modules/datasource/hexpm-bob/index.js +3 -3
  16. package/dist/modules/datasource/hexpm-bob/index.js.map +1 -1
  17. package/dist/modules/datasource/maven/util.js +1 -1
  18. package/dist/modules/datasource/maven/util.js.map +1 -1
  19. package/dist/modules/datasource/packagist/schema.js +2 -1
  20. package/dist/modules/datasource/packagist/schema.js.map +1 -1
  21. package/dist/modules/datasource/pypi/common.js +1 -1
  22. package/dist/modules/datasource/pypi/common.js.map +1 -1
  23. package/dist/modules/datasource/rpm/repomd.js +2 -1
  24. package/dist/modules/datasource/rpm/repomd.js.map +1 -1
  25. package/dist/modules/datasource/sbt-package/util.js +3 -3
  26. package/dist/modules/datasource/sbt-package/util.js.map +1 -1
  27. package/dist/modules/datasource/terraform-provider/index.js +1 -1
  28. package/dist/modules/datasource/terraform-provider/index.js.map +1 -1
  29. package/dist/modules/manager/ansible-galaxy/util.js +4 -4
  30. package/dist/modules/manager/ansible-galaxy/util.js.map +1 -1
  31. package/dist/modules/manager/asdf/upgradeable-tooling.js +5 -5
  32. package/dist/modules/manager/asdf/upgradeable-tooling.js.map +1 -1
  33. package/dist/modules/manager/bazel-module/extract.js +2 -1
  34. package/dist/modules/manager/bazel-module/extract.js.map +1 -1
  35. package/dist/modules/manager/bazel-module/parser/repo-rules.js +1 -1
  36. package/dist/modules/manager/bazel-module/parser/repo-rules.js.map +1 -1
  37. package/dist/modules/manager/bitbucket-pipelines/extract.js +2 -2
  38. package/dist/modules/manager/bitbucket-pipelines/extract.js.map +1 -1
  39. package/dist/modules/manager/bun/utils.js +2 -1
  40. package/dist/modules/manager/bun/utils.js.map +1 -1
  41. package/dist/modules/manager/bundler/extract.js +1 -1
  42. package/dist/modules/manager/bundler/extract.js.map +1 -1
  43. package/dist/modules/manager/cake/index.js.map +1 -1
  44. package/dist/modules/manager/composer/schema.js +2 -2
  45. package/dist/modules/manager/composer/schema.js.map +1 -1
  46. package/dist/modules/manager/cpanfile/language.js.map +1 -1
  47. package/dist/modules/manager/cpanfile/parser.js +4 -4
  48. package/dist/modules/manager/cpanfile/parser.js.map +1 -1
  49. package/dist/modules/manager/crossplane/extract.js +2 -1
  50. package/dist/modules/manager/crossplane/extract.js.map +1 -1
  51. package/dist/modules/manager/deps-edn/extract.js +1 -1
  52. package/dist/modules/manager/deps-edn/extract.js.map +1 -1
  53. package/dist/modules/manager/deps-edn/parser.js.map +1 -1
  54. package/dist/modules/manager/dockerfile/extract.js +2 -2
  55. package/dist/modules/manager/dockerfile/extract.js.map +1 -1
  56. package/dist/modules/manager/flux/extract.js +2 -2
  57. package/dist/modules/manager/flux/extract.js.map +1 -1
  58. package/dist/modules/manager/git-submodules/extract.js +1 -1
  59. package/dist/modules/manager/git-submodules/extract.js.map +1 -1
  60. package/dist/modules/manager/gomod/artifacts.js +1 -1
  61. package/dist/modules/manager/gomod/artifacts.js.map +1 -1
  62. package/dist/modules/manager/gradle/extract/consistent-versions-plugin.js +2 -2
  63. package/dist/modules/manager/gradle/extract/consistent-versions-plugin.js.map +1 -1
  64. package/dist/modules/manager/gradle-wrapper/artifacts.js +2 -2
  65. package/dist/modules/manager/gradle-wrapper/artifacts.js.map +1 -1
  66. package/dist/modules/manager/helmv3/utils.js +2 -1
  67. package/dist/modules/manager/helmv3/utils.js.map +1 -1
  68. package/dist/modules/manager/hermit/extract.js +1 -1
  69. package/dist/modules/manager/hermit/extract.js.map +1 -1
  70. package/dist/modules/manager/homebrew/utils.js +3 -3
  71. package/dist/modules/manager/homebrew/utils.js.map +1 -1
  72. package/dist/modules/manager/jsonnet-bundler/extract.js +2 -1
  73. package/dist/modules/manager/jsonnet-bundler/extract.js.map +1 -1
  74. package/dist/modules/manager/leiningen/extract.js +2 -2
  75. package/dist/modules/manager/leiningen/extract.js.map +1 -1
  76. package/dist/modules/manager/maven-wrapper/artifacts.js +6 -6
  77. package/dist/modules/manager/maven-wrapper/artifacts.js.map +1 -1
  78. package/dist/modules/manager/mise/backends.js +3 -3
  79. package/dist/modules/manager/mise/backends.js.map +1 -1
  80. package/dist/modules/manager/mise/upgradeable-tooling.js +1 -1
  81. package/dist/modules/manager/mise/upgradeable-tooling.js.map +1 -1
  82. package/dist/modules/manager/npm/extract/common/dependency.js +2 -2
  83. package/dist/modules/manager/npm/extract/common/dependency.js.map +1 -1
  84. package/dist/modules/manager/npm/extract/post/locked-versions.js +2 -1
  85. package/dist/modules/manager/npm/extract/post/locked-versions.js.map +1 -1
  86. package/dist/modules/manager/npm/post-update/index.js +1 -1
  87. package/dist/modules/manager/npm/post-update/index.js.map +1 -1
  88. package/dist/modules/manager/npm/post-update/npm.js +2 -1
  89. package/dist/modules/manager/npm/post-update/npm.js.map +1 -1
  90. package/dist/modules/manager/npm/post-update/yarn.js +2 -2
  91. package/dist/modules/manager/npm/post-update/yarn.js.map +1 -1
  92. package/dist/modules/manager/npm/schema.js +2 -1
  93. package/dist/modules/manager/npm/schema.js.map +1 -1
  94. package/dist/modules/manager/npm/update/locked-dependency/yarn-lock/get-locked.js +2 -1
  95. package/dist/modules/manager/npm/update/locked-dependency/yarn-lock/get-locked.js.map +1 -1
  96. package/dist/modules/manager/npm/update/locked-dependency/yarn-lock/replace.js +1 -1
  97. package/dist/modules/manager/npm/update/locked-dependency/yarn-lock/replace.js.map +1 -1
  98. package/dist/modules/manager/nuget/extract.js +1 -1
  99. package/dist/modules/manager/nuget/extract.js.map +1 -1
  100. package/dist/modules/manager/nvm/extract.js +2 -1
  101. package/dist/modules/manager/nvm/extract.js.map +1 -1
  102. package/dist/modules/manager/osgi/extract.js +2 -1
  103. package/dist/modules/manager/osgi/extract.js.map +1 -1
  104. package/dist/modules/manager/pep621/processors/uv.js +2 -1
  105. package/dist/modules/manager/pep621/processors/uv.js.map +1 -1
  106. package/dist/modules/manager/pip_requirements/extract.js +1 -1
  107. package/dist/modules/manager/pip_requirements/extract.js.map +1 -1
  108. package/dist/modules/manager/pip_setup/extract.js +3 -3
  109. package/dist/modules/manager/pip_setup/extract.js.map +1 -1
  110. package/dist/modules/manager/pixi/schema.js +2 -1
  111. package/dist/modules/manager/pixi/schema.js.map +1 -1
  112. package/dist/modules/manager/setup-cfg/extract.js +1 -1
  113. package/dist/modules/manager/setup-cfg/extract.js.map +1 -1
  114. package/dist/modules/manager/sveltos/util.js +1 -1
  115. package/dist/modules/manager/sveltos/util.js.map +1 -1
  116. package/dist/modules/manager/typst/extract.js +2 -2
  117. package/dist/modules/manager/typst/extract.js.map +1 -1
  118. package/dist/modules/platform/azure/issue.js +2 -1
  119. package/dist/modules/platform/azure/issue.js.map +1 -1
  120. package/dist/modules/platform/bitbucket/index.js +1 -1
  121. package/dist/modules/platform/bitbucket/index.js.map +1 -1
  122. package/dist/modules/platform/bitbucket/schema.js +2 -1
  123. package/dist/modules/platform/bitbucket/schema.js.map +1 -1
  124. package/dist/modules/platform/codecommit/codecommit-client.js +2 -1
  125. package/dist/modules/platform/codecommit/codecommit-client.js.map +1 -1
  126. package/dist/modules/platform/gerrit/utils.js +1 -1
  127. package/dist/modules/platform/gerrit/utils.js.map +1 -1
  128. package/dist/modules/platform/github/index.js +8 -8
  129. package/dist/modules/platform/github/index.js.map +1 -1
  130. package/dist/modules/platform/github/massage-markdown-links.js +6 -3
  131. package/dist/modules/platform/github/massage-markdown-links.js.map +1 -1
  132. package/dist/modules/versioning/apk/index.js +15 -15
  133. package/dist/modules/versioning/apk/index.js.map +1 -1
  134. package/dist/modules/versioning/bazel-module/bzlmod-version.js +3 -2
  135. package/dist/modules/versioning/bazel-module/bzlmod-version.js.map +1 -1
  136. package/dist/modules/versioning/bazel-module/index.js +2 -1
  137. package/dist/modules/versioning/bazel-module/index.js.map +1 -1
  138. package/dist/modules/versioning/composer/index.js +2 -2
  139. package/dist/modules/versioning/composer/index.js.map +1 -1
  140. package/dist/modules/versioning/conan/range.js +4 -3
  141. package/dist/modules/versioning/conan/range.js.map +1 -1
  142. package/dist/modules/versioning/conda/index.js +4 -3
  143. package/dist/modules/versioning/conda/index.js.map +1 -1
  144. package/dist/modules/versioning/distro.js +2 -1
  145. package/dist/modules/versioning/distro.js.map +1 -1
  146. package/dist/modules/versioning/generic.js +2 -1
  147. package/dist/modules/versioning/generic.js.map +1 -1
  148. package/dist/modules/versioning/hashicorp/convertor.js +1 -1
  149. package/dist/modules/versioning/hashicorp/convertor.js.map +1 -1
  150. package/dist/modules/versioning/npm/range.js +1 -1
  151. package/dist/modules/versioning/npm/range.js.map +1 -1
  152. package/dist/modules/versioning/nuget/range.js +2 -1
  153. package/dist/modules/versioning/nuget/range.js.map +1 -1
  154. package/dist/modules/versioning/perl/index.js +1 -1
  155. package/dist/modules/versioning/perl/index.js.map +1 -1
  156. package/dist/modules/versioning/poetry/transform.js +2 -2
  157. package/dist/modules/versioning/poetry/transform.js.map +1 -1
  158. package/dist/modules/versioning/rez/pattern.js.map +1 -1
  159. package/dist/modules/versioning/ruby/index.js +1 -1
  160. package/dist/modules/versioning/ruby/index.js.map +1 -1
  161. package/dist/modules/versioning/semver/index.js +2 -1
  162. package/dist/modules/versioning/semver/index.js.map +1 -1
  163. package/dist/modules/versioning/semver-coerced/index.js +1 -1
  164. package/dist/modules/versioning/semver-coerced/index.js.map +1 -1
  165. package/dist/util/emoji.js.map +1 -1
  166. package/dist/util/exec/containerbase.js +2 -1
  167. package/dist/util/exec/containerbase.js.map +1 -1
  168. package/dist/util/exec/env.js +2 -1
  169. package/dist/util/exec/env.js.map +1 -1
  170. package/dist/util/git/private-key.js +1 -1
  171. package/dist/util/git/private-key.js.map +1 -1
  172. package/dist/util/github/graphql/datasource-fetcher.js +2 -1
  173. package/dist/util/github/graphql/datasource-fetcher.js.map +1 -1
  174. package/dist/util/http/forgejo.js +2 -1
  175. package/dist/util/http/forgejo.js.map +1 -1
  176. package/dist/util/http/gitea.js +2 -1
  177. package/dist/util/http/gitea.js.map +1 -1
  178. package/dist/util/number.js +2 -1
  179. package/dist/util/number.js.map +1 -1
  180. package/dist/util/string-match.js +1 -1
  181. package/dist/util/string-match.js.map +1 -1
  182. package/dist/util/url.js +2 -2
  183. package/dist/util/url.js.map +1 -1
  184. package/dist/workers/global/config/parse/cli.js +1 -1
  185. package/dist/workers/global/config/parse/cli.js.map +1 -1
  186. package/dist/workers/global/config/parse/coersions.js +2 -1
  187. package/dist/workers/global/config/parse/coersions.js.map +1 -1
  188. package/dist/workers/global/config/parse/host-rules-from-env.js +2 -1
  189. package/dist/workers/global/config/parse/host-rules-from-env.js.map +1 -1
  190. package/dist/workers/repository/model/commit-message.js +2 -1
  191. package/dist/workers/repository/model/commit-message.js.map +1 -1
  192. package/dist/workers/repository/model/semantic-commit-message.js +2 -1
  193. package/dist/workers/repository/model/semantic-commit-message.js.map +1 -1
  194. package/dist/workers/repository/update/pr/changelog/common.js +1 -1
  195. package/dist/workers/repository/update/pr/changelog/common.js.map +1 -1
  196. package/dist/workers/repository/updates/generate.js +1 -1
  197. package/dist/workers/repository/updates/generate.js.map +1 -1
  198. package/package.json +1 -1
  199. package/renovate-schema.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"util.js","names":["packageCache.get","HttpError","packageCache.set","packageCache.getCacheType"],"sources":["../../../../lib/modules/datasource/maven/util.ts"],"sourcesContent":["import { Readable } from 'node:stream';\nimport { GetObjectCommand } from '@aws-sdk/client-s3';\nimport { XmlDocument } from 'xmldoc';\nimport { HOST_DISABLED } from '../../../constants/error-messages.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { ExternalHostError } from '../../../types/errors/external-host-error.ts';\nimport * as packageCache from '../../../util/cache/package/index.ts';\nimport { PackageHttpCacheProvider } from '../../../util/http/cache/package-http-cache-provider.ts';\nimport { type Http, HttpError } from '../../../util/http/index.ts';\nimport type { HttpOptions, HttpResponse } from '../../../util/http/types.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { Result } from '../../../util/result.ts';\nimport { getS3Client, parseS3Url } from '../../../util/s3.ts';\nimport { streamToString } from '../../../util/streams.ts';\nimport { asTimestamp } from '../../../util/timestamp.ts';\nimport { ensureTrailingSlash, isHttpUrl } from '../../../util/url.ts';\nimport { getGoogleAuthToken } from '../util.ts';\nimport { isMavenCentral } from './common.ts';\nimport { CachedMavenXml } from './schema.ts';\nimport type {\n DependencyInfo,\n MavenDependency,\n MavenFetchResult,\n MavenFetchSuccess,\n} from './types.ts';\n\nfunction isTemporaryError(err: HttpError): boolean {\n if (err.code === 'ECONNRESET') {\n return true;\n }\n\n if (err.response) {\n const status = err.response.statusCode;\n return status === 429 || (status >= 500 && status < 600);\n }\n\n return false;\n}\n\nfunction isHostError(err: HttpError): boolean {\n return err.code === 'ETIMEDOUT';\n}\n\nfunction isNotFoundError(err: HttpError): boolean {\n return err.code === 'ENOTFOUND' || err.response?.statusCode === 404;\n}\n\nfunction isPermissionsIssue(err: HttpError): boolean {\n const status = err.response?.statusCode;\n return status === 401 || status === 403;\n}\n\nfunction isConnectionError(err: HttpError): boolean {\n return (\n err.code === 'EAI_AGAIN' ||\n err.code === 'ERR_TLS_CERT_ALTNAME_INVALID' ||\n err.code === 'ECONNREFUSED'\n );\n}\n\nfunction isUnsupportedHostError(err: HttpError): boolean {\n return err.name === 'UnsupportedProtocolError';\n}\n\nconst cacheProvider = new PackageHttpCacheProvider({\n namespace: 'datasource-maven:cache-provider',\n softTtlMinutes: 15,\n checkAuthorizationHeader: true,\n checkCacheControlHeader: false, // Maven doesn't respond with `cache-control` headers\n writeSchema: CachedMavenXml,\n});\n\n// Release POMs and timestamped snapshot POMs are immutable once published, so we can cache them much longer than mutable metadata files.\nconst pomCacheProvider = new PackageHttpCacheProvider({\n namespace: 'datasource-maven:pom-cache-provider',\n softTtlMinutes: 60 * 24 * 28, // 28 days before we'll give it another check, just in case it's updated\n checkAuthorizationHeader: true,\n checkCacheControlHeader: false,\n writeSchema: CachedMavenXml,\n});\n\nfunction selectCacheProvider(url: string): PackageHttpCacheProvider {\n // Non-timestamped -SNAPSHOT.pom files are mutable; everything else ending in .pom (release POMs and timestamped snapshot POMs) is immutable.\n if (url.endsWith('.pom') && !url.endsWith('-SNAPSHOT.pom')) {\n return pomCacheProvider;\n }\n return cacheProvider;\n}\n\nconst METADATA_NOT_FOUND_NAMESPACE =\n 'datasource-maven:metadata-not-found' as const;\nconst METADATA_NOT_FOUND_TTL_MINUTES = 60 * 12; // 12 hours\n\n/** introduces jitter to make sure that a given repo's cache expiring doesn't lead to many requests leading to high traffic and/or rate limits */\nfunction getMetadataNotFoundTtl(): number {\n const jitter = Math.floor(Math.random() * 60 * 2); // 0–120 minutes\n return METADATA_NOT_FOUND_TTL_MINUTES + jitter;\n}\n\nfunction isMetadataUrl(url: string): boolean {\n return url.endsWith('/maven-metadata.xml');\n}\n\nexport async function downloadHttpProtocol(\n http: Http,\n pkgUrl: URL | string,\n opts: HttpOptions = {},\n): Promise<MavenFetchResult> {\n const url = pkgUrl.toString();\n\n if (isMetadataUrl(url)) {\n const cacheHasNotFoundResponse = await packageCache.get<true>(\n METADATA_NOT_FOUND_NAMESPACE,\n url,\n );\n if (cacheHasNotFoundResponse) {\n logger.trace(\n { url },\n 'Returning cached 404 response for the metadata-metadata URL request',\n );\n return Result.err({ type: 'not-found' });\n }\n }\n\n const fetchResult = await Result.wrap<HttpResponse>(\n http.getText(url, { ...opts, cacheProvider: selectCacheProvider(url) }),\n )\n .transform((res): MavenFetchSuccess => {\n const result: MavenFetchSuccess = { data: res.body };\n\n if (!res.authorization) {\n result.isCacheable = true;\n }\n\n const lastModified = asTimestamp(res?.headers?.['last-modified']);\n if (lastModified) {\n result.lastModified = lastModified;\n }\n\n return result;\n })\n .catch(async (err): Promise<MavenFetchResult> => {\n /* v8 ignore next: never happens, needs for type narrowing */\n if (!(err instanceof HttpError)) {\n return Result.err({ type: 'unknown', err });\n }\n\n const failedUrl = url;\n if (err.message === HOST_DISABLED) {\n logger.trace({ failedUrl }, 'Host disabled');\n return Result.err({ type: 'host-disabled' });\n }\n\n if (isNotFoundError(err)) {\n logger.trace({ failedUrl }, `Url not found`);\n if (isMetadataUrl(failedUrl)) {\n await packageCache.set(\n METADATA_NOT_FOUND_NAMESPACE,\n failedUrl,\n true,\n getMetadataNotFoundTtl(),\n );\n }\n return Result.err({ type: 'not-found' });\n }\n\n if (isHostError(err)) {\n logger.debug(`Cannot connect to host ${failedUrl}`);\n return Result.err({ type: 'host-error' });\n }\n\n if (isPermissionsIssue(err)) {\n logger.debug(\n `Dependency lookup unauthorized. Please add authentication with a hostRule for ${failedUrl}`,\n );\n return Result.err({ type: 'permission-issue' });\n }\n\n if (isTemporaryError(err)) {\n logger.debug({ failedUrl, err }, 'Temporary error');\n\n if (isMavenCentral(url)) {\n const statusCode = err?.response?.statusCode;\n if (statusCode === 429) {\n if (packageCache.getCacheType() === 'redis') {\n logger.once.warn(\n { failedUrl },\n 'Maven Central rate limiting detected despite Redis caching.',\n );\n } else {\n logger.once.warn(\n { failedUrl },\n 'Maven Central rate limiting detected. Persistent caching required.',\n );\n }\n }\n return Result.err({ type: 'maven-central-temporary-error', err });\n }\n return Result.err({ type: 'temporary-error' });\n }\n\n if (isConnectionError(err)) {\n logger.debug(`Connection refused to maven registry ${failedUrl}`);\n return Result.err({ type: 'connection-error' });\n }\n\n if (isUnsupportedHostError(err)) {\n logger.debug(`Unsupported host ${failedUrl}`);\n return Result.err({ type: 'unsupported-host' });\n }\n\n logger.info({ failedUrl, err }, 'Unknown HTTP download error');\n return Result.err({ type: 'unknown', err });\n });\n\n const { err } = fetchResult.unwrap();\n if (err?.type === 'maven-central-temporary-error') {\n throw new ExternalHostError(err.err);\n }\n\n return fetchResult;\n}\n\nexport async function downloadHttpContent(\n http: Http,\n pkgUrl: URL | string,\n opts: HttpOptions = {},\n): Promise<string | null> {\n const fetchResult = await downloadHttpProtocol(http, pkgUrl, opts);\n return fetchResult.transform(({ data }) => data).unwrapOrNull();\n}\n\nfunction isS3NotFound(err: Error): boolean {\n return err.message === 'NotFound' || err.message === 'NoSuchKey';\n}\n\nexport async function downloadS3Protocol(\n pkgUrl: URL,\n): Promise<MavenFetchResult> {\n logger.trace({ url: pkgUrl.toString() }, `Attempting to load S3 dependency`);\n\n const s3Url = parseS3Url(pkgUrl);\n if (!s3Url) {\n return Result.err({ type: 'invalid-url' });\n }\n\n return await Result.wrap(() => {\n const command = new GetObjectCommand(s3Url);\n const client = getS3Client();\n return client.send(command);\n })\n .transform(\n async ({\n Body,\n LastModified,\n DeleteMarker,\n }): Promise<MavenFetchResult> => {\n if (DeleteMarker) {\n logger.trace(\n { failedUrl: pkgUrl.toString() },\n 'Maven S3 lookup error: DeleteMarker encountered',\n );\n return Result.err({ type: 'not-found' });\n }\n\n if (!(Body instanceof Readable)) {\n logger.debug(\n { failedUrl: pkgUrl.toString() },\n 'Maven S3 lookup error: unsupported Body type',\n );\n return Result.err({ type: 'unsupported-format' });\n }\n\n const data = await streamToString(Body);\n const result: MavenFetchSuccess = { data };\n\n const lastModified = asTimestamp(LastModified);\n if (lastModified) {\n result.lastModified = lastModified;\n }\n\n return Result.ok(result);\n },\n )\n .catch((err): MavenFetchResult => {\n if (!(err instanceof Error)) {\n return Result.err(err);\n }\n\n const failedUrl = pkgUrl.toString();\n\n if (err.name === 'CredentialsProviderError') {\n logger.debug(\n { failedUrl },\n 'Maven S3 lookup error: credentials provider error, check \"AWS_ACCESS_KEY_ID\" and \"AWS_SECRET_ACCESS_KEY\" variables',\n );\n return Result.err({ type: 'credentials-error' });\n }\n\n if (err.message === 'Region is missing') {\n logger.debug(\n { failedUrl },\n 'Maven S3 lookup error: missing region, check \"AWS_REGION\" variable',\n );\n return Result.err({ type: 'missing-aws-region' });\n }\n\n if (isS3NotFound(err)) {\n logger.trace({ failedUrl }, 'Maven S3 lookup error: object not found');\n return Result.err({ type: 'not-found' });\n }\n\n logger.debug({ failedUrl, err }, 'Maven S3 lookup error: unknown error');\n return Result.err({ type: 'unknown', err });\n });\n}\n\nexport async function downloadArtifactRegistryProtocol(\n http: Http,\n pkgUrl: URL,\n): Promise<MavenFetchResult> {\n const opts: HttpOptions = {};\n const host = pkgUrl.host;\n const path = pkgUrl.pathname;\n\n logger.trace({ host, path }, `Using google auth for Maven repository`);\n const auth = await getGoogleAuthToken();\n if (auth) {\n opts.headers = { authorization: `Basic ${auth}` };\n } else {\n logger.once.debug(\n { host, path },\n 'Could not get Google access token, using no auth',\n );\n }\n\n const url = pkgUrl.toString().replace('artifactregistry:', 'https:');\n\n return downloadHttpProtocol(http, url, opts);\n}\n\nfunction containsPlaceholder(str: string): boolean {\n return regEx(/\\${.*?}/g).test(str);\n}\n\nfunction removeKnownPlaceholders(str: string): string {\n return str.replace(regEx(/\\/tree\\/\\${[^}]+}/), '');\n}\n\nexport function getMavenUrl(\n dependency: MavenDependency,\n repoUrl: string,\n path: string,\n): URL {\n return new URL(\n `${dependency.dependencyUrl}/${path}`,\n ensureTrailingSlash(repoUrl),\n );\n}\n\nexport async function downloadMaven(\n http: Http,\n url: URL,\n): Promise<MavenFetchResult> {\n const protocol = url.protocol;\n\n let result: MavenFetchResult = Result.err({ type: 'unsupported-protocol' });\n\n if (isHttpUrl(url)) {\n result = await downloadHttpProtocol(http, url);\n }\n\n if (protocol === 'artifactregistry:') {\n result = await downloadArtifactRegistryProtocol(http, url);\n }\n\n if (protocol === 's3:') {\n result = await downloadS3Protocol(url);\n }\n\n return result.onError((err) => {\n if (err.type === 'unsupported-protocol') {\n logger.debug(\n { url: url.toString() },\n `Maven lookup error: unsupported protocol (${protocol})`,\n );\n }\n });\n}\n\nexport async function downloadMavenXml(\n http: Http,\n url: URL,\n): Promise<MavenFetchResult<XmlDocument>> {\n const rawResult = await downloadMaven(http, url);\n return rawResult.transform((result): MavenFetchResult<XmlDocument> => {\n try {\n return Result.ok({\n ...result,\n data: new XmlDocument(result.data),\n });\n } catch (err) {\n return Result.err({ type: 'xml-parse-error', err });\n }\n });\n}\n\nexport function getDependencyParts(packageName: string): MavenDependency {\n const [group, name] = packageName.split(':');\n const dependencyUrl = `${group.replace(regEx(/\\./g), '/')}/${name}`;\n return {\n display: packageName,\n group,\n name,\n dependencyUrl,\n };\n}\n\nfunction extractSnapshotVersion(metadata: XmlDocument): string | null {\n // Parse the maven-metadata.xml for the snapshot version and determine\n // the fixed version of the latest deployed snapshot.\n // The metadata descriptor can be found at\n // https://maven.apache.org/ref/3.3.3/maven-repository-metadata/repository-metadata.html\n //\n // Basically, we need to replace -SNAPSHOT with the artifact timestanp & build number,\n // so for example 1.0.0-SNAPSHOT will become 1.0.0-<timestamp>-<buildNumber>\n const version = metadata\n .descendantWithPath('version')\n ?.val?.replace('-SNAPSHOT', '');\n\n const snapshot = metadata.descendantWithPath('versioning.snapshot');\n const timestamp = snapshot?.childNamed('timestamp')?.val;\n const build = snapshot?.childNamed('buildNumber')?.val;\n\n // If we weren't able to parse out the required 3 version elements,\n // return null because we can't determine the fixed version of the latest snapshot.\n if (!version || !timestamp || !build) {\n return null;\n }\n return `${version}-${timestamp}-${build}`;\n}\n\nasync function getSnapshotFullVersion(\n http: Http,\n version: string,\n dependency: MavenDependency,\n repoUrl: string,\n): Promise<string | null> {\n // To determine what actual files are available for the snapshot, first we have to fetch and parse\n // the metadata located at http://<repo>/<group>/<artifact>/<version-SNAPSHOT>/maven-metadata.xml\n const metadataUrl = getMavenUrl(\n dependency,\n repoUrl,\n `${version}/maven-metadata.xml`,\n );\n\n const metadataXmlResult = await downloadMavenXml(http, metadataUrl);\n\n return metadataXmlResult\n .transform(({ data }) =>\n Result.wrapNullable(extractSnapshotVersion(data), {\n type: 'snapshot-extract-error',\n }),\n )\n .unwrapOrNull();\n}\n\nfunction isSnapshotVersion(version: string): boolean {\n if (version.endsWith('-SNAPSHOT')) {\n return true;\n }\n return false;\n}\n\nexport async function createUrlForDependencyPom(\n http: Http,\n version: string,\n dependency: MavenDependency,\n repoUrl: string,\n): Promise<string> {\n if (isSnapshotVersion(version)) {\n // By default, Maven snapshots are deployed to the repository with fixed file names.\n // Resolve the full, actual pom file name for the version.\n const fullVersion = await getSnapshotFullVersion(\n http,\n version,\n dependency,\n repoUrl,\n );\n\n // If we were able to resolve the version, use that, otherwise fall back to using -SNAPSHOT\n if (fullVersion !== null) {\n // TODO: types (#22198)\n return `${version}/${dependency.name}-${fullVersion}.pom`;\n }\n }\n\n // TODO: types (#22198)\n return `${version}/${dependency.name}-${version}.pom`;\n}\n\nexport async function getDependencyInfo(\n http: Http,\n dependency: MavenDependency,\n repoUrl: string,\n version: string,\n recursionLimit = 5,\n): Promise<DependencyInfo> {\n const path = await createUrlForDependencyPom(\n http,\n version,\n dependency,\n repoUrl,\n );\n\n const pomUrl = getMavenUrl(dependency, repoUrl, path);\n const pomXmlResult = await downloadMavenXml(http, pomUrl);\n const dependencyInfoResult = await pomXmlResult.transform(\n async ({ data: pomContent }) => {\n const result: DependencyInfo = {};\n\n const homepage = pomContent.valueWithPath('url');\n if (homepage && !containsPlaceholder(homepage)) {\n result.homepage = homepage;\n }\n\n const sourceUrl = pomContent.valueWithPath('scm.url');\n if (\n sourceUrl &&\n !containsPlaceholder(removeKnownPlaceholders(sourceUrl))\n ) {\n result.sourceUrl = sourceUrl\n .replace(regEx(/^scm:/), '')\n .replace(regEx(/^git:/), '')\n .replace(regEx(/^git@github.com:/), 'https://github.com/')\n .replace(regEx(/^git@github.com\\//), 'https://github.com/');\n\n if (result.sourceUrl.startsWith('//')) {\n // most likely the result of us stripping scm:, git: etc\n // going with prepending https: here which should result in potential information retrival\n result.sourceUrl = `https:${result.sourceUrl}`;\n }\n }\n\n const relocation = pomContent.descendantWithPath(\n 'distributionManagement.relocation',\n );\n if (relocation) {\n const relocationGroup =\n relocation.valueWithPath('groupId') ?? dependency.group;\n const relocationName =\n relocation.valueWithPath('artifactId') ?? dependency.name;\n result.replacementName = `${relocationGroup}:${relocationName}`;\n const relocationVersion = relocation.valueWithPath('version');\n result.replacementVersion = relocationVersion ?? version;\n const relocationMessage = relocation.valueWithPath('message');\n if (relocationMessage) {\n result.deprecationMessage = relocationMessage;\n }\n }\n\n const groupId = pomContent.valueWithPath('groupId');\n if (groupId) {\n result.packageScope = groupId;\n }\n\n const parent = pomContent.childNamed('parent');\n if (\n recursionLimit > 0 &&\n parent &&\n (!result.sourceUrl || !result.homepage)\n ) {\n // if we found a parent and are missing some information\n // trying to get the scm/homepage information from it\n const [parentGroupId, parentArtifactId, parentVersion] = [\n 'groupId',\n 'artifactId',\n 'version',\n ].map((k) => parent.valueWithPath(k)?.replace(/\\s+/g, ''));\n if (parentGroupId && parentArtifactId && parentVersion) {\n const parentDisplayId = `${parentGroupId}:${parentArtifactId}`;\n const parentDependency = getDependencyParts(parentDisplayId);\n const parentInformation = await getDependencyInfo(\n http,\n parentDependency,\n repoUrl,\n parentVersion,\n recursionLimit - 1,\n );\n if (!result.sourceUrl && parentInformation.sourceUrl) {\n result.sourceUrl = parentInformation.sourceUrl;\n }\n if (!result.homepage && parentInformation.homepage) {\n result.homepage = parentInformation.homepage;\n }\n }\n }\n\n return result;\n },\n );\n\n return dependencyInfoResult.unwrapOr({});\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"util.js","names":["packageCache.get","HttpError","packageCache.set","packageCache.getCacheType"],"sources":["../../../../lib/modules/datasource/maven/util.ts"],"sourcesContent":["import { Readable } from 'node:stream';\nimport { GetObjectCommand } from '@aws-sdk/client-s3';\nimport { XmlDocument } from 'xmldoc';\nimport { HOST_DISABLED } from '../../../constants/error-messages.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { ExternalHostError } from '../../../types/errors/external-host-error.ts';\nimport * as packageCache from '../../../util/cache/package/index.ts';\nimport { PackageHttpCacheProvider } from '../../../util/http/cache/package-http-cache-provider.ts';\nimport { type Http, HttpError } from '../../../util/http/index.ts';\nimport type { HttpOptions, HttpResponse } from '../../../util/http/types.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { Result } from '../../../util/result.ts';\nimport { getS3Client, parseS3Url } from '../../../util/s3.ts';\nimport { streamToString } from '../../../util/streams.ts';\nimport { asTimestamp } from '../../../util/timestamp.ts';\nimport { ensureTrailingSlash, isHttpUrl } from '../../../util/url.ts';\nimport { getGoogleAuthToken } from '../util.ts';\nimport { isMavenCentral } from './common.ts';\nimport { CachedMavenXml } from './schema.ts';\nimport type {\n DependencyInfo,\n MavenDependency,\n MavenFetchResult,\n MavenFetchSuccess,\n} from './types.ts';\n\nfunction isTemporaryError(err: HttpError): boolean {\n if (err.code === 'ECONNRESET') {\n return true;\n }\n\n if (err.response) {\n const status = err.response.statusCode;\n return status === 429 || (status >= 500 && status < 600);\n }\n\n return false;\n}\n\nfunction isHostError(err: HttpError): boolean {\n return err.code === 'ETIMEDOUT';\n}\n\nfunction isNotFoundError(err: HttpError): boolean {\n return err.code === 'ENOTFOUND' || err.response?.statusCode === 404;\n}\n\nfunction isPermissionsIssue(err: HttpError): boolean {\n const status = err.response?.statusCode;\n return status === 401 || status === 403;\n}\n\nfunction isConnectionError(err: HttpError): boolean {\n return (\n err.code === 'EAI_AGAIN' ||\n err.code === 'ERR_TLS_CERT_ALTNAME_INVALID' ||\n err.code === 'ECONNREFUSED'\n );\n}\n\nfunction isUnsupportedHostError(err: HttpError): boolean {\n return err.name === 'UnsupportedProtocolError';\n}\n\nconst cacheProvider = new PackageHttpCacheProvider({\n namespace: 'datasource-maven:cache-provider',\n softTtlMinutes: 15,\n checkAuthorizationHeader: true,\n checkCacheControlHeader: false, // Maven doesn't respond with `cache-control` headers\n writeSchema: CachedMavenXml,\n});\n\n// Release POMs and timestamped snapshot POMs are immutable once published, so we can cache them much longer than mutable metadata files.\nconst pomCacheProvider = new PackageHttpCacheProvider({\n namespace: 'datasource-maven:pom-cache-provider',\n softTtlMinutes: 60 * 24 * 28, // 28 days before we'll give it another check, just in case it's updated\n checkAuthorizationHeader: true,\n checkCacheControlHeader: false,\n writeSchema: CachedMavenXml,\n});\n\nfunction selectCacheProvider(url: string): PackageHttpCacheProvider {\n // Non-timestamped -SNAPSHOT.pom files are mutable; everything else ending in .pom (release POMs and timestamped snapshot POMs) is immutable.\n if (url.endsWith('.pom') && !url.endsWith('-SNAPSHOT.pom')) {\n return pomCacheProvider;\n }\n return cacheProvider;\n}\n\nconst METADATA_NOT_FOUND_NAMESPACE =\n 'datasource-maven:metadata-not-found' as const;\nconst METADATA_NOT_FOUND_TTL_MINUTES = 60 * 12; // 12 hours\n\n/** introduces jitter to make sure that a given repo's cache expiring doesn't lead to many requests leading to high traffic and/or rate limits */\nfunction getMetadataNotFoundTtl(): number {\n const jitter = Math.floor(Math.random() * 60 * 2); // 0–120 minutes\n return METADATA_NOT_FOUND_TTL_MINUTES + jitter;\n}\n\nfunction isMetadataUrl(url: string): boolean {\n return url.endsWith('/maven-metadata.xml');\n}\n\nexport async function downloadHttpProtocol(\n http: Http,\n pkgUrl: URL | string,\n opts: HttpOptions = {},\n): Promise<MavenFetchResult> {\n const url = pkgUrl.toString();\n\n if (isMetadataUrl(url)) {\n const cacheHasNotFoundResponse = await packageCache.get<true>(\n METADATA_NOT_FOUND_NAMESPACE,\n url,\n );\n if (cacheHasNotFoundResponse) {\n logger.trace(\n { url },\n 'Returning cached 404 response for the metadata-metadata URL request',\n );\n return Result.err({ type: 'not-found' });\n }\n }\n\n const fetchResult = await Result.wrap<HttpResponse>(\n http.getText(url, { ...opts, cacheProvider: selectCacheProvider(url) }),\n )\n .transform((res): MavenFetchSuccess => {\n const result: MavenFetchSuccess = { data: res.body };\n\n if (!res.authorization) {\n result.isCacheable = true;\n }\n\n const lastModified = asTimestamp(res?.headers?.['last-modified']);\n if (lastModified) {\n result.lastModified = lastModified;\n }\n\n return result;\n })\n .catch(async (err): Promise<MavenFetchResult> => {\n /* v8 ignore next: never happens, needs for type narrowing */\n if (!(err instanceof HttpError)) {\n return Result.err({ type: 'unknown', err });\n }\n\n const failedUrl = url;\n if (err.message === HOST_DISABLED) {\n logger.trace({ failedUrl }, 'Host disabled');\n return Result.err({ type: 'host-disabled' });\n }\n\n if (isNotFoundError(err)) {\n logger.trace({ failedUrl }, `Url not found`);\n if (isMetadataUrl(failedUrl)) {\n await packageCache.set(\n METADATA_NOT_FOUND_NAMESPACE,\n failedUrl,\n true,\n getMetadataNotFoundTtl(),\n );\n }\n return Result.err({ type: 'not-found' });\n }\n\n if (isHostError(err)) {\n logger.debug(`Cannot connect to host ${failedUrl}`);\n return Result.err({ type: 'host-error' });\n }\n\n if (isPermissionsIssue(err)) {\n logger.debug(\n `Dependency lookup unauthorized. Please add authentication with a hostRule for ${failedUrl}`,\n );\n return Result.err({ type: 'permission-issue' });\n }\n\n if (isTemporaryError(err)) {\n logger.debug({ failedUrl, err }, 'Temporary error');\n\n if (isMavenCentral(url)) {\n const statusCode = err?.response?.statusCode;\n if (statusCode === 429) {\n if (packageCache.getCacheType() === 'redis') {\n logger.once.warn(\n { failedUrl },\n 'Maven Central rate limiting detected despite Redis caching.',\n );\n } else {\n logger.once.warn(\n { failedUrl },\n 'Maven Central rate limiting detected. Persistent caching required.',\n );\n }\n }\n return Result.err({ type: 'maven-central-temporary-error', err });\n }\n return Result.err({ type: 'temporary-error' });\n }\n\n if (isConnectionError(err)) {\n logger.debug(`Connection refused to maven registry ${failedUrl}`);\n return Result.err({ type: 'connection-error' });\n }\n\n if (isUnsupportedHostError(err)) {\n logger.debug(`Unsupported host ${failedUrl}`);\n return Result.err({ type: 'unsupported-host' });\n }\n\n logger.info({ failedUrl, err }, 'Unknown HTTP download error');\n return Result.err({ type: 'unknown', err });\n });\n\n const { err } = fetchResult.unwrap();\n if (err?.type === 'maven-central-temporary-error') {\n throw new ExternalHostError(err.err);\n }\n\n return fetchResult;\n}\n\nexport async function downloadHttpContent(\n http: Http,\n pkgUrl: URL | string,\n opts: HttpOptions = {},\n): Promise<string | null> {\n const fetchResult = await downloadHttpProtocol(http, pkgUrl, opts);\n return fetchResult.transform(({ data }) => data).unwrapOrNull();\n}\n\nfunction isS3NotFound(err: Error): boolean {\n return err.message === 'NotFound' || err.message === 'NoSuchKey';\n}\n\nexport async function downloadS3Protocol(\n pkgUrl: URL,\n): Promise<MavenFetchResult> {\n logger.trace({ url: pkgUrl.toString() }, `Attempting to load S3 dependency`);\n\n const s3Url = parseS3Url(pkgUrl);\n if (!s3Url) {\n return Result.err({ type: 'invalid-url' });\n }\n\n return await Result.wrap(() => {\n const command = new GetObjectCommand(s3Url);\n const client = getS3Client();\n return client.send(command);\n })\n .transform(\n async ({\n Body,\n LastModified,\n DeleteMarker,\n }): Promise<MavenFetchResult> => {\n if (DeleteMarker) {\n logger.trace(\n { failedUrl: pkgUrl.toString() },\n 'Maven S3 lookup error: DeleteMarker encountered',\n );\n return Result.err({ type: 'not-found' });\n }\n\n if (!(Body instanceof Readable)) {\n logger.debug(\n { failedUrl: pkgUrl.toString() },\n 'Maven S3 lookup error: unsupported Body type',\n );\n return Result.err({ type: 'unsupported-format' });\n }\n\n const data = await streamToString(Body);\n const result: MavenFetchSuccess = { data };\n\n const lastModified = asTimestamp(LastModified);\n if (lastModified) {\n result.lastModified = lastModified;\n }\n\n return Result.ok(result);\n },\n )\n .catch((err): MavenFetchResult => {\n if (!(err instanceof Error)) {\n return Result.err(err);\n }\n\n const failedUrl = pkgUrl.toString();\n\n if (err.name === 'CredentialsProviderError') {\n logger.debug(\n { failedUrl },\n 'Maven S3 lookup error: credentials provider error, check \"AWS_ACCESS_KEY_ID\" and \"AWS_SECRET_ACCESS_KEY\" variables',\n );\n return Result.err({ type: 'credentials-error' });\n }\n\n if (err.message === 'Region is missing') {\n logger.debug(\n { failedUrl },\n 'Maven S3 lookup error: missing region, check \"AWS_REGION\" variable',\n );\n return Result.err({ type: 'missing-aws-region' });\n }\n\n if (isS3NotFound(err)) {\n logger.trace({ failedUrl }, 'Maven S3 lookup error: object not found');\n return Result.err({ type: 'not-found' });\n }\n\n logger.debug({ failedUrl, err }, 'Maven S3 lookup error: unknown error');\n return Result.err({ type: 'unknown', err });\n });\n}\n\nexport async function downloadArtifactRegistryProtocol(\n http: Http,\n pkgUrl: URL,\n): Promise<MavenFetchResult> {\n const opts: HttpOptions = {};\n const host = pkgUrl.host;\n const path = pkgUrl.pathname;\n\n logger.trace({ host, path }, `Using google auth for Maven repository`);\n const auth = await getGoogleAuthToken();\n if (auth) {\n opts.headers = { authorization: `Basic ${auth}` };\n } else {\n logger.once.debug(\n { host, path },\n 'Could not get Google access token, using no auth',\n );\n }\n\n const url = pkgUrl.toString().replace('artifactregistry:', 'https:');\n\n return downloadHttpProtocol(http, url, opts);\n}\n\nfunction containsPlaceholder(str: string): boolean {\n return regEx(/\\${.*?}/g).test(str);\n}\n\nfunction removeKnownPlaceholders(str: string): string {\n return str.replace(regEx(/\\/tree\\/\\${[^}]+}/), '');\n}\n\nexport function getMavenUrl(\n dependency: MavenDependency,\n repoUrl: string,\n path: string,\n): URL {\n return new URL(\n `${dependency.dependencyUrl}/${path}`,\n ensureTrailingSlash(repoUrl),\n );\n}\n\nexport async function downloadMaven(\n http: Http,\n url: URL,\n): Promise<MavenFetchResult> {\n const protocol = url.protocol;\n\n let result: MavenFetchResult = Result.err({ type: 'unsupported-protocol' });\n\n if (isHttpUrl(url)) {\n result = await downloadHttpProtocol(http, url);\n }\n\n if (protocol === 'artifactregistry:') {\n result = await downloadArtifactRegistryProtocol(http, url);\n }\n\n if (protocol === 's3:') {\n result = await downloadS3Protocol(url);\n }\n\n return result.onError((err) => {\n if (err.type === 'unsupported-protocol') {\n logger.debug(\n { url: url.toString() },\n `Maven lookup error: unsupported protocol (${protocol})`,\n );\n }\n });\n}\n\nexport async function downloadMavenXml(\n http: Http,\n url: URL,\n): Promise<MavenFetchResult<XmlDocument>> {\n const rawResult = await downloadMaven(http, url);\n return rawResult.transform((result): MavenFetchResult<XmlDocument> => {\n try {\n return Result.ok({\n ...result,\n data: new XmlDocument(result.data),\n });\n } catch (err) {\n return Result.err({ type: 'xml-parse-error', err });\n }\n });\n}\n\nexport function getDependencyParts(packageName: string): MavenDependency {\n const [group, name] = packageName.split(':');\n const dependencyUrl = `${group.replace(regEx(/\\./g), '/')}/${name}`;\n return {\n display: packageName,\n group,\n name,\n dependencyUrl,\n };\n}\n\nfunction extractSnapshotVersion(metadata: XmlDocument): string | null {\n // Parse the maven-metadata.xml for the snapshot version and determine\n // the fixed version of the latest deployed snapshot.\n // The metadata descriptor can be found at\n // https://maven.apache.org/ref/3.3.3/maven-repository-metadata/repository-metadata.html\n //\n // Basically, we need to replace -SNAPSHOT with the artifact timestanp & build number,\n // so for example 1.0.0-SNAPSHOT will become 1.0.0-<timestamp>-<buildNumber>\n const version = metadata\n .descendantWithPath('version')\n ?.val?.replace('-SNAPSHOT', '');\n\n const snapshot = metadata.descendantWithPath('versioning.snapshot');\n const timestamp = snapshot?.childNamed('timestamp')?.val;\n const build = snapshot?.childNamed('buildNumber')?.val;\n\n // If we weren't able to parse out the required 3 version elements,\n // return null because we can't determine the fixed version of the latest snapshot.\n if (!version || !timestamp || !build) {\n return null;\n }\n return `${version}-${timestamp}-${build}`;\n}\n\nasync function getSnapshotFullVersion(\n http: Http,\n version: string,\n dependency: MavenDependency,\n repoUrl: string,\n): Promise<string | null> {\n // To determine what actual files are available for the snapshot, first we have to fetch and parse\n // the metadata located at http://<repo>/<group>/<artifact>/<version-SNAPSHOT>/maven-metadata.xml\n const metadataUrl = getMavenUrl(\n dependency,\n repoUrl,\n `${version}/maven-metadata.xml`,\n );\n\n const metadataXmlResult = await downloadMavenXml(http, metadataUrl);\n\n return metadataXmlResult\n .transform(({ data }) =>\n Result.wrapNullable(extractSnapshotVersion(data), {\n type: 'snapshot-extract-error',\n }),\n )\n .unwrapOrNull();\n}\n\nfunction isSnapshotVersion(version: string): boolean {\n if (version.endsWith('-SNAPSHOT')) {\n return true;\n }\n return false;\n}\n\nexport async function createUrlForDependencyPom(\n http: Http,\n version: string,\n dependency: MavenDependency,\n repoUrl: string,\n): Promise<string> {\n if (isSnapshotVersion(version)) {\n // By default, Maven snapshots are deployed to the repository with fixed file names.\n // Resolve the full, actual pom file name for the version.\n const fullVersion = await getSnapshotFullVersion(\n http,\n version,\n dependency,\n repoUrl,\n );\n\n // If we were able to resolve the version, use that, otherwise fall back to using -SNAPSHOT\n if (fullVersion !== null) {\n // TODO: types (#22198)\n return `${version}/${dependency.name}-${fullVersion}.pom`;\n }\n }\n\n // TODO: types (#22198)\n return `${version}/${dependency.name}-${version}.pom`;\n}\n\nexport async function getDependencyInfo(\n http: Http,\n dependency: MavenDependency,\n repoUrl: string,\n version: string,\n recursionLimit = 5,\n): Promise<DependencyInfo> {\n const path = await createUrlForDependencyPom(\n http,\n version,\n dependency,\n repoUrl,\n );\n\n const pomUrl = getMavenUrl(dependency, repoUrl, path);\n const pomXmlResult = await downloadMavenXml(http, pomUrl);\n const dependencyInfoResult = await pomXmlResult.transform(\n async ({ data: pomContent }) => {\n const result: DependencyInfo = {};\n\n const homepage = pomContent.valueWithPath('url');\n if (homepage && !containsPlaceholder(homepage)) {\n result.homepage = homepage;\n }\n\n const sourceUrl = pomContent.valueWithPath('scm.url');\n if (\n sourceUrl &&\n !containsPlaceholder(removeKnownPlaceholders(sourceUrl))\n ) {\n result.sourceUrl = sourceUrl\n .replace(regEx(/^scm:/), '')\n .replace(regEx(/^git:/), '')\n .replace(regEx(/^git@github.com:/), 'https://github.com/')\n .replace(regEx(/^git@github.com\\//), 'https://github.com/');\n\n if (result.sourceUrl.startsWith('//')) {\n // most likely the result of us stripping scm:, git: etc\n // going with prepending https: here which should result in potential information retrival\n result.sourceUrl = `https:${result.sourceUrl}`;\n }\n }\n\n const relocation = pomContent.descendantWithPath(\n 'distributionManagement.relocation',\n );\n if (relocation) {\n const relocationGroup =\n relocation.valueWithPath('groupId') ?? dependency.group;\n const relocationName =\n relocation.valueWithPath('artifactId') ?? dependency.name;\n result.replacementName = `${relocationGroup}:${relocationName}`;\n const relocationVersion = relocation.valueWithPath('version');\n result.replacementVersion = relocationVersion ?? version;\n const relocationMessage = relocation.valueWithPath('message');\n if (relocationMessage) {\n result.deprecationMessage = relocationMessage;\n }\n }\n\n const groupId = pomContent.valueWithPath('groupId');\n if (groupId) {\n result.packageScope = groupId;\n }\n\n const parent = pomContent.childNamed('parent');\n if (\n recursionLimit > 0 &&\n parent &&\n (!result.sourceUrl || !result.homepage)\n ) {\n // if we found a parent and are missing some information\n // trying to get the scm/homepage information from it\n const [parentGroupId, parentArtifactId, parentVersion] = [\n 'groupId',\n 'artifactId',\n 'version',\n ].map((k) => parent.valueWithPath(k)?.replace(regEx(/\\s+/g), ''));\n if (parentGroupId && parentArtifactId && parentVersion) {\n const parentDisplayId = `${parentGroupId}:${parentArtifactId}`;\n const parentDependency = getDependencyParts(parentDisplayId);\n const parentInformation = await getDependencyInfo(\n http,\n parentDependency,\n repoUrl,\n parentVersion,\n recursionLimit - 1,\n );\n if (!result.sourceUrl && parentInformation.sourceUrl) {\n result.sourceUrl = parentInformation.sourceUrl;\n }\n if (!result.homepage && parentInformation.homepage) {\n result.homepage = parentInformation.homepage;\n }\n }\n }\n\n return result;\n },\n );\n\n return dependencyInfoResult.unwrapOr({});\n}\n"],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { regEx } from "../../../util/regex.js";
1
2
  import { logger } from "../../../logger/index.js";
2
3
  import { LooseArray, LooseRecord, Nullish } from "../../../util/schema-utils/index.js";
3
4
  import { MaybeTimestamp } from "../../../util/timestamp.js";
@@ -63,7 +64,7 @@ function extractReleaseResult(...composerReleasesArrays) {
63
64
  let deprecationMessage;
64
65
  for (const composerReleasesArray of composerReleasesArrays) for (const composerRelease of composerReleasesArray) {
65
66
  const dep = {
66
- version: composerRelease.version.replace(/^v/, ""),
67
+ version: composerRelease.version.replace(regEx(/^v/), ""),
67
68
  gitRef: composerRelease.version
68
69
  };
69
70
  const releaseTimestamp = composerRelease["published-time"] ?? composerRelease.time;
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","names":[],"sources":["../../../../lib/modules/datasource/packagist/schema.ts"],"sourcesContent":["import { isString, isUndefined } from '@sindresorhus/is';\nimport { z } from 'zod/v4';\nimport { logger } from '../../../logger/index.ts';\nimport {\n LooseArray,\n LooseRecord,\n Nullish,\n} from '../../../util/schema-utils/index.ts';\nimport { MaybeTimestamp } from '../../../util/timestamp.ts';\nimport type { Release, ReleaseResult } from '../types.ts';\n\nexport const MinifiedArray = z\n .array(z.record(z.string(), z.unknown()))\n .transform((xs) => {\n // Ported from: https://github.com/composer/metadata-minifier/blob/main/src/MetadataMinifier.php#L17\n if (xs.length === 0) {\n return xs;\n }\n\n const prevVals: Record<string, unknown> = {};\n for (const x of xs) {\n for (const key of Object.keys(x)) {\n prevVals[key] ??= undefined;\n }\n\n for (const key of Object.keys(prevVals)) {\n const val = x[key];\n if (val === '__unset') {\n delete x[key];\n prevVals[key] = undefined;\n continue;\n }\n\n if (!isUndefined(val)) {\n prevVals[key] = val;\n continue;\n }\n\n if (!isUndefined(prevVals[key])) {\n x[key] = prevVals[key];\n continue;\n }\n }\n }\n\n return xs;\n });\nexport type MinifiedArray = z.infer<typeof MinifiedArray>;\n\nexport const ComposerRelease = z.object({\n version: z.union([z.string(), z.number().transform((v) => v.toString())]),\n homepage: z.string().nullable().catch(null),\n source: z.object({ url: z.string() }).nullable().catch(null),\n time: MaybeTimestamp,\n ['published-time']: Nullish(MaybeTimestamp),\n require: z.object({ php: z.string() }).nullable().catch(null),\n abandoned: z.union([z.string(), z.boolean()]).optional().catch(undefined),\n});\nexport type ComposerRelease = z.infer<typeof ComposerRelease>;\n\nexport const ComposerReleases = z\n .union([\n MinifiedArray.pipe(LooseArray(ComposerRelease)),\n LooseRecord(ComposerRelease).transform((map) => Object.values(map)),\n ])\n .catch([]);\nexport type ComposerReleases = z.infer<typeof ComposerReleases>;\n\nexport const ComposerPackagesResponse = z\n .object({\n packageName: z.string(),\n packagesResponse: z.object({\n packages: z.record(z.string(), z.unknown()),\n }),\n })\n .transform(\n ({ packageName, packagesResponse }) =>\n packagesResponse.packages[packageName],\n )\n .transform((xs) => ComposerReleases.parse(xs));\nexport type ComposerPackagesResponse = z.infer<typeof ComposerPackagesResponse>;\n\nexport function parsePackagesResponse(\n packageName: string,\n packagesResponse: unknown,\n): ComposerReleases {\n try {\n return ComposerPackagesResponse.parse({ packageName, packagesResponse });\n } catch (err) {\n logger.debug(\n { packageName, err },\n `Error parsing packagist response for ${packageName}`,\n );\n return [];\n }\n}\n\nexport function extractReleaseResult(\n ...composerReleasesArrays: ComposerReleases[]\n): ReleaseResult | null {\n const releases: Release[] = [];\n let homepage: string | null | undefined;\n let sourceUrl: string | null | undefined;\n let deprecationMessage: string | undefined;\n\n for (const composerReleasesArray of composerReleasesArrays) {\n for (const composerRelease of composerReleasesArray) {\n const version = composerRelease.version.replace(/^v/, '');\n const gitRef = composerRelease.version;\n\n const dep: Release = { version, gitRef };\n\n // Packagist's `published-time` reflects when the version was actually published to the registry;\n // prefer it over `time` (the git tag's `releasedAt`, which could be when the commit that the tag points at was pushed, not the time the release itself was made public to the world), falling back when absent.\n const releaseTimestamp =\n composerRelease['published-time'] ?? composerRelease.time;\n if (releaseTimestamp) {\n dep.releaseTimestamp = releaseTimestamp;\n }\n\n if (composerRelease.require?.php) {\n dep.constraints = { php: [composerRelease.require.php] };\n }\n\n if (composerRelease.abandoned) {\n dep.isDeprecated = true;\n deprecationMessage ??= getAbandonedMessage(composerRelease.abandoned);\n // TODO #44060 when `abandoned` is a package name, emit replacementName/replacementVersion to open a replacement PR\n }\n\n releases.push(dep);\n\n if (!homepage && composerRelease.homepage) {\n homepage = composerRelease.homepage;\n }\n\n if (!sourceUrl && composerRelease.source?.url) {\n sourceUrl = composerRelease.source.url;\n }\n }\n }\n\n if (releases.length === 0) {\n return null;\n }\n\n const result: ReleaseResult = { releases };\n\n if (homepage) {\n result.homepage = homepage;\n }\n\n if (sourceUrl) {\n result.sourceUrl = sourceUrl;\n }\n\n if (deprecationMessage) {\n result.deprecationMessage = deprecationMessage;\n }\n\n return result;\n}\n\nfunction getAbandonedMessage(abandoned: string | boolean): string {\n const message = 'This package is abandoned and no longer maintained.';\n if (isString(abandoned)) {\n return `${message} The author suggests using the \\`${abandoned}\\` package instead.`;\n }\n return message;\n}\n\nexport function extractDepReleases(\n composerReleases: unknown,\n): ReleaseResult | null {\n const parsedReleases = ComposerReleases.parse(composerReleases);\n return extractReleaseResult(parsedReleases);\n}\n\nexport function parsePackagesResponses(\n packageName: string,\n packagesResponses: unknown[],\n): ReleaseResult | null {\n const releaseArrays = packagesResponses.map((pkgResp) =>\n parsePackagesResponse(packageName, pkgResp),\n );\n return extractReleaseResult(...releaseArrays);\n}\n\nexport const HashSpec = z.union([\n z\n .object({ sha256: z.string().nullable() })\n .transform(({ sha256 }) => ({ hash: sha256 })),\n z\n .object({ sha1: z.string().nullable() })\n .transform(({ sha1 }) => ({ hash: sha1 })),\n]);\nexport type HashSpec = z.infer<typeof HashSpec>;\n\nexport const RegistryFile = z.intersection(\n HashSpec,\n z.object({ key: z.string() }),\n);\nexport type RegistryFile = z.infer<typeof RegistryFile>;\n\nexport const PackagesResponse = z.object({\n packages: LooseRecord(ComposerReleases).catch({}),\n});\nexport type PackagesResponse = z.infer<typeof PackagesResponse>;\n\nexport const PackagistFile = PackagesResponse.merge(\n z.object({\n providers: LooseRecord(HashSpec)\n .transform((x) =>\n Object.fromEntries(\n Object.entries(x).map(([key, { hash }]) => [key, hash]),\n ),\n )\n .catch({}),\n }),\n);\nexport type PackagistFile = z.infer<typeof PackagistFile>;\n\nexport const RegistryMeta = z\n .record(z.string(), z.unknown())\n .catch({})\n .pipe(\n PackagistFile.merge(\n z.object({\n ['includes']: LooseRecord(HashSpec)\n .transform((x) =>\n Object.entries(x).map(([name, { hash }]) => ({ key: name, hash })),\n )\n .catch([]),\n ['provider-includes']: LooseRecord(HashSpec)\n .transform((x) =>\n Object.entries(x).map(([key, { hash }]) => ({ key, hash })),\n )\n .catch([]),\n ['providers-lazy-url']: z.string().nullable().catch(null),\n ['providers-url']: z.string().nullable().catch(null),\n ['metadata-url']: z.string().nullable().catch(null),\n ['available-packages']: z.array(z.string()).nullable().catch(null),\n }),\n ),\n )\n .transform(\n ({\n ['includes']: includesFiles,\n ['packages']: packages,\n ['provider-includes']: files,\n ['providers']: providerPackages,\n ['providers-lazy-url']: providersLazyUrl,\n ['providers-url']: providersUrl,\n ['metadata-url']: metadataUrl,\n ['available-packages']: availablePackages,\n }) => {\n const includesPackages: Record<string, ReleaseResult | null> = {};\n return {\n packages,\n includesFiles,\n providerPackages,\n files,\n providersUrl,\n providersLazyUrl,\n metadataUrl,\n includesPackages,\n availablePackages,\n };\n },\n );\nexport type RegistryMeta = z.infer<typeof RegistryMeta>;\n"],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","names":[],"sources":["../../../../lib/modules/datasource/packagist/schema.ts"],"sourcesContent":["import { isString, isUndefined } from '@sindresorhus/is';\nimport { z } from 'zod/v4';\nimport { logger } from '../../../logger/index.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport {\n LooseArray,\n LooseRecord,\n Nullish,\n} from '../../../util/schema-utils/index.ts';\nimport { MaybeTimestamp } from '../../../util/timestamp.ts';\nimport type { Release, ReleaseResult } from '../types.ts';\n\nexport const MinifiedArray = z\n .array(z.record(z.string(), z.unknown()))\n .transform((xs) => {\n // Ported from: https://github.com/composer/metadata-minifier/blob/main/src/MetadataMinifier.php#L17\n if (xs.length === 0) {\n return xs;\n }\n\n const prevVals: Record<string, unknown> = {};\n for (const x of xs) {\n for (const key of Object.keys(x)) {\n prevVals[key] ??= undefined;\n }\n\n for (const key of Object.keys(prevVals)) {\n const val = x[key];\n if (val === '__unset') {\n delete x[key];\n prevVals[key] = undefined;\n continue;\n }\n\n if (!isUndefined(val)) {\n prevVals[key] = val;\n continue;\n }\n\n if (!isUndefined(prevVals[key])) {\n x[key] = prevVals[key];\n continue;\n }\n }\n }\n\n return xs;\n });\nexport type MinifiedArray = z.infer<typeof MinifiedArray>;\n\nexport const ComposerRelease = z.object({\n version: z.union([z.string(), z.number().transform((v) => v.toString())]),\n homepage: z.string().nullable().catch(null),\n source: z.object({ url: z.string() }).nullable().catch(null),\n time: MaybeTimestamp,\n ['published-time']: Nullish(MaybeTimestamp),\n require: z.object({ php: z.string() }).nullable().catch(null),\n abandoned: z.union([z.string(), z.boolean()]).optional().catch(undefined),\n});\nexport type ComposerRelease = z.infer<typeof ComposerRelease>;\n\nexport const ComposerReleases = z\n .union([\n MinifiedArray.pipe(LooseArray(ComposerRelease)),\n LooseRecord(ComposerRelease).transform((map) => Object.values(map)),\n ])\n .catch([]);\nexport type ComposerReleases = z.infer<typeof ComposerReleases>;\n\nexport const ComposerPackagesResponse = z\n .object({\n packageName: z.string(),\n packagesResponse: z.object({\n packages: z.record(z.string(), z.unknown()),\n }),\n })\n .transform(\n ({ packageName, packagesResponse }) =>\n packagesResponse.packages[packageName],\n )\n .transform((xs) => ComposerReleases.parse(xs));\nexport type ComposerPackagesResponse = z.infer<typeof ComposerPackagesResponse>;\n\nexport function parsePackagesResponse(\n packageName: string,\n packagesResponse: unknown,\n): ComposerReleases {\n try {\n return ComposerPackagesResponse.parse({ packageName, packagesResponse });\n } catch (err) {\n logger.debug(\n { packageName, err },\n `Error parsing packagist response for ${packageName}`,\n );\n return [];\n }\n}\n\nexport function extractReleaseResult(\n ...composerReleasesArrays: ComposerReleases[]\n): ReleaseResult | null {\n const releases: Release[] = [];\n let homepage: string | null | undefined;\n let sourceUrl: string | null | undefined;\n let deprecationMessage: string | undefined;\n\n for (const composerReleasesArray of composerReleasesArrays) {\n for (const composerRelease of composerReleasesArray) {\n const version = composerRelease.version.replace(regEx(/^v/), '');\n const gitRef = composerRelease.version;\n\n const dep: Release = { version, gitRef };\n\n // Packagist's `published-time` reflects when the version was actually published to the registry;\n // prefer it over `time` (the git tag's `releasedAt`, which could be when the commit that the tag points at was pushed, not the time the release itself was made public to the world), falling back when absent.\n const releaseTimestamp =\n composerRelease['published-time'] ?? composerRelease.time;\n if (releaseTimestamp) {\n dep.releaseTimestamp = releaseTimestamp;\n }\n\n if (composerRelease.require?.php) {\n dep.constraints = { php: [composerRelease.require.php] };\n }\n\n if (composerRelease.abandoned) {\n dep.isDeprecated = true;\n deprecationMessage ??= getAbandonedMessage(composerRelease.abandoned);\n // TODO #44060 when `abandoned` is a package name, emit replacementName/replacementVersion to open a replacement PR\n }\n\n releases.push(dep);\n\n if (!homepage && composerRelease.homepage) {\n homepage = composerRelease.homepage;\n }\n\n if (!sourceUrl && composerRelease.source?.url) {\n sourceUrl = composerRelease.source.url;\n }\n }\n }\n\n if (releases.length === 0) {\n return null;\n }\n\n const result: ReleaseResult = { releases };\n\n if (homepage) {\n result.homepage = homepage;\n }\n\n if (sourceUrl) {\n result.sourceUrl = sourceUrl;\n }\n\n if (deprecationMessage) {\n result.deprecationMessage = deprecationMessage;\n }\n\n return result;\n}\n\nfunction getAbandonedMessage(abandoned: string | boolean): string {\n const message = 'This package is abandoned and no longer maintained.';\n if (isString(abandoned)) {\n return `${message} The author suggests using the \\`${abandoned}\\` package instead.`;\n }\n return message;\n}\n\nexport function extractDepReleases(\n composerReleases: unknown,\n): ReleaseResult | null {\n const parsedReleases = ComposerReleases.parse(composerReleases);\n return extractReleaseResult(parsedReleases);\n}\n\nexport function parsePackagesResponses(\n packageName: string,\n packagesResponses: unknown[],\n): ReleaseResult | null {\n const releaseArrays = packagesResponses.map((pkgResp) =>\n parsePackagesResponse(packageName, pkgResp),\n );\n return extractReleaseResult(...releaseArrays);\n}\n\nexport const HashSpec = z.union([\n z\n .object({ sha256: z.string().nullable() })\n .transform(({ sha256 }) => ({ hash: sha256 })),\n z\n .object({ sha1: z.string().nullable() })\n .transform(({ sha1 }) => ({ hash: sha1 })),\n]);\nexport type HashSpec = z.infer<typeof HashSpec>;\n\nexport const RegistryFile = z.intersection(\n HashSpec,\n z.object({ key: z.string() }),\n);\nexport type RegistryFile = z.infer<typeof RegistryFile>;\n\nexport const PackagesResponse = z.object({\n packages: LooseRecord(ComposerReleases).catch({}),\n});\nexport type PackagesResponse = z.infer<typeof PackagesResponse>;\n\nexport const PackagistFile = PackagesResponse.merge(\n z.object({\n providers: LooseRecord(HashSpec)\n .transform((x) =>\n Object.fromEntries(\n Object.entries(x).map(([key, { hash }]) => [key, hash]),\n ),\n )\n .catch({}),\n }),\n);\nexport type PackagistFile = z.infer<typeof PackagistFile>;\n\nexport const RegistryMeta = z\n .record(z.string(), z.unknown())\n .catch({})\n .pipe(\n PackagistFile.merge(\n z.object({\n ['includes']: LooseRecord(HashSpec)\n .transform((x) =>\n Object.entries(x).map(([name, { hash }]) => ({ key: name, hash })),\n )\n .catch([]),\n ['provider-includes']: LooseRecord(HashSpec)\n .transform((x) =>\n Object.entries(x).map(([key, { hash }]) => ({ key, hash })),\n )\n .catch([]),\n ['providers-lazy-url']: z.string().nullable().catch(null),\n ['providers-url']: z.string().nullable().catch(null),\n ['metadata-url']: z.string().nullable().catch(null),\n ['available-packages']: z.array(z.string()).nullable().catch(null),\n }),\n ),\n )\n .transform(\n ({\n ['includes']: includesFiles,\n ['packages']: packages,\n ['provider-includes']: files,\n ['providers']: providerPackages,\n ['providers-lazy-url']: providersLazyUrl,\n ['providers-url']: providersUrl,\n ['metadata-url']: metadataUrl,\n ['available-packages']: availablePackages,\n }) => {\n const includesPackages: Record<string, ReleaseResult | null> = {};\n return {\n packages,\n includesFiles,\n providerPackages,\n files,\n providersUrl,\n providersLazyUrl,\n metadataUrl,\n includesPackages,\n availablePackages,\n };\n },\n );\nexport type RegistryMeta = z.infer<typeof RegistryMeta>;\n"],"mappings":"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"}
@@ -6,7 +6,7 @@ function isGitHubRepo(url) {
6
6
  return !!m && m[1] !== "sponsors";
7
7
  }
8
8
  function normalizePythonDepName(name) {
9
- return name.replace(/[-_.]+/g, "-").toLowerCase();
9
+ return name.replace(regEx(/[-_.]+/g), "-").toLowerCase();
10
10
  }
11
11
  //#endregion
12
12
  export { isGitHubRepo, normalizePythonDepName };
@@ -1 +1 @@
1
- {"version":3,"file":"common.js","names":[],"sources":["../../../../lib/modules/datasource/pypi/common.ts"],"sourcesContent":["import { regEx } from '../../../util/regex.ts';\n\nconst githubRepoPattern = regEx(/^https?:\\/\\/github\\.com\\/([^/]+)\\/[^/]+$/);\n\nexport function isGitHubRepo(url: string): boolean {\n const m = url.match(githubRepoPattern);\n return !!m && m[1] !== 'sponsors';\n}\n\n// https://packaging.python.org/en/latest/specifications/name-normalization/\nexport function normalizePythonDepName(name: string): string {\n return name.replace(/[-_.]+/g, '-').toLowerCase();\n}\n"],"mappings":";;AAEA,MAAM,oBAAoB,MAAM,0CAA0C;AAE1E,SAAgB,aAAa,KAAsB;CACjD,MAAM,IAAI,IAAI,MAAM,iBAAiB;CACrC,OAAO,CAAC,CAAC,KAAK,EAAE,OAAO;AACzB;AAGA,SAAgB,uBAAuB,MAAsB;CAC3D,OAAO,KAAK,QAAQ,WAAW,GAAG,CAAC,CAAC,YAAY;AAClD"}
1
+ {"version":3,"file":"common.js","names":[],"sources":["../../../../lib/modules/datasource/pypi/common.ts"],"sourcesContent":["import { regEx } from '../../../util/regex.ts';\n\nconst githubRepoPattern = regEx(/^https?:\\/\\/github\\.com\\/([^/]+)\\/[^/]+$/);\n\nexport function isGitHubRepo(url: string): boolean {\n const m = url.match(githubRepoPattern);\n return !!m && m[1] !== 'sponsors';\n}\n\n// https://packaging.python.org/en/latest/specifications/name-normalization/\nexport function normalizePythonDepName(name: string): string {\n return name.replace(regEx(/[-_.]+/g), '-').toLowerCase();\n}\n"],"mappings":";;AAEA,MAAM,oBAAoB,MAAM,0CAA0C;AAE1E,SAAgB,aAAa,KAAsB;CACjD,MAAM,IAAI,IAAI,MAAM,iBAAiB;CACrC,OAAO,CAAC,CAAC,KAAK,EAAE,OAAO;AACzB;AAGA,SAAgB,uBAAuB,MAAsB;CAC3D,OAAO,KAAK,QAAQ,MAAM,SAAS,GAAG,GAAG,CAAC,CAAC,YAAY;AACzD"}
@@ -1,3 +1,4 @@
1
+ import { regEx } from "../../../util/regex.js";
1
2
  import { logger } from "../../../logger/index.js";
2
3
  import { joinUrlParts } from "../../../util/url.js";
3
4
  import { repomdXmlFileName } from "./common.js";
@@ -10,7 +11,7 @@ function getPrimaryRepodataUrl(xml, registryUrl, repomdUrl) {
10
11
  if (!locationElement) throw new Error(`No location element found in ${repomdUrl}`);
11
12
  const href = locationElement.attr.href;
12
13
  if (!href) throw new Error(`No href found in ${repomdUrl}`);
13
- const registryUrlWithoutRepodata = registryUrl.replace(/\/repodata\/?$/, "/");
14
+ const registryUrlWithoutRepodata = registryUrl.replace(regEx(/\/repodata\/?$/), "/");
14
15
  return joinUrlParts(registryUrlWithoutRepodata, href);
15
16
  }
16
17
  async function fetchPrimaryGzipUrl(http, registryUrl) {
@@ -1 +1 @@
1
- {"version":3,"file":"repomd.js","names":[],"sources":["../../../../lib/modules/datasource/rpm/repomd.ts"],"sourcesContent":["import { XmlDocument } from 'xmldoc';\nimport { logger } from '../../../logger/index.ts';\nimport type { Http } from '../../../util/http/index.ts';\nimport { joinUrlParts } from '../../../util/url.ts';\nimport { datasource, repomdXmlFileName } from './common.ts';\n\nfunction getPrimaryRepodataUrl(\n xml: XmlDocument,\n registryUrl: string,\n repomdUrl: string,\n): string {\n const primaryData = xml.childWithAttribute('type', 'primary');\n\n if (!primaryData) {\n throw new Error(`No primary data found in ${repomdUrl}`);\n }\n\n const locationElement = primaryData.childNamed('location');\n if (!locationElement) {\n throw new Error(`No location element found in ${repomdUrl}`);\n }\n\n const href = locationElement.attr.href;\n if (!href) {\n throw new Error(`No href found in ${repomdUrl}`);\n }\n\n // replace trailing \"repodata/\" from registryUrl, if it exists, with a \"/\"\n // because href includes \"repodata/\"\n const registryUrlWithoutRepodata = registryUrl.replace(/\\/repodata\\/?$/, '/');\n\n return joinUrlParts(registryUrlWithoutRepodata, href);\n}\n\nexport async function fetchPrimaryGzipUrl(\n http: Http,\n registryUrl: string,\n): Promise<string> {\n const repomdUrl = joinUrlParts(registryUrl, repomdXmlFileName);\n const response = await http.getText(repomdUrl.toString());\n const repomdBody = response.body.trimStart();\n\n // repomd.xml may omit the XML declaration and start directly with the root element\n if (!(repomdBody.startsWith('<?xml') || repomdBody.startsWith('<repomd'))) {\n logger.debug({ datasource, url: repomdUrl }, 'Invalid response format');\n throw new Error(\n `${repomdUrl} is not in XML format. Response body: ${response.body}`,\n );\n }\n\n const xml = new XmlDocument(repomdBody);\n\n try {\n return getPrimaryRepodataUrl(xml, registryUrl, repomdUrl.toString());\n } catch (err) {\n if (\n err instanceof Error &&\n err.message.startsWith('No primary data found')\n ) {\n logger.debug(\n `No primary data found in ${repomdUrl}, xml contents: ${response.body}`,\n );\n }\n\n throw err;\n }\n}\n"],"mappings":";;;;;AAMA,SAAS,sBACP,KACA,aACA,WACQ;CACR,MAAM,cAAc,IAAI,mBAAmB,QAAQ,SAAS;CAE5D,IAAI,CAAC,aACH,MAAM,IAAI,MAAM,4BAA4B,WAAW;CAGzD,MAAM,kBAAkB,YAAY,WAAW,UAAU;CACzD,IAAI,CAAC,iBACH,MAAM,IAAI,MAAM,gCAAgC,WAAW;CAG7D,MAAM,OAAO,gBAAgB,KAAK;CAClC,IAAI,CAAC,MACH,MAAM,IAAI,MAAM,oBAAoB,WAAW;CAKjD,MAAM,6BAA6B,YAAY,QAAQ,kBAAkB,GAAG;CAE5E,OAAO,aAAa,4BAA4B,IAAI;AACtD;AAEA,eAAsB,oBACpB,MACA,aACiB;CACjB,MAAM,YAAY,aAAa,aAAa,iBAAiB;CAC7D,MAAM,WAAW,MAAM,KAAK,QAAQ,UAAU,SAAS,CAAC;CACxD,MAAM,aAAa,SAAS,KAAK,UAAU;CAG3C,IAAI,EAAE,WAAW,WAAW,OAAO,KAAK,WAAW,WAAW,SAAS,IAAI;EACzE,OAAO,MAAM;GAAE,YAAA;GAAY,KAAK;EAAU,GAAG,yBAAyB;EACtE,MAAM,IAAI,MACR,GAAG,UAAU,wCAAwC,SAAS,MAChE;CACF;CAEA,MAAM,MAAM,IAAI,YAAY,UAAU;CAEtC,IAAI;EACF,OAAO,sBAAsB,KAAK,aAAa,UAAU,SAAS,CAAC;CACrE,SAAS,KAAK;EACZ,IACE,eAAe,SACf,IAAI,QAAQ,WAAW,uBAAuB,GAE9C,OAAO,MACL,4BAA4B,UAAU,kBAAkB,SAAS,MACnE;EAGF,MAAM;CACR;AACF"}
1
+ {"version":3,"file":"repomd.js","names":[],"sources":["../../../../lib/modules/datasource/rpm/repomd.ts"],"sourcesContent":["import { XmlDocument } from 'xmldoc';\nimport { logger } from '../../../logger/index.ts';\nimport type { Http } from '../../../util/http/index.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { joinUrlParts } from '../../../util/url.ts';\nimport { datasource, repomdXmlFileName } from './common.ts';\n\nfunction getPrimaryRepodataUrl(\n xml: XmlDocument,\n registryUrl: string,\n repomdUrl: string,\n): string {\n const primaryData = xml.childWithAttribute('type', 'primary');\n\n if (!primaryData) {\n throw new Error(`No primary data found in ${repomdUrl}`);\n }\n\n const locationElement = primaryData.childNamed('location');\n if (!locationElement) {\n throw new Error(`No location element found in ${repomdUrl}`);\n }\n\n const href = locationElement.attr.href;\n if (!href) {\n throw new Error(`No href found in ${repomdUrl}`);\n }\n\n // replace trailing \"repodata/\" from registryUrl, if it exists, with a \"/\"\n // because href includes \"repodata/\"\n const registryUrlWithoutRepodata = registryUrl.replace(\n regEx(/\\/repodata\\/?$/),\n '/',\n );\n\n return joinUrlParts(registryUrlWithoutRepodata, href);\n}\n\nexport async function fetchPrimaryGzipUrl(\n http: Http,\n registryUrl: string,\n): Promise<string> {\n const repomdUrl = joinUrlParts(registryUrl, repomdXmlFileName);\n const response = await http.getText(repomdUrl.toString());\n const repomdBody = response.body.trimStart();\n\n // repomd.xml may omit the XML declaration and start directly with the root element\n if (!(repomdBody.startsWith('<?xml') || repomdBody.startsWith('<repomd'))) {\n logger.debug({ datasource, url: repomdUrl }, 'Invalid response format');\n throw new Error(\n `${repomdUrl} is not in XML format. Response body: ${response.body}`,\n );\n }\n\n const xml = new XmlDocument(repomdBody);\n\n try {\n return getPrimaryRepodataUrl(xml, registryUrl, repomdUrl.toString());\n } catch (err) {\n if (\n err instanceof Error &&\n err.message.startsWith('No primary data found')\n ) {\n logger.debug(\n `No primary data found in ${repomdUrl}, xml contents: ${response.body}`,\n );\n }\n\n throw err;\n }\n}\n"],"mappings":";;;;;;AAOA,SAAS,sBACP,KACA,aACA,WACQ;CACR,MAAM,cAAc,IAAI,mBAAmB,QAAQ,SAAS;CAE5D,IAAI,CAAC,aACH,MAAM,IAAI,MAAM,4BAA4B,WAAW;CAGzD,MAAM,kBAAkB,YAAY,WAAW,UAAU;CACzD,IAAI,CAAC,iBACH,MAAM,IAAI,MAAM,gCAAgC,WAAW;CAG7D,MAAM,OAAO,gBAAgB,KAAK;CAClC,IAAI,CAAC,MACH,MAAM,IAAI,MAAM,oBAAoB,WAAW;CAKjD,MAAM,6BAA6B,YAAY,QAC7C,MAAM,gBAAgB,GACtB,GACF;CAEA,OAAO,aAAa,4BAA4B,IAAI;AACtD;AAEA,eAAsB,oBACpB,MACA,aACiB;CACjB,MAAM,YAAY,aAAa,aAAa,iBAAiB;CAC7D,MAAM,WAAW,MAAM,KAAK,QAAQ,UAAU,SAAS,CAAC;CACxD,MAAM,aAAa,SAAS,KAAK,UAAU;CAG3C,IAAI,EAAE,WAAW,WAAW,OAAO,KAAK,WAAW,WAAW,SAAS,IAAI;EACzE,OAAO,MAAM;GAAE,YAAA;GAAY,KAAK;EAAU,GAAG,yBAAyB;EACtE,MAAM,IAAI,MACR,GAAG,UAAU,wCAAwC,SAAS,MAChE;CACF;CAEA,MAAM,MAAM,IAAI,YAAY,UAAU;CAEtC,IAAI;EACF,OAAO,sBAAsB,KAAK,aAAa,UAAU,SAAS,CAAC;CACrE,SAAS,KAAK;EACZ,IACE,eAAe,SACf,IAAI,QAAQ,WAAW,uBAAuB,GAE9C,OAAO,MACL,4BAA4B,UAAU,kBAAkB,SAAS,MACnE;EAGF,MAAM;CACR;AACF"}
@@ -1,10 +1,10 @@
1
- import { coerceArray } from "../../../util/array.js";
1
+ import { regEx } from "../../../util/regex.js";
2
2
  import { filterMap } from "../../../util/filter-map.js";
3
3
  import { compare } from "../../versioning/maven/compare.js";
4
4
  //#region lib/modules/datasource/sbt-package/util.ts
5
- const linkRegExp = /(?<=href=['"])[^'"]*(?=\/['"])/gi;
5
+ const linkRegExp = regEx(/href=['"](?<href>[^'"]*)\/['"]/gi);
6
6
  function extractPageLinks(html, filterMapHref) {
7
- const unfiltered = coerceArray(html.match(linkRegExp));
7
+ const unfiltered = Array.from(html.matchAll(linkRegExp), (m) => m.groups.href);
8
8
  return filterMap(unfiltered, filterMapHref);
9
9
  }
10
10
  function getLatestVersion(versions) {
@@ -1 +1 @@
1
- {"version":3,"file":"util.js","names":[],"sources":["../../../../lib/modules/datasource/sbt-package/util.ts"],"sourcesContent":["import { coerceArray } from '../../../util/array.ts';\nimport { filterMap } from '../../../util/filter-map.ts';\nimport { compare } from '../../versioning/maven/compare.ts';\n\nconst linkRegExp = /(?<=href=['\"])[^'\"]*(?=\\/['\"])/gi;\n\nexport function extractPageLinks(\n html: string,\n filterMapHref: (href: string) => string | null | undefined,\n): string[] {\n const unfiltered = coerceArray(html.match(linkRegExp));\n return filterMap(unfiltered, filterMapHref);\n}\n\nexport function getLatestVersion(versions: string[] | null): string | null {\n if (versions?.length) {\n return versions.reduce((latestVersion, version) =>\n compare(version, latestVersion) === 1 ? version : latestVersion,\n );\n }\n return null;\n}\n"],"mappings":";;;;AAIA,MAAM,aAAa;AAEnB,SAAgB,iBACd,MACA,eACU;CACV,MAAM,aAAa,YAAY,KAAK,MAAM,UAAU,CAAC;CACrD,OAAO,UAAU,YAAY,aAAa;AAC5C;AAEA,SAAgB,iBAAiB,UAA0C;CACzE,IAAI,UAAU,QACZ,OAAO,SAAS,QAAQ,eAAe,YACrC,QAAQ,SAAS,aAAa,MAAM,IAAI,UAAU,aACpD;CAEF,OAAO;AACT"}
1
+ {"version":3,"file":"util.js","names":[],"sources":["../../../../lib/modules/datasource/sbt-package/util.ts"],"sourcesContent":["import { filterMap } from '../../../util/filter-map.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { compare } from '../../versioning/maven/compare.ts';\n\nconst linkRegExp = regEx(/href=['\"](?<href>[^'\"]*)\\/['\"]/gi);\n\nexport function extractPageLinks(\n html: string,\n filterMapHref: (href: string) => string | null | undefined,\n): string[] {\n const unfiltered = Array.from(\n html.matchAll(linkRegExp),\n (m) => m.groups!.href,\n );\n return filterMap(unfiltered, filterMapHref);\n}\n\nexport function getLatestVersion(versions: string[] | null): string | null {\n if (versions?.length) {\n return versions.reduce((latestVersion, version) =>\n compare(version, latestVersion) === 1 ? version : latestVersion,\n );\n }\n return null;\n}\n"],"mappings":";;;;AAIA,MAAM,aAAa,MAAM,kCAAkC;AAE3D,SAAgB,iBACd,MACA,eACU;CACV,MAAM,aAAa,MAAM,KACvB,KAAK,SAAS,UAAU,IACvB,MAAM,EAAE,OAAQ,IACnB;CACA,OAAO,UAAU,YAAY,aAAa;AAC5C;AAEA,SAAgB,iBAAiB,UAA0C;CACzE,IAAI,UAAU,QACZ,OAAO,SAAS,QAAQ,eAAe,YACrC,QAAQ,SAAS,aAAa,MAAM,IAAI,UAAU,aACpD;CAEF,OAAO;AACT"}
@@ -205,7 +205,7 @@ var TerraformProviderDatasource = class TerraformProviderDatasource extends Terr
205
205
  }, `Failed to retrieve zip hashes from ${zipHashUrl}`);
206
206
  return;
207
207
  }
208
- return rawHashData.trimEnd().split("\n").map((line) => line.split(/\s/)[0]);
208
+ return rawHashData.trimEnd().split("\n").map((line) => line.split(regEx(/\s/))[0]);
209
209
  }
210
210
  getZipHashes(zipHashUrl) {
211
211
  return withCache({
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["hashicorpVersioning.id","p.map","HttpError"],"sources":["../../../../lib/modules/datasource/terraform-provider/index.ts"],"sourcesContent":["import { logger } from '../../../logger/index.ts';\nimport { ExternalHostError } from '../../../types/errors/external-host-error.ts';\nimport { withCache } from '../../../util/cache/package/with-cache.ts';\nimport { HttpError } from '../../../util/http/index.ts';\nimport * as p from '../../../util/promises.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { getQueryString, joinUrlParts } from '../../../util/url.ts';\nimport * as hashicorpVersioning from '../../versioning/hashicorp/index.ts';\nimport { TerraformDatasource } from '../terraform-module/base.ts';\nimport { createSDBackendURL } from '../terraform-module/utils.ts';\nimport type { GetReleasesConfig, ReleaseResult } from '../types.ts';\nimport {\n OpenTofuProviderDocsResponse,\n OpenTofuProviderPackagesResponse,\n type TerraformBuild,\n TerraformProviderReleaseBackend,\n TerraformProviderV2Response,\n TerraformProviderVersions,\n TerraformRegistryBuildResponse,\n TerraformRegistryVersions,\n VersionDetailResponse,\n} from './schema.ts';\n\nexport class TerraformProviderDatasource extends TerraformDatasource {\n static override readonly id = 'terraform-provider';\n\n static readonly hashicorpReleaseUrl = 'https://releases.hashicorp.com';\n\n static readonly defaultRegistryUrls = [\n TerraformProviderDatasource.terraformRegistryUrl,\n TerraformProviderDatasource.hashicorpReleaseUrl,\n ];\n\n static repositoryRegex = regEx(/^hashicorp\\/(?<packageName>\\S+)$/);\n\n constructor() {\n super(TerraformProviderDatasource.id);\n }\n\n override readonly defaultRegistryUrls =\n TerraformProviderDatasource.defaultRegistryUrls;\n\n override readonly defaultVersioning = hashicorpVersioning.id;\n\n override readonly registryStrategy = 'hunt';\n\n override readonly releaseTimestampSupport = true;\n override readonly releaseTimestampNote =\n 'The release timestamp is only available for `registry.terraform.io` (v2 API) and `registry.opentofu.org` (via `api.opentofu.org`). Other registries using the Provider Registry Protocol do not provide timestamps.';\n override readonly sourceUrlSupport = 'package';\n override readonly sourceUrlNote =\n 'For `registry.terraform.io`, the source URL is taken from the `source` field of the v2 API response. For `registry.opentofu.org`, it is derived from the package name following the OpenTofu registry policy of `github.com/NAMESPACE/terraform-provider-NAME`.';\n\n private async _getReleases({\n packageName,\n registryUrl,\n }: GetReleasesConfig): Promise<ReleaseResult | null> {\n /* v8 ignore next 3 -- should never happen */\n if (!registryUrl) {\n return null;\n }\n logger.trace(\n `terraform-provider.getDependencies() packageName: ${packageName}`,\n );\n\n if (registryUrl === TerraformProviderDatasource.terraformRegistryUrl) {\n return await this.queryTerraformRegistryV2(registryUrl, packageName);\n }\n if (\n registryUrl === TerraformProviderDatasource.openTofuRegistryUrl ||\n registryUrl === TerraformProviderDatasource.openTofuApiUrl\n ) {\n return await this.queryOpenTofuRegistry(packageName);\n }\n if (registryUrl === TerraformProviderDatasource.hashicorpReleaseUrl) {\n return await this.queryReleaseBackend(packageName, registryUrl);\n }\n\n // Fall back to the standard Provider Registry Protocol for other registries.\n return await this.queryProviderRegistry(registryUrl, packageName);\n }\n\n getReleases(config: GetReleasesConfig): Promise<ReleaseResult | null> {\n const url = config.registryUrl;\n const repo = TerraformProviderDatasource.getRepository(config);\n return withCache(\n {\n namespace: `datasource-${TerraformProviderDatasource.id}`,\n key: `getReleases:${url}/${repo}`,\n fallback: true,\n },\n () => this._getReleases(config),\n );\n }\n\n private static getRepository({ packageName }: GetReleasesConfig): string {\n return packageName.includes('/') ? packageName : `hashicorp/${packageName}`;\n }\n\n /**\n * Query the Terraform Registry using the undocumented v2 JSON:API.\n *\n * Returns release timestamps for all versions, unlike the v1 API\n * which only exposed the timestamp for the latest version.\n */\n private async queryTerraformRegistryV2(\n registryUrl: string,\n packageName: string,\n ): Promise<ReleaseResult> {\n const repository = TerraformProviderDatasource.getRepository({\n packageName,\n });\n const providerUrl = `${joinUrlParts(\n registryUrl,\n 'v2/providers',\n repository,\n )}?${getQueryString({ include: 'provider-versions' })}`;\n const { body: res } = await this.http.getJson(\n providerUrl,\n TerraformProviderV2Response,\n );\n res.homepage = `${registryUrl}/providers/${repository}`;\n return res;\n }\n\n /**\n * Query the OpenTofu registry docs API.\n * https://api.opentofu.org/\n *\n * Used when the registry URL is `registry.opentofu.org`.\n * Queries `api.opentofu.org` for provider versions with release timestamps.\n */\n private async queryOpenTofuRegistry(\n packageName: string,\n ): Promise<ReleaseResult> {\n const repository = TerraformProviderDatasource.getRepository({\n packageName,\n });\n const docsUrl = joinUrlParts(\n TerraformProviderDatasource.openTofuApiUrl,\n 'registry/docs/providers',\n repository,\n 'index.json',\n );\n const { body: res } = await this.http.getJson(\n docsUrl,\n OpenTofuProviderDocsResponse,\n );\n res.homepage = `https://search.opentofu.org/provider/${repository}`;\n\n // The OpenTofu registry only indexes providers hosted on GitHub under the\n // `NAMESPACE/terraform-provider-NAME` repository naming convention, so the\n // source URL can be derived deterministically from the package name.\n // https://github.com/opentofu/registry/blob/main/PROCEDURES.md\n const [namespace, name] = repository.split('/');\n res.sourceUrl = `https://github.com/${namespace}/terraform-provider-${name}`;\n\n return res;\n }\n\n /**\n * Query a registry using the Provider Registry Protocol that all registries\n * are required to implement.\n * https://www.terraform.io/internals/provider-registry-protocol\n */\n private async queryProviderRegistry(\n registryUrl: string,\n packageName: string,\n ): Promise<ReleaseResult> {\n const repository = TerraformProviderDatasource.getRepository({\n packageName,\n });\n const serviceDiscovery =\n await this.getTerraformServiceDiscoveryResult(registryUrl);\n const backendURL = createSDBackendURL(\n registryUrl,\n 'providers.v1',\n serviceDiscovery,\n `${repository}/versions`,\n );\n const res = (await this.http.getJson(backendURL, TerraformProviderVersions))\n .body;\n const dep: ReleaseResult = {\n releases: res.versions.map(({ version }) => ({\n version,\n })),\n };\n return dep;\n }\n\n private async queryReleaseBackend(\n packageName: string,\n registryURL: string,\n ): Promise<ReleaseResult | null> {\n const hashicorpPackage = packageName.replace('hashicorp/', '');\n const backendLookUpName = `terraform-provider-${hashicorpPackage}`;\n const backendURL = joinUrlParts(\n registryURL,\n backendLookUpName,\n `index.json`,\n );\n const res = (\n await this.http.getJson(backendURL, TerraformProviderReleaseBackend)\n ).body;\n\n const dep: ReleaseResult = {\n releases: Object.keys(res.versions).map((version) => ({\n version,\n })),\n sourceUrl: joinUrlParts(\n 'https://github.com/terraform-providers',\n backendLookUpName,\n ),\n };\n return dep;\n }\n\n private async _getBuilds(\n registryURL: string,\n repository: string,\n version: string,\n ): Promise<TerraformBuild[] | null> {\n if (registryURL === TerraformProviderDatasource.hashicorpReleaseUrl) {\n // check if registryURL === secondary backend\n const repositoryRegexResult =\n TerraformProviderDatasource.repositoryRegex.exec(repository)?.groups;\n if (!repositoryRegexResult) {\n // non hashicorp builds are not supported with releases.hashicorp.com\n return null;\n }\n const packageName = repositoryRegexResult.packageName;\n const backendLookUpName = `terraform-provider-${packageName}`;\n let versionReleaseBackend: VersionDetailResponse;\n try {\n versionReleaseBackend = await this.getReleaseBackendIndex(\n backendLookUpName,\n version,\n );\n } catch (err) {\n if (err instanceof ExternalHostError) {\n throw err;\n }\n logger.debug(\n { err, backendLookUpName, version },\n `Failed to retrieve builds for ${backendLookUpName} ${version}`,\n );\n // throw an error to disable caching\n throw new ExternalHostError(err);\n }\n return versionReleaseBackend.builds;\n }\n\n // check public or private Terraform registry\n const serviceDiscovery =\n await this.getTerraformServiceDiscoveryResult(registryURL);\n if (!serviceDiscovery) {\n // throw an error to disable caching\n throw new ExternalHostError(\n new Error(`Service discovery not found for ${registryURL}`),\n );\n }\n const backendURL = createSDBackendURL(\n registryURL,\n 'providers.v1',\n serviceDiscovery,\n repository,\n );\n const versionsResponse = (\n await this.http.getJson(\n `${backendURL}/versions`,\n TerraformRegistryVersions,\n )\n ).body;\n if (!versionsResponse.versions) {\n // throw an error to disable caching\n throw new ExternalHostError(\n new Error(`Failed to retrieve version list for ${backendURL}`),\n );\n }\n const builds = versionsResponse.versions.find(\n (value) => value.version === version,\n );\n if (!builds) {\n // should never happen, but just in case\n // throw an error to disable caching\n throw new ExternalHostError(\n new Error(\n `No builds found for ${repository}:${version} on ${registryURL}`,\n ),\n );\n }\n const result = await p.map(\n builds.platforms,\n async (platform) => {\n const buildURL = `${backendURL}/${version}/download/${platform.os}/${platform.arch}`;\n try {\n const res = (\n await this.http.getJson(buildURL, TerraformRegistryBuildResponse)\n ).body;\n const newBuild: TerraformBuild = {\n name: repository,\n url: res.download_url,\n version,\n ...res,\n };\n return newBuild;\n } catch (err) {\n /* v8 ignore next 3 -- hard to test */\n if (err instanceof ExternalHostError) {\n throw err;\n }\n logger.debug({ err, url: buildURL }, 'Failed to retrieve build');\n // throw an error to disable caching\n throw new ExternalHostError(err);\n }\n },\n { concurrency: 4 },\n );\n\n return result;\n }\n\n getBuilds(\n registryURL: string,\n repository: string,\n version: string,\n ): Promise<TerraformBuild[] | null> {\n return withCache(\n {\n namespace: `datasource-${TerraformProviderDatasource.id}`,\n key: `getBuilds:${registryURL}/${repository}/${version}`,\n },\n () => this._getBuilds(registryURL, repository, version),\n );\n }\n\n /**\n * A single platform's download endpoint returns the hashes for all platforms,\n * so we query `linux/amd64` and fall back to `/versions` discovery only when a\n * provider lacks that platform (404).\n * See https://github.com/opentofu/opentofu/pull/3434\n */\n private async _getProviderPackages(\n repository: string,\n version: string,\n ): Promise<string[] | null> {\n const baseUrl = joinUrlParts(\n TerraformProviderDatasource.openTofuRegistryUrl,\n 'v1/providers',\n repository,\n );\n\n try {\n try {\n const { body } = await this.http.getJson(\n `${baseUrl}/${version}/download/linux/amd64`,\n OpenTofuProviderPackagesResponse,\n );\n return body;\n } catch (err) {\n if (!(err instanceof HttpError) || err.response?.statusCode !== 404) {\n throw err;\n }\n }\n return await this._getProviderPackagesForAvailablePlatform(\n baseUrl,\n version,\n );\n } catch (err) {\n if (err instanceof ExternalHostError) {\n throw err;\n }\n logger.debug(\n { err, repository, version },\n `Failed to retrieve provider packages for ${repository}@${version}`,\n );\n throw new ExternalHostError(err);\n }\n }\n\n /**\n * Some providers do not publish a `linux/amd64` build, so discover an\n * available platform via `/versions` and fetch its download endpoint.\n */\n private async _getProviderPackagesForAvailablePlatform(\n baseUrl: string,\n version: string,\n ): Promise<string[] | null> {\n const { body: versionsResponse } = await this.http.getJson(\n `${baseUrl}/versions`,\n TerraformRegistryVersions,\n );\n const platform = versionsResponse.versions?.find(\n (entry) => entry.version === version,\n )?.platforms?.[0];\n if (!platform) {\n return null;\n }\n const { body: hashes } = await this.http.getJson(\n `${baseUrl}/${version}/download/${platform.os}/${platform.arch}`,\n OpenTofuProviderPackagesResponse,\n );\n return hashes;\n }\n\n getProviderPackages(\n repository: string,\n version: string,\n ): Promise<string[] | null> {\n return withCache(\n {\n namespace: `datasource-${TerraformProviderDatasource.id}`,\n key: `getProviderPackages:${repository}/${version}`,\n },\n () => this._getProviderPackages(repository, version),\n );\n }\n\n private async _getZipHashes(\n zipHashUrl: string,\n ): Promise<string[] | undefined> {\n // The hashes are formatted as the result of sha256sum in plain text, each line: <hash>\\t<filename>\n let rawHashData: string;\n try {\n rawHashData = (await this.http.getText(zipHashUrl)).body;\n } catch (err) {\n /* v8 ignore next 3 -- hard to test */\n if (err instanceof ExternalHostError) {\n throw err;\n }\n logger.debug(\n { err, zipHashUrl },\n `Failed to retrieve zip hashes from ${zipHashUrl}`,\n );\n return undefined;\n }\n\n return rawHashData\n .trimEnd()\n .split('\\n')\n .map((line) => line.split(/\\s/)[0]);\n }\n\n getZipHashes(zipHashUrl: string): Promise<string[] | undefined> {\n return withCache(\n {\n namespace: `datasource-${TerraformProviderDatasource.id}`,\n key: `getZipHashes:${zipHashUrl}`,\n },\n () => this._getZipHashes(zipHashUrl),\n );\n }\n\n private async _getReleaseBackendIndex(\n backendLookUpName: string,\n version: string,\n ): Promise<VersionDetailResponse> {\n return (\n await this.http.getJson(\n `${TerraformProviderDatasource.hashicorpReleaseUrl}/${backendLookUpName}/${version}/index.json`,\n VersionDetailResponse,\n )\n ).body;\n }\n\n getReleaseBackendIndex(\n backendLookUpName: string,\n version: string,\n ): Promise<VersionDetailResponse> {\n return withCache(\n {\n namespace: `datasource-${TerraformProviderDatasource.id}`,\n key: `getReleaseBackendIndex:${backendLookUpName}/${version}`,\n },\n () => this._getReleaseBackendIndex(backendLookUpName, version),\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAuBA,IAAa,8BAAb,MAAa,oCAAoC,oBAAoB;CACnE,OAAyB,KAAK;CAE9B,OAAgB,sBAAsB;CAEtC,OAAgB,sBAAsB,CACpC,4BAA4B,sBAC5B,4BAA4B,mBAC9B;CAEA,OAAO,kBAAkB,MAAM,kCAAkC;CAEjE,cAAc;EACZ,MAAM,4BAA4B,EAAE;CACtC;CAEA,sBACE,4BAA4B;CAE9B,oBAAsCA;CAEtC,mBAAqC;CAErC,0BAA4C;CAC5C,uBACE;CACF,mBAAqC;CACrC,gBACE;CAEF,MAAc,aAAa,EACzB,aACA,eACmD;;EAEnD,IAAI,CAAC,aACH,OAAO;EAET,OAAO,MACL,qDAAqD,aACvD;EAEA,IAAI,gBAAgB,4BAA4B,sBAC9C,OAAO,MAAM,KAAK,yBAAyB,aAAa,WAAW;EAErE,IACE,gBAAgB,4BAA4B,uBAC5C,gBAAgB,4BAA4B,gBAE5C,OAAO,MAAM,KAAK,sBAAsB,WAAW;EAErD,IAAI,gBAAgB,4BAA4B,qBAC9C,OAAO,MAAM,KAAK,oBAAoB,aAAa,WAAW;EAIhE,OAAO,MAAM,KAAK,sBAAsB,aAAa,WAAW;CAClE;CAEA,YAAY,QAA0D;EACpE,MAAM,MAAM,OAAO;EACnB,MAAM,OAAO,4BAA4B,cAAc,MAAM;EAC7D,OAAO,UACL;GACE,WAAW,cAAc,4BAA4B;GACrD,KAAK,eAAe,IAAI,GAAG;GAC3B,UAAU;EACZ,SACM,KAAK,aAAa,MAAM,CAChC;CACF;CAEA,OAAe,cAAc,EAAE,eAA0C;EACvE,OAAO,YAAY,SAAS,GAAG,IAAI,cAAc,aAAa;CAChE;;;;;;;CAQA,MAAc,yBACZ,aACA,aACwB;EACxB,MAAM,aAAa,4BAA4B,cAAc,EAC3D,YACF,CAAC;EACD,MAAM,cAAc,GAAG,aACrB,aACA,gBACA,UACF,EAAE,GAAG,eAAe,EAAE,SAAS,oBAAoB,CAAC;EACpD,MAAM,EAAE,MAAM,QAAQ,MAAM,KAAK,KAAK,QACpC,aACA,2BACF;EACA,IAAI,WAAW,GAAG,YAAY,aAAa;EAC3C,OAAO;CACT;;;;;;;;CASA,MAAc,sBACZ,aACwB;EACxB,MAAM,aAAa,4BAA4B,cAAc,EAC3D,YACF,CAAC;EACD,MAAM,UAAU,aACd,4BAA4B,gBAC5B,2BACA,YACA,YACF;EACA,MAAM,EAAE,MAAM,QAAQ,MAAM,KAAK,KAAK,QACpC,SACA,4BACF;EACA,IAAI,WAAW,wCAAwC;EAMvD,MAAM,CAAC,WAAW,QAAQ,WAAW,MAAM,GAAG;EAC9C,IAAI,YAAY,sBAAsB,UAAU,sBAAsB;EAEtE,OAAO;CACT;;;;;;CAOA,MAAc,sBACZ,aACA,aACwB;EACxB,MAAM,aAAa,4BAA4B,cAAc,EAC3D,YACF,CAAC;EACD,MAAM,mBACJ,MAAM,KAAK,mCAAmC,WAAW;EAC3D,MAAM,aAAa,mBACjB,aACA,gBACA,kBACA,GAAG,WAAW,UAChB;EAQA,OAAO,EAJL,WAHW,MAAM,KAAK,KAAK,QAAQ,YAAY,yBAAyB,EAAA,CACvE,KAEa,SAAS,KAAK,EAAE,eAAe,EAC3C,QACF,EAAE,EAEK;CACX;CAEA,MAAc,oBACZ,aACA,aAC+B;EAE/B,MAAM,oBAAoB,sBADD,YAAY,QAAQ,cAAc,EACI;EAC/D,MAAM,aAAa,aACjB,aACA,mBACA,YACF;EACA,MAAM,OACJ,MAAM,KAAK,KAAK,QAAQ,YAAY,+BAA+B,EAAA,CACnE;EAWF,OAAO;GARL,UAAU,OAAO,KAAK,IAAI,QAAQ,CAAC,CAAC,KAAK,aAAa,EACpD,QACF,EAAE;GACF,WAAW,aACT,0CACA,iBACF;EAEO;CACX;CAEA,MAAc,WACZ,aACA,YACA,SACkC;EAClC,IAAI,gBAAgB,4BAA4B,qBAAqB;GAEnE,MAAM,wBACJ,4BAA4B,gBAAgB,KAAK,UAAU,CAAC,EAAE;GAChE,IAAI,CAAC,uBAEH,OAAO;GAGT,MAAM,oBAAoB,sBADN,sBAAsB;GAE1C,IAAI;GACJ,IAAI;IACF,wBAAwB,MAAM,KAAK,uBACjC,mBACA,OACF;GACF,SAAS,KAAK;IACZ,IAAI,eAAe,mBACjB,MAAM;IAER,OAAO,MACL;KAAE;KAAK;KAAmB;IAAQ,GAClC,iCAAiC,kBAAkB,GAAG,SACxD;IAEA,MAAM,IAAI,kBAAkB,GAAG;GACjC;GACA,OAAO,sBAAsB;EAC/B;EAGA,MAAM,mBACJ,MAAM,KAAK,mCAAmC,WAAW;EAC3D,IAAI,CAAC,kBAEH,MAAM,IAAI,kCACR,IAAI,MAAM,mCAAmC,aAAa,CAC5D;EAEF,MAAM,aAAa,mBACjB,aACA,gBACA,kBACA,UACF;EACA,MAAM,oBACJ,MAAM,KAAK,KAAK,QACd,GAAG,WAAW,YACd,yBACF,EAAA,CACA;EACF,IAAI,CAAC,iBAAiB,UAEpB,MAAM,IAAI,kCACR,IAAI,MAAM,uCAAuC,YAAY,CAC/D;EAEF,MAAM,SAAS,iBAAiB,SAAS,MACtC,UAAU,MAAM,YAAY,OAC/B;EACA,IAAI,CAAC,QAGH,MAAM,IAAI,kCACR,IAAI,MACF,uBAAuB,WAAW,GAAG,QAAQ,MAAM,aACrD,CACF;EA8BF,OAAO,MA5BcC,IACnB,OAAO,WACP,OAAO,aAAa;GAClB,MAAM,WAAW,GAAG,WAAW,GAAG,QAAQ,YAAY,SAAS,GAAG,GAAG,SAAS;GAC9E,IAAI;IACF,MAAM,OACJ,MAAM,KAAK,KAAK,QAAQ,UAAU,8BAA8B,EAAA,CAChE;IAOF,OAAO;KALL,MAAM;KACN,KAAK,IAAI;KACT;KACA,GAAG;IAES;GAChB,SAAS,KAAK;;IAEZ,IAAI,eAAe,mBACjB,MAAM;IAER,OAAO,MAAM;KAAE;KAAK,KAAK;IAAS,GAAG,0BAA0B;IAE/D,MAAM,IAAI,kBAAkB,GAAG;GACjC;EACF,GACA,EAAE,aAAa,EAAE,CACnB;CAGF;CAEA,UACE,aACA,YACA,SACkC;EAClC,OAAO,UACL;GACE,WAAW,cAAc,4BAA4B;GACrD,KAAK,aAAa,YAAY,GAAG,WAAW,GAAG;EACjD,SACM,KAAK,WAAW,aAAa,YAAY,OAAO,CACxD;CACF;;;;;;;CAQA,MAAc,qBACZ,YACA,SAC0B;EAC1B,MAAM,UAAU,aACd,4BAA4B,qBAC5B,gBACA,UACF;EAEA,IAAI;GACF,IAAI;IACF,MAAM,EAAE,SAAS,MAAM,KAAK,KAAK,QAC/B,GAAG,QAAQ,GAAG,QAAQ,wBACtB,gCACF;IACA,OAAO;GACT,SAAS,KAAK;IACZ,IAAI,EAAE,eAAeC,iBAAc,IAAI,UAAU,eAAe,KAC9D,MAAM;GAEV;GACA,OAAO,MAAM,KAAK,yCAChB,SACA,OACF;EACF,SAAS,KAAK;GACZ,IAAI,eAAe,mBACjB,MAAM;GAER,OAAO,MACL;IAAE;IAAK;IAAY;GAAQ,GAC3B,4CAA4C,WAAW,GAAG,SAC5D;GACA,MAAM,IAAI,kBAAkB,GAAG;EACjC;CACF;;;;;CAMA,MAAc,yCACZ,SACA,SAC0B;EAC1B,MAAM,EAAE,MAAM,qBAAqB,MAAM,KAAK,KAAK,QACjD,GAAG,QAAQ,YACX,yBACF;EACA,MAAM,WAAW,iBAAiB,UAAU,MACzC,UAAU,MAAM,YAAY,OAC/B,CAAC,EAAE,YAAY;EACf,IAAI,CAAC,UACH,OAAO;EAET,MAAM,EAAE,MAAM,WAAW,MAAM,KAAK,KAAK,QACvC,GAAG,QAAQ,GAAG,QAAQ,YAAY,SAAS,GAAG,GAAG,SAAS,QAC1D,gCACF;EACA,OAAO;CACT;CAEA,oBACE,YACA,SAC0B;EAC1B,OAAO,UACL;GACE,WAAW,cAAc,4BAA4B;GACrD,KAAK,uBAAuB,WAAW,GAAG;EAC5C,SACM,KAAK,qBAAqB,YAAY,OAAO,CACrD;CACF;CAEA,MAAc,cACZ,YAC+B;EAE/B,IAAI;EACJ,IAAI;GACF,eAAe,MAAM,KAAK,KAAK,QAAQ,UAAU,EAAA,CAAG;EACtD,SAAS,KAAK;;GAEZ,IAAI,eAAe,mBACjB,MAAM;GAER,OAAO,MACL;IAAE;IAAK;GAAW,GAClB,sCAAsC,YACxC;GACA;EACF;EAEA,OAAO,YACJ,QAAQ,CAAC,CACT,MAAM,IAAI,CAAC,CACX,KAAK,SAAS,KAAK,MAAM,IAAI,CAAC,CAAC,EAAE;CACtC;CAEA,aAAa,YAAmD;EAC9D,OAAO,UACL;GACE,WAAW,cAAc,4BAA4B;GACrD,KAAK,gBAAgB;EACvB,SACM,KAAK,cAAc,UAAU,CACrC;CACF;CAEA,MAAc,wBACZ,mBACA,SACgC;EAChC,QACE,MAAM,KAAK,KAAK,QACd,GAAG,4BAA4B,oBAAoB,GAAG,kBAAkB,GAAG,QAAQ,cACnF,qBACF,EAAA,CACA;CACJ;CAEA,uBACE,mBACA,SACgC;EAChC,OAAO,UACL;GACE,WAAW,cAAc,4BAA4B;GACrD,KAAK,0BAA0B,kBAAkB,GAAG;EACtD,SACM,KAAK,wBAAwB,mBAAmB,OAAO,CAC/D;CACF;AACF"}
1
+ {"version":3,"file":"index.js","names":["hashicorpVersioning.id","p.map","HttpError"],"sources":["../../../../lib/modules/datasource/terraform-provider/index.ts"],"sourcesContent":["import { logger } from '../../../logger/index.ts';\nimport { ExternalHostError } from '../../../types/errors/external-host-error.ts';\nimport { withCache } from '../../../util/cache/package/with-cache.ts';\nimport { HttpError } from '../../../util/http/index.ts';\nimport * as p from '../../../util/promises.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { getQueryString, joinUrlParts } from '../../../util/url.ts';\nimport * as hashicorpVersioning from '../../versioning/hashicorp/index.ts';\nimport { TerraformDatasource } from '../terraform-module/base.ts';\nimport { createSDBackendURL } from '../terraform-module/utils.ts';\nimport type { GetReleasesConfig, ReleaseResult } from '../types.ts';\nimport {\n OpenTofuProviderDocsResponse,\n OpenTofuProviderPackagesResponse,\n type TerraformBuild,\n TerraformProviderReleaseBackend,\n TerraformProviderV2Response,\n TerraformProviderVersions,\n TerraformRegistryBuildResponse,\n TerraformRegistryVersions,\n VersionDetailResponse,\n} from './schema.ts';\n\nexport class TerraformProviderDatasource extends TerraformDatasource {\n static override readonly id = 'terraform-provider';\n\n static readonly hashicorpReleaseUrl = 'https://releases.hashicorp.com';\n\n static readonly defaultRegistryUrls = [\n TerraformProviderDatasource.terraformRegistryUrl,\n TerraformProviderDatasource.hashicorpReleaseUrl,\n ];\n\n static repositoryRegex = regEx(/^hashicorp\\/(?<packageName>\\S+)$/);\n\n constructor() {\n super(TerraformProviderDatasource.id);\n }\n\n override readonly defaultRegistryUrls =\n TerraformProviderDatasource.defaultRegistryUrls;\n\n override readonly defaultVersioning = hashicorpVersioning.id;\n\n override readonly registryStrategy = 'hunt';\n\n override readonly releaseTimestampSupport = true;\n override readonly releaseTimestampNote =\n 'The release timestamp is only available for `registry.terraform.io` (v2 API) and `registry.opentofu.org` (via `api.opentofu.org`). Other registries using the Provider Registry Protocol do not provide timestamps.';\n override readonly sourceUrlSupport = 'package';\n override readonly sourceUrlNote =\n 'For `registry.terraform.io`, the source URL is taken from the `source` field of the v2 API response. For `registry.opentofu.org`, it is derived from the package name following the OpenTofu registry policy of `github.com/NAMESPACE/terraform-provider-NAME`.';\n\n private async _getReleases({\n packageName,\n registryUrl,\n }: GetReleasesConfig): Promise<ReleaseResult | null> {\n /* v8 ignore next 3 -- should never happen */\n if (!registryUrl) {\n return null;\n }\n logger.trace(\n `terraform-provider.getDependencies() packageName: ${packageName}`,\n );\n\n if (registryUrl === TerraformProviderDatasource.terraformRegistryUrl) {\n return await this.queryTerraformRegistryV2(registryUrl, packageName);\n }\n if (\n registryUrl === TerraformProviderDatasource.openTofuRegistryUrl ||\n registryUrl === TerraformProviderDatasource.openTofuApiUrl\n ) {\n return await this.queryOpenTofuRegistry(packageName);\n }\n if (registryUrl === TerraformProviderDatasource.hashicorpReleaseUrl) {\n return await this.queryReleaseBackend(packageName, registryUrl);\n }\n\n // Fall back to the standard Provider Registry Protocol for other registries.\n return await this.queryProviderRegistry(registryUrl, packageName);\n }\n\n getReleases(config: GetReleasesConfig): Promise<ReleaseResult | null> {\n const url = config.registryUrl;\n const repo = TerraformProviderDatasource.getRepository(config);\n return withCache(\n {\n namespace: `datasource-${TerraformProviderDatasource.id}`,\n key: `getReleases:${url}/${repo}`,\n fallback: true,\n },\n () => this._getReleases(config),\n );\n }\n\n private static getRepository({ packageName }: GetReleasesConfig): string {\n return packageName.includes('/') ? packageName : `hashicorp/${packageName}`;\n }\n\n /**\n * Query the Terraform Registry using the undocumented v2 JSON:API.\n *\n * Returns release timestamps for all versions, unlike the v1 API\n * which only exposed the timestamp for the latest version.\n */\n private async queryTerraformRegistryV2(\n registryUrl: string,\n packageName: string,\n ): Promise<ReleaseResult> {\n const repository = TerraformProviderDatasource.getRepository({\n packageName,\n });\n const providerUrl = `${joinUrlParts(\n registryUrl,\n 'v2/providers',\n repository,\n )}?${getQueryString({ include: 'provider-versions' })}`;\n const { body: res } = await this.http.getJson(\n providerUrl,\n TerraformProviderV2Response,\n );\n res.homepage = `${registryUrl}/providers/${repository}`;\n return res;\n }\n\n /**\n * Query the OpenTofu registry docs API.\n * https://api.opentofu.org/\n *\n * Used when the registry URL is `registry.opentofu.org`.\n * Queries `api.opentofu.org` for provider versions with release timestamps.\n */\n private async queryOpenTofuRegistry(\n packageName: string,\n ): Promise<ReleaseResult> {\n const repository = TerraformProviderDatasource.getRepository({\n packageName,\n });\n const docsUrl = joinUrlParts(\n TerraformProviderDatasource.openTofuApiUrl,\n 'registry/docs/providers',\n repository,\n 'index.json',\n );\n const { body: res } = await this.http.getJson(\n docsUrl,\n OpenTofuProviderDocsResponse,\n );\n res.homepage = `https://search.opentofu.org/provider/${repository}`;\n\n // The OpenTofu registry only indexes providers hosted on GitHub under the\n // `NAMESPACE/terraform-provider-NAME` repository naming convention, so the\n // source URL can be derived deterministically from the package name.\n // https://github.com/opentofu/registry/blob/main/PROCEDURES.md\n const [namespace, name] = repository.split('/');\n res.sourceUrl = `https://github.com/${namespace}/terraform-provider-${name}`;\n\n return res;\n }\n\n /**\n * Query a registry using the Provider Registry Protocol that all registries\n * are required to implement.\n * https://www.terraform.io/internals/provider-registry-protocol\n */\n private async queryProviderRegistry(\n registryUrl: string,\n packageName: string,\n ): Promise<ReleaseResult> {\n const repository = TerraformProviderDatasource.getRepository({\n packageName,\n });\n const serviceDiscovery =\n await this.getTerraformServiceDiscoveryResult(registryUrl);\n const backendURL = createSDBackendURL(\n registryUrl,\n 'providers.v1',\n serviceDiscovery,\n `${repository}/versions`,\n );\n const res = (await this.http.getJson(backendURL, TerraformProviderVersions))\n .body;\n const dep: ReleaseResult = {\n releases: res.versions.map(({ version }) => ({\n version,\n })),\n };\n return dep;\n }\n\n private async queryReleaseBackend(\n packageName: string,\n registryURL: string,\n ): Promise<ReleaseResult | null> {\n const hashicorpPackage = packageName.replace('hashicorp/', '');\n const backendLookUpName = `terraform-provider-${hashicorpPackage}`;\n const backendURL = joinUrlParts(\n registryURL,\n backendLookUpName,\n `index.json`,\n );\n const res = (\n await this.http.getJson(backendURL, TerraformProviderReleaseBackend)\n ).body;\n\n const dep: ReleaseResult = {\n releases: Object.keys(res.versions).map((version) => ({\n version,\n })),\n sourceUrl: joinUrlParts(\n 'https://github.com/terraform-providers',\n backendLookUpName,\n ),\n };\n return dep;\n }\n\n private async _getBuilds(\n registryURL: string,\n repository: string,\n version: string,\n ): Promise<TerraformBuild[] | null> {\n if (registryURL === TerraformProviderDatasource.hashicorpReleaseUrl) {\n // check if registryURL === secondary backend\n const repositoryRegexResult =\n TerraformProviderDatasource.repositoryRegex.exec(repository)?.groups;\n if (!repositoryRegexResult) {\n // non hashicorp builds are not supported with releases.hashicorp.com\n return null;\n }\n const packageName = repositoryRegexResult.packageName;\n const backendLookUpName = `terraform-provider-${packageName}`;\n let versionReleaseBackend: VersionDetailResponse;\n try {\n versionReleaseBackend = await this.getReleaseBackendIndex(\n backendLookUpName,\n version,\n );\n } catch (err) {\n if (err instanceof ExternalHostError) {\n throw err;\n }\n logger.debug(\n { err, backendLookUpName, version },\n `Failed to retrieve builds for ${backendLookUpName} ${version}`,\n );\n // throw an error to disable caching\n throw new ExternalHostError(err);\n }\n return versionReleaseBackend.builds;\n }\n\n // check public or private Terraform registry\n const serviceDiscovery =\n await this.getTerraformServiceDiscoveryResult(registryURL);\n if (!serviceDiscovery) {\n // throw an error to disable caching\n throw new ExternalHostError(\n new Error(`Service discovery not found for ${registryURL}`),\n );\n }\n const backendURL = createSDBackendURL(\n registryURL,\n 'providers.v1',\n serviceDiscovery,\n repository,\n );\n const versionsResponse = (\n await this.http.getJson(\n `${backendURL}/versions`,\n TerraformRegistryVersions,\n )\n ).body;\n if (!versionsResponse.versions) {\n // throw an error to disable caching\n throw new ExternalHostError(\n new Error(`Failed to retrieve version list for ${backendURL}`),\n );\n }\n const builds = versionsResponse.versions.find(\n (value) => value.version === version,\n );\n if (!builds) {\n // should never happen, but just in case\n // throw an error to disable caching\n throw new ExternalHostError(\n new Error(\n `No builds found for ${repository}:${version} on ${registryURL}`,\n ),\n );\n }\n const result = await p.map(\n builds.platforms,\n async (platform) => {\n const buildURL = `${backendURL}/${version}/download/${platform.os}/${platform.arch}`;\n try {\n const res = (\n await this.http.getJson(buildURL, TerraformRegistryBuildResponse)\n ).body;\n const newBuild: TerraformBuild = {\n name: repository,\n url: res.download_url,\n version,\n ...res,\n };\n return newBuild;\n } catch (err) {\n /* v8 ignore next 3 -- hard to test */\n if (err instanceof ExternalHostError) {\n throw err;\n }\n logger.debug({ err, url: buildURL }, 'Failed to retrieve build');\n // throw an error to disable caching\n throw new ExternalHostError(err);\n }\n },\n { concurrency: 4 },\n );\n\n return result;\n }\n\n getBuilds(\n registryURL: string,\n repository: string,\n version: string,\n ): Promise<TerraformBuild[] | null> {\n return withCache(\n {\n namespace: `datasource-${TerraformProviderDatasource.id}`,\n key: `getBuilds:${registryURL}/${repository}/${version}`,\n },\n () => this._getBuilds(registryURL, repository, version),\n );\n }\n\n /**\n * A single platform's download endpoint returns the hashes for all platforms,\n * so we query `linux/amd64` and fall back to `/versions` discovery only when a\n * provider lacks that platform (404).\n * See https://github.com/opentofu/opentofu/pull/3434\n */\n private async _getProviderPackages(\n repository: string,\n version: string,\n ): Promise<string[] | null> {\n const baseUrl = joinUrlParts(\n TerraformProviderDatasource.openTofuRegistryUrl,\n 'v1/providers',\n repository,\n );\n\n try {\n try {\n const { body } = await this.http.getJson(\n `${baseUrl}/${version}/download/linux/amd64`,\n OpenTofuProviderPackagesResponse,\n );\n return body;\n } catch (err) {\n if (!(err instanceof HttpError) || err.response?.statusCode !== 404) {\n throw err;\n }\n }\n return await this._getProviderPackagesForAvailablePlatform(\n baseUrl,\n version,\n );\n } catch (err) {\n if (err instanceof ExternalHostError) {\n throw err;\n }\n logger.debug(\n { err, repository, version },\n `Failed to retrieve provider packages for ${repository}@${version}`,\n );\n throw new ExternalHostError(err);\n }\n }\n\n /**\n * Some providers do not publish a `linux/amd64` build, so discover an\n * available platform via `/versions` and fetch its download endpoint.\n */\n private async _getProviderPackagesForAvailablePlatform(\n baseUrl: string,\n version: string,\n ): Promise<string[] | null> {\n const { body: versionsResponse } = await this.http.getJson(\n `${baseUrl}/versions`,\n TerraformRegistryVersions,\n );\n const platform = versionsResponse.versions?.find(\n (entry) => entry.version === version,\n )?.platforms?.[0];\n if (!platform) {\n return null;\n }\n const { body: hashes } = await this.http.getJson(\n `${baseUrl}/${version}/download/${platform.os}/${platform.arch}`,\n OpenTofuProviderPackagesResponse,\n );\n return hashes;\n }\n\n getProviderPackages(\n repository: string,\n version: string,\n ): Promise<string[] | null> {\n return withCache(\n {\n namespace: `datasource-${TerraformProviderDatasource.id}`,\n key: `getProviderPackages:${repository}/${version}`,\n },\n () => this._getProviderPackages(repository, version),\n );\n }\n\n private async _getZipHashes(\n zipHashUrl: string,\n ): Promise<string[] | undefined> {\n // The hashes are formatted as the result of sha256sum in plain text, each line: <hash>\\t<filename>\n let rawHashData: string;\n try {\n rawHashData = (await this.http.getText(zipHashUrl)).body;\n } catch (err) {\n /* v8 ignore next 3 -- hard to test */\n if (err instanceof ExternalHostError) {\n throw err;\n }\n logger.debug(\n { err, zipHashUrl },\n `Failed to retrieve zip hashes from ${zipHashUrl}`,\n );\n return undefined;\n }\n\n return rawHashData\n .trimEnd()\n .split('\\n')\n .map((line) => line.split(regEx(/\\s/))[0]);\n }\n\n getZipHashes(zipHashUrl: string): Promise<string[] | undefined> {\n return withCache(\n {\n namespace: `datasource-${TerraformProviderDatasource.id}`,\n key: `getZipHashes:${zipHashUrl}`,\n },\n () => this._getZipHashes(zipHashUrl),\n );\n }\n\n private async _getReleaseBackendIndex(\n backendLookUpName: string,\n version: string,\n ): Promise<VersionDetailResponse> {\n return (\n await this.http.getJson(\n `${TerraformProviderDatasource.hashicorpReleaseUrl}/${backendLookUpName}/${version}/index.json`,\n VersionDetailResponse,\n )\n ).body;\n }\n\n getReleaseBackendIndex(\n backendLookUpName: string,\n version: string,\n ): Promise<VersionDetailResponse> {\n return withCache(\n {\n namespace: `datasource-${TerraformProviderDatasource.id}`,\n key: `getReleaseBackendIndex:${backendLookUpName}/${version}`,\n },\n () => this._getReleaseBackendIndex(backendLookUpName, version),\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAuBA,IAAa,8BAAb,MAAa,oCAAoC,oBAAoB;CACnE,OAAyB,KAAK;CAE9B,OAAgB,sBAAsB;CAEtC,OAAgB,sBAAsB,CACpC,4BAA4B,sBAC5B,4BAA4B,mBAC9B;CAEA,OAAO,kBAAkB,MAAM,kCAAkC;CAEjE,cAAc;EACZ,MAAM,4BAA4B,EAAE;CACtC;CAEA,sBACE,4BAA4B;CAE9B,oBAAsCA;CAEtC,mBAAqC;CAErC,0BAA4C;CAC5C,uBACE;CACF,mBAAqC;CACrC,gBACE;CAEF,MAAc,aAAa,EACzB,aACA,eACmD;;EAEnD,IAAI,CAAC,aACH,OAAO;EAET,OAAO,MACL,qDAAqD,aACvD;EAEA,IAAI,gBAAgB,4BAA4B,sBAC9C,OAAO,MAAM,KAAK,yBAAyB,aAAa,WAAW;EAErE,IACE,gBAAgB,4BAA4B,uBAC5C,gBAAgB,4BAA4B,gBAE5C,OAAO,MAAM,KAAK,sBAAsB,WAAW;EAErD,IAAI,gBAAgB,4BAA4B,qBAC9C,OAAO,MAAM,KAAK,oBAAoB,aAAa,WAAW;EAIhE,OAAO,MAAM,KAAK,sBAAsB,aAAa,WAAW;CAClE;CAEA,YAAY,QAA0D;EACpE,MAAM,MAAM,OAAO;EACnB,MAAM,OAAO,4BAA4B,cAAc,MAAM;EAC7D,OAAO,UACL;GACE,WAAW,cAAc,4BAA4B;GACrD,KAAK,eAAe,IAAI,GAAG;GAC3B,UAAU;EACZ,SACM,KAAK,aAAa,MAAM,CAChC;CACF;CAEA,OAAe,cAAc,EAAE,eAA0C;EACvE,OAAO,YAAY,SAAS,GAAG,IAAI,cAAc,aAAa;CAChE;;;;;;;CAQA,MAAc,yBACZ,aACA,aACwB;EACxB,MAAM,aAAa,4BAA4B,cAAc,EAC3D,YACF,CAAC;EACD,MAAM,cAAc,GAAG,aACrB,aACA,gBACA,UACF,EAAE,GAAG,eAAe,EAAE,SAAS,oBAAoB,CAAC;EACpD,MAAM,EAAE,MAAM,QAAQ,MAAM,KAAK,KAAK,QACpC,aACA,2BACF;EACA,IAAI,WAAW,GAAG,YAAY,aAAa;EAC3C,OAAO;CACT;;;;;;;;CASA,MAAc,sBACZ,aACwB;EACxB,MAAM,aAAa,4BAA4B,cAAc,EAC3D,YACF,CAAC;EACD,MAAM,UAAU,aACd,4BAA4B,gBAC5B,2BACA,YACA,YACF;EACA,MAAM,EAAE,MAAM,QAAQ,MAAM,KAAK,KAAK,QACpC,SACA,4BACF;EACA,IAAI,WAAW,wCAAwC;EAMvD,MAAM,CAAC,WAAW,QAAQ,WAAW,MAAM,GAAG;EAC9C,IAAI,YAAY,sBAAsB,UAAU,sBAAsB;EAEtE,OAAO;CACT;;;;;;CAOA,MAAc,sBACZ,aACA,aACwB;EACxB,MAAM,aAAa,4BAA4B,cAAc,EAC3D,YACF,CAAC;EACD,MAAM,mBACJ,MAAM,KAAK,mCAAmC,WAAW;EAC3D,MAAM,aAAa,mBACjB,aACA,gBACA,kBACA,GAAG,WAAW,UAChB;EAQA,OAAO,EAJL,WAHW,MAAM,KAAK,KAAK,QAAQ,YAAY,yBAAyB,EAAA,CACvE,KAEa,SAAS,KAAK,EAAE,eAAe,EAC3C,QACF,EAAE,EAEK;CACX;CAEA,MAAc,oBACZ,aACA,aAC+B;EAE/B,MAAM,oBAAoB,sBADD,YAAY,QAAQ,cAAc,EACI;EAC/D,MAAM,aAAa,aACjB,aACA,mBACA,YACF;EACA,MAAM,OACJ,MAAM,KAAK,KAAK,QAAQ,YAAY,+BAA+B,EAAA,CACnE;EAWF,OAAO;GARL,UAAU,OAAO,KAAK,IAAI,QAAQ,CAAC,CAAC,KAAK,aAAa,EACpD,QACF,EAAE;GACF,WAAW,aACT,0CACA,iBACF;EAEO;CACX;CAEA,MAAc,WACZ,aACA,YACA,SACkC;EAClC,IAAI,gBAAgB,4BAA4B,qBAAqB;GAEnE,MAAM,wBACJ,4BAA4B,gBAAgB,KAAK,UAAU,CAAC,EAAE;GAChE,IAAI,CAAC,uBAEH,OAAO;GAGT,MAAM,oBAAoB,sBADN,sBAAsB;GAE1C,IAAI;GACJ,IAAI;IACF,wBAAwB,MAAM,KAAK,uBACjC,mBACA,OACF;GACF,SAAS,KAAK;IACZ,IAAI,eAAe,mBACjB,MAAM;IAER,OAAO,MACL;KAAE;KAAK;KAAmB;IAAQ,GAClC,iCAAiC,kBAAkB,GAAG,SACxD;IAEA,MAAM,IAAI,kBAAkB,GAAG;GACjC;GACA,OAAO,sBAAsB;EAC/B;EAGA,MAAM,mBACJ,MAAM,KAAK,mCAAmC,WAAW;EAC3D,IAAI,CAAC,kBAEH,MAAM,IAAI,kCACR,IAAI,MAAM,mCAAmC,aAAa,CAC5D;EAEF,MAAM,aAAa,mBACjB,aACA,gBACA,kBACA,UACF;EACA,MAAM,oBACJ,MAAM,KAAK,KAAK,QACd,GAAG,WAAW,YACd,yBACF,EAAA,CACA;EACF,IAAI,CAAC,iBAAiB,UAEpB,MAAM,IAAI,kCACR,IAAI,MAAM,uCAAuC,YAAY,CAC/D;EAEF,MAAM,SAAS,iBAAiB,SAAS,MACtC,UAAU,MAAM,YAAY,OAC/B;EACA,IAAI,CAAC,QAGH,MAAM,IAAI,kCACR,IAAI,MACF,uBAAuB,WAAW,GAAG,QAAQ,MAAM,aACrD,CACF;EA8BF,OAAO,MA5BcC,IACnB,OAAO,WACP,OAAO,aAAa;GAClB,MAAM,WAAW,GAAG,WAAW,GAAG,QAAQ,YAAY,SAAS,GAAG,GAAG,SAAS;GAC9E,IAAI;IACF,MAAM,OACJ,MAAM,KAAK,KAAK,QAAQ,UAAU,8BAA8B,EAAA,CAChE;IAOF,OAAO;KALL,MAAM;KACN,KAAK,IAAI;KACT;KACA,GAAG;IAES;GAChB,SAAS,KAAK;;IAEZ,IAAI,eAAe,mBACjB,MAAM;IAER,OAAO,MAAM;KAAE;KAAK,KAAK;IAAS,GAAG,0BAA0B;IAE/D,MAAM,IAAI,kBAAkB,GAAG;GACjC;EACF,GACA,EAAE,aAAa,EAAE,CACnB;CAGF;CAEA,UACE,aACA,YACA,SACkC;EAClC,OAAO,UACL;GACE,WAAW,cAAc,4BAA4B;GACrD,KAAK,aAAa,YAAY,GAAG,WAAW,GAAG;EACjD,SACM,KAAK,WAAW,aAAa,YAAY,OAAO,CACxD;CACF;;;;;;;CAQA,MAAc,qBACZ,YACA,SAC0B;EAC1B,MAAM,UAAU,aACd,4BAA4B,qBAC5B,gBACA,UACF;EAEA,IAAI;GACF,IAAI;IACF,MAAM,EAAE,SAAS,MAAM,KAAK,KAAK,QAC/B,GAAG,QAAQ,GAAG,QAAQ,wBACtB,gCACF;IACA,OAAO;GACT,SAAS,KAAK;IACZ,IAAI,EAAE,eAAeC,iBAAc,IAAI,UAAU,eAAe,KAC9D,MAAM;GAEV;GACA,OAAO,MAAM,KAAK,yCAChB,SACA,OACF;EACF,SAAS,KAAK;GACZ,IAAI,eAAe,mBACjB,MAAM;GAER,OAAO,MACL;IAAE;IAAK;IAAY;GAAQ,GAC3B,4CAA4C,WAAW,GAAG,SAC5D;GACA,MAAM,IAAI,kBAAkB,GAAG;EACjC;CACF;;;;;CAMA,MAAc,yCACZ,SACA,SAC0B;EAC1B,MAAM,EAAE,MAAM,qBAAqB,MAAM,KAAK,KAAK,QACjD,GAAG,QAAQ,YACX,yBACF;EACA,MAAM,WAAW,iBAAiB,UAAU,MACzC,UAAU,MAAM,YAAY,OAC/B,CAAC,EAAE,YAAY;EACf,IAAI,CAAC,UACH,OAAO;EAET,MAAM,EAAE,MAAM,WAAW,MAAM,KAAK,KAAK,QACvC,GAAG,QAAQ,GAAG,QAAQ,YAAY,SAAS,GAAG,GAAG,SAAS,QAC1D,gCACF;EACA,OAAO;CACT;CAEA,oBACE,YACA,SAC0B;EAC1B,OAAO,UACL;GACE,WAAW,cAAc,4BAA4B;GACrD,KAAK,uBAAuB,WAAW,GAAG;EAC5C,SACM,KAAK,qBAAqB,YAAY,OAAO,CACrD;CACF;CAEA,MAAc,cACZ,YAC+B;EAE/B,IAAI;EACJ,IAAI;GACF,eAAe,MAAM,KAAK,KAAK,QAAQ,UAAU,EAAA,CAAG;EACtD,SAAS,KAAK;;GAEZ,IAAI,eAAe,mBACjB,MAAM;GAER,OAAO,MACL;IAAE;IAAK;GAAW,GAClB,sCAAsC,YACxC;GACA;EACF;EAEA,OAAO,YACJ,QAAQ,CAAC,CACT,MAAM,IAAI,CAAC,CACX,KAAK,SAAS,KAAK,MAAM,MAAM,IAAI,CAAC,CAAC,CAAC,EAAE;CAC7C;CAEA,aAAa,YAAmD;EAC9D,OAAO,UACL;GACE,WAAW,cAAc,4BAA4B;GACrD,KAAK,gBAAgB;EACvB,SACM,KAAK,cAAc,UAAU,CACrC;CACF;CAEA,MAAc,wBACZ,mBACA,SACgC;EAChC,QACE,MAAM,KAAK,KAAK,QACd,GAAG,4BAA4B,oBAAoB,GAAG,kBAAkB,GAAG,QAAQ,cACnF,qBACF,EAAA,CACA;CACJ;CAEA,uBACE,mBACA,SACgC;EAChC,OAAO,UACL;GACE,WAAW,cAAc,4BAA4B;GACrD,KAAK,0BAA0B,kBAAkB,GAAG;EACtD,SACM,KAAK,wBAAwB,mBAAmB,OAAO,CAC/D;CACF;AACF"}
@@ -1,9 +1,9 @@
1
1
  import { regEx } from "../../../util/regex.js";
2
2
  //#region lib/modules/manager/ansible-galaxy/util.ts
3
- const newBlockRegEx = /^\s*-\s*((\w+):\s*(.*))$/;
4
- const blockLineRegEx = /^\s*((\w+):\s*(\S+))\s*$/;
5
- const galaxyDepRegex = /[\w-]+\.[\w-]+/;
6
- const dependencyRegex = /^dependencies:/;
3
+ const newBlockRegEx = regEx(/^\s*-\s*((\w+):\s*(.*))$/);
4
+ const blockLineRegEx = regEx(/^\s*((\w+):\s*(\S+))\s*$/);
5
+ const galaxyDepRegex = regEx(/[\w-]+\.[\w-]+/);
6
+ const dependencyRegex = regEx(/^dependencies:/);
7
7
  const galaxyRegEx = regEx(/^\s+["']?(?<packageName>[\w.]+)["']?:\s*["']?(?<version>.+?)["']?\s*(\s#.*)?$/);
8
8
  const nameMatchRegex = regEx(/(?<source>((git\+)?(?:(git|ssh|https?):\/\/)?(.*@)?(?<hostname>[\w.-]+)(?:(:\d+)?\/|:))(?<depName>[\w./-]+)(?:\.git)?)(,(?<version>[\w.]*))?/);
9
9
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"util.js","names":[],"sources":["../../../../lib/modules/manager/ansible-galaxy/util.ts"],"sourcesContent":["import { regEx } from '../../../util/regex.ts';\n\nexport const newBlockRegEx = /^\\s*-\\s*((\\w+):\\s*(.*))$/;\nexport const blockLineRegEx = /^\\s*((\\w+):\\s*(\\S+))\\s*$/;\nexport const galaxyDepRegex = /[\\w-]+\\.[\\w-]+/;\nexport const dependencyRegex = /^dependencies:/;\nexport const galaxyRegEx = regEx(\n /^\\s+[\"']?(?<packageName>[\\w.]+)[\"']?:\\s*[\"']?(?<version>.+?)[\"']?\\s*(\\s#.*)?$/,\n);\nexport const nameMatchRegex = regEx(\n /(?<source>((git\\+)?(?:(git|ssh|https?):\\/\\/)?(.*@)?(?<hostname>[\\w.-]+)(?:(:\\d+)?\\/|:))(?<depName>[\\w./-]+)(?:\\.git)?)(,(?<version>[\\w.]*))?/,\n);\n"],"mappings":";;AAEA,MAAa,gBAAgB;AAC7B,MAAa,iBAAiB;AAC9B,MAAa,iBAAiB;AAC9B,MAAa,kBAAkB;AAC/B,MAAa,cAAc,MACzB,+EACF;AACA,MAAa,iBAAiB,MAC5B,8IACF"}
1
+ {"version":3,"file":"util.js","names":[],"sources":["../../../../lib/modules/manager/ansible-galaxy/util.ts"],"sourcesContent":["import { regEx } from '../../../util/regex.ts';\n\nexport const newBlockRegEx = regEx(/^\\s*-\\s*((\\w+):\\s*(.*))$/);\nexport const blockLineRegEx = regEx(/^\\s*((\\w+):\\s*(\\S+))\\s*$/);\nexport const galaxyDepRegex = regEx(/[\\w-]+\\.[\\w-]+/);\nexport const dependencyRegex = regEx(/^dependencies:/);\nexport const galaxyRegEx = regEx(\n /^\\s+[\"']?(?<packageName>[\\w.]+)[\"']?:\\s*[\"']?(?<version>.+?)[\"']?\\s*(\\s#.*)?$/,\n);\nexport const nameMatchRegex = regEx(\n /(?<source>((git\\+)?(?:(git|ssh|https?):\\/\\/)?(.*@)?(?<hostname>[\\w.-]+)(?:(:\\d+)?\\/|:))(?<depName>[\\w./-]+)(?:\\.git)?)(,(?<version>[\\w.]*))?/,\n);\n"],"mappings":";;AAEA,MAAa,gBAAgB,MAAM,0BAA0B;AAC7D,MAAa,iBAAiB,MAAM,0BAA0B;AAC9D,MAAa,iBAAiB,MAAM,gBAAgB;AACpD,MAAa,kBAAkB,MAAM,gBAAgB;AACrD,MAAa,cAAc,MACzB,+EACF;AACA,MAAa,iBAAiB,MAC5B,8IACF"}
@@ -21,7 +21,7 @@ const hugoDefinition = {
21
21
  datasource: GithubReleasesDatasource.id,
22
22
  packageName: "gohugoio/hugo",
23
23
  extractVersion: "^v(?<version>\\S+)",
24
- currentValue: version.replace(/^extended_/, "")
24
+ currentValue: version.replace(regEx(/^extended_/), "")
25
25
  })
26
26
  };
27
27
  const upgradeableTooling = {
@@ -389,25 +389,25 @@ const upgradeableTooling = {
389
389
  java: {
390
390
  asdfPluginUrl: "https://github.com/halcyon/asdf-java",
391
391
  config: (version) => {
392
- const adoptOpenJdkMatches = /^adoptopenjdk-(?<version>\d\S+)/.exec(version)?.groups;
392
+ const adoptOpenJdkMatches = regEx(/^adoptopenjdk-(?<version>\d\S+)/).exec(version)?.groups;
393
393
  if (adoptOpenJdkMatches) return {
394
394
  datasource: JavaVersionDatasource.id,
395
395
  packageName: "java-jdk",
396
396
  currentValue: adoptOpenJdkMatches.version
397
397
  };
398
- const adoptOpenJreMatches = /^adoptopenjdk-jre-(?<version>\d\S+)/.exec(version)?.groups;
398
+ const adoptOpenJreMatches = regEx(/^adoptopenjdk-jre-(?<version>\d\S+)/).exec(version)?.groups;
399
399
  if (adoptOpenJreMatches) return {
400
400
  datasource: JavaVersionDatasource.id,
401
401
  packageName: "java-jre",
402
402
  currentValue: adoptOpenJreMatches.version
403
403
  };
404
- const temurinJdkMatches = /^temurin-(?<version>\d\S+)/.exec(version)?.groups;
404
+ const temurinJdkMatches = regEx(/^temurin-(?<version>\d\S+)/).exec(version)?.groups;
405
405
  if (temurinJdkMatches) return {
406
406
  datasource: JavaVersionDatasource.id,
407
407
  packageName: "java-jdk",
408
408
  currentValue: temurinJdkMatches.version
409
409
  };
410
- const temurinJreMatches = /^temurin-jre-(?<version>\d\S+)/.exec(version)?.groups;
410
+ const temurinJreMatches = regEx(/^temurin-jre-(?<version>\d\S+)/).exec(version)?.groups;
411
411
  if (temurinJreMatches) return {
412
412
  datasource: JavaVersionDatasource.id,
413
413
  packageName: "java-jre",