renovate 43.209.4 → 43.210.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/dist/modules/datasource/bitbucket-tags/index.js +6 -5
  2. package/dist/modules/datasource/bitbucket-tags/index.js.map +1 -1
  3. package/dist/modules/datasource/bitbucket-tags/schema.js +20 -0
  4. package/dist/modules/datasource/bitbucket-tags/schema.js.map +1 -0
  5. package/dist/modules/datasource/conan/index.js +2 -2
  6. package/dist/modules/datasource/conan/index.js.map +1 -1
  7. package/dist/modules/datasource/conda/index.js +3 -3
  8. package/dist/modules/datasource/conda/index.js.map +1 -1
  9. package/dist/modules/datasource/conda/schema.js +17 -0
  10. package/dist/modules/datasource/conda/schema.js.map +1 -0
  11. package/dist/modules/datasource/crate/index.js +3 -2
  12. package/dist/modules/datasource/crate/index.js.map +1 -1
  13. package/dist/modules/datasource/crate/schema.js +8 -1
  14. package/dist/modules/datasource/crate/schema.js.map +1 -1
  15. package/dist/modules/datasource/gradle-version/index.js +2 -2
  16. package/dist/modules/datasource/gradle-version/index.js.map +1 -1
  17. package/dist/modules/datasource/gradle-version/schema.js +2 -2
  18. package/dist/modules/datasource/gradle-version/schema.js.map +1 -1
  19. package/dist/modules/datasource/jenkins-plugins/index.js +7 -6
  20. package/dist/modules/datasource/jenkins-plugins/index.js.map +1 -1
  21. package/dist/modules/datasource/jenkins-plugins/schema.js +20 -0
  22. package/dist/modules/datasource/jenkins-plugins/schema.js.map +1 -0
  23. package/dist/modules/datasource/nuget/schema.js +26 -0
  24. package/dist/modules/datasource/nuget/schema.js.map +1 -0
  25. package/dist/modules/datasource/nuget/v3.js +7 -4
  26. package/dist/modules/datasource/nuget/v3.js.map +1 -1
  27. package/dist/modules/datasource/puppet-forge/index.js +5 -18
  28. package/dist/modules/datasource/puppet-forge/index.js.map +1 -1
  29. package/dist/modules/datasource/puppet-forge/schema.js +28 -0
  30. package/dist/modules/datasource/puppet-forge/schema.js.map +1 -0
  31. package/dist/modules/datasource/repology/index.js +2 -1
  32. package/dist/modules/datasource/repology/index.js.map +1 -1
  33. package/dist/modules/datasource/repology/schema.js +14 -0
  34. package/dist/modules/datasource/repology/schema.js.map +1 -0
  35. package/dist/modules/datasource/terraform-provider/index.js +6 -6
  36. package/dist/modules/datasource/terraform-provider/index.js.map +1 -1
  37. package/dist/modules/datasource/terraform-provider/schema.js +37 -1
  38. package/dist/modules/datasource/terraform-provider/schema.js.map +1 -1
  39. package/dist/modules/manager/fingerprint.generated.js +1 -1
  40. package/dist/modules/manager/fingerprint.generated.js.map +1 -1
  41. package/dist/modules/manager/npm/extract/pnpm.js +2 -2
  42. package/dist/modules/manager/npm/extract/pnpm.js.map +1 -1
  43. package/dist/modules/manager/terraform/lockfile/hash.js.map +1 -1
  44. package/dist/modules/platform/azure/azure-got-wrapper.js +4 -1
  45. package/dist/modules/platform/azure/azure-got-wrapper.js.map +1 -1
  46. package/dist/modules/platform/azure/index.js +13 -16
  47. package/dist/modules/platform/azure/index.js.map +1 -1
  48. package/dist/modules/platform/azure/issue.js +197 -0
  49. package/dist/modules/platform/azure/issue.js.map +1 -0
  50. package/dist/modules/platform/azure/types.js.map +1 -1
  51. package/dist/modules/platform/azure/util.js +6 -1
  52. package/dist/modules/platform/azure/util.js.map +1 -1
  53. package/dist/modules/platform/types.d.ts +2 -0
  54. package/dist/util/merge-confidence/index.js +2 -1
  55. package/dist/util/merge-confidence/index.js.map +1 -1
  56. package/dist/util/merge-confidence/schema.js +7 -0
  57. package/dist/util/merge-confidence/schema.js.map +1 -0
  58. package/package.json +2 -2
@@ -4,6 +4,7 @@ import { asTimestamp } from "../../../util/timestamp.js";
4
4
  import { Datasource } from "../datasource.js";
5
5
  import { BitbucketHttp } from "../../../util/http/bitbucket.js";
6
6
  import { RepoInfo } from "../../platform/bitbucket/schema.js";
7
+ import { BitbucketCommits, BitbucketTag, BitbucketTags } from "./schema.js";
7
8
  //#region lib/modules/datasource/bitbucket-tags/index.ts
8
9
  var BitbucketTagsDatasource = class BitbucketTagsDatasource extends Datasource {
9
10
  static id = "bitbucket-tags";
@@ -30,7 +31,7 @@ var BitbucketTagsDatasource = class BitbucketTagsDatasource extends Datasource {
30
31
  }
31
32
  async _getReleases({ registryUrl, packageName: repo }) {
32
33
  const url = `/2.0/repositories/${repo}/refs/tags`;
33
- const bitbucketTags = (await this.bitbucketHttp.getJsonUnchecked(url, { paginate: true })).body.values;
34
+ const bitbucketTags = (await this.bitbucketHttp.getJson(url, { paginate: true }, BitbucketTags)).body;
34
35
  return {
35
36
  sourceUrl: BitbucketTagsDatasource.getSourceUrl(repo, registryUrl),
36
37
  registryUrl: BitbucketTagsDatasource.getRegistryURL(registryUrl),
@@ -50,7 +51,7 @@ var BitbucketTagsDatasource = class BitbucketTagsDatasource extends Datasource {
50
51
  }
51
52
  async _getTagCommit(_registryUrl, repo, tag) {
52
53
  const url = `/2.0/repositories/${repo}/refs/tags/${tag}`;
53
- return (await this.bitbucketHttp.getJsonUnchecked(url)).body.target?.hash ?? null;
54
+ return (await this.bitbucketHttp.getJson(url, BitbucketTag)).body.target?.hash ?? null;
54
55
  }
55
56
  getTagCommit(registryUrl, repo, tag) {
56
57
  return withCache({
@@ -71,9 +72,9 @@ var BitbucketTagsDatasource = class BitbucketTagsDatasource extends Datasource {
71
72
  async _getDigest({ packageName: repo, registryUrl }, newValue) {
72
73
  if (newValue?.length) return this.getTagCommit(registryUrl, repo, newValue);
73
74
  const url = `/2.0/repositories/${repo}/commits/${await this.getMainBranch(BitbucketTagsDatasource.getRegistryURL(registryUrl), repo)}`;
74
- const bitbucketCommits = (await this.bitbucketHttp.getJsonUnchecked(url)).body;
75
- if (bitbucketCommits.values.length === 0) return null;
76
- return bitbucketCommits.values[0].hash;
75
+ const bitbucketCommits = (await this.bitbucketHttp.getJson(url, BitbucketCommits)).body;
76
+ if (bitbucketCommits.length === 0) return null;
77
+ return bitbucketCommits[0].hash;
77
78
  }
78
79
  getDigest(config, newValue) {
79
80
  return withCache({
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../lib/modules/datasource/bitbucket-tags/index.ts"],"sourcesContent":["import type { PackageCacheNamespace } from '../../../util/cache/package/types.ts';\nimport { withCache } from '../../../util/cache/package/with-cache.ts';\nimport { BitbucketHttp } from '../../../util/http/bitbucket.ts';\nimport { asTimestamp } from '../../../util/timestamp.ts';\nimport { ensureTrailingSlash } from '../../../util/url.ts';\nimport { RepoInfo } from '../../platform/bitbucket/schema.ts';\nimport type { PagedResult } from '../../platform/bitbucket/types.ts';\nimport { Datasource } from '../datasource.ts';\nimport type {\n DigestConfig,\n GetReleasesConfig,\n ReleaseResult,\n} from '../types.ts';\nimport type { BitbucketCommit, BitbucketTag } from './types.ts';\n\nexport class BitbucketTagsDatasource extends Datasource {\n static readonly id = 'bitbucket-tags';\n\n bitbucketHttp = new BitbucketHttp(BitbucketTagsDatasource.id);\n\n static readonly customRegistrySupport = true;\n\n static readonly registryStrategy = 'first';\n\n static readonly defaultRegistryUrls = ['https://bitbucket.org'];\n\n static readonly releaseTimestampSupport = true;\n static readonly releaseTimestampNote =\n 'The release timestamp is determined from the `date` field in the results.';\n static readonly sourceUrlSupport = 'package';\n static readonly sourceUrlNote =\n 'The source URL is determined by using the `packageName` and `registryUrl`.';\n\n static readonly cacheNamespace: PackageCacheNamespace = `datasource-${BitbucketTagsDatasource.id}`;\n\n constructor() {\n super(BitbucketTagsDatasource.id);\n }\n\n static getRegistryURL(registryUrl?: string): string {\n // fallback to default API endpoint if custom not provided\n return registryUrl ?? this.defaultRegistryUrls[0];\n }\n\n static getCacheKey(\n registryUrl: string | undefined,\n repo: string,\n type: string,\n ): string {\n return `${BitbucketTagsDatasource.getRegistryURL(\n registryUrl,\n )}:${repo}:${type}`;\n }\n\n static getSourceUrl(packageName: string, registryUrl?: string): string {\n const url = BitbucketTagsDatasource.getRegistryURL(registryUrl);\n const normalizedUrl = ensureTrailingSlash(url);\n return `${normalizedUrl}${packageName}`;\n }\n\n // getReleases fetches list of tags for the repository\n private async _getReleases({\n registryUrl,\n packageName: repo,\n }: GetReleasesConfig): Promise<ReleaseResult | null> {\n const url = `/2.0/repositories/${repo}/refs/tags`;\n const bitbucketTags = (\n await this.bitbucketHttp.getJsonUnchecked<PagedResult<BitbucketTag>>(\n url,\n {\n paginate: true,\n },\n )\n ).body.values;\n\n const dependency: ReleaseResult = {\n sourceUrl: BitbucketTagsDatasource.getSourceUrl(repo, registryUrl),\n registryUrl: BitbucketTagsDatasource.getRegistryURL(registryUrl),\n releases: bitbucketTags.map(({ name, target }) => ({\n version: name,\n gitRef: name,\n releaseTimestamp: asTimestamp(target?.date),\n })),\n };\n\n return dependency;\n }\n\n getReleases(config: GetReleasesConfig): Promise<ReleaseResult | null> {\n return withCache(\n {\n namespace: BitbucketTagsDatasource.cacheNamespace,\n key: BitbucketTagsDatasource.getCacheKey(\n config.registryUrl,\n config.packageName,\n 'tags',\n ),\n fallback: true,\n },\n () => this._getReleases(config),\n );\n }\n\n // getTagCommit fetched the commit has for specified tag\n private async _getTagCommit(\n _registryUrl: string | undefined,\n repo: string,\n tag: string,\n ): Promise<string | null> {\n const url = `/2.0/repositories/${repo}/refs/tags/${tag}`;\n\n const bitbucketTag = (\n await this.bitbucketHttp.getJsonUnchecked<BitbucketTag>(url)\n ).body;\n\n return bitbucketTag.target?.hash ?? null;\n }\n\n getTagCommit(\n registryUrl: string | undefined,\n repo: string,\n tag: string,\n ): Promise<string | null> {\n return withCache(\n {\n namespace: BitbucketTagsDatasource.cacheNamespace,\n key: BitbucketTagsDatasource.getCacheKey(\n registryUrl,\n repo,\n `tag-${tag}`,\n ),\n },\n () => this._getTagCommit(registryUrl, repo, tag),\n );\n }\n\n private async _getMainBranch(\n _registryUrl: string,\n repo: string,\n ): Promise<string> {\n return (\n await this.bitbucketHttp.getJson(`/2.0/repositories/${repo}`, RepoInfo)\n ).body.mainbranch;\n }\n\n getMainBranch(registryUrl: string, repo: string): Promise<string> {\n return withCache(\n {\n namespace: BitbucketTagsDatasource.cacheNamespace,\n key: BitbucketTagsDatasource.getCacheKey(\n registryUrl,\n repo,\n 'mainbranch',\n ),\n ttlMinutes: 60,\n },\n () => this._getMainBranch(registryUrl, repo),\n );\n }\n\n // getDigest fetched the latest commit for repository main branch\n // however, if newValue is provided, then getTagCommit is called\n private async _getDigest(\n { packageName: repo, registryUrl }: DigestConfig,\n newValue?: string,\n ): Promise<string | null> {\n if (newValue?.length) {\n return this.getTagCommit(registryUrl, repo, newValue);\n }\n\n const mainBranch = await this.getMainBranch(\n BitbucketTagsDatasource.getRegistryURL(registryUrl),\n repo,\n );\n\n const url = `/2.0/repositories/${repo}/commits/${mainBranch}`;\n const bitbucketCommits = (\n await this.bitbucketHttp.getJsonUnchecked<PagedResult<BitbucketCommit>>(\n url,\n )\n ).body;\n\n if (bitbucketCommits.values.length === 0) {\n return null;\n }\n\n return bitbucketCommits.values[0].hash;\n }\n\n override getDigest(\n config: DigestConfig,\n newValue?: string,\n ): Promise<string | null> {\n return withCache(\n {\n namespace: BitbucketTagsDatasource.cacheNamespace,\n key: BitbucketTagsDatasource.getCacheKey(\n config.registryUrl,\n config.packageName,\n 'digest',\n ),\n fallback: true,\n },\n () => this._getDigest(config, newValue),\n );\n }\n}\n"],"mappings":";;;;;;;AAeA,IAAa,0BAAb,MAAa,gCAAgC,WAAW;CACtD,OAAgB,KAAK;CAErB,gBAAgB,IAAI,cAAc,wBAAwB,EAAE;CAE5D,OAAgB,wBAAwB;CAExC,OAAgB,mBAAmB;CAEnC,OAAgB,sBAAsB,CAAC,uBAAuB;CAE9D,OAAgB,0BAA0B;CAC1C,OAAgB,uBACd;CACF,OAAgB,mBAAmB;CACnC,OAAgB,gBACd;CAEF,OAAgB,iBAAwC,cAAc,wBAAwB;CAE9F,cAAc;EACZ,MAAM,wBAAwB,EAAE;CAClC;CAEA,OAAO,eAAe,aAA8B;EAElD,OAAO,eAAe,KAAK,oBAAoB;CACjD;CAEA,OAAO,YACL,aACA,MACA,MACQ;EACR,OAAO,GAAG,wBAAwB,eAChC,WACF,EAAE,GAAG,KAAK,GAAG;CACf;CAEA,OAAO,aAAa,aAAqB,aAA8B;EAGrE,OAAO,GADe,oBADV,wBAAwB,eAAe,WACP,CACtB,IAAI;CAC5B;CAGA,MAAc,aAAa,EACzB,aACA,aAAa,QACsC;EACnD,MAAM,MAAM,qBAAqB,KAAK;EACtC,MAAM,iBACJ,MAAM,KAAK,cAAc,iBACvB,KACA,EACE,UAAU,KACZ,CACF,GACA,KAAK;EAYP,OAAO;GATL,WAAW,wBAAwB,aAAa,MAAM,WAAW;GACjE,aAAa,wBAAwB,eAAe,WAAW;GAC/D,UAAU,cAAc,KAAK,EAAE,MAAM,cAAc;IACjD,SAAS;IACT,QAAQ;IACR,kBAAkB,YAAY,QAAQ,IAAI;GAC5C,EAAE;EAGY;CAClB;CAEA,YAAY,QAA0D;EACpE,OAAO,UACL;GACE,WAAW,wBAAwB;GACnC,KAAK,wBAAwB,YAC3B,OAAO,aACP,OAAO,aACP,MACF;GACA,UAAU;EACZ,SACM,KAAK,aAAa,MAAM,CAChC;CACF;CAGA,MAAc,cACZ,cACA,MACA,KACwB;EACxB,MAAM,MAAM,qBAAqB,KAAK,aAAa;EAMnD,QAHE,MAAM,KAAK,cAAc,iBAA+B,GAAG,GAC3D,KAEkB,QAAQ,QAAQ;CACtC;CAEA,aACE,aACA,MACA,KACwB;EACxB,OAAO,UACL;GACE,WAAW,wBAAwB;GACnC,KAAK,wBAAwB,YAC3B,aACA,MACA,OAAO,KACT;EACF,SACM,KAAK,cAAc,aAAa,MAAM,GAAG,CACjD;CACF;CAEA,MAAc,eACZ,cACA,MACiB;EACjB,QACE,MAAM,KAAK,cAAc,QAAQ,qBAAqB,QAAQ,QAAQ,GACtE,KAAK;CACT;CAEA,cAAc,aAAqB,MAA+B;EAChE,OAAO,UACL;GACE,WAAW,wBAAwB;GACnC,KAAK,wBAAwB,YAC3B,aACA,MACA,YACF;GACA,YAAY;EACd,SACM,KAAK,eAAe,aAAa,IAAI,CAC7C;CACF;CAIA,MAAc,WACZ,EAAE,aAAa,MAAM,eACrB,UACwB;EACxB,IAAI,UAAU,QACZ,OAAO,KAAK,aAAa,aAAa,MAAM,QAAQ;EAQtD,MAAM,MAAM,qBAAqB,KAAK,WAAW,MALxB,KAAK,cAC5B,wBAAwB,eAAe,WAAW,GAClD,IACF;EAGA,MAAM,oBACJ,MAAM,KAAK,cAAc,iBACvB,GACF,GACA;EAEF,IAAI,iBAAiB,OAAO,WAAW,GACrC,OAAO;EAGT,OAAO,iBAAiB,OAAO,GAAG;CACpC;CAEA,UACE,QACA,UACwB;EACxB,OAAO,UACL;GACE,WAAW,wBAAwB;GACnC,KAAK,wBAAwB,YAC3B,OAAO,aACP,OAAO,aACP,QACF;GACA,UAAU;EACZ,SACM,KAAK,WAAW,QAAQ,QAAQ,CACxC;CACF;AACF"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../lib/modules/datasource/bitbucket-tags/index.ts"],"sourcesContent":["import type { PackageCacheNamespace } from '../../../util/cache/package/types.ts';\nimport { withCache } from '../../../util/cache/package/with-cache.ts';\nimport { BitbucketHttp } from '../../../util/http/bitbucket.ts';\nimport { asTimestamp } from '../../../util/timestamp.ts';\nimport { ensureTrailingSlash } from '../../../util/url.ts';\nimport { RepoInfo } from '../../platform/bitbucket/schema.ts';\nimport { Datasource } from '../datasource.ts';\nimport type {\n DigestConfig,\n GetReleasesConfig,\n ReleaseResult,\n} from '../types.ts';\nimport { BitbucketCommits, BitbucketTag, BitbucketTags } from './schema.ts';\n\nexport class BitbucketTagsDatasource extends Datasource {\n static readonly id = 'bitbucket-tags';\n\n bitbucketHttp = new BitbucketHttp(BitbucketTagsDatasource.id);\n\n static readonly customRegistrySupport = true;\n\n static readonly registryStrategy = 'first';\n\n static readonly defaultRegistryUrls = ['https://bitbucket.org'];\n\n static readonly releaseTimestampSupport = true;\n static readonly releaseTimestampNote =\n 'The release timestamp is determined from the `date` field in the results.';\n static readonly sourceUrlSupport = 'package';\n static readonly sourceUrlNote =\n 'The source URL is determined by using the `packageName` and `registryUrl`.';\n\n static readonly cacheNamespace: PackageCacheNamespace = `datasource-${BitbucketTagsDatasource.id}`;\n\n constructor() {\n super(BitbucketTagsDatasource.id);\n }\n\n static getRegistryURL(registryUrl?: string): string {\n // fallback to default API endpoint if custom not provided\n return registryUrl ?? this.defaultRegistryUrls[0];\n }\n\n static getCacheKey(\n registryUrl: string | undefined,\n repo: string,\n type: string,\n ): string {\n return `${BitbucketTagsDatasource.getRegistryURL(\n registryUrl,\n )}:${repo}:${type}`;\n }\n\n static getSourceUrl(packageName: string, registryUrl?: string): string {\n const url = BitbucketTagsDatasource.getRegistryURL(registryUrl);\n const normalizedUrl = ensureTrailingSlash(url);\n return `${normalizedUrl}${packageName}`;\n }\n\n // getReleases fetches list of tags for the repository\n private async _getReleases({\n registryUrl,\n packageName: repo,\n }: GetReleasesConfig): Promise<ReleaseResult | null> {\n const url = `/2.0/repositories/${repo}/refs/tags`;\n const bitbucketTags = (\n await this.bitbucketHttp.getJson(url, { paginate: true }, BitbucketTags)\n ).body;\n\n const dependency: ReleaseResult = {\n sourceUrl: BitbucketTagsDatasource.getSourceUrl(repo, registryUrl),\n registryUrl: BitbucketTagsDatasource.getRegistryURL(registryUrl),\n releases: bitbucketTags.map(({ name, target }) => ({\n version: name,\n gitRef: name,\n releaseTimestamp: asTimestamp(target?.date),\n })),\n };\n\n return dependency;\n }\n\n getReleases(config: GetReleasesConfig): Promise<ReleaseResult | null> {\n return withCache(\n {\n namespace: BitbucketTagsDatasource.cacheNamespace,\n key: BitbucketTagsDatasource.getCacheKey(\n config.registryUrl,\n config.packageName,\n 'tags',\n ),\n fallback: true,\n },\n () => this._getReleases(config),\n );\n }\n\n // getTagCommit fetched the commit has for specified tag\n private async _getTagCommit(\n _registryUrl: string | undefined,\n repo: string,\n tag: string,\n ): Promise<string | null> {\n const url = `/2.0/repositories/${repo}/refs/tags/${tag}`;\n\n const bitbucketTag = (await this.bitbucketHttp.getJson(url, BitbucketTag))\n .body;\n\n return bitbucketTag.target?.hash ?? null;\n }\n\n getTagCommit(\n registryUrl: string | undefined,\n repo: string,\n tag: string,\n ): Promise<string | null> {\n return withCache(\n {\n namespace: BitbucketTagsDatasource.cacheNamespace,\n key: BitbucketTagsDatasource.getCacheKey(\n registryUrl,\n repo,\n `tag-${tag}`,\n ),\n },\n () => this._getTagCommit(registryUrl, repo, tag),\n );\n }\n\n private async _getMainBranch(\n _registryUrl: string,\n repo: string,\n ): Promise<string> {\n return (\n await this.bitbucketHttp.getJson(`/2.0/repositories/${repo}`, RepoInfo)\n ).body.mainbranch;\n }\n\n getMainBranch(registryUrl: string, repo: string): Promise<string> {\n return withCache(\n {\n namespace: BitbucketTagsDatasource.cacheNamespace,\n key: BitbucketTagsDatasource.getCacheKey(\n registryUrl,\n repo,\n 'mainbranch',\n ),\n ttlMinutes: 60,\n },\n () => this._getMainBranch(registryUrl, repo),\n );\n }\n\n // getDigest fetched the latest commit for repository main branch\n // however, if newValue is provided, then getTagCommit is called\n private async _getDigest(\n { packageName: repo, registryUrl }: DigestConfig,\n newValue?: string,\n ): Promise<string | null> {\n if (newValue?.length) {\n return this.getTagCommit(registryUrl, repo, newValue);\n }\n\n const mainBranch = await this.getMainBranch(\n BitbucketTagsDatasource.getRegistryURL(registryUrl),\n repo,\n );\n\n const url = `/2.0/repositories/${repo}/commits/${mainBranch}`;\n const bitbucketCommits = (\n await this.bitbucketHttp.getJson(url, BitbucketCommits)\n ).body;\n\n if (bitbucketCommits.length === 0) {\n return null;\n }\n\n return bitbucketCommits[0].hash;\n }\n\n override getDigest(\n config: DigestConfig,\n newValue?: string,\n ): Promise<string | null> {\n return withCache(\n {\n namespace: BitbucketTagsDatasource.cacheNamespace,\n key: BitbucketTagsDatasource.getCacheKey(\n config.registryUrl,\n config.packageName,\n 'digest',\n ),\n fallback: true,\n },\n () => this._getDigest(config, newValue),\n );\n }\n}\n"],"mappings":";;;;;;;;AAcA,IAAa,0BAAb,MAAa,gCAAgC,WAAW;CACtD,OAAgB,KAAK;CAErB,gBAAgB,IAAI,cAAc,wBAAwB,EAAE;CAE5D,OAAgB,wBAAwB;CAExC,OAAgB,mBAAmB;CAEnC,OAAgB,sBAAsB,CAAC,uBAAuB;CAE9D,OAAgB,0BAA0B;CAC1C,OAAgB,uBACd;CACF,OAAgB,mBAAmB;CACnC,OAAgB,gBACd;CAEF,OAAgB,iBAAwC,cAAc,wBAAwB;CAE9F,cAAc;EACZ,MAAM,wBAAwB,EAAE;CAClC;CAEA,OAAO,eAAe,aAA8B;EAElD,OAAO,eAAe,KAAK,oBAAoB;CACjD;CAEA,OAAO,YACL,aACA,MACA,MACQ;EACR,OAAO,GAAG,wBAAwB,eAChC,WACF,EAAE,GAAG,KAAK,GAAG;CACf;CAEA,OAAO,aAAa,aAAqB,aAA8B;EAGrE,OAAO,GADe,oBADV,wBAAwB,eAAe,WACP,CACtB,IAAI;CAC5B;CAGA,MAAc,aAAa,EACzB,aACA,aAAa,QACsC;EACnD,MAAM,MAAM,qBAAqB,KAAK;EACtC,MAAM,iBACJ,MAAM,KAAK,cAAc,QAAQ,KAAK,EAAE,UAAU,KAAK,GAAG,aAAa,GACvE;EAYF,OAAO;GATL,WAAW,wBAAwB,aAAa,MAAM,WAAW;GACjE,aAAa,wBAAwB,eAAe,WAAW;GAC/D,UAAU,cAAc,KAAK,EAAE,MAAM,cAAc;IACjD,SAAS;IACT,QAAQ;IACR,kBAAkB,YAAY,QAAQ,IAAI;GAC5C,EAAE;EAGY;CAClB;CAEA,YAAY,QAA0D;EACpE,OAAO,UACL;GACE,WAAW,wBAAwB;GACnC,KAAK,wBAAwB,YAC3B,OAAO,aACP,OAAO,aACP,MACF;GACA,UAAU;EACZ,SACM,KAAK,aAAa,MAAM,CAChC;CACF;CAGA,MAAc,cACZ,cACA,MACA,KACwB;EACxB,MAAM,MAAM,qBAAqB,KAAK,aAAa;EAKnD,QAHsB,MAAM,KAAK,cAAc,QAAQ,KAAK,YAAY,GACrE,KAEiB,QAAQ,QAAQ;CACtC;CAEA,aACE,aACA,MACA,KACwB;EACxB,OAAO,UACL;GACE,WAAW,wBAAwB;GACnC,KAAK,wBAAwB,YAC3B,aACA,MACA,OAAO,KACT;EACF,SACM,KAAK,cAAc,aAAa,MAAM,GAAG,CACjD;CACF;CAEA,MAAc,eACZ,cACA,MACiB;EACjB,QACE,MAAM,KAAK,cAAc,QAAQ,qBAAqB,QAAQ,QAAQ,GACtE,KAAK;CACT;CAEA,cAAc,aAAqB,MAA+B;EAChE,OAAO,UACL;GACE,WAAW,wBAAwB;GACnC,KAAK,wBAAwB,YAC3B,aACA,MACA,YACF;GACA,YAAY;EACd,SACM,KAAK,eAAe,aAAa,IAAI,CAC7C;CACF;CAIA,MAAc,WACZ,EAAE,aAAa,MAAM,eACrB,UACwB;EACxB,IAAI,UAAU,QACZ,OAAO,KAAK,aAAa,aAAa,MAAM,QAAQ;EAQtD,MAAM,MAAM,qBAAqB,KAAK,WAAW,MALxB,KAAK,cAC5B,wBAAwB,eAAe,WAAW,GAClD,IACF;EAGA,MAAM,oBACJ,MAAM,KAAK,cAAc,QAAQ,KAAK,gBAAgB,GACtD;EAEF,IAAI,iBAAiB,WAAW,GAC9B,OAAO;EAGT,OAAO,iBAAiB,GAAG;CAC7B;CAEA,UACE,QACA,UACwB;EACxB,OAAO,UACL;GACE,WAAW,wBAAwB;GACnC,KAAK,wBAAwB,YAC3B,OAAO,aACP,OAAO,aACP,QACF;GACA,UAAU;EACZ,SACM,KAAK,WAAW,QAAQ,QAAQ,CACxC;CACF;AACF"}
@@ -0,0 +1,20 @@
1
+ import { LooseArray } from "../../../util/schema-utils/index.js";
2
+ import { z } from "zod/v4";
3
+ //#region lib/modules/datasource/bitbucket-tags/schema.ts
4
+ const BitbucketTag = z.object({
5
+ name: z.string(),
6
+ target: z.object({
7
+ date: z.string().optional(),
8
+ hash: z.string().optional()
9
+ }).optional()
10
+ });
11
+ const BitbucketTags = z.object({ values: LooseArray(BitbucketTag) }).transform((body) => body.values);
12
+ const BitbucketCommit = z.object({
13
+ hash: z.string(),
14
+ date: z.string().optional()
15
+ });
16
+ const BitbucketCommits = z.object({ values: LooseArray(BitbucketCommit) }).transform((body) => body.values);
17
+ //#endregion
18
+ export { BitbucketCommits, BitbucketTag, BitbucketTags };
19
+
20
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","names":[],"sources":["../../../../lib/modules/datasource/bitbucket-tags/schema.ts"],"sourcesContent":["import { z } from 'zod/v4';\nimport { LooseArray } from '../../../util/schema-utils/index.ts';\n\nexport const BitbucketTag = z.object({\n name: z.string(),\n target: z\n .object({\n date: z.string().optional(),\n hash: z.string().optional(),\n })\n .optional(),\n});\n\nexport const BitbucketTags = z\n .object({\n values: LooseArray(BitbucketTag),\n })\n .transform((body) => body.values);\n\nconst BitbucketCommit = z.object({\n hash: z.string(),\n date: z.string().optional(),\n});\n\nexport const BitbucketCommits = z\n .object({\n values: LooseArray(BitbucketCommit),\n })\n .transform((body) => body.values);\n"],"mappings":";;;AAGA,MAAa,eAAe,EAAE,OAAO;CACnC,MAAM,EAAE,OAAO;CACf,QAAQ,EACL,OAAO;EACN,MAAM,EAAE,OAAO,EAAE,SAAS;EAC1B,MAAM,EAAE,OAAO,EAAE,SAAS;CAC5B,CAAC,EACA,SAAS;AACd,CAAC;AAED,MAAa,gBAAgB,EAC1B,OAAO,EACN,QAAQ,WAAW,YAAY,EACjC,CAAC,EACA,WAAW,SAAS,KAAK,MAAM;AAElC,MAAM,kBAAkB,EAAE,OAAO;CAC/B,MAAM,EAAE,OAAO;CACf,MAAM,EAAE,OAAO,EAAE,SAAS;AAC5B,CAAC;AAED,MAAa,mBAAmB,EAC7B,OAAO,EACN,QAAQ,WAAW,eAAe,EACpC,CAAC,EACA,WAAW,SAAS,KAAK,MAAM"}
@@ -61,8 +61,8 @@ var ConanDatasource = class ConanDatasource extends Datasource {
61
61
  const url = ensureTrailingSlash(registryUrl);
62
62
  const lookupUrl = joinUrlParts(url, `v2/conans/search?q=${conanPackage.conanName}`);
63
63
  try {
64
- const rep = await this.http.getJsonUnchecked(lookupUrl);
65
- const conanJson = ConanJSON.parse(rep.body);
64
+ const rep = await this.http.getJson(lookupUrl, ConanJSON);
65
+ const conanJson = rep.body;
66
66
  if (conanJson) {
67
67
  logger.trace({ lookupUrl }, "Got conan api result");
68
68
  const dep = { releases: [] };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["allVersioning.get"],"sources":["../../../../lib/modules/datasource/conan/index.ts"],"sourcesContent":["import { isString, isUndefined } from '@sindresorhus/is';\nimport { logger } from '../../../logger/index.ts';\nimport { withCache } from '../../../util/cache/package/with-cache.ts';\nimport { GithubHttp } from '../../../util/http/github.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { ensureTrailingSlash, joinUrlParts } from '../../../util/url.ts';\nimport * as allVersioning from '../../versioning/index.ts';\nimport { Datasource } from '../datasource.ts';\nimport type {\n DigestConfig,\n GetReleasesConfig,\n Release,\n ReleaseResult,\n} from '../types.ts';\nimport { isArtifactoryServer } from '../util.ts';\nimport { datasource, defaultRegistryUrl, getConanPackage } from './common.ts';\nimport {\n ConanCenterReleases,\n ConanJSON,\n ConanLatestRevision,\n ConanProperties,\n ConanRevisionJSON,\n} from './schema.ts';\n\nexport class ConanDatasource extends Datasource {\n static readonly id = datasource;\n\n override readonly defaultRegistryUrls = [defaultRegistryUrl];\n\n override readonly caching = true;\n\n override readonly registryStrategy = 'merge';\n\n githubHttp: GithubHttp;\n\n override readonly sourceUrlSupport = 'package';\n override readonly sourceUrlNote =\n 'The source URL is supported only if the package is served from the Artifactory servers. In which case we determine it from the `properties[conan.package.url]` field in the results.';\n\n constructor(id = ConanDatasource.id) {\n super(id);\n this.githubHttp = new GithubHttp(id);\n }\n\n async getConanCenterReleases(\n conanName: string,\n userAndChannel: string,\n ): Promise<ReleaseResult | null> {\n if (userAndChannel && userAndChannel !== '@_/_') {\n logger.debug(\n { conanName, userAndChannel },\n 'User/channel not supported for Conan Center lookups',\n );\n return null;\n }\n const url = `https://api.github.com/repos/conan-io/conan-center-index/contents/recipes/${conanName}/config.yml`;\n const { body: result } = await this.githubHttp.getYaml(\n url,\n { headers: { accept: 'application/vnd.github.v3.raw' } },\n ConanCenterReleases,\n );\n return result;\n }\n\n private async _getDigest(\n { registryUrl, packageName }: DigestConfig,\n newValue?: string,\n ): Promise<string | null> {\n if (isUndefined(newValue) || isUndefined(registryUrl)) {\n return null;\n }\n const url = ensureTrailingSlash(registryUrl);\n const conanPackage = getConanPackage(packageName);\n const revisionLookUp = joinUrlParts(\n url,\n 'v2/conans/',\n conanPackage.conanName,\n newValue,\n conanPackage.userAndChannel,\n '/revisions',\n );\n const { body: digest } = await this.http.getJson(\n revisionLookUp,\n ConanLatestRevision,\n );\n return digest;\n }\n\n override getDigest(\n config: DigestConfig,\n newValue?: string,\n ): Promise<string | null> {\n return withCache(\n {\n namespace: `datasource-${datasource}`,\n // TODO: types (#22198)\n key: `getDigest:${config.registryUrl!}:${config.packageName}:${newValue!}`,\n fallback: true,\n },\n () => this._getDigest(config, newValue),\n );\n }\n\n private async _getReleases({\n registryUrl,\n packageName,\n }: GetReleasesConfig): Promise<ReleaseResult | null> {\n const conanPackage = getConanPackage(packageName);\n const userAndChannel = `@${conanPackage.userAndChannel}`;\n if (\n isString(registryUrl) &&\n ensureTrailingSlash(registryUrl) === defaultRegistryUrl\n ) {\n return this.getConanCenterReleases(\n conanPackage.conanName,\n userAndChannel,\n );\n }\n\n logger.trace(\n { packageName, registryUrl },\n 'Looking up conan api dependency',\n );\n\n if (registryUrl) {\n const url = ensureTrailingSlash(registryUrl);\n const lookupUrl = joinUrlParts(\n url,\n `v2/conans/search?q=${conanPackage.conanName}`,\n );\n\n try {\n const rep = await this.http.getJsonUnchecked(lookupUrl);\n const conanJson = ConanJSON.parse(rep.body);\n if (conanJson) {\n logger.trace({ lookupUrl }, 'Got conan api result');\n const dep: ReleaseResult = { releases: [] };\n\n const conanJsonReleases: Release[] = conanJson\n .filter(({ userChannel }) => userChannel === userAndChannel)\n .map(({ version }) => ({ version }));\n dep.releases.push(...conanJsonReleases);\n\n try {\n if (isArtifactoryServer(rep)) {\n const conanApiRegexp = regEx(\n /(?<host>.*)\\/artifactory\\/api\\/conan\\/(?<repo>[^/]+)/,\n );\n const groups = conanApiRegexp.exec(url)?.groups;\n if (!groups) {\n return dep;\n }\n const semver = allVersioning.get('semver');\n\n const sortedReleases = dep.releases\n .filter((release) => semver.isVersion(release.version))\n .sort((a, b) => semver.sortVersions(a.version, b.version));\n\n const latestVersion = sortedReleases.at(-1)?.version;\n\n if (!latestVersion) {\n return dep;\n }\n logger.debug(\n `Conan package ${packageName} has latest version ${latestVersion}`,\n );\n\n const latestRevisionUrl = joinUrlParts(\n url,\n `v2/conans/${conanPackage.conanName}/${latestVersion}/${conanPackage.userAndChannel}/latest`,\n );\n const {\n body: { revision: packageRev },\n } = await this.http.getJson(latestRevisionUrl, ConanRevisionJSON);\n\n const [user, channel] = conanPackage.userAndChannel.split('/');\n const packageUrl = joinUrlParts(\n `${groups.host}/artifactory/api/storage/${groups.repo}`,\n `${user}/${conanPackage.conanName}/${latestVersion}/${channel}/${packageRev}/export/conanfile.py?properties=conan.package.url`,\n );\n const { body: conanProperties } = await this.http.getJson(\n packageUrl,\n ConanProperties,\n );\n const { sourceUrl } = conanProperties;\n if (sourceUrl) {\n dep.sourceUrl = sourceUrl;\n }\n }\n } catch (err) {\n logger.debug({ err }, \"Couldn't determine Conan package url\");\n }\n return dep;\n }\n } catch (err) {\n this.handleGenericErrors(err);\n }\n }\n\n return null;\n }\n\n getReleases(config: GetReleasesConfig): Promise<ReleaseResult | null> {\n return withCache(\n {\n namespace: `datasource-${datasource}`,\n // TODO: types (#22198)\n key: `getReleases:${config.registryUrl}:${config.packageName}`,\n fallback: true,\n },\n () => this._getReleases(config),\n );\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["allVersioning.get"],"sources":["../../../../lib/modules/datasource/conan/index.ts"],"sourcesContent":["import { isString, isUndefined } from '@sindresorhus/is';\nimport { logger } from '../../../logger/index.ts';\nimport { withCache } from '../../../util/cache/package/with-cache.ts';\nimport { GithubHttp } from '../../../util/http/github.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { ensureTrailingSlash, joinUrlParts } from '../../../util/url.ts';\nimport * as allVersioning from '../../versioning/index.ts';\nimport { Datasource } from '../datasource.ts';\nimport type {\n DigestConfig,\n GetReleasesConfig,\n Release,\n ReleaseResult,\n} from '../types.ts';\nimport { isArtifactoryServer } from '../util.ts';\nimport { datasource, defaultRegistryUrl, getConanPackage } from './common.ts';\nimport {\n ConanCenterReleases,\n ConanJSON,\n ConanLatestRevision,\n ConanProperties,\n ConanRevisionJSON,\n} from './schema.ts';\n\nexport class ConanDatasource extends Datasource {\n static readonly id = datasource;\n\n override readonly defaultRegistryUrls = [defaultRegistryUrl];\n\n override readonly caching = true;\n\n override readonly registryStrategy = 'merge';\n\n githubHttp: GithubHttp;\n\n override readonly sourceUrlSupport = 'package';\n override readonly sourceUrlNote =\n 'The source URL is supported only if the package is served from the Artifactory servers. In which case we determine it from the `properties[conan.package.url]` field in the results.';\n\n constructor(id = ConanDatasource.id) {\n super(id);\n this.githubHttp = new GithubHttp(id);\n }\n\n async getConanCenterReleases(\n conanName: string,\n userAndChannel: string,\n ): Promise<ReleaseResult | null> {\n if (userAndChannel && userAndChannel !== '@_/_') {\n logger.debug(\n { conanName, userAndChannel },\n 'User/channel not supported for Conan Center lookups',\n );\n return null;\n }\n const url = `https://api.github.com/repos/conan-io/conan-center-index/contents/recipes/${conanName}/config.yml`;\n const { body: result } = await this.githubHttp.getYaml(\n url,\n { headers: { accept: 'application/vnd.github.v3.raw' } },\n ConanCenterReleases,\n );\n return result;\n }\n\n private async _getDigest(\n { registryUrl, packageName }: DigestConfig,\n newValue?: string,\n ): Promise<string | null> {\n if (isUndefined(newValue) || isUndefined(registryUrl)) {\n return null;\n }\n const url = ensureTrailingSlash(registryUrl);\n const conanPackage = getConanPackage(packageName);\n const revisionLookUp = joinUrlParts(\n url,\n 'v2/conans/',\n conanPackage.conanName,\n newValue,\n conanPackage.userAndChannel,\n '/revisions',\n );\n const { body: digest } = await this.http.getJson(\n revisionLookUp,\n ConanLatestRevision,\n );\n return digest;\n }\n\n override getDigest(\n config: DigestConfig,\n newValue?: string,\n ): Promise<string | null> {\n return withCache(\n {\n namespace: `datasource-${datasource}`,\n // TODO: types (#22198)\n key: `getDigest:${config.registryUrl!}:${config.packageName}:${newValue!}`,\n fallback: true,\n },\n () => this._getDigest(config, newValue),\n );\n }\n\n private async _getReleases({\n registryUrl,\n packageName,\n }: GetReleasesConfig): Promise<ReleaseResult | null> {\n const conanPackage = getConanPackage(packageName);\n const userAndChannel = `@${conanPackage.userAndChannel}`;\n if (\n isString(registryUrl) &&\n ensureTrailingSlash(registryUrl) === defaultRegistryUrl\n ) {\n return this.getConanCenterReleases(\n conanPackage.conanName,\n userAndChannel,\n );\n }\n\n logger.trace(\n { packageName, registryUrl },\n 'Looking up conan api dependency',\n );\n\n if (registryUrl) {\n const url = ensureTrailingSlash(registryUrl);\n const lookupUrl = joinUrlParts(\n url,\n `v2/conans/search?q=${conanPackage.conanName}`,\n );\n\n try {\n const rep = await this.http.getJson(lookupUrl, ConanJSON);\n const conanJson = rep.body;\n if (conanJson) {\n logger.trace({ lookupUrl }, 'Got conan api result');\n const dep: ReleaseResult = { releases: [] };\n\n const conanJsonReleases: Release[] = conanJson\n .filter(({ userChannel }) => userChannel === userAndChannel)\n .map(({ version }) => ({ version }));\n dep.releases.push(...conanJsonReleases);\n\n try {\n if (isArtifactoryServer(rep)) {\n const conanApiRegexp = regEx(\n /(?<host>.*)\\/artifactory\\/api\\/conan\\/(?<repo>[^/]+)/,\n );\n const groups = conanApiRegexp.exec(url)?.groups;\n if (!groups) {\n return dep;\n }\n const semver = allVersioning.get('semver');\n\n const sortedReleases = dep.releases\n .filter((release) => semver.isVersion(release.version))\n .sort((a, b) => semver.sortVersions(a.version, b.version));\n\n const latestVersion = sortedReleases.at(-1)?.version;\n\n if (!latestVersion) {\n return dep;\n }\n logger.debug(\n `Conan package ${packageName} has latest version ${latestVersion}`,\n );\n\n const latestRevisionUrl = joinUrlParts(\n url,\n `v2/conans/${conanPackage.conanName}/${latestVersion}/${conanPackage.userAndChannel}/latest`,\n );\n const {\n body: { revision: packageRev },\n } = await this.http.getJson(latestRevisionUrl, ConanRevisionJSON);\n\n const [user, channel] = conanPackage.userAndChannel.split('/');\n const packageUrl = joinUrlParts(\n `${groups.host}/artifactory/api/storage/${groups.repo}`,\n `${user}/${conanPackage.conanName}/${latestVersion}/${channel}/${packageRev}/export/conanfile.py?properties=conan.package.url`,\n );\n const { body: conanProperties } = await this.http.getJson(\n packageUrl,\n ConanProperties,\n );\n const { sourceUrl } = conanProperties;\n if (sourceUrl) {\n dep.sourceUrl = sourceUrl;\n }\n }\n } catch (err) {\n logger.debug({ err }, \"Couldn't determine Conan package url\");\n }\n return dep;\n }\n } catch (err) {\n this.handleGenericErrors(err);\n }\n }\n\n return null;\n }\n\n getReleases(config: GetReleasesConfig): Promise<ReleaseResult | null> {\n return withCache(\n {\n namespace: `datasource-${datasource}`,\n // TODO: types (#22198)\n key: `getReleases:${config.registryUrl}:${config.packageName}`,\n fallback: true,\n },\n () => this._getReleases(config),\n );\n }\n}\n"],"mappings":"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"}
@@ -9,6 +9,7 @@ import { Timestamp } from "../../../util/timestamp.js";
9
9
  import { Datasource } from "../datasource.js";
10
10
  import { datasource, defaultRegistryUrl } from "./common.js";
11
11
  import { getReleases } from "./prefix-dev.js";
12
+ import { CondaPackage } from "./schema.js";
12
13
  //#region lib/modules/datasource/conda/index.ts
13
14
  var CondaDatasource = class extends Datasource {
14
15
  static id = datasource;
@@ -33,14 +34,13 @@ var CondaDatasource = class extends Datasource {
33
34
  }
34
35
  const url = joinUrlParts(registryUrl, packageName);
35
36
  const result = { releases: [] };
36
- let response;
37
37
  try {
38
- response = await this.http.getJsonUnchecked(url);
38
+ const response = await this.http.getJson(url, CondaPackage);
39
39
  result.homepage = response.body.html_url;
40
40
  result.sourceUrl = response.body.dev_url;
41
41
  const releaseDate = {};
42
42
  for (const file of coerceArray(response.body.files)) releaseDate[file.version] ??= Timestamp.parse(file.upload_time);
43
- response.body.versions.forEach((version) => {
43
+ coerceArray(response.body.versions).forEach((version) => {
44
44
  const thisRelease = {
45
45
  version,
46
46
  releaseTimestamp: releaseDate[version]
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["prefixDev.getReleases","HttpError"],"sources":["../../../../lib/modules/datasource/conda/index.ts"],"sourcesContent":["import { logger } from '../../../logger/index.ts';\nimport { ExternalHostError } from '../../../types/errors/external-host-error.ts';\nimport { coerceArray } from '../../../util/array.ts';\nimport { withCache } from '../../../util/cache/package/with-cache.ts';\nimport { HttpError } from '../../../util/http/index.ts';\nimport { Timestamp } from '../../../util/timestamp.ts';\nimport { ensureTrailingSlash, joinUrlParts } from '../../../util/url.ts';\nimport { Datasource } from '../datasource.ts';\nimport type { GetReleasesConfig, Release, ReleaseResult } from '../types.ts';\nimport { datasource, defaultRegistryUrl } from './common.ts';\nimport * as prefixDev from './prefix-dev.ts';\nimport type { CondaPackage } from './types.ts';\n\nexport class CondaDatasource extends Datasource {\n static readonly id = datasource;\n\n constructor() {\n super(datasource);\n }\n\n override readonly customRegistrySupport = true;\n\n override readonly registryStrategy = 'hunt';\n\n override readonly defaultRegistryUrls = [defaultRegistryUrl];\n\n override readonly caching = true;\n\n override readonly sourceUrlSupport = 'package';\n override readonly sourceUrlNote =\n 'The source URL is determined from the `dev_url` field in the results.';\n\n private async _getReleases({\n registryUrl,\n packageName,\n }: GetReleasesConfig): Promise<ReleaseResult | null> {\n logger.trace({ registryUrl, packageName }, 'fetching conda package');\n\n if (!registryUrl) {\n return null;\n }\n\n // fast.prefix.dev is a alias, deprecated, but still running.\n // We expect registryUrl to be `https://prefix.dev/${channel}` here.\n if (\n registryUrl.startsWith('https://prefix.dev/') ||\n registryUrl.startsWith('https://fast.prefix.dev/')\n ) {\n // Since the registryUrl contains at least 3 `/` ,\n // the channel varitable won't be undefined in any case.\n const channel = ensureTrailingSlash(registryUrl).split('/').at(-2)!;\n\n return prefixDev.getReleases(this.http, channel, packageName);\n }\n\n const url = joinUrlParts(registryUrl, packageName);\n\n const result: ReleaseResult = {\n releases: [],\n };\n\n let response: { body: CondaPackage };\n\n try {\n response = await this.http.getJsonUnchecked(url);\n\n result.homepage = response.body.html_url;\n result.sourceUrl = response.body.dev_url;\n\n const releaseDate: Record<string, Timestamp> = {};\n // we assume all packages are roughly released on the same time\n for (const file of coerceArray(response.body.files)) {\n releaseDate[file.version] ??= Timestamp.parse(file.upload_time);\n }\n\n response.body.versions.forEach((version: string) => {\n const thisRelease: Release = {\n version,\n releaseTimestamp: releaseDate[version],\n };\n result.releases.push(thisRelease);\n });\n } catch (err) {\n if (err instanceof HttpError) {\n if (err.response?.statusCode !== 404) {\n throw new ExternalHostError(err);\n }\n }\n this.handleGenericErrors(err);\n }\n\n return result.releases.length ? result : null;\n }\n\n getReleases(config: GetReleasesConfig): Promise<ReleaseResult | null> {\n return withCache(\n {\n namespace: `datasource-${datasource}`,\n // TODO: types (#22198)\n key: `${config.registryUrl}:${config.packageName}`,\n fallback: true,\n },\n () => this._getReleases(config),\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;AAaA,IAAa,kBAAb,cAAqC,WAAW;CAC9C,OAAgB,KAAK;CAErB,cAAc;EACZ,MAAM,UAAU;CAClB;CAEA,wBAA0C;CAE1C,mBAAqC;CAErC,sBAAwC,CAAC,kBAAkB;CAE3D,UAA4B;CAE5B,mBAAqC;CACrC,gBACE;CAEF,MAAc,aAAa,EACzB,aACA,eACmD;EACnD,OAAO,MAAM;GAAE;GAAa;EAAY,GAAG,wBAAwB;EAEnE,IAAI,CAAC,aACH,OAAO;EAKT,IACE,YAAY,WAAW,qBAAqB,KAC5C,YAAY,WAAW,0BAA0B,GACjD;GAGA,MAAM,UAAU,oBAAoB,WAAW,EAAE,MAAM,GAAG,EAAE,GAAG,EAAE;GAEjE,OAAOA,YAAsB,KAAK,MAAM,SAAS,WAAW;EAC9D;EAEA,MAAM,MAAM,aAAa,aAAa,WAAW;EAEjD,MAAM,SAAwB,EAC5B,UAAU,CAAC,EACb;EAEA,IAAI;EAEJ,IAAI;GACF,WAAW,MAAM,KAAK,KAAK,iBAAiB,GAAG;GAE/C,OAAO,WAAW,SAAS,KAAK;GAChC,OAAO,YAAY,SAAS,KAAK;GAEjC,MAAM,cAAyC,CAAC;GAEhD,KAAK,MAAM,QAAQ,YAAY,SAAS,KAAK,KAAK,GAChD,YAAY,KAAK,aAAa,UAAU,MAAM,KAAK,WAAW;GAGhE,SAAS,KAAK,SAAS,SAAS,YAAoB;IAClD,MAAM,cAAuB;KAC3B;KACA,kBAAkB,YAAY;IAChC;IACA,OAAO,SAAS,KAAK,WAAW;GAClC,CAAC;EACH,SAAS,KAAK;GACZ,IAAI,eAAeC;QACb,IAAI,UAAU,eAAe,KAC/B,MAAM,IAAI,kBAAkB,GAAG;GAAA;GAGnC,KAAK,oBAAoB,GAAG;EAC9B;EAEA,OAAO,OAAO,SAAS,SAAS,SAAS;CAC3C;CAEA,YAAY,QAA0D;EACpE,OAAO,UACL;GACE,WAAW,cAAc;GAEzB,KAAK,GAAG,OAAO,YAAY,GAAG,OAAO;GACrC,UAAU;EACZ,SACM,KAAK,aAAa,MAAM,CAChC;CACF;AACF"}
1
+ {"version":3,"file":"index.js","names":["prefixDev.getReleases","HttpError"],"sources":["../../../../lib/modules/datasource/conda/index.ts"],"sourcesContent":["import { logger } from '../../../logger/index.ts';\nimport { ExternalHostError } from '../../../types/errors/external-host-error.ts';\nimport { coerceArray } from '../../../util/array.ts';\nimport { withCache } from '../../../util/cache/package/with-cache.ts';\nimport { HttpError } from '../../../util/http/index.ts';\nimport { Timestamp } from '../../../util/timestamp.ts';\nimport { ensureTrailingSlash, joinUrlParts } from '../../../util/url.ts';\nimport { Datasource } from '../datasource.ts';\nimport type { GetReleasesConfig, Release, ReleaseResult } from '../types.ts';\nimport { datasource, defaultRegistryUrl } from './common.ts';\nimport * as prefixDev from './prefix-dev.ts';\nimport { CondaPackage } from './schema.ts';\n\nexport class CondaDatasource extends Datasource {\n static readonly id = datasource;\n\n constructor() {\n super(datasource);\n }\n\n override readonly customRegistrySupport = true;\n\n override readonly registryStrategy = 'hunt';\n\n override readonly defaultRegistryUrls = [defaultRegistryUrl];\n\n override readonly caching = true;\n\n override readonly sourceUrlSupport = 'package';\n override readonly sourceUrlNote =\n 'The source URL is determined from the `dev_url` field in the results.';\n\n private async _getReleases({\n registryUrl,\n packageName,\n }: GetReleasesConfig): Promise<ReleaseResult | null> {\n logger.trace({ registryUrl, packageName }, 'fetching conda package');\n\n if (!registryUrl) {\n return null;\n }\n\n // fast.prefix.dev is a alias, deprecated, but still running.\n // We expect registryUrl to be `https://prefix.dev/${channel}` here.\n if (\n registryUrl.startsWith('https://prefix.dev/') ||\n registryUrl.startsWith('https://fast.prefix.dev/')\n ) {\n // Since the registryUrl contains at least 3 `/` ,\n // the channel varitable won't be undefined in any case.\n const channel = ensureTrailingSlash(registryUrl).split('/').at(-2)!;\n\n return prefixDev.getReleases(this.http, channel, packageName);\n }\n\n const url = joinUrlParts(registryUrl, packageName);\n\n const result: ReleaseResult = {\n releases: [],\n };\n\n try {\n const response = await this.http.getJson(url, CondaPackage);\n\n result.homepage = response.body.html_url;\n result.sourceUrl = response.body.dev_url;\n\n const releaseDate: Record<string, Timestamp> = {};\n // we assume all packages are roughly released on the same time\n for (const file of coerceArray(response.body.files)) {\n releaseDate[file.version] ??= Timestamp.parse(file.upload_time);\n }\n\n coerceArray(response.body.versions).forEach((version: string) => {\n const thisRelease: Release = {\n version,\n releaseTimestamp: releaseDate[version],\n };\n result.releases.push(thisRelease);\n });\n } catch (err) {\n if (err instanceof HttpError) {\n if (err.response?.statusCode !== 404) {\n throw new ExternalHostError(err);\n }\n }\n this.handleGenericErrors(err);\n }\n\n return result.releases.length ? result : null;\n }\n\n getReleases(config: GetReleasesConfig): Promise<ReleaseResult | null> {\n return withCache(\n {\n namespace: `datasource-${datasource}`,\n // TODO: types (#22198)\n key: `${config.registryUrl}:${config.packageName}`,\n fallback: true,\n },\n () => this._getReleases(config),\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAaA,IAAa,kBAAb,cAAqC,WAAW;CAC9C,OAAgB,KAAK;CAErB,cAAc;EACZ,MAAM,UAAU;CAClB;CAEA,wBAA0C;CAE1C,mBAAqC;CAErC,sBAAwC,CAAC,kBAAkB;CAE3D,UAA4B;CAE5B,mBAAqC;CACrC,gBACE;CAEF,MAAc,aAAa,EACzB,aACA,eACmD;EACnD,OAAO,MAAM;GAAE;GAAa;EAAY,GAAG,wBAAwB;EAEnE,IAAI,CAAC,aACH,OAAO;EAKT,IACE,YAAY,WAAW,qBAAqB,KAC5C,YAAY,WAAW,0BAA0B,GACjD;GAGA,MAAM,UAAU,oBAAoB,WAAW,EAAE,MAAM,GAAG,EAAE,GAAG,EAAE;GAEjE,OAAOA,YAAsB,KAAK,MAAM,SAAS,WAAW;EAC9D;EAEA,MAAM,MAAM,aAAa,aAAa,WAAW;EAEjD,MAAM,SAAwB,EAC5B,UAAU,CAAC,EACb;EAEA,IAAI;GACF,MAAM,WAAW,MAAM,KAAK,KAAK,QAAQ,KAAK,YAAY;GAE1D,OAAO,WAAW,SAAS,KAAK;GAChC,OAAO,YAAY,SAAS,KAAK;GAEjC,MAAM,cAAyC,CAAC;GAEhD,KAAK,MAAM,QAAQ,YAAY,SAAS,KAAK,KAAK,GAChD,YAAY,KAAK,aAAa,UAAU,MAAM,KAAK,WAAW;GAGhE,YAAY,SAAS,KAAK,QAAQ,EAAE,SAAS,YAAoB;IAC/D,MAAM,cAAuB;KAC3B;KACA,kBAAkB,YAAY;IAChC;IACA,OAAO,SAAS,KAAK,WAAW;GAClC,CAAC;EACH,SAAS,KAAK;GACZ,IAAI,eAAeC;QACb,IAAI,UAAU,eAAe,KAC/B,MAAM,IAAI,kBAAkB,GAAG;GAAA;GAGnC,KAAK,oBAAoB,GAAG;EAC9B;EAEA,OAAO,OAAO,SAAS,SAAS,SAAS;CAC3C;CAEA,YAAY,QAA0D;EACpE,OAAO,UACL;GACE,WAAW,cAAc;GAEzB,KAAK,GAAG,OAAO,YAAY,GAAG,OAAO;GACrC,UAAU;EACZ,SACM,KAAK,aAAa,MAAM,CAChC;CACF;AACF"}
@@ -0,0 +1,17 @@
1
+ import { LooseArray } from "../../../util/schema-utils/index.js";
2
+ import { z } from "zod/v4";
3
+ //#region lib/modules/datasource/conda/schema.ts
4
+ const CondaFile = z.object({
5
+ version: z.string(),
6
+ upload_time: z.string().optional()
7
+ });
8
+ const CondaPackage = z.object({
9
+ html_url: z.string().optional(),
10
+ dev_url: z.string().optional(),
11
+ files: LooseArray(CondaFile).optional(),
12
+ versions: z.array(z.string()).optional()
13
+ });
14
+ //#endregion
15
+ export { CondaPackage };
16
+
17
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","names":[],"sources":["../../../../lib/modules/datasource/conda/schema.ts"],"sourcesContent":["import { z } from 'zod/v4';\nimport { LooseArray } from '../../../util/schema-utils/index.ts';\n\nexport const CondaFile = z.object({\n version: z.string(),\n upload_time: z.string().optional(),\n});\n\nexport const CondaPackage = z.object({\n html_url: z.string().optional(),\n dev_url: z.string().optional(),\n files: LooseArray(CondaFile).optional(),\n versions: z.array(z.string()).optional(),\n});\n\nexport type CondaPackage = z.infer<typeof CondaPackage>;\n"],"mappings":";;;AAGA,MAAa,YAAY,EAAE,OAAO;CAChC,SAAS,EAAE,OAAO;CAClB,aAAa,EAAE,OAAO,EAAE,SAAS;AACnC,CAAC;AAED,MAAa,eAAe,EAAE,OAAO;CACnC,UAAU,EAAE,OAAO,EAAE,SAAS;CAC9B,SAAS,EAAE,OAAO,EAAE,SAAS;CAC7B,OAAO,WAAW,SAAS,EAAE,SAAS;CACtC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AACzC,CAAC"}
@@ -13,7 +13,7 @@ import { asTimestamp } from "../../../util/timestamp.js";
13
13
  import { Datasource } from "../datasource.js";
14
14
  import { memCacheProvider } from "../../../util/http/cache/memory-http-cache-provider.js";
15
15
  import { createSimpleGit } from "../../../util/git/index.js";
16
- import { RegistryConfig, ReleaseTimestamp } from "./schema.js";
16
+ import { CrateMetadataResponse, RegistryConfig, ReleaseTimestamp } from "./schema.js";
17
17
  import upath from "upath";
18
18
  //#region lib/modules/datasource/crate/index.ts
19
19
  var CrateDatasource = class CrateDatasource extends Datasource {
@@ -108,7 +108,8 @@ var CrateDatasource = class CrateDatasource extends Datasource {
108
108
  registryUrl: info.rawUrl
109
109
  }, "downloading crate metadata");
110
110
  try {
111
- return (await this.http.getJsonUnchecked(crateUrl)).body.crate;
111
+ const { body } = await this.http.getJson(crateUrl, CrateMetadataResponse);
112
+ return body.crate;
112
113
  } catch (err) {
113
114
  logger.debug({
114
115
  err,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["cargoVersioning.id","memCache.get"],"sources":["../../../../lib/modules/datasource/crate/index.ts"],"sourcesContent":["import upath from 'upath';\nimport { GlobalConfig } from '../../../config/global.ts';\nimport { logger } from '../../../logger/index.ts';\nimport * as memCache from '../../../util/cache/memory/index.ts';\nimport { withCache } from '../../../util/cache/package/with-cache.ts';\nimport { privateCacheDir, readCacheFile } from '../../../util/fs/index.ts';\nimport { createSimpleGit } from '../../../util/git/index.ts';\nimport { toSha256 } from '../../../util/hash.ts';\nimport { memCacheProvider } from '../../../util/http/cache/memory-http-cache-provider.ts';\nimport { acquireLock } from '../../../util/mutex.ts';\nimport { newlineRegex, regEx } from '../../../util/regex.ts';\nimport { Json } from '../../../util/schema-utils/index.ts';\nimport { asTimestamp } from '../../../util/timestamp.ts';\nimport { joinUrlParts, parseUrl } from '../../../util/url.ts';\nimport * as cargoVersioning from '../../versioning/cargo/index.ts';\nimport { Datasource } from '../datasource.ts';\nimport type {\n GetReleasesConfig,\n PostprocessReleaseConfig,\n PostprocessReleaseResult,\n Release,\n ReleaseResult,\n} from '../types.ts';\nimport { RegistryConfig, ReleaseTimestamp } from './schema.ts';\nimport type {\n CrateMetadata,\n CrateRecord,\n RegistryFlavor,\n RegistryInfo,\n} from './types.ts';\n\ntype CloneResult =\n | {\n err: Error;\n clonePath?: undefined;\n }\n | {\n clonePath: string;\n err?: undefined;\n };\n\nexport class CrateDatasource extends Datasource {\n static readonly id = 'crate';\n\n constructor() {\n super(CrateDatasource.id);\n }\n\n override defaultRegistryUrls = ['sparse+https://index.crates.io/'];\n\n override defaultVersioning = cargoVersioning.id;\n\n override readonly sourceUrlSupport = 'package';\n override readonly sourceUrlNote =\n 'The source URL is determined from the `repository` field in the results.';\n\n override readonly releaseTimestampSupport = true;\n override readonly releaseTimestampNote =\n 'The release timestamp is determined from `pubtime` field from crates.io index if available, or `version.created_at` field from crates.io API otherwise.';\n\n private async _getReleases({\n packageName,\n registryUrl,\n }: GetReleasesConfig): Promise<ReleaseResult | null> {\n /* v8 ignore if -- should never happen */\n if (!registryUrl) {\n logger.warn(\n 'crate datasource: No registryUrl specified, cannot perform getReleases',\n );\n return null;\n }\n\n const registryInfo = await CrateDatasource.fetchRegistryInfo({\n packageName,\n registryUrl,\n });\n if (!registryInfo) {\n logger.debug(`Could not fetch registry info from ${registryUrl}`);\n return null;\n }\n\n const dependencyUrl = CrateDatasource.getDependencyUrl(\n registryInfo,\n packageName,\n );\n\n const payload = await this.fetchCrateRecordsPayload(\n registryInfo,\n packageName,\n );\n const lines = payload\n .split(newlineRegex) // break into lines\n .map((line) => line.trim()) // remove whitespace\n .filter((line) => line.length !== 0) // remove empty lines\n .map((line) => JSON.parse(line) as CrateRecord); // parse\n\n const metadata = await this.getCrateMetadata(registryInfo, packageName);\n\n const result: ReleaseResult = {\n dependencyUrl,\n releases: [],\n };\n\n if (metadata?.homepage) {\n result.homepage = metadata.homepage;\n }\n\n if (metadata?.repository) {\n result.sourceUrl = metadata.repository;\n }\n\n result.releases = lines\n .map((line) => {\n const versionOrig = line.vers;\n const version = versionOrig.replace(/\\+.*$/, '');\n const release: Release = { version };\n\n if (versionOrig !== version) {\n release.versionOrig = versionOrig;\n }\n\n if (line.yanked) {\n release.isDeprecated = true;\n }\n\n if (line.rust_version) {\n release.constraints = { rust: [line.rust_version] };\n }\n\n if (line.pubtime) {\n release.releaseTimestamp = asTimestamp(line.pubtime);\n }\n\n return release;\n })\n .filter((release) => release.version);\n if (!result.releases.length) {\n return null;\n }\n\n return result;\n }\n\n getReleases(config: GetReleasesConfig): Promise<ReleaseResult | null> {\n return withCache(\n {\n namespace: `datasource-${CrateDatasource.id}`,\n // TODO: types (#22198)\n key: `${config.registryUrl}/${config.packageName}`,\n cacheable: CrateDatasource.isCratesIo(config.registryUrl),\n fallback: true,\n },\n () => this._getReleases(config),\n );\n }\n\n /**\n * Fetches the registry's config.json which provides the API base URL\n * and download URL template.\n * See: https://doc.rust-lang.org/cargo/reference/registry-index.html#index-configuration\n */\n private async fetchRegistryConfig(\n info: RegistryInfo,\n ): Promise<RegistryConfig | null> {\n const cacheKey = `crate-datasource/registry-config/${info.rawUrl}`;\n const cached = memCache.get<RegistryConfig>(cacheKey);\n if (cached) {\n return cached;\n }\n\n if (info.clonePath) {\n try {\n const configPath = upath.join(info.clonePath, 'config.json');\n const content = await readCacheFile(configPath, 'utf8');\n const parsed = Json.pipe(RegistryConfig).parse(content);\n memCache.set(cacheKey, parsed);\n return parsed;\n } catch {\n logger.debug(\n { registryUrl: info.rawUrl },\n 'Could not read config.json from cloned registry',\n );\n }\n } else {\n try {\n const configUrl = joinUrlParts(info.rawUrl, 'config.json');\n const { body } = await this.http.getJson(configUrl, RegistryConfig);\n memCache.set(cacheKey, body);\n return body;\n } catch {\n logger.debug(\n { registryUrl: info.rawUrl },\n 'Could not fetch registry config.json',\n );\n }\n }\n\n return null;\n }\n\n private async _getCrateMetadata(\n info: RegistryInfo,\n packageName: string,\n ): Promise<CrateMetadata | null> {\n const registryConfig = await this.fetchRegistryConfig(info);\n if (!registryConfig?.api) {\n return null;\n }\n\n const apiBaseUrl = joinUrlParts(registryConfig.api, 'api/v1/');\n\n // The `?include=` suffix is required to avoid unnecessary database queries\n // on the crates.io server. This lets us work around the regular request\n // throttling of one request per second.\n const crateUrl = `${apiBaseUrl}crates/${packageName}?include=`;\n\n logger.trace(\n { crateUrl, packageName, registryUrl: info.rawUrl },\n 'downloading crate metadata',\n );\n\n try {\n interface Response {\n crate: CrateMetadata;\n }\n const response = await this.http.getJsonUnchecked<Response>(crateUrl);\n return response.body.crate;\n } catch (err) {\n logger.debug(\n { err, packageName, registryUrl: info.rawUrl },\n 'failed to download crate metadata',\n );\n }\n\n return null;\n }\n\n public getCrateMetadata(\n info: RegistryInfo,\n packageName: string,\n ): Promise<CrateMetadata | null> {\n return withCache(\n {\n namespace: `datasource-${CrateDatasource.id}-metadata`,\n key: `${info.rawUrl}/${packageName}`,\n cacheable: info.flavor === 'crates.io',\n ttlMinutes: 24 * 60, // 24 hours\n },\n () => this._getCrateMetadata(info, packageName),\n );\n }\n\n public async fetchCrateRecordsPayload(\n info: RegistryInfo,\n packageName: string,\n ): Promise<string> {\n if (info.clonePath) {\n const path = upath.join(\n info.clonePath,\n ...CrateDatasource.getIndexSuffix(packageName),\n );\n return readCacheFile(path, 'utf8');\n }\n\n // sparse index\n const packageSuffix = CrateDatasource.getIndexSuffix(\n packageName.toLowerCase(),\n );\n const crateUrl = joinUrlParts(info.rawUrl, ...packageSuffix);\n logger.trace(\n { crateUrl, packageName, registryUrl: info.rawUrl },\n 'fetching crate records from sparse index',\n );\n try {\n return (await this.http.getText(crateUrl)).body;\n } catch (err) {\n this.handleGenericErrors(err);\n }\n }\n\n /**\n * Computes the dependency URL for a crate, given\n * registry information\n */\n private static getDependencyUrl(\n info: RegistryInfo,\n packageName: string,\n ): string {\n switch (info.flavor) {\n case 'crates.io':\n return `https://crates.io/crates/${packageName}`;\n case 'cloudsmith': {\n // input: https://dl.cloudsmith.io/basic/$org/$repo/cargo/index.git\n const tokens = info.url.pathname.split('/');\n const org = tokens[2];\n const repo = tokens[3];\n return `https://cloudsmith.io/~${org}/repos/${repo}/packages/detail/cargo/${packageName}`;\n }\n default:\n return `${info.url}/${packageName}`;\n }\n }\n\n /**\n * Given a Git URL, computes a semi-human-readable name for a folder in which to\n * clone the repository.\n */\n private static cacheDirFromUrl(url: URL): string {\n const proto = url.protocol.replace(regEx(/:$/), '');\n const host = url.hostname;\n const hash = toSha256(url.pathname).substring(0, 7);\n\n return `crate-registry-${proto}-${host}-${hash}`;\n }\n\n private static isSparseRegistry(url: string): boolean {\n const parsed = parseUrl(url);\n if (!parsed) {\n return false;\n }\n return parsed.protocol.startsWith('sparse+');\n }\n\n /**\n * Fetches information about a registry, by url.\n * If no url is given, assumes crates.io.\n * If an url is given, assumes it's a valid Git repository\n * url and clones it to cache.\n */\n private static async fetchRegistryInfo({\n packageName,\n registryUrl,\n }: GetReleasesConfig): Promise<RegistryInfo | null> {\n /* v8 ignore next 3 -- should never happen */\n if (!registryUrl) {\n return null;\n }\n\n const isSparseRegistry = CrateDatasource.isSparseRegistry(registryUrl);\n const registryFetchUrl = isSparseRegistry\n ? registryUrl.replace(/^sparse\\+/, '')\n : registryUrl;\n\n const url = parseUrl(registryFetchUrl);\n if (!url) {\n logger.debug(`Could not parse registry URL ${registryFetchUrl}`);\n return null;\n }\n\n let flavor: RegistryFlavor;\n if (url.hostname === 'index.crates.io') {\n flavor = 'crates.io';\n } else if (url.hostname === 'dl.cloudsmith.io') {\n flavor = 'cloudsmith';\n } else {\n flavor = 'other';\n }\n\n const registry: RegistryInfo = {\n flavor,\n rawUrl: registryFetchUrl,\n url,\n };\n\n if (\n registry.flavor !== 'crates.io' &&\n !GlobalConfig.get('allowCustomCrateRegistries')\n ) {\n logger.warn(\n 'crate datasource: allowCustomCrateRegistries=true is required for registries other than crates.io, bailing out',\n );\n return null;\n }\n if (!isSparseRegistry) {\n const cacheKey = `crate-datasource/registry-clone-path/${registryFetchUrl}`;\n const lockKey = registryFetchUrl;\n\n const executionTimeout = GlobalConfig.get('executionTimeout') * 60 * 1000;\n const gitTimeout = GlobalConfig.get('gitTimeout') || executionTimeout;\n const releaseLock = await acquireLock(\n lockKey,\n 'crate-registry',\n gitTimeout,\n );\n try {\n const cached = memCache.get<CloneResult>(cacheKey);\n\n if (cached?.err) {\n logger.warn(\n { err: cached.err, packageName, registryFetchUrl },\n 'Previous git clone failed, bailing out.',\n );\n return null;\n }\n\n if (cached?.clonePath) {\n registry.clonePath = cached.clonePath;\n return registry;\n }\n\n const clonePath = upath.join(\n privateCacheDir(),\n CrateDatasource.cacheDirFromUrl(url),\n );\n\n const result = await CrateDatasource.clone(\n registryFetchUrl,\n clonePath,\n packageName,\n );\n\n memCache.set(cacheKey, result);\n\n if (result.err) {\n logger.warn(\n { err: result.err, packageName, registryFetchUrl },\n 'Git clone failed, bailing out.',\n );\n return null;\n }\n\n registry.clonePath = result.clonePath;\n } finally {\n releaseLock();\n }\n }\n\n return registry;\n }\n\n private static async clone(\n registryFetchUrl: string,\n clonePath: string,\n packageName: string,\n ): Promise<CloneResult> {\n logger.info(\n { clonePath, registryFetchUrl },\n `Cloning private cargo registry`,\n );\n\n const git = createSimpleGit({\n config: { maxConcurrentProcesses: 1 },\n });\n\n try {\n await git.clone(registryFetchUrl, clonePath, {\n '--depth': 1,\n });\n return { clonePath };\n } catch (err) {\n if (\n err.message.includes(\n 'fatal: dumb http transport does not support shallow capabilities',\n )\n ) {\n logger.info(\n { packageName, registryFetchUrl },\n 'failed to shallow clone git registry, doing full clone',\n );\n try {\n await git.clone(registryFetchUrl, clonePath);\n return { clonePath };\n } catch (err) {\n logger.warn(\n { err, packageName, registryFetchUrl },\n 'failed cloning git registry',\n );\n return { err };\n }\n } else {\n logger.warn(\n { err, packageName, registryFetchUrl },\n 'failed cloning git registry',\n );\n return { err };\n }\n }\n }\n\n private static isCratesIo(registryUrl: string | undefined): boolean {\n if (!registryUrl) {\n return false;\n }\n const normalized = registryUrl.replace(regEx(/^sparse\\+/), '');\n const parsed = parseUrl(normalized);\n return parsed?.hostname === 'index.crates.io';\n }\n\n public static getIndexSuffix(packageName: string): string[] {\n const len = packageName.length;\n\n if (len === 1) {\n return ['1', packageName];\n }\n if (len === 2) {\n return ['2', packageName];\n }\n if (len === 3) {\n return ['3', packageName[0], packageName];\n }\n\n return [packageName.slice(0, 2), packageName.slice(2, 4), packageName];\n }\n\n private async _postprocessRelease(\n { packageName, registryUrl }: PostprocessReleaseConfig,\n release: Release,\n ): Promise<PostprocessReleaseResult> {\n if (release.releaseTimestamp) {\n return release;\n }\n\n // Look up the registry config from cache (populated during getReleases)\n const rawUrl = registryUrl?.replace(/^sparse\\+/, '');\n if (!rawUrl) {\n return release;\n }\n const cacheKey = `crate-datasource/registry-config/${rawUrl}`;\n const config = memCache.get<{ dl: string; api?: string }>(cacheKey);\n if (!config?.api) {\n return release;\n }\n\n const apiBaseUrl = joinUrlParts(config.api, 'api/v1/');\n const url = `${apiBaseUrl}crates/${packageName}/${release.versionOrig ?? release.version}`;\n logger.trace(\n { url, packageName, version: release.version, registryUrl },\n 'fetching crate release timestamp',\n );\n // Getting release timestamp could become unnecessary if the manual backfill of `pubtime` mentioned in\n // https://github.com/rust-lang/cargo/issues/15491 is done for all packages.\n const { body: releaseTimestamp } = await this.http.getJson(\n url,\n { cacheProvider: memCacheProvider },\n ReleaseTimestamp,\n );\n release.releaseTimestamp = releaseTimestamp;\n return release;\n }\n\n override postprocessRelease(\n config: PostprocessReleaseConfig,\n release: Release,\n ): Promise<PostprocessReleaseResult> {\n return withCache(\n {\n namespace: `datasource-crate`,\n key: `postprocessRelease:${config.registryUrl}:${config.packageName}:${release.version}`,\n ttlMinutes: 7 * 24 * 60,\n cacheable: CrateDatasource.isCratesIo(config.registryUrl ?? undefined),\n },\n () => this._postprocessRelease(config, release),\n );\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["cargoVersioning.id","memCache.get"],"sources":["../../../../lib/modules/datasource/crate/index.ts"],"sourcesContent":["import upath from 'upath';\nimport { GlobalConfig } from '../../../config/global.ts';\nimport { logger } from '../../../logger/index.ts';\nimport * as memCache from '../../../util/cache/memory/index.ts';\nimport { withCache } from '../../../util/cache/package/with-cache.ts';\nimport { privateCacheDir, readCacheFile } from '../../../util/fs/index.ts';\nimport { createSimpleGit } from '../../../util/git/index.ts';\nimport { toSha256 } from '../../../util/hash.ts';\nimport { memCacheProvider } from '../../../util/http/cache/memory-http-cache-provider.ts';\nimport { acquireLock } from '../../../util/mutex.ts';\nimport { newlineRegex, regEx } from '../../../util/regex.ts';\nimport { Json } from '../../../util/schema-utils/index.ts';\nimport { asTimestamp } from '../../../util/timestamp.ts';\nimport { joinUrlParts, parseUrl } from '../../../util/url.ts';\nimport * as cargoVersioning from '../../versioning/cargo/index.ts';\nimport { Datasource } from '../datasource.ts';\nimport type {\n GetReleasesConfig,\n PostprocessReleaseConfig,\n PostprocessReleaseResult,\n Release,\n ReleaseResult,\n} from '../types.ts';\nimport type { CrateMetadata } from './schema.ts';\nimport {\n CrateMetadataResponse,\n RegistryConfig,\n ReleaseTimestamp,\n} from './schema.ts';\nimport type { CrateRecord, RegistryFlavor, RegistryInfo } from './types.ts';\n\ntype CloneResult =\n | {\n err: Error;\n clonePath?: undefined;\n }\n | {\n clonePath: string;\n err?: undefined;\n };\n\nexport class CrateDatasource extends Datasource {\n static readonly id = 'crate';\n\n constructor() {\n super(CrateDatasource.id);\n }\n\n override defaultRegistryUrls = ['sparse+https://index.crates.io/'];\n\n override defaultVersioning = cargoVersioning.id;\n\n override readonly sourceUrlSupport = 'package';\n override readonly sourceUrlNote =\n 'The source URL is determined from the `repository` field in the results.';\n\n override readonly releaseTimestampSupport = true;\n override readonly releaseTimestampNote =\n 'The release timestamp is determined from `pubtime` field from crates.io index if available, or `version.created_at` field from crates.io API otherwise.';\n\n private async _getReleases({\n packageName,\n registryUrl,\n }: GetReleasesConfig): Promise<ReleaseResult | null> {\n /* v8 ignore if -- should never happen */\n if (!registryUrl) {\n logger.warn(\n 'crate datasource: No registryUrl specified, cannot perform getReleases',\n );\n return null;\n }\n\n const registryInfo = await CrateDatasource.fetchRegistryInfo({\n packageName,\n registryUrl,\n });\n if (!registryInfo) {\n logger.debug(`Could not fetch registry info from ${registryUrl}`);\n return null;\n }\n\n const dependencyUrl = CrateDatasource.getDependencyUrl(\n registryInfo,\n packageName,\n );\n\n const payload = await this.fetchCrateRecordsPayload(\n registryInfo,\n packageName,\n );\n const lines = payload\n .split(newlineRegex) // break into lines\n .map((line) => line.trim()) // remove whitespace\n .filter((line) => line.length !== 0) // remove empty lines\n .map((line) => JSON.parse(line) as CrateRecord); // parse\n\n const metadata = await this.getCrateMetadata(registryInfo, packageName);\n\n const result: ReleaseResult = {\n dependencyUrl,\n releases: [],\n };\n\n if (metadata?.homepage) {\n result.homepage = metadata.homepage;\n }\n\n if (metadata?.repository) {\n result.sourceUrl = metadata.repository;\n }\n\n result.releases = lines\n .map((line) => {\n const versionOrig = line.vers;\n const version = versionOrig.replace(/\\+.*$/, '');\n const release: Release = { version };\n\n if (versionOrig !== version) {\n release.versionOrig = versionOrig;\n }\n\n if (line.yanked) {\n release.isDeprecated = true;\n }\n\n if (line.rust_version) {\n release.constraints = { rust: [line.rust_version] };\n }\n\n if (line.pubtime) {\n release.releaseTimestamp = asTimestamp(line.pubtime);\n }\n\n return release;\n })\n .filter((release) => release.version);\n if (!result.releases.length) {\n return null;\n }\n\n return result;\n }\n\n getReleases(config: GetReleasesConfig): Promise<ReleaseResult | null> {\n return withCache(\n {\n namespace: `datasource-${CrateDatasource.id}`,\n // TODO: types (#22198)\n key: `${config.registryUrl}/${config.packageName}`,\n cacheable: CrateDatasource.isCratesIo(config.registryUrl),\n fallback: true,\n },\n () => this._getReleases(config),\n );\n }\n\n /**\n * Fetches the registry's config.json which provides the API base URL\n * and download URL template.\n * See: https://doc.rust-lang.org/cargo/reference/registry-index.html#index-configuration\n */\n private async fetchRegistryConfig(\n info: RegistryInfo,\n ): Promise<RegistryConfig | null> {\n const cacheKey = `crate-datasource/registry-config/${info.rawUrl}`;\n const cached = memCache.get<RegistryConfig>(cacheKey);\n if (cached) {\n return cached;\n }\n\n if (info.clonePath) {\n try {\n const configPath = upath.join(info.clonePath, 'config.json');\n const content = await readCacheFile(configPath, 'utf8');\n const parsed = Json.pipe(RegistryConfig).parse(content);\n memCache.set(cacheKey, parsed);\n return parsed;\n } catch {\n logger.debug(\n { registryUrl: info.rawUrl },\n 'Could not read config.json from cloned registry',\n );\n }\n } else {\n try {\n const configUrl = joinUrlParts(info.rawUrl, 'config.json');\n const { body } = await this.http.getJson(configUrl, RegistryConfig);\n memCache.set(cacheKey, body);\n return body;\n } catch {\n logger.debug(\n { registryUrl: info.rawUrl },\n 'Could not fetch registry config.json',\n );\n }\n }\n\n return null;\n }\n\n private async _getCrateMetadata(\n info: RegistryInfo,\n packageName: string,\n ): Promise<CrateMetadata | null> {\n const registryConfig = await this.fetchRegistryConfig(info);\n if (!registryConfig?.api) {\n return null;\n }\n\n const apiBaseUrl = joinUrlParts(registryConfig.api, 'api/v1/');\n\n // The `?include=` suffix is required to avoid unnecessary database queries\n // on the crates.io server. This lets us work around the regular request\n // throttling of one request per second.\n const crateUrl = `${apiBaseUrl}crates/${packageName}?include=`;\n\n logger.trace(\n { crateUrl, packageName, registryUrl: info.rawUrl },\n 'downloading crate metadata',\n );\n\n try {\n const { body } = await this.http.getJson(crateUrl, CrateMetadataResponse);\n return body.crate;\n } catch (err) {\n logger.debug(\n { err, packageName, registryUrl: info.rawUrl },\n 'failed to download crate metadata',\n );\n }\n\n return null;\n }\n\n public getCrateMetadata(\n info: RegistryInfo,\n packageName: string,\n ): Promise<CrateMetadata | null> {\n return withCache(\n {\n namespace: `datasource-${CrateDatasource.id}-metadata`,\n key: `${info.rawUrl}/${packageName}`,\n cacheable: info.flavor === 'crates.io',\n ttlMinutes: 24 * 60, // 24 hours\n },\n () => this._getCrateMetadata(info, packageName),\n );\n }\n\n public async fetchCrateRecordsPayload(\n info: RegistryInfo,\n packageName: string,\n ): Promise<string> {\n if (info.clonePath) {\n const path = upath.join(\n info.clonePath,\n ...CrateDatasource.getIndexSuffix(packageName),\n );\n return readCacheFile(path, 'utf8');\n }\n\n // sparse index\n const packageSuffix = CrateDatasource.getIndexSuffix(\n packageName.toLowerCase(),\n );\n const crateUrl = joinUrlParts(info.rawUrl, ...packageSuffix);\n logger.trace(\n { crateUrl, packageName, registryUrl: info.rawUrl },\n 'fetching crate records from sparse index',\n );\n try {\n return (await this.http.getText(crateUrl)).body;\n } catch (err) {\n this.handleGenericErrors(err);\n }\n }\n\n /**\n * Computes the dependency URL for a crate, given\n * registry information\n */\n private static getDependencyUrl(\n info: RegistryInfo,\n packageName: string,\n ): string {\n switch (info.flavor) {\n case 'crates.io':\n return `https://crates.io/crates/${packageName}`;\n case 'cloudsmith': {\n // input: https://dl.cloudsmith.io/basic/$org/$repo/cargo/index.git\n const tokens = info.url.pathname.split('/');\n const org = tokens[2];\n const repo = tokens[3];\n return `https://cloudsmith.io/~${org}/repos/${repo}/packages/detail/cargo/${packageName}`;\n }\n default:\n return `${info.url}/${packageName}`;\n }\n }\n\n /**\n * Given a Git URL, computes a semi-human-readable name for a folder in which to\n * clone the repository.\n */\n private static cacheDirFromUrl(url: URL): string {\n const proto = url.protocol.replace(regEx(/:$/), '');\n const host = url.hostname;\n const hash = toSha256(url.pathname).substring(0, 7);\n\n return `crate-registry-${proto}-${host}-${hash}`;\n }\n\n private static isSparseRegistry(url: string): boolean {\n const parsed = parseUrl(url);\n if (!parsed) {\n return false;\n }\n return parsed.protocol.startsWith('sparse+');\n }\n\n /**\n * Fetches information about a registry, by url.\n * If no url is given, assumes crates.io.\n * If an url is given, assumes it's a valid Git repository\n * url and clones it to cache.\n */\n private static async fetchRegistryInfo({\n packageName,\n registryUrl,\n }: GetReleasesConfig): Promise<RegistryInfo | null> {\n /* v8 ignore next 3 -- should never happen */\n if (!registryUrl) {\n return null;\n }\n\n const isSparseRegistry = CrateDatasource.isSparseRegistry(registryUrl);\n const registryFetchUrl = isSparseRegistry\n ? registryUrl.replace(/^sparse\\+/, '')\n : registryUrl;\n\n const url = parseUrl(registryFetchUrl);\n if (!url) {\n logger.debug(`Could not parse registry URL ${registryFetchUrl}`);\n return null;\n }\n\n let flavor: RegistryFlavor;\n if (url.hostname === 'index.crates.io') {\n flavor = 'crates.io';\n } else if (url.hostname === 'dl.cloudsmith.io') {\n flavor = 'cloudsmith';\n } else {\n flavor = 'other';\n }\n\n const registry: RegistryInfo = {\n flavor,\n rawUrl: registryFetchUrl,\n url,\n };\n\n if (\n registry.flavor !== 'crates.io' &&\n !GlobalConfig.get('allowCustomCrateRegistries')\n ) {\n logger.warn(\n 'crate datasource: allowCustomCrateRegistries=true is required for registries other than crates.io, bailing out',\n );\n return null;\n }\n if (!isSparseRegistry) {\n const cacheKey = `crate-datasource/registry-clone-path/${registryFetchUrl}`;\n const lockKey = registryFetchUrl;\n\n const executionTimeout = GlobalConfig.get('executionTimeout') * 60 * 1000;\n const gitTimeout = GlobalConfig.get('gitTimeout') || executionTimeout;\n const releaseLock = await acquireLock(\n lockKey,\n 'crate-registry',\n gitTimeout,\n );\n try {\n const cached = memCache.get<CloneResult>(cacheKey);\n\n if (cached?.err) {\n logger.warn(\n { err: cached.err, packageName, registryFetchUrl },\n 'Previous git clone failed, bailing out.',\n );\n return null;\n }\n\n if (cached?.clonePath) {\n registry.clonePath = cached.clonePath;\n return registry;\n }\n\n const clonePath = upath.join(\n privateCacheDir(),\n CrateDatasource.cacheDirFromUrl(url),\n );\n\n const result = await CrateDatasource.clone(\n registryFetchUrl,\n clonePath,\n packageName,\n );\n\n memCache.set(cacheKey, result);\n\n if (result.err) {\n logger.warn(\n { err: result.err, packageName, registryFetchUrl },\n 'Git clone failed, bailing out.',\n );\n return null;\n }\n\n registry.clonePath = result.clonePath;\n } finally {\n releaseLock();\n }\n }\n\n return registry;\n }\n\n private static async clone(\n registryFetchUrl: string,\n clonePath: string,\n packageName: string,\n ): Promise<CloneResult> {\n logger.info(\n { clonePath, registryFetchUrl },\n `Cloning private cargo registry`,\n );\n\n const git = createSimpleGit({\n config: { maxConcurrentProcesses: 1 },\n });\n\n try {\n await git.clone(registryFetchUrl, clonePath, {\n '--depth': 1,\n });\n return { clonePath };\n } catch (err) {\n if (\n err.message.includes(\n 'fatal: dumb http transport does not support shallow capabilities',\n )\n ) {\n logger.info(\n { packageName, registryFetchUrl },\n 'failed to shallow clone git registry, doing full clone',\n );\n try {\n await git.clone(registryFetchUrl, clonePath);\n return { clonePath };\n } catch (err) {\n logger.warn(\n { err, packageName, registryFetchUrl },\n 'failed cloning git registry',\n );\n return { err };\n }\n } else {\n logger.warn(\n { err, packageName, registryFetchUrl },\n 'failed cloning git registry',\n );\n return { err };\n }\n }\n }\n\n private static isCratesIo(registryUrl: string | undefined): boolean {\n if (!registryUrl) {\n return false;\n }\n const normalized = registryUrl.replace(regEx(/^sparse\\+/), '');\n const parsed = parseUrl(normalized);\n return parsed?.hostname === 'index.crates.io';\n }\n\n public static getIndexSuffix(packageName: string): string[] {\n const len = packageName.length;\n\n if (len === 1) {\n return ['1', packageName];\n }\n if (len === 2) {\n return ['2', packageName];\n }\n if (len === 3) {\n return ['3', packageName[0], packageName];\n }\n\n return [packageName.slice(0, 2), packageName.slice(2, 4), packageName];\n }\n\n private async _postprocessRelease(\n { packageName, registryUrl }: PostprocessReleaseConfig,\n release: Release,\n ): Promise<PostprocessReleaseResult> {\n if (release.releaseTimestamp) {\n return release;\n }\n\n // Look up the registry config from cache (populated during getReleases)\n const rawUrl = registryUrl?.replace(/^sparse\\+/, '');\n if (!rawUrl) {\n return release;\n }\n const cacheKey = `crate-datasource/registry-config/${rawUrl}`;\n const config = memCache.get<{ dl: string; api?: string }>(cacheKey);\n if (!config?.api) {\n return release;\n }\n\n const apiBaseUrl = joinUrlParts(config.api, 'api/v1/');\n const url = `${apiBaseUrl}crates/${packageName}/${release.versionOrig ?? release.version}`;\n logger.trace(\n { url, packageName, version: release.version, registryUrl },\n 'fetching crate release timestamp',\n );\n // Getting release timestamp could become unnecessary if the manual backfill of `pubtime` mentioned in\n // https://github.com/rust-lang/cargo/issues/15491 is done for all packages.\n const { body: releaseTimestamp } = await this.http.getJson(\n url,\n { cacheProvider: memCacheProvider },\n ReleaseTimestamp,\n );\n release.releaseTimestamp = releaseTimestamp;\n return release;\n }\n\n override postprocessRelease(\n config: PostprocessReleaseConfig,\n release: Release,\n ): Promise<PostprocessReleaseResult> {\n return withCache(\n {\n namespace: `datasource-crate`,\n key: `postprocessRelease:${config.registryUrl}:${config.packageName}:${release.version}`,\n ttlMinutes: 7 * 24 * 60,\n cacheable: CrateDatasource.isCratesIo(config.registryUrl ?? undefined),\n },\n () => this._postprocessRelease(config, release),\n );\n }\n}\n"],"mappings":"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"}
@@ -6,7 +6,14 @@ const RegistryConfig = z.object({
6
6
  api: z.string().optional()
7
7
  });
8
8
  const ReleaseTimestamp = z.object({ version: z.object({ created_at: MaybeTimestamp }) }).transform(({ version: { created_at } }) => created_at).nullable().catch(null);
9
+ const CrateMetadata = z.object({
10
+ description: z.string().optional(),
11
+ documentation: z.string().optional(),
12
+ homepage: z.string().optional(),
13
+ repository: z.string().optional()
14
+ });
15
+ const CrateMetadataResponse = z.object({ crate: CrateMetadata });
9
16
  //#endregion
10
- export { RegistryConfig, ReleaseTimestamp };
17
+ export { CrateMetadataResponse, RegistryConfig, ReleaseTimestamp };
11
18
 
12
19
  //# sourceMappingURL=schema.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","names":[],"sources":["../../../../lib/modules/datasource/crate/schema.ts"],"sourcesContent":["import { z } from 'zod/v4';\nimport { MaybeTimestamp } from '../../../util/timestamp.ts';\n\nexport const RegistryConfig = z.object({\n dl: z.string(),\n api: z.string().optional(),\n});\nexport type RegistryConfig = z.infer<typeof RegistryConfig>;\n\nexport const ReleaseTimestamp = z\n .object({\n version: z.object({\n created_at: MaybeTimestamp,\n }),\n })\n .transform(({ version: { created_at } }) => created_at)\n .nullable()\n .catch(null);\n"],"mappings":";;;AAGA,MAAa,iBAAiB,EAAE,OAAO;CACrC,IAAI,EAAE,OAAO;CACb,KAAK,EAAE,OAAO,EAAE,SAAS;AAC3B,CAAC;AAGD,MAAa,mBAAmB,EAC7B,OAAO,EACN,SAAS,EAAE,OAAO,EAChB,YAAY,eACd,CAAC,EACH,CAAC,EACA,WAAW,EAAE,SAAS,EAAE,mBAAmB,UAAU,EACrD,SAAS,EACT,MAAM,IAAI"}
1
+ {"version":3,"file":"schema.js","names":[],"sources":["../../../../lib/modules/datasource/crate/schema.ts"],"sourcesContent":["import { z } from 'zod/v4';\nimport { MaybeTimestamp } from '../../../util/timestamp.ts';\n\nexport const RegistryConfig = z.object({\n dl: z.string(),\n api: z.string().optional(),\n});\nexport type RegistryConfig = z.infer<typeof RegistryConfig>;\n\nexport const ReleaseTimestamp = z\n .object({\n version: z.object({\n created_at: MaybeTimestamp,\n }),\n })\n .transform(({ version: { created_at } }) => created_at)\n .nullable()\n .catch(null);\n\nexport const CrateMetadata = z.object({\n description: z.string().optional(),\n documentation: z.string().optional(),\n homepage: z.string().optional(),\n repository: z.string().optional(),\n});\nexport type CrateMetadata = z.infer<typeof CrateMetadata>;\n\nexport const CrateMetadataResponse = z.object({\n crate: CrateMetadata,\n});\nexport type CrateMetadataResponse = z.infer<typeof CrateMetadataResponse>;\n"],"mappings":";;;AAGA,MAAa,iBAAiB,EAAE,OAAO;CACrC,IAAI,EAAE,OAAO;CACb,KAAK,EAAE,OAAO,EAAE,SAAS;AAC3B,CAAC;AAGD,MAAa,mBAAmB,EAC7B,OAAO,EACN,SAAS,EAAE,OAAO,EAChB,YAAY,eACd,CAAC,EACH,CAAC,EACA,WAAW,EAAE,SAAS,EAAE,mBAAmB,UAAU,EACrD,SAAS,EACT,MAAM,IAAI;AAEb,MAAa,gBAAgB,EAAE,OAAO;CACpC,aAAa,EAAE,OAAO,EAAE,SAAS;CACjC,eAAe,EAAE,OAAO,EAAE,SAAS;CACnC,UAAU,EAAE,OAAO,EAAE,SAAS;CAC9B,YAAY,EAAE,OAAO,EAAE,SAAS;AAClC,CAAC;AAGD,MAAa,wBAAwB,EAAE,OAAO,EAC5C,OAAO,cACT,CAAC"}
@@ -3,7 +3,7 @@ import { id } from "../../versioning/gradle/index.js";
3
3
  import { withCache } from "../../../util/cache/package/with-cache.js";
4
4
  import { asTimestamp } from "../../../util/timestamp.js";
5
5
  import { Datasource } from "../datasource.js";
6
- import { GradleReleasesSchema } from "./schema.js";
6
+ import { GradleReleases } from "./schema.js";
7
7
  //#region lib/modules/datasource/gradle-version/index.ts
8
8
  var GradleVersionDatasource = class GradleVersionDatasource extends Datasource {
9
9
  static id = "gradle-version";
@@ -22,7 +22,7 @@ var GradleVersionDatasource = class GradleVersionDatasource extends Datasource {
22
22
  if (!registryUrl) return null;
23
23
  let releases;
24
24
  try {
25
- releases = (await this.http.getJson(registryUrl, GradleReleasesSchema)).body.filter((release) => !release.snapshot && !release.nightly).map((release) => {
25
+ releases = (await this.http.getJson(registryUrl, GradleReleases)).body.filter((release) => !release.snapshot && !release.nightly).map((release) => {
26
26
  const { version, buildTime } = release;
27
27
  const result = {
28
28
  version,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["gradleVersioning.id"],"sources":["../../../../lib/modules/datasource/gradle-version/index.ts"],"sourcesContent":["import { withCache } from '../../../util/cache/package/with-cache.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { asTimestamp } from '../../../util/timestamp.ts';\nimport * as gradleVersioning from '../../versioning/gradle/index.ts';\nimport { Datasource } from '../datasource.ts';\nimport type { GetReleasesConfig, Release, ReleaseResult } from '../types.ts';\nimport { GradleReleasesSchema } from './schema.ts';\n\nexport class GradleVersionDatasource extends Datasource {\n static readonly id = 'gradle-version';\n\n constructor() {\n super(GradleVersionDatasource.id);\n }\n\n override readonly defaultRegistryUrls = [\n 'https://services.gradle.org/versions/all',\n ];\n\n override readonly defaultVersioning = gradleVersioning.id;\n\n override readonly registryStrategy = 'merge';\n\n override readonly releaseTimestampSupport = true;\n override readonly releaseTimestampNote =\n 'The release timestamp is determined from the `buildTime` field in the results.';\n override readonly sourceUrlSupport = 'package';\n override readonly sourceUrlNote =\n 'We use the URL: https://github.com/gradle/gradle.';\n\n private async _getReleases({\n registryUrl,\n }: GetReleasesConfig): Promise<ReleaseResult | null> {\n /* v8 ignore next 3 -- should never happen */\n if (!registryUrl) {\n return null;\n }\n\n let releases: Release[];\n try {\n const response = await this.http.getJson(\n registryUrl,\n GradleReleasesSchema,\n );\n releases = response.body\n .filter((release) => !release.snapshot && !release.nightly)\n .map((release) => {\n const { version, buildTime } = release;\n\n const gitRef = GradleVersionDatasource.getGitRef(release.version);\n\n const releaseTimestamp = asTimestamp(buildTime);\n\n const result: Release = { version, gitRef, releaseTimestamp };\n\n if (release.broken) {\n result.isDeprecated = true;\n }\n\n return result;\n });\n } catch (err) {\n this.handleGenericErrors(err);\n }\n\n const res: ReleaseResult = {\n releases,\n homepage: 'https://gradle.org',\n sourceUrl: 'https://github.com/gradle/gradle',\n };\n if (res.releases.length) {\n return res;\n }\n return null;\n }\n\n getReleases(config: GetReleasesConfig): Promise<ReleaseResult | null> {\n return withCache(\n {\n namespace: `datasource-${GradleVersionDatasource.id}`,\n // TODO: types (#22198)\n key: `${config.registryUrl}`,\n fallback: true,\n },\n () => this._getReleases(config),\n );\n }\n\n /**\n * Calculate `gitTag` based on `version`:\n * - `8.1.2` -> `v8.1.2`\n * - `8.2` -> `v8.2.0`\n * - `8.2-rc-1` -> `v8.2.0-RC1`\n * - `8.2-milestone-1` -> `v8.2.0-M1`\n */\n private static getGitRef(version: string): string {\n const [versionPart, typePart, unstablePart] = version.split(\n regEx(/-([a-z]+)-/),\n );\n\n let suffix = '';\n if (typePart === 'rc') {\n suffix = `-RC${unstablePart}`;\n } else if (typePart === 'milestone') {\n suffix = `-M${unstablePart}`;\n }\n\n const [major, minor, patch = '0'] = versionPart.split('.');\n return `v${major}.${minor}.${patch}${suffix}`;\n }\n}\n"],"mappings":";;;;;;;AAQA,IAAa,0BAAb,MAAa,gCAAgC,WAAW;CACtD,OAAgB,KAAK;CAErB,cAAc;EACZ,MAAM,wBAAwB,EAAE;CAClC;CAEA,sBAAwC,CACtC,0CACF;CAEA,oBAAsCA;CAEtC,mBAAqC;CAErC,0BAA4C;CAC5C,uBACE;CACF,mBAAqC;CACrC,gBACE;CAEF,MAAc,aAAa,EACzB,eACmD;;EAEnD,IAAI,CAAC,aACH,OAAO;EAGT,IAAI;EACJ,IAAI;GAKF,YAAW,MAJY,KAAK,KAAK,QAC/B,aACA,oBACF,GACoB,KACjB,QAAQ,YAAY,CAAC,QAAQ,YAAY,CAAC,QAAQ,OAAO,EACzD,KAAK,YAAY;IAChB,MAAM,EAAE,SAAS,cAAc;IAM/B,MAAM,SAAkB;KAAE;KAAS,QAJpB,wBAAwB,UAAU,QAAQ,OAIjB;KAAG,kBAFlB,YAAY,SAEqB;IAAE;IAE5D,IAAI,QAAQ,QACV,OAAO,eAAe;IAGxB,OAAO;GACT,CAAC;EACL,SAAS,KAAK;GACZ,KAAK,oBAAoB,GAAG;EAC9B;EAEA,MAAM,MAAqB;GACzB;GACA,UAAU;GACV,WAAW;EACb;EACA,IAAI,IAAI,SAAS,QACf,OAAO;EAET,OAAO;CACT;CAEA,YAAY,QAA0D;EACpE,OAAO,UACL;GACE,WAAW,cAAc,wBAAwB;GAEjD,KAAK,GAAG,OAAO;GACf,UAAU;EACZ,SACM,KAAK,aAAa,MAAM,CAChC;CACF;;;;;;;;CASA,OAAe,UAAU,SAAyB;EAChD,MAAM,CAAC,aAAa,UAAU,gBAAgB,QAAQ,MACpD,MAAM,YAAY,CACpB;EAEA,IAAI,SAAS;EACb,IAAI,aAAa,MACf,SAAS,MAAM;OACV,IAAI,aAAa,aACtB,SAAS,KAAK;EAGhB,MAAM,CAAC,OAAO,OAAO,QAAQ,OAAO,YAAY,MAAM,GAAG;EACzD,OAAO,IAAI,MAAM,GAAG,MAAM,GAAG,QAAQ;CACvC;AACF"}
1
+ {"version":3,"file":"index.js","names":["gradleVersioning.id"],"sources":["../../../../lib/modules/datasource/gradle-version/index.ts"],"sourcesContent":["import { withCache } from '../../../util/cache/package/with-cache.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { asTimestamp } from '../../../util/timestamp.ts';\nimport * as gradleVersioning from '../../versioning/gradle/index.ts';\nimport { Datasource } from '../datasource.ts';\nimport type { GetReleasesConfig, Release, ReleaseResult } from '../types.ts';\nimport { GradleReleases } from './schema.ts';\n\nexport class GradleVersionDatasource extends Datasource {\n static readonly id = 'gradle-version';\n\n constructor() {\n super(GradleVersionDatasource.id);\n }\n\n override readonly defaultRegistryUrls = [\n 'https://services.gradle.org/versions/all',\n ];\n\n override readonly defaultVersioning = gradleVersioning.id;\n\n override readonly registryStrategy = 'merge';\n\n override readonly releaseTimestampSupport = true;\n override readonly releaseTimestampNote =\n 'The release timestamp is determined from the `buildTime` field in the results.';\n override readonly sourceUrlSupport = 'package';\n override readonly sourceUrlNote =\n 'We use the URL: https://github.com/gradle/gradle.';\n\n private async _getReleases({\n registryUrl,\n }: GetReleasesConfig): Promise<ReleaseResult | null> {\n /* v8 ignore next 3 -- should never happen */\n if (!registryUrl) {\n return null;\n }\n\n let releases: Release[];\n try {\n const response = await this.http.getJson(registryUrl, GradleReleases);\n releases = response.body\n .filter((release) => !release.snapshot && !release.nightly)\n .map((release) => {\n const { version, buildTime } = release;\n\n const gitRef = GradleVersionDatasource.getGitRef(release.version);\n\n const releaseTimestamp = asTimestamp(buildTime);\n\n const result: Release = { version, gitRef, releaseTimestamp };\n\n if (release.broken) {\n result.isDeprecated = true;\n }\n\n return result;\n });\n } catch (err) {\n this.handleGenericErrors(err);\n }\n\n const res: ReleaseResult = {\n releases,\n homepage: 'https://gradle.org',\n sourceUrl: 'https://github.com/gradle/gradle',\n };\n if (res.releases.length) {\n return res;\n }\n return null;\n }\n\n getReleases(config: GetReleasesConfig): Promise<ReleaseResult | null> {\n return withCache(\n {\n namespace: `datasource-${GradleVersionDatasource.id}`,\n // TODO: types (#22198)\n key: `${config.registryUrl}`,\n fallback: true,\n },\n () => this._getReleases(config),\n );\n }\n\n /**\n * Calculate `gitTag` based on `version`:\n * - `8.1.2` -> `v8.1.2`\n * - `8.2` -> `v8.2.0`\n * - `8.2-rc-1` -> `v8.2.0-RC1`\n * - `8.2-milestone-1` -> `v8.2.0-M1`\n */\n private static getGitRef(version: string): string {\n const [versionPart, typePart, unstablePart] = version.split(\n regEx(/-([a-z]+)-/),\n );\n\n let suffix = '';\n if (typePart === 'rc') {\n suffix = `-RC${unstablePart}`;\n } else if (typePart === 'milestone') {\n suffix = `-M${unstablePart}`;\n }\n\n const [major, minor, patch = '0'] = versionPart.split('.');\n return `v${major}.${minor}.${patch}${suffix}`;\n }\n}\n"],"mappings":";;;;;;;AAQA,IAAa,0BAAb,MAAa,gCAAgC,WAAW;CACtD,OAAgB,KAAK;CAErB,cAAc;EACZ,MAAM,wBAAwB,EAAE;CAClC;CAEA,sBAAwC,CACtC,0CACF;CAEA,oBAAsCA;CAEtC,mBAAqC;CAErC,0BAA4C;CAC5C,uBACE;CACF,mBAAqC;CACrC,gBACE;CAEF,MAAc,aAAa,EACzB,eACmD;;EAEnD,IAAI,CAAC,aACH,OAAO;EAGT,IAAI;EACJ,IAAI;GAEF,YAAW,MADY,KAAK,KAAK,QAAQ,aAAa,cAAc,GAChD,KACjB,QAAQ,YAAY,CAAC,QAAQ,YAAY,CAAC,QAAQ,OAAO,EACzD,KAAK,YAAY;IAChB,MAAM,EAAE,SAAS,cAAc;IAM/B,MAAM,SAAkB;KAAE;KAAS,QAJpB,wBAAwB,UAAU,QAAQ,OAIjB;KAAG,kBAFlB,YAAY,SAEqB;IAAE;IAE5D,IAAI,QAAQ,QACV,OAAO,eAAe;IAGxB,OAAO;GACT,CAAC;EACL,SAAS,KAAK;GACZ,KAAK,oBAAoB,GAAG;EAC9B;EAEA,MAAM,MAAqB;GACzB;GACA,UAAU;GACV,WAAW;EACb;EACA,IAAI,IAAI,SAAS,QACf,OAAO;EAET,OAAO;CACT;CAEA,YAAY,QAA0D;EACpE,OAAO,UACL;GACE,WAAW,cAAc,wBAAwB;GAEjD,KAAK,GAAG,OAAO;GACf,UAAU;EACZ,SACM,KAAK,aAAa,MAAM,CAChC;CACF;;;;;;;;CASA,OAAe,UAAU,SAAyB;EAChD,MAAM,CAAC,aAAa,UAAU,gBAAgB,QAAQ,MACpD,MAAM,YAAY,CACpB;EAEA,IAAI,SAAS;EACb,IAAI,aAAa,MACf,SAAS,MAAM;OACV,IAAI,aAAa,aACtB,SAAS,KAAK;EAGhB,MAAM,CAAC,OAAO,OAAO,QAAQ,OAAO,YAAY,MAAM,GAAG;EACzD,OAAO,IAAI,MAAM,GAAG,MAAM,GAAG,QAAQ;CACvC;AACF"}
@@ -1,6 +1,6 @@
1
1
  import { LooseArray } from "../../../util/schema-utils/index.js";
2
2
  import { z } from "zod/v4";
3
- const GradleReleasesSchema = LooseArray(z.object({
3
+ const GradleReleases = LooseArray(z.object({
4
4
  buildTime: z.string().optional(),
5
5
  broken: z.boolean().optional(),
6
6
  milestoneFor: z.string().optional(),
@@ -10,6 +10,6 @@ const GradleReleasesSchema = LooseArray(z.object({
10
10
  version: z.string()
11
11
  }));
12
12
  //#endregion
13
- export { GradleReleasesSchema };
13
+ export { GradleReleases };
14
14
 
15
15
  //# sourceMappingURL=schema.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","names":[],"sources":["../../../../lib/modules/datasource/gradle-version/schema.ts"],"sourcesContent":["import { z } from 'zod/v4';\nimport { LooseArray } from '../../../util/schema-utils/index.ts';\n\nexport const GradleRelease = z.object({\n buildTime: z.string().optional(),\n broken: z.boolean().optional(),\n milestoneFor: z.string().optional(),\n nightly: z.boolean().optional(),\n rcFor: z.string().optional(),\n snapshot: z.boolean().optional(),\n version: z.string(),\n});\n\nexport const GradleReleasesSchema = LooseArray(GradleRelease);\n"],"mappings":";;AAaA,MAAa,uBAAuB,WAVP,EAAE,OAAO;CACpC,WAAW,EAAE,OAAO,EAAE,SAAS;CAC/B,QAAQ,EAAE,QAAQ,EAAE,SAAS;CAC7B,cAAc,EAAE,OAAO,EAAE,SAAS;CAClC,SAAS,EAAE,QAAQ,EAAE,SAAS;CAC9B,OAAO,EAAE,OAAO,EAAE,SAAS;CAC3B,UAAU,EAAE,QAAQ,EAAE,SAAS;CAC/B,SAAS,EAAE,OAAO;AACpB,CAE+C,CAAa"}
1
+ {"version":3,"file":"schema.js","names":[],"sources":["../../../../lib/modules/datasource/gradle-version/schema.ts"],"sourcesContent":["import { z } from 'zod/v4';\nimport { LooseArray } from '../../../util/schema-utils/index.ts';\n\nexport const GradleRelease = z.object({\n buildTime: z.string().optional(),\n broken: z.boolean().optional(),\n milestoneFor: z.string().optional(),\n nightly: z.boolean().optional(),\n rcFor: z.string().optional(),\n snapshot: z.boolean().optional(),\n version: z.string(),\n});\n\nexport const GradleReleases = LooseArray(GradleRelease);\n"],"mappings":";;AAaA,MAAa,iBAAiB,WAVD,EAAE,OAAO;CACpC,WAAW,EAAE,OAAO,EAAE,SAAS;CAC/B,QAAQ,EAAE,QAAQ,EAAE,SAAS;CAC7B,cAAc,EAAE,OAAO,EAAE,SAAS;CAClC,SAAS,EAAE,QAAQ,EAAE,SAAS;CAC9B,OAAO,EAAE,OAAO,EAAE,SAAS;CAC3B,UAAU,EAAE,QAAQ,EAAE,SAAS;CAC/B,SAAS,EAAE,OAAO;AACpB,CAEyC,CAAa"}
@@ -4,6 +4,7 @@ import { ensureTrailingSlash } from "../../../util/url.js";
4
4
  import { withCache } from "../../../util/cache/package/with-cache.js";
5
5
  import { asTimestamp } from "../../../util/timestamp.js";
6
6
  import { Datasource } from "../datasource.js";
7
+ import { JenkinsPluginsInfoResponse, JenkinsPluginsVersionsResponse } from "./schema.js";
7
8
  //#region lib/modules/datasource/jenkins-plugins/index.ts
8
9
  var JenkinsPluginsDatasource = class JenkinsPluginsDatasource extends Datasource {
9
10
  static id = "jenkins-plugins";
@@ -31,9 +32,9 @@ var JenkinsPluginsDatasource = class JenkinsPluginsDatasource extends Datasource
31
32
  return result;
32
33
  }
33
34
  async _getJenkinsPluginInfo(updateSiteUrl) {
34
- const { plugins } = await this.getJenkinsUpdateCenterResponse(`${updateSiteUrl}${JenkinsPluginsDatasource.packageInfoPath}`);
35
+ const { plugins } = await this.getJenkinsUpdateCenterResponse(`${updateSiteUrl}${JenkinsPluginsDatasource.packageInfoPath}`, JenkinsPluginsInfoResponse);
35
36
  const info = {};
36
- for (const name of Object.keys(plugins ?? [])) info[name] = {
37
+ for (const name of Object.keys(plugins)) info[name] = {
37
38
  releases: [],
38
39
  sourceUrl: plugins[name]?.scm
39
40
  };
@@ -47,9 +48,9 @@ var JenkinsPluginsDatasource = class JenkinsPluginsDatasource extends Datasource
47
48
  }, () => this._getJenkinsPluginInfo(updateSiteUrl));
48
49
  }
49
50
  async _getJenkinsPluginVersions(updateSiteUrl) {
50
- const { plugins } = await this.getJenkinsUpdateCenterResponse(`${updateSiteUrl}${JenkinsPluginsDatasource.packageVersionsPath}`);
51
+ const { plugins } = await this.getJenkinsUpdateCenterResponse(`${updateSiteUrl}${JenkinsPluginsDatasource.packageVersionsPath}`, JenkinsPluginsVersionsResponse);
51
52
  const versions = {};
52
- for (const name of Object.keys(plugins ?? [])) versions[name] = Object.keys(plugins[name]).map((version) => {
53
+ for (const name of Object.keys(plugins)) versions[name] = Object.keys(plugins[name]).map((version) => {
53
54
  const downloadUrl = plugins[name][version]?.url;
54
55
  const buildDate = plugins[name][version]?.buildDate;
55
56
  const releaseTimestamp = plugins[name][version]?.releaseTimestamp ?? asTimestamp(buildDate);
@@ -70,12 +71,12 @@ var JenkinsPluginsDatasource = class JenkinsPluginsDatasource extends Datasource
70
71
  key: "versions"
71
72
  }, () => this._getJenkinsPluginVersions(updateSiteUrl));
72
73
  }
73
- async getJenkinsUpdateCenterResponse(url) {
74
+ async getJenkinsUpdateCenterResponse(url, schema) {
74
75
  let response;
75
76
  try {
76
77
  logger.debug(`jenkins-plugins: Fetching Jenkins plugins from ${url}`);
77
78
  const startTime = Date.now();
78
- response = (await this.http.getJsonUnchecked(url)).body;
79
+ response = (await this.http.getJson(url, schema)).body;
79
80
  const durationMs = Math.round(Date.now() - startTime);
80
81
  logger.debug({ durationMs }, `jenkins-plugins: Fetched Jenkins plugins from ${url}`);
81
82
  } catch (err) /* istanbul ignore next */ {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../lib/modules/datasource/jenkins-plugins/index.ts"],"sourcesContent":["import { logger } from '../../../logger/index.ts';\nimport { withCache } from '../../../util/cache/package/with-cache.ts';\nimport { clone } from '../../../util/clone.ts';\nimport { asTimestamp } from '../../../util/timestamp.ts';\nimport { ensureTrailingSlash } from '../../../util/url.ts';\nimport { Datasource } from '../datasource.ts';\nimport type { GetReleasesConfig, Release, ReleaseResult } from '../types.ts';\nimport type {\n JenkinsPluginsInfoResponse,\n JenkinsPluginsVersionsResponse,\n} from './types.ts';\n\nexport class JenkinsPluginsDatasource extends Datasource {\n static readonly id = 'jenkins-plugins';\n\n constructor() {\n super(JenkinsPluginsDatasource.id);\n }\n\n override readonly customRegistrySupport = true;\n\n override readonly defaultRegistryUrls = ['https://updates.jenkins.io'];\n\n override readonly registryStrategy = 'hunt';\n\n private static readonly packageInfoPath = 'current/update-center.actual.json';\n private static readonly packageVersionsPath = 'current/plugin-versions.json';\n\n override readonly releaseTimestampSupport = true;\n override readonly releaseTimestampNote =\n 'The releaseTimestamp is determined from the `releaseTimestamp` or `buildDate` field in the results.';\n override readonly sourceUrlSupport = 'package';\n override readonly sourceUrlNote =\n 'The source URL is determined from the `scm` field in the results.';\n\n 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 const updateSiteUrl = ensureTrailingSlash(registryUrl);\n\n const plugins = await this.getJenkinsPluginInfo(updateSiteUrl);\n const plugin = plugins[packageName];\n if (!plugin) {\n return null;\n }\n\n const result = clone(plugin);\n const versions = await this.getJenkinsPluginVersions(updateSiteUrl);\n const releases = versions[packageName];\n result.releases = releases ? clone(releases) : [];\n return result;\n }\n\n private async _getJenkinsPluginInfo(\n updateSiteUrl: string,\n ): Promise<Record<string, ReleaseResult>> {\n const { plugins } =\n await this.getJenkinsUpdateCenterResponse<JenkinsPluginsInfoResponse>(\n `${updateSiteUrl}${JenkinsPluginsDatasource.packageInfoPath}`,\n );\n\n const info: Record<string, ReleaseResult> = {};\n for (const name of Object.keys(plugins ?? [])) {\n info[name] = {\n releases: [], // releases\n sourceUrl: plugins[name]?.scm,\n };\n }\n return info;\n }\n\n getJenkinsPluginInfo(\n updateSiteUrl: string,\n ): Promise<Record<string, ReleaseResult>> {\n return withCache(\n {\n namespace: `datasource-${JenkinsPluginsDatasource.id}`,\n key: 'info',\n ttlMinutes: 1440,\n },\n () => this._getJenkinsPluginInfo(updateSiteUrl),\n );\n }\n\n private async _getJenkinsPluginVersions(\n updateSiteUrl: string,\n ): Promise<Record<string, Release[]>> {\n const { plugins } =\n await this.getJenkinsUpdateCenterResponse<JenkinsPluginsVersionsResponse>(\n `${updateSiteUrl}${JenkinsPluginsDatasource.packageVersionsPath}`,\n );\n\n const versions: Record<string, Release[]> = {};\n for (const name of Object.keys(plugins ?? [])) {\n versions[name] = Object.keys(plugins[name]).map((version) => {\n const downloadUrl = plugins[name][version]?.url;\n const buildDate = plugins[name][version]?.buildDate;\n const releaseTimestamp =\n plugins[name][version]?.releaseTimestamp ?? asTimestamp(buildDate);\n const jenkins = plugins[name][version]?.requiredCore;\n const constraints = jenkins ? { jenkins: [`>=${jenkins}`] } : undefined;\n return {\n version,\n downloadUrl,\n releaseTimestamp,\n ...(constraints && { constraints }),\n };\n });\n }\n return versions;\n }\n\n getJenkinsPluginVersions(\n updateSiteUrl: string,\n ): Promise<Record<string, Release[]>> {\n return withCache(\n {\n namespace: `datasource-${JenkinsPluginsDatasource.id}`,\n key: 'versions',\n },\n () => this._getJenkinsPluginVersions(updateSiteUrl),\n );\n }\n\n private async getJenkinsUpdateCenterResponse<T>(url: string): Promise<T> {\n let response: T;\n\n try {\n logger.debug(`jenkins-plugins: Fetching Jenkins plugins from ${url}`);\n const startTime = Date.now();\n response = (await this.http.getJsonUnchecked<T>(url)).body;\n const durationMs = Math.round(Date.now() - startTime);\n logger.debug(\n { durationMs },\n `jenkins-plugins: Fetched Jenkins plugins from ${url}`,\n );\n } catch (err) /* istanbul ignore next */ {\n this.handleGenericErrors(err);\n }\n\n return response;\n }\n}\n"],"mappings":";;;;;;;AAYA,IAAa,2BAAb,MAAa,iCAAiC,WAAW;CACvD,OAAgB,KAAK;CAErB,cAAc;EACZ,MAAM,yBAAyB,EAAE;CACnC;CAEA,wBAA0C;CAE1C,sBAAwC,CAAC,4BAA4B;CAErE,mBAAqC;CAErC,OAAwB,kBAAkB;CAC1C,OAAwB,sBAAsB;CAE9C,0BAA4C;CAC5C,uBACE;CACF,mBAAqC;CACrC,gBACE;CAEF,MAAM,YAAY,EAChB,aACA,eACmD;;EAEnD,IAAI,CAAC,aACH,OAAO;EAET,MAAM,gBAAgB,oBAAoB,WAAW;EAGrD,MAAM,UAAS,MADO,KAAK,qBAAqB,aAAa,GACtC;EACvB,IAAI,CAAC,QACH,OAAO;EAGT,MAAM,SAAS,MAAM,MAAM;EAE3B,MAAM,YAAW,MADM,KAAK,yBAAyB,aAAa,GACxC;EAC1B,OAAO,WAAW,WAAW,MAAM,QAAQ,IAAI,CAAC;EAChD,OAAO;CACT;CAEA,MAAc,sBACZ,eACwC;EACxC,MAAM,EAAE,YACN,MAAM,KAAK,+BACT,GAAG,gBAAgB,yBAAyB,iBAC9C;EAEF,MAAM,OAAsC,CAAC;EAC7C,KAAK,MAAM,QAAQ,OAAO,KAAK,WAAW,CAAC,CAAC,GAC1C,KAAK,QAAQ;GACX,UAAU,CAAC;GACX,WAAW,QAAQ,OAAO;EAC5B;EAEF,OAAO;CACT;CAEA,qBACE,eACwC;EACxC,OAAO,UACL;GACE,WAAW,cAAc,yBAAyB;GAClD,KAAK;GACL,YAAY;EACd,SACM,KAAK,sBAAsB,aAAa,CAChD;CACF;CAEA,MAAc,0BACZ,eACoC;EACpC,MAAM,EAAE,YACN,MAAM,KAAK,+BACT,GAAG,gBAAgB,yBAAyB,qBAC9C;EAEF,MAAM,WAAsC,CAAC;EAC7C,KAAK,MAAM,QAAQ,OAAO,KAAK,WAAW,CAAC,CAAC,GAC1C,SAAS,QAAQ,OAAO,KAAK,QAAQ,KAAK,EAAE,KAAK,YAAY;GAC3D,MAAM,cAAc,QAAQ,MAAM,UAAU;GAC5C,MAAM,YAAY,QAAQ,MAAM,UAAU;GAC1C,MAAM,mBACJ,QAAQ,MAAM,UAAU,oBAAoB,YAAY,SAAS;GACnE,MAAM,UAAU,QAAQ,MAAM,UAAU;GACxC,MAAM,cAAc,UAAU,EAAE,SAAS,CAAC,KAAK,SAAS,EAAE,IAAI,KAAA;GAC9D,OAAO;IACL;IACA;IACA;IACA,GAAI,eAAe,EAAE,YAAY;GACnC;EACF,CAAC;EAEH,OAAO;CACT;CAEA,yBACE,eACoC;EACpC,OAAO,UACL;GACE,WAAW,cAAc,yBAAyB;GAClD,KAAK;EACP,SACM,KAAK,0BAA0B,aAAa,CACpD;CACF;CAEA,MAAc,+BAAkC,KAAyB;EACvE,IAAI;EAEJ,IAAI;GACF,OAAO,MAAM,kDAAkD,KAAK;GACpE,MAAM,YAAY,KAAK,IAAI;GAC3B,YAAY,MAAM,KAAK,KAAK,iBAAoB,GAAG,GAAG;GACtD,MAAM,aAAa,KAAK,MAAM,KAAK,IAAI,IAAI,SAAS;GACpD,OAAO,MACL,EAAE,WAAW,GACb,iDAAiD,KACnD;EACF,SAAS,kCAAgC;GACvC,KAAK,oBAAoB,GAAG;EAC9B;EAEA,OAAO;CACT;AACF"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../lib/modules/datasource/jenkins-plugins/index.ts"],"sourcesContent":["import { type ZodType } from 'zod/v4';\nimport { logger } from '../../../logger/index.ts';\nimport { withCache } from '../../../util/cache/package/with-cache.ts';\nimport { clone } from '../../../util/clone.ts';\nimport { asTimestamp } from '../../../util/timestamp.ts';\nimport { ensureTrailingSlash } from '../../../util/url.ts';\nimport { Datasource } from '../datasource.ts';\nimport type { GetReleasesConfig, Release, ReleaseResult } from '../types.ts';\nimport {\n JenkinsPluginsInfoResponse,\n JenkinsPluginsVersionsResponse,\n} from './schema.ts';\n\nexport class JenkinsPluginsDatasource extends Datasource {\n static readonly id = 'jenkins-plugins';\n\n constructor() {\n super(JenkinsPluginsDatasource.id);\n }\n\n override readonly customRegistrySupport = true;\n\n override readonly defaultRegistryUrls = ['https://updates.jenkins.io'];\n\n override readonly registryStrategy = 'hunt';\n\n private static readonly packageInfoPath = 'current/update-center.actual.json';\n private static readonly packageVersionsPath = 'current/plugin-versions.json';\n\n override readonly releaseTimestampSupport = true;\n override readonly releaseTimestampNote =\n 'The releaseTimestamp is determined from the `releaseTimestamp` or `buildDate` field in the results.';\n override readonly sourceUrlSupport = 'package';\n override readonly sourceUrlNote =\n 'The source URL is determined from the `scm` field in the results.';\n\n 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 const updateSiteUrl = ensureTrailingSlash(registryUrl);\n\n const plugins = await this.getJenkinsPluginInfo(updateSiteUrl);\n const plugin = plugins[packageName];\n if (!plugin) {\n return null;\n }\n\n const result = clone(plugin);\n const versions = await this.getJenkinsPluginVersions(updateSiteUrl);\n const releases = versions[packageName];\n result.releases = releases ? clone(releases) : [];\n return result;\n }\n\n private async _getJenkinsPluginInfo(\n updateSiteUrl: string,\n ): Promise<Record<string, ReleaseResult>> {\n const { plugins } = await this.getJenkinsUpdateCenterResponse(\n `${updateSiteUrl}${JenkinsPluginsDatasource.packageInfoPath}`,\n JenkinsPluginsInfoResponse,\n );\n\n const info: Record<string, ReleaseResult> = {};\n for (const name of Object.keys(plugins)) {\n info[name] = {\n releases: [], // releases\n sourceUrl: plugins[name]?.scm,\n };\n }\n return info;\n }\n\n getJenkinsPluginInfo(\n updateSiteUrl: string,\n ): Promise<Record<string, ReleaseResult>> {\n return withCache(\n {\n namespace: `datasource-${JenkinsPluginsDatasource.id}`,\n key: 'info',\n ttlMinutes: 1440,\n },\n () => this._getJenkinsPluginInfo(updateSiteUrl),\n );\n }\n\n private async _getJenkinsPluginVersions(\n updateSiteUrl: string,\n ): Promise<Record<string, Release[]>> {\n const { plugins } = await this.getJenkinsUpdateCenterResponse(\n `${updateSiteUrl}${JenkinsPluginsDatasource.packageVersionsPath}`,\n JenkinsPluginsVersionsResponse,\n );\n\n const versions: Record<string, Release[]> = {};\n for (const name of Object.keys(plugins)) {\n versions[name] = Object.keys(plugins[name]).map((version) => {\n const downloadUrl = plugins[name][version]?.url;\n const buildDate = plugins[name][version]?.buildDate;\n const releaseTimestamp =\n plugins[name][version]?.releaseTimestamp ?? asTimestamp(buildDate);\n const jenkins = plugins[name][version]?.requiredCore;\n const constraints = jenkins ? { jenkins: [`>=${jenkins}`] } : undefined;\n return {\n version,\n downloadUrl,\n releaseTimestamp,\n ...(constraints && { constraints }),\n };\n });\n }\n return versions;\n }\n\n getJenkinsPluginVersions(\n updateSiteUrl: string,\n ): Promise<Record<string, Release[]>> {\n return withCache(\n {\n namespace: `datasource-${JenkinsPluginsDatasource.id}`,\n key: 'versions',\n },\n () => this._getJenkinsPluginVersions(updateSiteUrl),\n );\n }\n\n private async getJenkinsUpdateCenterResponse<T>(\n url: string,\n schema: ZodType<T>,\n ): Promise<T> {\n let response: T;\n\n try {\n logger.debug(`jenkins-plugins: Fetching Jenkins plugins from ${url}`);\n const startTime = Date.now();\n response = (await this.http.getJson(url, schema)).body;\n const durationMs = Math.round(Date.now() - startTime);\n logger.debug(\n { durationMs },\n `jenkins-plugins: Fetched Jenkins plugins from ${url}`,\n );\n } catch (err) /* istanbul ignore next */ {\n this.handleGenericErrors(err);\n }\n\n return response;\n }\n}\n"],"mappings":";;;;;;;;AAaA,IAAa,2BAAb,MAAa,iCAAiC,WAAW;CACvD,OAAgB,KAAK;CAErB,cAAc;EACZ,MAAM,yBAAyB,EAAE;CACnC;CAEA,wBAA0C;CAE1C,sBAAwC,CAAC,4BAA4B;CAErE,mBAAqC;CAErC,OAAwB,kBAAkB;CAC1C,OAAwB,sBAAsB;CAE9C,0BAA4C;CAC5C,uBACE;CACF,mBAAqC;CACrC,gBACE;CAEF,MAAM,YAAY,EAChB,aACA,eACmD;;EAEnD,IAAI,CAAC,aACH,OAAO;EAET,MAAM,gBAAgB,oBAAoB,WAAW;EAGrD,MAAM,UAAS,MADO,KAAK,qBAAqB,aAAa,GACtC;EACvB,IAAI,CAAC,QACH,OAAO;EAGT,MAAM,SAAS,MAAM,MAAM;EAE3B,MAAM,YAAW,MADM,KAAK,yBAAyB,aAAa,GACxC;EAC1B,OAAO,WAAW,WAAW,MAAM,QAAQ,IAAI,CAAC;EAChD,OAAO;CACT;CAEA,MAAc,sBACZ,eACwC;EACxC,MAAM,EAAE,YAAY,MAAM,KAAK,+BAC7B,GAAG,gBAAgB,yBAAyB,mBAC5C,0BACF;EAEA,MAAM,OAAsC,CAAC;EAC7C,KAAK,MAAM,QAAQ,OAAO,KAAK,OAAO,GACpC,KAAK,QAAQ;GACX,UAAU,CAAC;GACX,WAAW,QAAQ,OAAO;EAC5B;EAEF,OAAO;CACT;CAEA,qBACE,eACwC;EACxC,OAAO,UACL;GACE,WAAW,cAAc,yBAAyB;GAClD,KAAK;GACL,YAAY;EACd,SACM,KAAK,sBAAsB,aAAa,CAChD;CACF;CAEA,MAAc,0BACZ,eACoC;EACpC,MAAM,EAAE,YAAY,MAAM,KAAK,+BAC7B,GAAG,gBAAgB,yBAAyB,uBAC5C,8BACF;EAEA,MAAM,WAAsC,CAAC;EAC7C,KAAK,MAAM,QAAQ,OAAO,KAAK,OAAO,GACpC,SAAS,QAAQ,OAAO,KAAK,QAAQ,KAAK,EAAE,KAAK,YAAY;GAC3D,MAAM,cAAc,QAAQ,MAAM,UAAU;GAC5C,MAAM,YAAY,QAAQ,MAAM,UAAU;GAC1C,MAAM,mBACJ,QAAQ,MAAM,UAAU,oBAAoB,YAAY,SAAS;GACnE,MAAM,UAAU,QAAQ,MAAM,UAAU;GACxC,MAAM,cAAc,UAAU,EAAE,SAAS,CAAC,KAAK,SAAS,EAAE,IAAI,KAAA;GAC9D,OAAO;IACL;IACA;IACA;IACA,GAAI,eAAe,EAAE,YAAY;GACnC;EACF,CAAC;EAEH,OAAO;CACT;CAEA,yBACE,eACoC;EACpC,OAAO,UACL;GACE,WAAW,cAAc,yBAAyB;GAClD,KAAK;EACP,SACM,KAAK,0BAA0B,aAAa,CACpD;CACF;CAEA,MAAc,+BACZ,KACA,QACY;EACZ,IAAI;EAEJ,IAAI;GACF,OAAO,MAAM,kDAAkD,KAAK;GACpE,MAAM,YAAY,KAAK,IAAI;GAC3B,YAAY,MAAM,KAAK,KAAK,QAAQ,KAAK,MAAM,GAAG;GAClD,MAAM,aAAa,KAAK,MAAM,KAAK,IAAI,IAAI,SAAS;GACpD,OAAO,MACL,EAAE,WAAW,GACb,iDAAiD,KACnD;EACF,SAAS,kCAAgC;GACvC,KAAK,oBAAoB,GAAG;EAC9B;EAEA,OAAO;CACT;AACF"}
@@ -0,0 +1,20 @@
1
+ import { MaybeTimestamp } from "../../../util/timestamp.js";
2
+ import { z } from "zod/v4";
3
+ //#region lib/modules/datasource/jenkins-plugins/schema.ts
4
+ const JenkinsPluginInfo = z.object({
5
+ name: z.string(),
6
+ scm: z.string().optional()
7
+ });
8
+ const JenkinsPluginsInfoResponse = z.object({ plugins: z.record(z.string(), JenkinsPluginInfo).default({}) });
9
+ const JenkinsPluginVersion = z.object({
10
+ version: z.string(),
11
+ buildDate: z.string().optional(),
12
+ url: z.string().optional(),
13
+ requiredCore: z.string().optional(),
14
+ releaseTimestamp: MaybeTimestamp.optional()
15
+ });
16
+ const JenkinsPluginsVersionsResponse = z.object({ plugins: z.record(z.string(), z.record(z.string(), JenkinsPluginVersion)).default({}) });
17
+ //#endregion
18
+ export { JenkinsPluginsInfoResponse, JenkinsPluginsVersionsResponse };
19
+
20
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","names":[],"sources":["../../../../lib/modules/datasource/jenkins-plugins/schema.ts"],"sourcesContent":["import { z } from 'zod/v4';\nimport { MaybeTimestamp } from '../../../util/timestamp.ts';\n\nexport const JenkinsPluginInfo = z.object({\n name: z.string(),\n scm: z.string().optional(),\n});\n\nexport const JenkinsPluginsInfoResponse = z.object({\n plugins: z.record(z.string(), JenkinsPluginInfo).default({}),\n});\nexport type JenkinsPluginsInfoResponse = z.infer<\n typeof JenkinsPluginsInfoResponse\n>;\n\nexport const JenkinsPluginVersion = z.object({\n version: z.string(),\n buildDate: z.string().optional(),\n url: z.string().optional(),\n requiredCore: z.string().optional(),\n releaseTimestamp: MaybeTimestamp.optional(),\n});\nexport type JenkinsPluginVersion = z.infer<typeof JenkinsPluginVersion>;\n\nexport const JenkinsPluginsVersionsResponse = z.object({\n plugins: z\n .record(z.string(), z.record(z.string(), JenkinsPluginVersion))\n .default({}),\n});\nexport type JenkinsPluginsVersionsResponse = z.infer<\n typeof JenkinsPluginsVersionsResponse\n>;\n"],"mappings":";;;AAGA,MAAa,oBAAoB,EAAE,OAAO;CACxC,MAAM,EAAE,OAAO;CACf,KAAK,EAAE,OAAO,EAAE,SAAS;AAC3B,CAAC;AAED,MAAa,6BAA6B,EAAE,OAAO,EACjD,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,iBAAiB,EAAE,QAAQ,CAAC,CAAC,EAC7D,CAAC;AAKD,MAAa,uBAAuB,EAAE,OAAO;CAC3C,SAAS,EAAE,OAAO;CAClB,WAAW,EAAE,OAAO,EAAE,SAAS;CAC/B,KAAK,EAAE,OAAO,EAAE,SAAS;CACzB,cAAc,EAAE,OAAO,EAAE,SAAS;CAClC,kBAAkB,eAAe,SAAS;AAC5C,CAAC;AAGD,MAAa,iCAAiC,EAAE,OAAO,EACrD,SAAS,EACN,OAAO,EAAE,OAAO,GAAG,EAAE,OAAO,EAAE,OAAO,GAAG,oBAAoB,CAAC,EAC7D,QAAQ,CAAC,CAAC,EACf,CAAC"}