renovate 44.71.2 → 44.72.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 (95) hide show
  1. package/dist/config/global.js.map +1 -1
  2. package/dist/config/options/index.js +2 -0
  3. package/dist/config/options/index.js.map +1 -1
  4. package/dist/config/presets/internal/security.preset.js.map +1 -1
  5. package/dist/config/types.js.map +1 -1
  6. package/dist/config/validation.js.map +1 -1
  7. package/dist/logger/config-serializer.js +7 -7
  8. package/dist/logger/config-serializer.js.map +1 -1
  9. package/dist/modules/datasource/conan/schema.js.map +1 -1
  10. package/dist/modules/datasource/deb/index.js +1 -1
  11. package/dist/modules/datasource/deb/index.js.map +1 -1
  12. package/dist/modules/datasource/deb/packages.js +1 -1
  13. package/dist/modules/datasource/deb/packages.js.map +1 -1
  14. package/dist/modules/datasource/docker/schema.js +1 -1
  15. package/dist/modules/datasource/docker/schema.js.map +1 -1
  16. package/dist/modules/datasource/orb/schema.js.map +1 -1
  17. package/dist/modules/datasource/terraform-module/schema.js.map +1 -1
  18. package/dist/modules/datasource/terraform-provider/schema.js.map +1 -1
  19. package/dist/modules/manager/argocd/extract.js +17 -15
  20. package/dist/modules/manager/argocd/extract.js.map +1 -1
  21. package/dist/modules/manager/bazel-module/rules.js.map +1 -1
  22. package/dist/modules/manager/cargo/schema.js.map +1 -1
  23. package/dist/modules/manager/dockerfile/extract.js.map +1 -1
  24. package/dist/modules/manager/fingerprint.generated.js +10 -10
  25. package/dist/modules/manager/fingerprint.generated.js.map +1 -1
  26. package/dist/modules/manager/fleet/extract.js +16 -7
  27. package/dist/modules/manager/fleet/extract.js.map +1 -1
  28. package/dist/modules/manager/flux/extract.js +4 -8
  29. package/dist/modules/manager/flux/extract.js.map +1 -1
  30. package/dist/modules/manager/gradle/extract/catalog.js.map +1 -1
  31. package/dist/modules/manager/helmfile/extract.js +12 -12
  32. package/dist/modules/manager/helmfile/extract.js.map +1 -1
  33. package/dist/modules/manager/helmsman/extract.js +8 -10
  34. package/dist/modules/manager/helmsman/extract.js.map +1 -1
  35. package/dist/modules/manager/helmv3/oci.js +22 -1
  36. package/dist/modules/manager/helmv3/oci.js.map +1 -1
  37. package/dist/modules/manager/helmv3/utils.js +2 -7
  38. package/dist/modules/manager/helmv3/utils.js.map +1 -1
  39. package/dist/modules/manager/kustomize/extract.js +6 -10
  40. package/dist/modules/manager/kustomize/extract.js.map +1 -1
  41. package/dist/modules/manager/mise/extract.js +1 -1
  42. package/dist/modules/manager/mise/extract.js.map +1 -1
  43. package/dist/modules/manager/nix/extract.js +2 -2
  44. package/dist/modules/manager/nix/extract.js.map +1 -1
  45. package/dist/modules/manager/npm/extract/index.js.map +1 -1
  46. package/dist/modules/manager/npm/post-update/index.js.map +1 -1
  47. package/dist/modules/manager/npm/post-update/npm.js.map +1 -1
  48. package/dist/modules/manager/npm/update/dependency/index.js.map +1 -1
  49. package/dist/modules/manager/ocb/extract.js +2 -2
  50. package/dist/modules/manager/ocb/extract.js.map +1 -1
  51. package/dist/modules/manager/pep723/utils.js +1 -1
  52. package/dist/modules/manager/pep723/utils.js.map +1 -1
  53. package/dist/modules/manager/pipenv/extract.js.map +1 -1
  54. package/dist/modules/manager/poetry/schema.js.map +1 -1
  55. package/dist/modules/manager/poetry/update-locked.js.map +1 -1
  56. package/dist/modules/manager/sveltos/extract.js +13 -19
  57. package/dist/modules/manager/sveltos/extract.js.map +1 -1
  58. package/dist/modules/manager/swift/artifacts.js +1 -1
  59. package/dist/modules/manager/swift/artifacts.js.map +1 -1
  60. package/dist/modules/manager/terraform/extractors/resources/helm-release.js +3 -10
  61. package/dist/modules/manager/terraform/extractors/resources/helm-release.js.map +1 -1
  62. package/dist/modules/manager/vendir/extract.js +3 -4
  63. package/dist/modules/manager/vendir/extract.js.map +1 -1
  64. package/dist/modules/platform/bitbucket/pr-cache.js.map +1 -1
  65. package/dist/modules/platform/forgejo/pr-cache.js.map +1 -1
  66. package/dist/modules/platform/gerrit/index.js.map +1 -1
  67. package/dist/modules/platform/gitea/pr-cache.js.map +1 -1
  68. package/dist/modules/platform/github/schema.js +1 -1
  69. package/dist/modules/platform/github/schema.js.map +1 -1
  70. package/dist/modules/platform/scm-manager/index.js.map +1 -1
  71. package/dist/modules/versioning/ruby/range.js.map +1 -1
  72. package/dist/util/cache/package/impl/redis.js.map +1 -1
  73. package/dist/util/cache/package/impl/sqlite.js.map +1 -1
  74. package/dist/util/cache/package/namespaces.js.map +1 -1
  75. package/dist/util/exec/index.js.map +1 -1
  76. package/dist/util/package-rules/merge-confidence.js +5 -0
  77. package/dist/util/package-rules/merge-confidence.js.map +1 -1
  78. package/dist/util/result.js.map +1 -1
  79. package/dist/util/yaml.js +1 -1
  80. package/dist/util/yaml.js.map +1 -1
  81. package/dist/workers/global/config/parse/additional-config-file.js +1 -1
  82. package/dist/workers/global/config/parse/additional-config-file.js.map +1 -1
  83. package/dist/workers/global/config/parse/file.js +1 -1
  84. package/dist/workers/global/config/parse/file.js.map +1 -1
  85. package/dist/workers/global/config/parse/host-rules-from-env.js.map +1 -1
  86. package/dist/workers/repository/dependency-dashboard.js.map +1 -1
  87. package/dist/workers/repository/error.js +1 -1
  88. package/dist/workers/repository/error.js.map +1 -1
  89. package/dist/workers/repository/index.js +1 -1
  90. package/dist/workers/repository/index.js.map +1 -1
  91. package/dist/workers/repository/onboarding/branch/onboarding-branch-cache.js.map +1 -1
  92. package/dist/workers/repository/onboarding/pr/pr-list.js.map +1 -1
  93. package/dist/workers/repository/update/branch/index.js.map +1 -1
  94. package/package.json +7 -7
  95. package/renovate-schema.json +2 -2
@@ -1,13 +1,12 @@
1
1
  import { regEx } from "../../../util/regex.js";
2
2
  import { logger } from "../../../logger/index.js";
3
3
  import { parseSingleYaml } from "../../../util/yaml.js";
4
- import { DockerDatasource } from "../../datasource/docker/index.js";
5
4
  import { HelmDatasource } from "../../datasource/helm/index.js";
6
- import { isOCIRegistry, removeOCIPrefix } from "../helmv3/oci.js";
5
+ import { getOciChartDep, isOCIRegistry } from "../helmv3/oci.js";
7
6
  import { isNonEmptyString, isTruthy } from "@sindresorhus/is";
8
7
  //#region lib/modules/manager/helmsman/extract.ts
9
8
  const chartRegex = regEx("^(?<registryRef>[^/]*)/(?<packageName>[^/]*)$");
10
- function createDep(key, doc) {
9
+ function createDep(key, doc, registryAliases) {
11
10
  const dep = {
12
11
  depName: key,
13
12
  datasource: HelmDatasource.id
@@ -19,11 +18,10 @@ function createDep(key, doc) {
19
18
  return dep;
20
19
  }
21
20
  dep.currentValue = anApp.version;
22
- if (isOCIRegistry(anApp.chart)) {
23
- dep.datasource = DockerDatasource.id;
24
- dep.packageName = removeOCIPrefix(anApp.chart);
25
- return dep;
26
- }
21
+ if (anApp.chart && isOCIRegistry(anApp.chart)) return {
22
+ ...dep,
23
+ ...getOciChartDep(anApp.chart, void 0, registryAliases)
24
+ };
27
25
  const regexResult = anApp.chart ? chartRegex.exec(anApp.chart) : null;
28
26
  if (!regexResult?.groups) {
29
27
  dep.skipReason = "invalid-url";
@@ -42,14 +40,14 @@ function createDep(key, doc) {
42
40
  dep.registryUrls = [registryUrl];
43
41
  return dep;
44
42
  }
45
- function extractPackageFile(content, packageFile, _config) {
43
+ function extractPackageFile(content, packageFile, config) {
46
44
  try {
47
45
  const doc = parseSingleYaml(content);
48
46
  if (!doc.apps) {
49
47
  logger.debug({ packageFile }, `Missing apps keys`);
50
48
  return null;
51
49
  }
52
- const deps = Object.keys(doc.apps).map((key) => createDep(key, doc)).filter(isTruthy);
50
+ const deps = Object.keys(doc.apps).map((key) => createDep(key, doc, config.registryAliases)).filter(isTruthy);
53
51
  if (deps.length === 0) return null;
54
52
  return { deps };
55
53
  } catch (err) /* istanbul ignore next */ {
@@ -1 +1 @@
1
- {"version":3,"file":"extract.js","names":[],"sources":["../../../../lib/modules/manager/helmsman/extract.ts"],"sourcesContent":["import { isNonEmptyString, isTruthy } from '@sindresorhus/is';\nimport { logger } from '../../../logger/index.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { parseSingleYaml } from '../../../util/yaml.ts';\nimport { DockerDatasource } from '../../datasource/docker/index.ts';\nimport { HelmDatasource } from '../../datasource/helm/index.ts';\nimport { isOCIRegistry, removeOCIPrefix } from '../helmv3/oci.ts';\nimport type {\n ExtractConfig,\n PackageDependency,\n PackageFileContent,\n} from '../types.ts';\nimport type { HelmsmanDocument } from './types.ts';\n\nconst chartRegex = regEx('^(?<registryRef>[^/]*)/(?<packageName>[^/]*)$');\n\nfunction createDep(\n key: string,\n doc: HelmsmanDocument,\n): PackageDependency | null {\n const dep: PackageDependency = {\n depName: key,\n datasource: HelmDatasource.id,\n };\n const anApp = doc.apps[key];\n if (!anApp) {\n return null;\n }\n\n if (!anApp.version) {\n dep.skipReason = 'unspecified-version';\n return dep;\n }\n dep.currentValue = anApp.version;\n\n // in case of OCI repository, we need a PackageDependency with a DockerDatasource and a packageName\n if (isOCIRegistry(anApp.chart)) {\n dep.datasource = DockerDatasource.id;\n dep.packageName = removeOCIPrefix(anApp.chart!);\n return dep;\n }\n\n const regexResult = anApp.chart ? chartRegex.exec(anApp.chart) : null;\n if (!regexResult?.groups) {\n dep.skipReason = 'invalid-url';\n return dep;\n }\n\n if (!isNonEmptyString(regexResult.groups.packageName)) {\n dep.skipReason = 'invalid-name';\n return dep;\n }\n dep.packageName = regexResult.groups.packageName;\n\n const registryUrl = doc.helmRepos[regexResult.groups.registryRef];\n if (!isNonEmptyString(registryUrl)) {\n dep.skipReason = 'no-repository';\n return dep;\n }\n dep.registryUrls = [registryUrl];\n\n return dep;\n}\n\nexport function extractPackageFile(\n content: string,\n packageFile: string,\n _config: ExtractConfig,\n): PackageFileContent | null {\n try {\n // TODO: use schema (#9610)\n const doc = parseSingleYaml<HelmsmanDocument>(content);\n if (!doc.apps) {\n logger.debug({ packageFile }, `Missing apps keys`);\n return null;\n }\n\n const deps = Object.keys(doc.apps)\n .map((key) => createDep(key, doc))\n .filter(isTruthy); // filter null values\n\n if (deps.length === 0) {\n return null;\n }\n\n return { deps };\n } catch (err) /* istanbul ignore next */ {\n if (err.stack?.startsWith('YAMLException:')) {\n logger.debug({ err, packageFile }, 'YAML exception extracting');\n } else {\n logger.debug({ err, packageFile }, 'Error extracting');\n }\n return null;\n }\n}\n"],"mappings":";;;;;;;;AAcA,MAAM,aAAa,MAAM,+CAA+C;AAExE,SAAS,UACP,KACA,KAC0B;CAC1B,MAAM,MAAyB;EAC7B,SAAS;EACT,YAAY,eAAe;CAC7B;CACA,MAAM,QAAQ,IAAI,KAAK;CACvB,IAAI,CAAC,OACH,OAAO;CAGT,IAAI,CAAC,MAAM,SAAS;EAClB,IAAI,aAAa;EACjB,OAAO;CACT;CACA,IAAI,eAAe,MAAM;CAGzB,IAAI,cAAc,MAAM,KAAK,GAAG;EAC9B,IAAI,aAAa,iBAAiB;EAClC,IAAI,cAAc,gBAAgB,MAAM,KAAM;EAC9C,OAAO;CACT;CAEA,MAAM,cAAc,MAAM,QAAQ,WAAW,KAAK,MAAM,KAAK,IAAI;CACjE,IAAI,CAAC,aAAa,QAAQ;EACxB,IAAI,aAAa;EACjB,OAAO;CACT;CAEA,IAAI,CAAC,iBAAiB,YAAY,OAAO,WAAW,GAAG;EACrD,IAAI,aAAa;EACjB,OAAO;CACT;CACA,IAAI,cAAc,YAAY,OAAO;CAErC,MAAM,cAAc,IAAI,UAAU,YAAY,OAAO;CACrD,IAAI,CAAC,iBAAiB,WAAW,GAAG;EAClC,IAAI,aAAa;EACjB,OAAO;CACT;CACA,IAAI,eAAe,CAAC,WAAW;CAE/B,OAAO;AACT;AAEA,SAAgB,mBACd,SACA,aACA,SAC2B;CAC3B,IAAI;EAEF,MAAM,MAAM,gBAAkC,OAAO;EACrD,IAAI,CAAC,IAAI,MAAM;GACb,OAAO,MAAM,EAAE,YAAY,GAAG,mBAAmB;GACjD,OAAO;EACT;EAEA,MAAM,OAAO,OAAO,KAAK,IAAI,IAAI,CAAC,CAC/B,KAAK,QAAQ,UAAU,KAAK,GAAG,CAAC,CAAC,CACjC,OAAO,QAAQ;EAElB,IAAI,KAAK,WAAW,GAClB,OAAO;EAGT,OAAO,EAAE,KAAK;CAChB,SAAS,gCAAgC;EACvC,IAAI,IAAI,OAAO,WAAW,gBAAgB,GACxC,OAAO,MAAM;GAAE;GAAK;EAAY,GAAG,2BAA2B;OAE9D,OAAO,MAAM;GAAE;GAAK;EAAY,GAAG,kBAAkB;EAEvD,OAAO;CACT;AACF"}
1
+ {"version":3,"file":"extract.js","names":[],"sources":["../../../../lib/modules/manager/helmsman/extract.ts"],"sourcesContent":["import { isNonEmptyString, isTruthy } from '@sindresorhus/is';\nimport { logger } from '../../../logger/index.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { parseSingleYaml } from '../../../util/yaml.ts';\nimport { HelmDatasource } from '../../datasource/helm/index.ts';\nimport { getOciChartDep, isOCIRegistry } from '../helmv3/oci.ts';\nimport type {\n ExtractConfig,\n PackageDependency,\n PackageFileContent,\n} from '../types.ts';\nimport type { HelmsmanDocument } from './types.ts';\n\nconst chartRegex = regEx('^(?<registryRef>[^/]*)/(?<packageName>[^/]*)$');\n\nfunction createDep(\n key: string,\n doc: HelmsmanDocument,\n registryAliases: Record<string, string> | undefined,\n): PackageDependency | null {\n const dep: PackageDependency = {\n depName: key,\n datasource: HelmDatasource.id,\n };\n const anApp = doc.apps[key];\n if (!anApp) {\n return null;\n }\n\n if (!anApp.version) {\n dep.skipReason = 'unspecified-version';\n return dep;\n }\n dep.currentValue = anApp.version;\n\n // in case of OCI repository, we need a PackageDependency with a DockerDatasource and a packageName\n if (anApp.chart && isOCIRegistry(anApp.chart)) {\n return {\n ...dep,\n ...getOciChartDep(anApp.chart, undefined, registryAliases),\n };\n }\n\n const regexResult = anApp.chart ? chartRegex.exec(anApp.chart) : null;\n if (!regexResult?.groups) {\n dep.skipReason = 'invalid-url';\n return dep;\n }\n\n if (!isNonEmptyString(regexResult.groups.packageName)) {\n dep.skipReason = 'invalid-name';\n return dep;\n }\n dep.packageName = regexResult.groups.packageName;\n\n const registryUrl = doc.helmRepos[regexResult.groups.registryRef];\n if (!isNonEmptyString(registryUrl)) {\n dep.skipReason = 'no-repository';\n return dep;\n }\n dep.registryUrls = [registryUrl];\n\n return dep;\n}\n\nexport function extractPackageFile(\n content: string,\n packageFile: string,\n config: ExtractConfig,\n): PackageFileContent | null {\n try {\n // TODO: use schema (#9610)\n const doc = parseSingleYaml<HelmsmanDocument>(content);\n if (!doc.apps) {\n logger.debug({ packageFile }, `Missing apps keys`);\n return null;\n }\n\n const deps = Object.keys(doc.apps)\n .map((key) => createDep(key, doc, config.registryAliases))\n .filter(isTruthy); // filter null values\n\n if (deps.length === 0) {\n return null;\n }\n\n return { deps };\n } catch (err) /* istanbul ignore next */ {\n if (err.stack?.startsWith('YAMLException:')) {\n logger.debug({ err, packageFile }, 'YAML exception extracting');\n } else {\n logger.debug({ err, packageFile }, 'Error extracting');\n }\n return null;\n }\n}\n"],"mappings":";;;;;;;AAaA,MAAM,aAAa,MAAM,+CAA+C;AAExE,SAAS,UACP,KACA,KACA,iBAC0B;CAC1B,MAAM,MAAyB;EAC7B,SAAS;EACT,YAAY,eAAe;CAC7B;CACA,MAAM,QAAQ,IAAI,KAAK;CACvB,IAAI,CAAC,OACH,OAAO;CAGT,IAAI,CAAC,MAAM,SAAS;EAClB,IAAI,aAAa;EACjB,OAAO;CACT;CACA,IAAI,eAAe,MAAM;CAGzB,IAAI,MAAM,SAAS,cAAc,MAAM,KAAK,GAC1C,OAAO;EACL,GAAG;EACH,GAAG,eAAe,MAAM,OAAO,KAAA,GAAW,eAAe;CAC3D;CAGF,MAAM,cAAc,MAAM,QAAQ,WAAW,KAAK,MAAM,KAAK,IAAI;CACjE,IAAI,CAAC,aAAa,QAAQ;EACxB,IAAI,aAAa;EACjB,OAAO;CACT;CAEA,IAAI,CAAC,iBAAiB,YAAY,OAAO,WAAW,GAAG;EACrD,IAAI,aAAa;EACjB,OAAO;CACT;CACA,IAAI,cAAc,YAAY,OAAO;CAErC,MAAM,cAAc,IAAI,UAAU,YAAY,OAAO;CACrD,IAAI,CAAC,iBAAiB,WAAW,GAAG;EAClC,IAAI,aAAa;EACjB,OAAO;CACT;CACA,IAAI,eAAe,CAAC,WAAW;CAE/B,OAAO;AACT;AAEA,SAAgB,mBACd,SACA,aACA,QAC2B;CAC3B,IAAI;EAEF,MAAM,MAAM,gBAAkC,OAAO;EACrD,IAAI,CAAC,IAAI,MAAM;GACb,OAAO,MAAM,EAAE,YAAY,GAAG,mBAAmB;GACjD,OAAO;EACT;EAEA,MAAM,OAAO,OAAO,KAAK,IAAI,IAAI,CAAC,CAC/B,KAAK,QAAQ,UAAU,KAAK,KAAK,OAAO,eAAe,CAAC,CAAC,CACzD,OAAO,QAAQ;EAElB,IAAI,KAAK,WAAW,GAClB,OAAO;EAGT,OAAO,EAAE,KAAK;CAChB,SAAS,gCAAgC;EACvC,IAAI,IAAI,OAAO,WAAW,gBAAgB,GACxC,OAAO,MAAM;GAAE;GAAK;EAAY,GAAG,2BAA2B;OAE9D,OAAO,MAAM;GAAE;GAAK;EAAY,GAAG,kBAAkB;EAEvD,OAAO;CACT;AACF"}
@@ -1,3 +1,6 @@
1
+ import { trimTrailingSlash } from "../../../util/url.js";
2
+ import { DockerDatasource } from "../../datasource/docker/index.js";
3
+ import { getDep } from "../dockerfile/extract.js";
1
4
  import { isNullOrUndefined, isString } from "@sindresorhus/is";
2
5
  //#region lib/modules/manager/helmv3/oci.ts
3
6
  function isOCIRegistry(repository) {
@@ -8,7 +11,25 @@ function removeOCIPrefix(repository) {
8
11
  if (isOCIRegistry(repository)) return repository.replace("oci://", "");
9
12
  return repository;
10
13
  }
14
+ /**
15
+ * Resolves a Helm chart stored in an OCI registry to the `docker` datasource.
16
+ *
17
+ * @param repository OCI registry or repository URL, with or without the `oci://` prefix
18
+ * @param chart chart name appended to `repository`, omit when `repository` already points to the chart
19
+ * @param registryAliases resolved the same way as for container image references
20
+ * @returns `datasource`, `packageName` and `pinDigests`. Callers set `depName`, `currentValue` and `depType`.
21
+ */
22
+ function getOciChartDep(repository, chart, registryAliases) {
23
+ const image = trimTrailingSlash(removeOCIPrefix(repository));
24
+ const { packageName, skipReason } = getDep(chart ? `${image}/${chart}` : image, false, registryAliases);
25
+ return {
26
+ datasource: DockerDatasource.id,
27
+ packageName,
28
+ ...skipReason && { skipReason },
29
+ pinDigests: false
30
+ };
31
+ }
11
32
  //#endregion
12
- export { isOCIRegistry, removeOCIPrefix };
33
+ export { getOciChartDep, isOCIRegistry, removeOCIPrefix };
13
34
 
14
35
  //# sourceMappingURL=oci.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"oci.js","names":[],"sources":["../../../../lib/modules/manager/helmv3/oci.ts"],"sourcesContent":["import { isNullOrUndefined, isString } from '@sindresorhus/is';\nimport type { Repository } from './types.ts';\n\nexport function isOCIRegistry(\n repository: Repository | string | null | undefined,\n): boolean {\n if (isNullOrUndefined(repository)) {\n return false;\n }\n const repo = isString(repository) ? repository : repository.repository;\n return repo.startsWith('oci://');\n}\n\nexport function removeOCIPrefix(repository: string): string {\n if (isOCIRegistry(repository)) {\n return repository.replace('oci://', '');\n }\n return repository;\n}\n"],"mappings":";;AAGA,SAAgB,cACd,YACS;CACT,IAAI,kBAAkB,UAAU,GAC9B,OAAO;CAGT,QADa,SAAS,UAAU,IAAI,aAAa,WAAW,WAAA,CAChD,WAAW,QAAQ;AACjC;AAEA,SAAgB,gBAAgB,YAA4B;CAC1D,IAAI,cAAc,UAAU,GAC1B,OAAO,WAAW,QAAQ,UAAU,EAAE;CAExC,OAAO;AACT"}
1
+ {"version":3,"file":"oci.js","names":[],"sources":["../../../../lib/modules/manager/helmv3/oci.ts"],"sourcesContent":["import { isNullOrUndefined, isString } from '@sindresorhus/is';\nimport { trimTrailingSlash } from '../../../util/url.ts';\nimport { DockerDatasource } from '../../datasource/docker/index.ts';\nimport { getDep } from '../dockerfile/extract.ts';\nimport type { PackageDependency } from '../types.ts';\nimport type { Repository } from './types.ts';\n\nexport function isOCIRegistry(\n repository: Repository | string | null | undefined,\n): boolean {\n if (isNullOrUndefined(repository)) {\n return false;\n }\n const repo = isString(repository) ? repository : repository.repository;\n return repo.startsWith('oci://');\n}\n\nexport function removeOCIPrefix(repository: string): string {\n if (isOCIRegistry(repository)) {\n return repository.replace('oci://', '');\n }\n return repository;\n}\n\n/**\n * Resolves a Helm chart stored in an OCI registry to the `docker` datasource.\n *\n * @param repository OCI registry or repository URL, with or without the `oci://` prefix\n * @param chart chart name appended to `repository`, omit when `repository` already points to the chart\n * @param registryAliases resolved the same way as for container image references\n * @returns `datasource`, `packageName` and `pinDigests`. Callers set `depName`, `currentValue` and `depType`.\n */\nexport function getOciChartDep(\n repository: string,\n chart?: string,\n registryAliases?: Record<string, string>,\n): PackageDependency {\n const image = trimTrailingSlash(removeOCIPrefix(repository));\n const { packageName, skipReason } = getDep(\n chart ? `${image}/${chart}` : image,\n false,\n registryAliases,\n );\n return {\n datasource: DockerDatasource.id,\n packageName,\n ...(skipReason && { skipReason }),\n // The version fields these managers update cannot carry a digest: Helm only\n // accepts one inside the OCI reference (`chart@sha256:...`, helm/helm#12690)\n // and Flux HelmCharts take semver only. A pin would fail in auto-replace\n // with \"Digest is not updated\".\n pinDigests: false,\n };\n}\n"],"mappings":";;;;;AAOA,SAAgB,cACd,YACS;CACT,IAAI,kBAAkB,UAAU,GAC9B,OAAO;CAGT,QADa,SAAS,UAAU,IAAI,aAAa,WAAW,WAAA,CAChD,WAAW,QAAQ;AACjC;AAEA,SAAgB,gBAAgB,YAA4B;CAC1D,IAAI,cAAc,UAAU,GAC1B,OAAO,WAAW,QAAQ,UAAU,EAAE;CAExC,OAAO;AACT;;;;;;;;;AAUA,SAAgB,eACd,YACA,OACA,iBACmB;CACnB,MAAM,QAAQ,kBAAkB,gBAAgB,UAAU,CAAC;CAC3D,MAAM,EAAE,aAAa,eAAe,OAClC,QAAQ,GAAG,MAAM,GAAG,UAAU,OAC9B,OACA,eACF;CACA,OAAO;EACL,YAAY,iBAAiB;EAC7B;EACA,GAAI,cAAc,EAAE,WAAW;EAK/B,YAAY;CACd;AACF"}
@@ -1,8 +1,7 @@
1
1
  import { regEx } from "../../../util/regex.js";
2
2
  import { logger } from "../../../logger/index.js";
3
3
  import { parseUrl } from "../../../util/url.js";
4
- import { DockerDatasource } from "../../datasource/docker/index.js";
5
- import { removeOCIPrefix } from "./oci.js";
4
+ import { getOciChartDep } from "./oci.js";
6
5
  import upath from "upath";
7
6
  //#region lib/modules/manager/helmv3/utils.ts
8
7
  function parseRepository(depName, repositoryURL) {
@@ -14,11 +13,7 @@ function parseRepository(depName, repositoryURL) {
14
13
  return res;
15
14
  }
16
15
  switch (url.protocol) {
17
- case "oci:":
18
- res.datasource = DockerDatasource.id;
19
- res.packageName = `${removeOCIPrefix(repositoryURL)}/${depName}`;
20
- res.pinDigests = false;
21
- break;
16
+ case "oci:": return getOciChartDep(repositoryURL, depName);
22
17
  case "file:":
23
18
  res.skipReason = "local-dependency";
24
19
  break;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","names":[],"sources":["../../../../lib/modules/manager/helmv3/utils.ts"],"sourcesContent":["import upath from 'upath';\nimport { logger } from '../../../logger/index.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { parseUrl } from '../../../util/url.ts';\nimport { DockerDatasource } from '../../datasource/docker/index.ts';\nimport type { PackageDependency } from '../types.ts';\nimport { removeOCIPrefix } from './oci.ts';\nimport type { ChartDefinition, Repository } from './types.ts';\n\nexport function parseRepository(\n depName: string,\n repositoryURL: string,\n): PackageDependency {\n const res: PackageDependency = {};\n\n const url = parseUrl(repositoryURL);\n if (!url) {\n logger.debug({ repositoryURL }, 'Error parsing url');\n res.skipReason = 'invalid-url';\n return res;\n }\n switch (url.protocol) {\n case 'oci:':\n res.datasource = DockerDatasource.id;\n res.packageName = `${removeOCIPrefix(repositoryURL)}/${depName}`;\n // https://github.com/helm/helm/issues/10312\n // https://github.com/helm/helm/issues/10678\n res.pinDigests = false;\n break;\n case 'file:':\n res.skipReason = 'local-dependency';\n break;\n default:\n res.registryUrls = [repositoryURL];\n }\n return res;\n}\n\n/**\n * Resolves alias in repository string.\n *\n * @param repository to be resolved string\n * @param registryAliases Records containing registryAliases as key and to be resolved URLs as values\n *\n * @returns resolved alias. If repository does not contain an alias the repository string will be returned. Should it contain an alias which can not be resolved using `registryAliases`, null will be returned\n */\nexport function resolveAlias(\n repository: string,\n registryAliases: Record<string, string>,\n): string | null {\n if (!isAlias(repository)) {\n return repository;\n }\n\n const repoWithPrefixRemoved = repository.slice(\n repository.startsWith('@') ? 1 : 6,\n );\n const alias = registryAliases[repoWithPrefixRemoved];\n if (alias) {\n return alias;\n }\n return null;\n}\n\nexport function getRepositories(definitions: ChartDefinition[]): Repository[] {\n const repositoryList = definitions\n .flatMap((value) => value.dependencies)\n .filter((dependency) => dependency.repository) // only keep non-local references --> if no repository is defined the chart will be searched in charts/<name>\n .filter((dependency) => !isAlias(dependency.repository)) // do not add registryAliases\n .filter((dependency) => !dependency.repository.startsWith('file:')) // skip repositories which are locally referenced\n .map((dependency) => {\n // remove additional keys to prevent interference at deduplication\n return {\n name: dependency.name,\n repository: dependency.repository,\n };\n });\n const dedup = new Set();\n return repositoryList.filter((el) => {\n const duplicate = dedup.has(el.repository);\n dedup.add(el.repository);\n return !duplicate;\n });\n}\n\nexport function isAlias(repository: string): boolean {\n if (!repository) {\n return false;\n }\n return repository.startsWith('@') || repository.startsWith('alias:');\n}\n\nexport function aliasRecordToRepositories(\n registryAliases: Record<string, string>,\n): Repository[] {\n return Object.entries(registryAliases)\n .filter(([, url]) => regEx(/^(?:https?|oci):\\/\\/.+/).exec(url))\n .map(([alias, url]) => {\n return {\n name: alias,\n repository: url,\n };\n });\n}\n\nexport function isFileInDir(dir: string, file: string): boolean {\n return upath.dirname(file) === dir;\n}\n"],"mappings":";;;;;;;AASA,SAAgB,gBACd,SACA,eACmB;CACnB,MAAM,MAAyB,CAAC;CAEhC,MAAM,MAAM,SAAS,aAAa;CAClC,IAAI,CAAC,KAAK;EACR,OAAO,MAAM,EAAE,cAAc,GAAG,mBAAmB;EACnD,IAAI,aAAa;EACjB,OAAO;CACT;CACA,QAAQ,IAAI,UAAZ;EACE,KAAK;GACH,IAAI,aAAa,iBAAiB;GAClC,IAAI,cAAc,GAAG,gBAAgB,aAAa,EAAE,GAAG;GAGvD,IAAI,aAAa;GACjB;EACF,KAAK;GACH,IAAI,aAAa;GACjB;EACF,SACE,IAAI,eAAe,CAAC,aAAa;CACrC;CACA,OAAO;AACT;;;;;;;;;AAUA,SAAgB,aACd,YACA,iBACe;CACf,IAAI,CAAC,QAAQ,UAAU,GACrB,OAAO;CAMT,MAAM,QAAQ,gBAHgB,WAAW,MACvC,WAAW,WAAW,GAAG,IAAI,IAAI,CAEe;CAClD,IAAI,OACF,OAAO;CAET,OAAO;AACT;AAEA,SAAgB,gBAAgB,aAA8C;CAC5E,MAAM,iBAAiB,YACpB,SAAS,UAAU,MAAM,YAAY,CAAC,CACtC,QAAQ,eAAe,WAAW,UAAU,CAAC,CAC7C,QAAQ,eAAe,CAAC,QAAQ,WAAW,UAAU,CAAC,CAAC,CACvD,QAAQ,eAAe,CAAC,WAAW,WAAW,WAAW,OAAO,CAAC,CAAC,CAClE,KAAK,eAAe;EAEnB,OAAO;GACL,MAAM,WAAW;GACjB,YAAY,WAAW;EACzB;CACF,CAAC;CACH,MAAM,wBAAQ,IAAI,IAAI;CACtB,OAAO,eAAe,QAAQ,OAAO;EACnC,MAAM,YAAY,MAAM,IAAI,GAAG,UAAU;EACzC,MAAM,IAAI,GAAG,UAAU;EACvB,OAAO,CAAC;CACV,CAAC;AACH;AAEA,SAAgB,QAAQ,YAA6B;CACnD,IAAI,CAAC,YACH,OAAO;CAET,OAAO,WAAW,WAAW,GAAG,KAAK,WAAW,WAAW,QAAQ;AACrE;AAEA,SAAgB,0BACd,iBACc;CACd,OAAO,OAAO,QAAQ,eAAe,CAAC,CACnC,QAAQ,GAAG,SAAS,MAAM,wBAAwB,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAC9D,KAAK,CAAC,OAAO,SAAS;EACrB,OAAO;GACL,MAAM;GACN,YAAY;EACd;CACF,CAAC;AACL;AAEA,SAAgB,YAAY,KAAa,MAAuB;CAC9D,OAAO,MAAM,QAAQ,IAAI,MAAM;AACjC"}
1
+ {"version":3,"file":"utils.js","names":[],"sources":["../../../../lib/modules/manager/helmv3/utils.ts"],"sourcesContent":["import upath from 'upath';\nimport { logger } from '../../../logger/index.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { parseUrl } from '../../../util/url.ts';\nimport type { PackageDependency } from '../types.ts';\nimport { getOciChartDep } from './oci.ts';\nimport type { ChartDefinition, Repository } from './types.ts';\n\nexport function parseRepository(\n depName: string,\n repositoryURL: string,\n): PackageDependency {\n const res: PackageDependency = {};\n\n const url = parseUrl(repositoryURL);\n if (!url) {\n logger.debug({ repositoryURL }, 'Error parsing url');\n res.skipReason = 'invalid-url';\n return res;\n }\n switch (url.protocol) {\n case 'oci:':\n return getOciChartDep(repositoryURL, depName);\n case 'file:':\n res.skipReason = 'local-dependency';\n break;\n default:\n res.registryUrls = [repositoryURL];\n }\n return res;\n}\n\n/**\n * Resolves alias in repository string.\n *\n * @param repository to be resolved string\n * @param registryAliases Records containing registryAliases as key and to be resolved URLs as values\n *\n * @returns resolved alias. If repository does not contain an alias the repository string will be returned. Should it contain an alias which can not be resolved using `registryAliases`, null will be returned\n */\nexport function resolveAlias(\n repository: string,\n registryAliases: Record<string, string>,\n): string | null {\n if (!isAlias(repository)) {\n return repository;\n }\n\n const repoWithPrefixRemoved = repository.slice(\n repository.startsWith('@') ? 1 : 6,\n );\n const alias = registryAliases[repoWithPrefixRemoved];\n if (alias) {\n return alias;\n }\n return null;\n}\n\nexport function getRepositories(definitions: ChartDefinition[]): Repository[] {\n const repositoryList = definitions\n .flatMap((value) => value.dependencies)\n .filter((dependency) => dependency.repository) // only keep non-local references --> if no repository is defined the chart will be searched in charts/<name>\n .filter((dependency) => !isAlias(dependency.repository)) // do not add registryAliases\n .filter((dependency) => !dependency.repository.startsWith('file:')) // skip repositories which are locally referenced\n .map((dependency) => {\n // remove additional keys to prevent interference at deduplication\n return {\n name: dependency.name,\n repository: dependency.repository,\n };\n });\n const dedup = new Set();\n return repositoryList.filter((el) => {\n const duplicate = dedup.has(el.repository);\n dedup.add(el.repository);\n return !duplicate;\n });\n}\n\nexport function isAlias(repository: string): boolean {\n if (!repository) {\n return false;\n }\n return repository.startsWith('@') || repository.startsWith('alias:');\n}\n\nexport function aliasRecordToRepositories(\n registryAliases: Record<string, string>,\n): Repository[] {\n return Object.entries(registryAliases)\n .filter(([, url]) => regEx(/^(?:https?|oci):\\/\\/.+/).exec(url))\n .map(([alias, url]) => {\n return {\n name: alias,\n repository: url,\n };\n });\n}\n\nexport function isFileInDir(dir: string, file: string): boolean {\n return upath.dirname(file) === dir;\n}\n"],"mappings":";;;;;;AAQA,SAAgB,gBACd,SACA,eACmB;CACnB,MAAM,MAAyB,CAAC;CAEhC,MAAM,MAAM,SAAS,aAAa;CAClC,IAAI,CAAC,KAAK;EACR,OAAO,MAAM,EAAE,cAAc,GAAG,mBAAmB;EACnD,IAAI,aAAa;EACjB,OAAO;CACT;CACA,QAAQ,IAAI,UAAZ;EACE,KAAK,QACH,OAAO,eAAe,eAAe,OAAO;EAC9C,KAAK;GACH,IAAI,aAAa;GACjB;EACF,SACE,IAAI,eAAe,CAAC,aAAa;CACrC;CACA,OAAO;AACT;;;;;;;;;AAUA,SAAgB,aACd,YACA,iBACe;CACf,IAAI,CAAC,QAAQ,UAAU,GACrB,OAAO;CAMT,MAAM,QAAQ,gBAHgB,WAAW,MACvC,WAAW,WAAW,GAAG,IAAI,IAAI,CAEe;CAClD,IAAI,OACF,OAAO;CAET,OAAO;AACT;AAEA,SAAgB,gBAAgB,aAA8C;CAC5E,MAAM,iBAAiB,YACpB,SAAS,UAAU,MAAM,YAAY,CAAC,CACtC,QAAQ,eAAe,WAAW,UAAU,CAAC,CAC7C,QAAQ,eAAe,CAAC,QAAQ,WAAW,UAAU,CAAC,CAAC,CACvD,QAAQ,eAAe,CAAC,WAAW,WAAW,WAAW,OAAO,CAAC,CAAC,CAClE,KAAK,eAAe;EAEnB,OAAO;GACL,MAAM,WAAW;GACjB,YAAY,WAAW;EACzB;CACF,CAAC;CACH,MAAM,wBAAQ,IAAI,IAAI;CACtB,OAAO,eAAe,QAAQ,OAAO;EACnC,MAAM,YAAY,MAAM,IAAI,GAAG,UAAU;EACzC,MAAM,IAAI,GAAG,UAAU;EACvB,OAAO,CAAC;CACV,CAAC;AACH;AAEA,SAAgB,QAAQ,YAA6B;CACnD,IAAI,CAAC,YACH,OAAO;CAET,OAAO,WAAW,WAAW,GAAG,KAAK,WAAW,WAAW,QAAQ;AACrE;AAEA,SAAgB,0BACd,iBACc;CACd,OAAO,OAAO,QAAQ,eAAe,CAAC,CACnC,QAAQ,GAAG,SAAS,MAAM,wBAAwB,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAC9D,KAAK,CAAC,OAAO,SAAS;EACrB,OAAO;GACL,MAAM;GACN,YAAY;EACd;CACF,CAAC;AACL;AAEA,SAAgB,YAAY,KAAa,MAAuB;CAC9D,OAAO,MAAM,QAAQ,IAAI,MAAM;AACjC"}
@@ -6,7 +6,7 @@ import { GitTagsDatasource } from "../../datasource/git-tags/index.js";
6
6
  import { GithubTagsDatasource } from "../../datasource/github-tags/index.js";
7
7
  import { HelmDatasource } from "../../datasource/helm/index.js";
8
8
  import { getDep } from "../dockerfile/extract.js";
9
- import { isOCIRegistry, removeOCIPrefix } from "../helmv3/oci.js";
9
+ import { getOciChartDep, isOCIRegistry } from "../helmv3/oci.js";
10
10
  import { isString } from "@sindresorhus/is";
11
11
  import querystring from "node:querystring";
12
12
  //#region lib/modules/manager/kustomize/extract.ts
@@ -93,15 +93,11 @@ function extractImage(image, aliases) {
93
93
  }
94
94
  function extractHelmChart(helmChart, aliases) {
95
95
  if (!helmChart.name) return null;
96
- if (isOCIRegistry(helmChart.repo)) {
97
- const dep = getDep(`${removeOCIPrefix(helmChart.repo)}/${helmChart.name}:${helmChart.version}`, false, aliases);
98
- delete dep.replaceString;
99
- return {
100
- ...dep,
101
- depName: helmChart.name,
102
- pinDigests: false
103
- };
104
- }
96
+ if (isOCIRegistry(helmChart.repo)) return {
97
+ ...getOciChartDep(helmChart.repo, helmChart.name, aliases),
98
+ depName: helmChart.name,
99
+ currentValue: helmChart.version
100
+ };
105
101
  return {
106
102
  depName: helmChart.name,
107
103
  currentValue: helmChart.version,
@@ -1 +1 @@
1
- {"version":3,"file":"extract.js","names":[],"sources":["../../../../lib/modules/manager/kustomize/extract.ts"],"sourcesContent":["import querystring from 'node:querystring';\nimport { isString } from '@sindresorhus/is';\nimport { logger } from '../../../logger/index.ts';\nimport { coerceArray } from '../../../util/array.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { parseSingleYaml } from '../../../util/yaml.ts';\nimport { GitTagsDatasource } from '../../datasource/git-tags/index.ts';\nimport { GithubTagsDatasource } from '../../datasource/github-tags/index.ts';\nimport { HelmDatasource } from '../../datasource/helm/index.ts';\nimport { getDep } from '../dockerfile/extract.ts';\nimport { isOCIRegistry, removeOCIPrefix } from '../helmv3/oci.ts';\nimport type {\n ExtractConfig,\n PackageDependency,\n PackageFileContent,\n} from '../types.ts';\nimport type { HelmChart, Image, Kustomize } from './types.ts';\n\n// URL specifications should follow the hashicorp URL format\n// https://github.com/hashicorp/go-getter#url-format\nconst gitUrl = regEx(\n /^(?:git::)?(?<url>(?:(?:(?:http|https|ssh):\\/\\/)?(?:.*@)?)?(?<path>(?:[^:/\\s]+(?::[0-9]+)?[:/])?(?<project>[^/\\s]+\\/[^/\\s]+)))(?<subdir>[^?\\s]*)\\?(?<queryString>.+)$/,\n);\n// regex to match URLs with \".git\" delimiter\nconst dotGitRegex = regEx(\n /^(?:git::)?(?<url>(?:(?:(?:http|https|ssh):\\/\\/)?(?:.*@)?)?(?<path>(?:[^:/\\s]+(?::[0-9]+)?[:/])?(?<project>[^?\\s]*(?:\\.git))))(?<subdir>[^?\\s]*)\\?(?<queryString>.+)$/,\n);\n// regex to match URLs with \"_git\" delimiter\nconst underscoreGitRegex = regEx(\n /^(?:git::)?(?<url>(?:(?:(?:http|https|ssh):\\/\\/)?(?:.*@)?)?(?<path>(?:[^:/\\s]+(?::[0-9]+)?[:/])?(?<project>[^?\\s]*)(?:_git\\/[^/\\s]+)))(?<subdir>[^?\\s]*)\\?(?<queryString>.+)$/,\n);\n// regex to match URLs having an extra \"//\"\nconst gitUrlWithPath = regEx(\n /^(?:git::)?(?<url>(?:(?:(?:http|https|ssh):\\/\\/)?(?:.*@)?)?(?<path>(?:[^:/\\s]+(?::[0-9]+)?[:/])(?<project>[^?\\s]+)))(?:\\/\\/)(?<subdir>[^?\\s]+)\\?(?<queryString>.+)$/,\n);\n\nexport function extractResource(base: string): PackageDependency | null {\n let match: RegExpExecArray | null;\n\n if (base.includes('_git')) {\n match = underscoreGitRegex.exec(base);\n } else if (base.includes('.git')) {\n match = dotGitRegex.exec(base);\n } else if (gitUrlWithPath.test(base)) {\n match = gitUrlWithPath.exec(base);\n } else {\n match = gitUrl.exec(base);\n }\n\n if (!match?.groups) {\n return null;\n }\n\n const { path, queryString } = match.groups;\n const params = querystring.parse(queryString);\n const refParam = Array.isArray(params.ref) ? params.ref[0] : params.ref;\n const versionParam = Array.isArray(params.version)\n ? params.version[0]\n : params.version;\n const currentValue = refParam ?? versionParam;\n if (!currentValue) {\n return null;\n }\n\n if (regEx(/(?:github\\.com)(?::|\\/)/).test(path)) {\n return {\n currentValue,\n datasource: GithubTagsDatasource.id,\n depName: match.groups.project.replace('.git', ''),\n };\n }\n\n return {\n datasource: GitTagsDatasource.id,\n depName: path.replace('.git', ''),\n packageName: match.groups.url,\n currentValue,\n };\n}\n\nexport function extractImage(\n image: Image,\n aliases?: Record<string, string>,\n): PackageDependency | null {\n if (!image.name) {\n return null;\n }\n const nameToSplit = image.newName ?? image.name;\n if (!isString(nameToSplit)) {\n logger.debug({ image }, 'Invalid image name');\n return null;\n }\n const nameDep = getDep(nameToSplit, false, aliases);\n const { depName } = nameDep;\n const { digest, newTag } = image;\n if (digest && newTag) {\n logger.debug(\n { newTag, digest },\n 'Kustomize ignores newTag when digest is provided. Pick one, or use `newTag: tag@digest`',\n );\n return {\n depName,\n currentValue: newTag,\n currentDigest: digest,\n skipReason: 'invalid-dependency-specification',\n };\n }\n\n if (digest) {\n if (!isString(digest) || !digest.startsWith('sha256:')) {\n return {\n depName,\n currentValue: digest,\n skipReason: 'invalid-value',\n };\n }\n\n return {\n ...nameDep,\n currentDigest: digest,\n replaceString: digest,\n };\n }\n\n if (newTag) {\n if (!isString(newTag) || newTag.startsWith('sha256:')) {\n return {\n depName,\n currentValue: newTag,\n skipReason: 'invalid-value',\n };\n }\n\n const dep = getDep(`${depName}:${newTag}`, false, aliases);\n return {\n ...dep,\n replaceString: newTag,\n autoReplaceStringTemplate:\n '{{newValue}}{{#if newDigest}}@{{newDigest}}{{/if}}',\n };\n }\n\n if (image.newName) {\n return {\n ...nameDep,\n replaceString: image.newName,\n };\n }\n\n return null;\n}\n\nexport function extractHelmChart(\n helmChart: HelmChart,\n aliases?: Record<string, string>,\n): PackageDependency | null {\n if (!helmChart.name) {\n return null;\n }\n\n if (isOCIRegistry(helmChart.repo)) {\n const dep = getDep(\n `${removeOCIPrefix(helmChart.repo)}/${helmChart.name}:${helmChart.version}`,\n false,\n aliases,\n );\n delete dep.replaceString;\n return {\n ...dep,\n depName: helmChart.name,\n // https://github.com/helm/helm/issues/10312\n // https://github.com/helm/helm/issues/10678\n pinDigests: false,\n };\n }\n\n return {\n depName: helmChart.name,\n currentValue: helmChart.version,\n registryUrls: [helmChart.repo],\n datasource: HelmDatasource.id,\n };\n}\n\nexport function parseKustomize(\n content: string,\n packageFile?: string,\n): Kustomize | null {\n let pkg: Kustomize | null = null;\n try {\n // TODO: use schema (#9610)\n pkg = parseSingleYaml(content);\n } catch /* istanbul ignore next */ {\n logger.debug({ packageFile }, 'Error parsing kustomize file');\n return null;\n }\n\n if (!pkg || isString(pkg)) {\n return null;\n }\n\n pkg.kind ??= 'Kustomization';\n\n if (!['Kustomization', 'Component'].includes(pkg.kind)) {\n return null;\n }\n\n return pkg;\n}\n\nexport function extractPackageFile(\n content: string,\n packageFile: string,\n config: ExtractConfig,\n): PackageFileContent | null {\n logger.trace(`kustomize.extractPackageFile(${packageFile})`);\n const deps: PackageDependency[] = [];\n\n const pkg = parseKustomize(content, packageFile);\n if (!pkg) {\n return null;\n }\n\n // grab the remote bases\n for (const base of coerceArray(pkg.bases).filter(isString)) {\n const dep = extractResource(base);\n if (dep) {\n deps.push({\n ...dep,\n depType: pkg.kind,\n });\n }\n }\n\n // grab the remote resources\n for (const resource of coerceArray(pkg.resources).filter(isString)) {\n const dep = extractResource(resource);\n if (dep) {\n deps.push({\n ...dep,\n depType: pkg.kind,\n });\n }\n }\n\n // grab the remote components\n for (const component of coerceArray(pkg.components).filter(isString)) {\n const dep = extractResource(component);\n if (dep) {\n deps.push({\n ...dep,\n depType: pkg.kind,\n });\n }\n }\n\n // grab the image tags\n for (const image of coerceArray(pkg.images)) {\n const dep = extractImage(image, config.registryAliases);\n if (dep) {\n deps.push({\n ...dep,\n depType: pkg.kind,\n });\n }\n }\n\n // grab the helm charts\n for (const helmChart of coerceArray(pkg.helmCharts)) {\n const dep = extractHelmChart(helmChart, config.registryAliases);\n if (dep) {\n deps.push({\n ...dep,\n depType: 'HelmChart',\n });\n }\n }\n\n if (!deps.length) {\n return null;\n }\n return { deps };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"extract.js","names":[],"sources":["../../../../lib/modules/manager/kustomize/extract.ts"],"sourcesContent":["import querystring from 'node:querystring';\nimport { isString } from '@sindresorhus/is';\nimport { logger } from '../../../logger/index.ts';\nimport { coerceArray } from '../../../util/array.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { parseSingleYaml } from '../../../util/yaml.ts';\nimport { GitTagsDatasource } from '../../datasource/git-tags/index.ts';\nimport { GithubTagsDatasource } from '../../datasource/github-tags/index.ts';\nimport { HelmDatasource } from '../../datasource/helm/index.ts';\nimport { getDep } from '../dockerfile/extract.ts';\nimport { getOciChartDep, isOCIRegistry } from '../helmv3/oci.ts';\nimport type {\n ExtractConfig,\n PackageDependency,\n PackageFileContent,\n} from '../types.ts';\nimport type { HelmChart, Image, Kustomize } from './types.ts';\n\n// URL specifications should follow the hashicorp URL format\n// https://github.com/hashicorp/go-getter#url-format\nconst gitUrl = regEx(\n /^(?:git::)?(?<url>(?:(?:(?:http|https|ssh):\\/\\/)?(?:.*@)?)?(?<path>(?:[^:/\\s]+(?::[0-9]+)?[:/])?(?<project>[^/\\s]+\\/[^/\\s]+)))(?<subdir>[^?\\s]*)\\?(?<queryString>.+)$/,\n);\n// regex to match URLs with \".git\" delimiter\nconst dotGitRegex = regEx(\n /^(?:git::)?(?<url>(?:(?:(?:http|https|ssh):\\/\\/)?(?:.*@)?)?(?<path>(?:[^:/\\s]+(?::[0-9]+)?[:/])?(?<project>[^?\\s]*(?:\\.git))))(?<subdir>[^?\\s]*)\\?(?<queryString>.+)$/,\n);\n// regex to match URLs with \"_git\" delimiter\nconst underscoreGitRegex = regEx(\n /^(?:git::)?(?<url>(?:(?:(?:http|https|ssh):\\/\\/)?(?:.*@)?)?(?<path>(?:[^:/\\s]+(?::[0-9]+)?[:/])?(?<project>[^?\\s]*)(?:_git\\/[^/\\s]+)))(?<subdir>[^?\\s]*)\\?(?<queryString>.+)$/,\n);\n// regex to match URLs having an extra \"//\"\nconst gitUrlWithPath = regEx(\n /^(?:git::)?(?<url>(?:(?:(?:http|https|ssh):\\/\\/)?(?:.*@)?)?(?<path>(?:[^:/\\s]+(?::[0-9]+)?[:/])(?<project>[^?\\s]+)))(?:\\/\\/)(?<subdir>[^?\\s]+)\\?(?<queryString>.+)$/,\n);\n\nexport function extractResource(base: string): PackageDependency | null {\n let match: RegExpExecArray | null;\n\n if (base.includes('_git')) {\n match = underscoreGitRegex.exec(base);\n } else if (base.includes('.git')) {\n match = dotGitRegex.exec(base);\n } else if (gitUrlWithPath.test(base)) {\n match = gitUrlWithPath.exec(base);\n } else {\n match = gitUrl.exec(base);\n }\n\n if (!match?.groups) {\n return null;\n }\n\n const { path, queryString } = match.groups;\n const params = querystring.parse(queryString);\n const refParam = Array.isArray(params.ref) ? params.ref[0] : params.ref;\n const versionParam = Array.isArray(params.version)\n ? params.version[0]\n : params.version;\n const currentValue = refParam ?? versionParam;\n if (!currentValue) {\n return null;\n }\n\n if (regEx(/(?:github\\.com)(?::|\\/)/).test(path)) {\n return {\n currentValue,\n datasource: GithubTagsDatasource.id,\n depName: match.groups.project.replace('.git', ''),\n };\n }\n\n return {\n datasource: GitTagsDatasource.id,\n depName: path.replace('.git', ''),\n packageName: match.groups.url,\n currentValue,\n };\n}\n\nexport function extractImage(\n image: Image,\n aliases?: Record<string, string>,\n): PackageDependency | null {\n if (!image.name) {\n return null;\n }\n const nameToSplit = image.newName ?? image.name;\n if (!isString(nameToSplit)) {\n logger.debug({ image }, 'Invalid image name');\n return null;\n }\n const nameDep = getDep(nameToSplit, false, aliases);\n const { depName } = nameDep;\n const { digest, newTag } = image;\n if (digest && newTag) {\n logger.debug(\n { newTag, digest },\n 'Kustomize ignores newTag when digest is provided. Pick one, or use `newTag: tag@digest`',\n );\n return {\n depName,\n currentValue: newTag,\n currentDigest: digest,\n skipReason: 'invalid-dependency-specification',\n };\n }\n\n if (digest) {\n if (!isString(digest) || !digest.startsWith('sha256:')) {\n return {\n depName,\n currentValue: digest,\n skipReason: 'invalid-value',\n };\n }\n\n return {\n ...nameDep,\n currentDigest: digest,\n replaceString: digest,\n };\n }\n\n if (newTag) {\n if (!isString(newTag) || newTag.startsWith('sha256:')) {\n return {\n depName,\n currentValue: newTag,\n skipReason: 'invalid-value',\n };\n }\n\n const dep = getDep(`${depName}:${newTag}`, false, aliases);\n return {\n ...dep,\n replaceString: newTag,\n autoReplaceStringTemplate:\n '{{newValue}}{{#if newDigest}}@{{newDigest}}{{/if}}',\n };\n }\n\n if (image.newName) {\n return {\n ...nameDep,\n replaceString: image.newName,\n };\n }\n\n return null;\n}\n\nexport function extractHelmChart(\n helmChart: HelmChart,\n aliases?: Record<string, string>,\n): PackageDependency | null {\n if (!helmChart.name) {\n return null;\n }\n\n if (isOCIRegistry(helmChart.repo)) {\n return {\n ...getOciChartDep(helmChart.repo, helmChart.name, aliases),\n depName: helmChart.name,\n currentValue: helmChart.version,\n };\n }\n\n return {\n depName: helmChart.name,\n currentValue: helmChart.version,\n registryUrls: [helmChart.repo],\n datasource: HelmDatasource.id,\n };\n}\n\nexport function parseKustomize(\n content: string,\n packageFile?: string,\n): Kustomize | null {\n let pkg: Kustomize | null = null;\n try {\n // TODO: use schema (#9610)\n pkg = parseSingleYaml(content);\n } catch /* istanbul ignore next */ {\n logger.debug({ packageFile }, 'Error parsing kustomize file');\n return null;\n }\n\n if (!pkg || isString(pkg)) {\n return null;\n }\n\n pkg.kind ??= 'Kustomization';\n\n if (!['Kustomization', 'Component'].includes(pkg.kind)) {\n return null;\n }\n\n return pkg;\n}\n\nexport function extractPackageFile(\n content: string,\n packageFile: string,\n config: ExtractConfig,\n): PackageFileContent | null {\n logger.trace(`kustomize.extractPackageFile(${packageFile})`);\n const deps: PackageDependency[] = [];\n\n const pkg = parseKustomize(content, packageFile);\n if (!pkg) {\n return null;\n }\n\n // grab the remote bases\n for (const base of coerceArray(pkg.bases).filter(isString)) {\n const dep = extractResource(base);\n if (dep) {\n deps.push({\n ...dep,\n depType: pkg.kind,\n });\n }\n }\n\n // grab the remote resources\n for (const resource of coerceArray(pkg.resources).filter(isString)) {\n const dep = extractResource(resource);\n if (dep) {\n deps.push({\n ...dep,\n depType: pkg.kind,\n });\n }\n }\n\n // grab the remote components\n for (const component of coerceArray(pkg.components).filter(isString)) {\n const dep = extractResource(component);\n if (dep) {\n deps.push({\n ...dep,\n depType: pkg.kind,\n });\n }\n }\n\n // grab the image tags\n for (const image of coerceArray(pkg.images)) {\n const dep = extractImage(image, config.registryAliases);\n if (dep) {\n deps.push({\n ...dep,\n depType: pkg.kind,\n });\n }\n }\n\n // grab the helm charts\n for (const helmChart of coerceArray(pkg.helmCharts)) {\n const dep = extractHelmChart(helmChart, config.registryAliases);\n if (dep) {\n deps.push({\n ...dep,\n depType: 'HelmChart',\n });\n }\n }\n\n if (!deps.length) {\n return null;\n }\n return { deps };\n}\n"],"mappings":"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"}
@@ -36,7 +36,7 @@ async function extractPackageFile(content, packageFile) {
36
36
  }
37
37
  } else logger.debug({
38
38
  lockFileName,
39
- error: lockFileParsed.error
39
+ err: lockFileParsed.error
40
40
  }, "Failed to parse mise lock file");
41
41
  }
42
42
  return result;
@@ -1 +1 @@
1
- {"version":3,"file":"extract.js","names":[],"sources":["../../../../lib/modules/manager/mise/extract.ts"],"sourcesContent":["import {\n isArray,\n isFunction,\n isNonEmptyObject,\n isNonEmptyString,\n isObject,\n isString,\n} from '@sindresorhus/is';\nimport { logger } from '../../../logger/index.ts';\nimport { readLocalFile } from '../../../util/fs/index.ts';\nimport { coerceObject } from '../../../util/object.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport type { StaticTooling } from '../asdf/types.ts';\nimport type { PackageDependency, PackageFileContent } from '../types.ts';\nimport {\n createAquaToolConfig,\n createCargoToolConfig,\n createDotnetToolConfig,\n createGemToolConfig,\n createGithubToolConfig,\n createGoToolConfig,\n createNpmToolConfig,\n createPipxToolConfig,\n createSpmToolConfig,\n createUbiToolConfig,\n} from './backends.ts';\nimport { getLockFileName, getLockedVersion } from './lockfile.ts';\nimport type { MiseTool, MiseToolOptions } from './schema.ts';\nimport { MiseLockFile } from './schema.ts';\nimport type { BackendToolingConfig, ToolingDefinition } from './types.ts';\nimport {\n asdfTooling,\n getOrderedMiseRegistryBackends,\n miseTooling,\n} from './upgradeable-tooling.ts';\nimport { parseTomlFile } from './utils.ts';\n\n// Tool names can have options in the tool name\n// e.g. ubi:tamasfe/taplo[matching=full,exe=taplo]\nconst optionInToolNameRegex = regEx(/^(?<name>.+?)(?:\\[(?<options>.+)\\])?$/);\n\n/**\n * Extracts mise tool dependencies from a mise configuration file.\n * Supports various backends (core, asdf, aqua, cargo, etc.) and\n * extracts locked versions when a corresponding lock file exists.\n */\nexport async function extractPackageFile(\n content: string,\n packageFile: string,\n): Promise<PackageFileContent | null> {\n logger.trace(`mise.extractPackageFile(${packageFile})`);\n\n const misefile = parseTomlFile(content, packageFile);\n if (!misefile) {\n return null;\n }\n\n const deps: PackageDependency[] = [];\n\n for (const [name, toolData] of Object.entries(misefile.tools)) {\n deps.push(extractToolEntry(name, toolData, 'tools'));\n }\n\n for (const [taskName, taskData] of Object.entries(misefile.tasks)) {\n for (const [name, toolData] of Object.entries(\n coerceObject(taskData.tools),\n )) {\n deps.push(extractToolEntry(name, toolData, `task-${taskName}-tools`));\n }\n }\n\n if (!deps.length) {\n return null;\n }\n\n const result: PackageFileContent = { deps };\n\n const lockFileName = getLockFileName(packageFile);\n const lockFileContent = await readLocalFile(lockFileName, 'utf8');\n\n if (lockFileContent) {\n const lockFileParsed = MiseLockFile.safeParse(lockFileContent);\n if (lockFileParsed.success) {\n result.lockFiles = [lockFileName];\n for (const dep of deps) {\n const lockedVersion = getLockedVersion(\n lockFileParsed.data,\n dep.depName!,\n );\n if (lockedVersion) {\n dep.lockedVersion = lockedVersion;\n }\n }\n } else {\n logger.debug(\n { lockFileName, error: lockFileParsed.error },\n 'Failed to parse mise lock file',\n );\n }\n }\n\n return result;\n}\n\nfunction parseVersion(toolData: MiseTool): string | null {\n if (isNonEmptyString(toolData)) {\n // Handle the string case\n // e.g. 'erlang = \"23.3\"'\n return toolData;\n }\n if (isArray(toolData, isString)) {\n // Handle the array case\n // e.g. 'erlang = [\"23.3\", \"24.0\"]'\n return toolData.length ? toolData[0] : null; // Get the first version in the array\n }\n if (isObject(toolData) && isNonEmptyString(toolData.version)) {\n // Handle the object case with a string version\n // e.g. 'python = { version = \"3.11.2\" }'\n return toolData.version;\n }\n return null; // Return null if no version is found\n}\n\nfunction parseOptions(\n optionsInName: string,\n toolOptions: MiseToolOptions,\n): MiseToolOptions {\n const options = isNonEmptyString(optionsInName)\n ? Object.fromEntries(\n optionsInName.split(',').map((option) => option.split('=', 2)),\n )\n : {};\n // Options in toolOptions will override options in the tool name\n return {\n ...options,\n ...toolOptions,\n };\n}\n\nfunction getToolConfig(\n backend: string,\n toolName: string,\n version: string,\n toolOptions: MiseToolOptions,\n): StaticTooling | BackendToolingConfig | null {\n switch (backend) {\n case '': {\n // If the tool name does not specify a backend, it should be a short name or an alias defined by users\n const staticResult = getRegistryToolConfig(toolName, version);\n if (staticResult) {\n return staticResult;\n }\n\n // Otherwise, see if we have any known short tool names that are in the `mise-registry.json` data file\n const backends = getOrderedMiseRegistryBackends(toolName);\n\n // prioritise the github backend as the best source for data\n if (backends.github) {\n const result = getToolConfig(\n 'github',\n backends.github,\n version,\n toolOptions,\n );\n // v8 ignore else -- TODO: add test #40625\n if (result !== null) {\n return result;\n }\n }\n\n for (const [backendType, backendName] of Object.entries(backends)) {\n const result = getToolConfig(\n backendType,\n backendName,\n version,\n toolOptions,\n );\n // v8 ignore else -- TODO: add test #40625\n if (result !== null) {\n return result;\n }\n }\n return null;\n }\n // We can specify core, asdf, vfox, aqua backends for tools in the default registry\n // e.g. 'core:rust', 'asdf:rust', 'vfox:clang', 'aqua:act'\n case 'core':\n return getConfigFromTooling(miseTooling, toolName, version);\n case 'asdf':\n return getConfigFromTooling(asdfTooling, toolName, version);\n case 'vfox':\n return getRegistryToolConfig(toolName, version);\n case 'aqua':\n return (\n getRegistryToolConfig(toolName, version) ??\n createAquaToolConfig(toolName, version)\n );\n case 'cargo':\n return createCargoToolConfig(toolName, version);\n case 'dotnet':\n return createDotnetToolConfig(toolName);\n case 'gem':\n return createGemToolConfig(toolName);\n case 'github':\n return createGithubToolConfig(toolName, version, toolOptions);\n case 'go':\n return createGoToolConfig(toolName);\n case 'npm':\n return createNpmToolConfig(toolName);\n case 'pipx':\n return createPipxToolConfig(toolName);\n case 'spm':\n return createSpmToolConfig(toolName);\n case 'ubi':\n return createUbiToolConfig(toolName, version, toolOptions);\n default:\n // Unsupported backend\n return null;\n }\n}\n\n/**\n * Get the tooling config for a short name defined in the default registry\n * @link https://mise.jdx.dev/registry.html\n */\nfunction getRegistryToolConfig(\n short: string,\n version: string,\n): StaticTooling | null {\n // Try to get the config from miseTooling first, then asdfTooling\n return (\n getConfigFromTooling(miseTooling, short, version) ??\n getConfigFromTooling(asdfTooling, short, version)\n );\n}\n\nfunction getConfigFromTooling(\n toolingSource: Record<string, ToolingDefinition>,\n name: string,\n version: string,\n): StaticTooling | null {\n const toolDefinition = toolingSource[name];\n if (!toolDefinition) {\n return null;\n } // Return null if no toolDefinition is found\n\n return (\n (isFunction(toolDefinition.config)\n ? toolDefinition.config(version)\n : toolDefinition.config) ?? null\n ); // Ensure null is returned instead of undefined\n}\n\nfunction extractToolEntry(\n name: string,\n toolData: MiseTool,\n depType: string,\n): PackageDependency {\n const version = parseVersion(toolData);\n const { name: depName, options: optionsInName } = optionInToolNameRegex.exec(\n name.trim(),\n )!.groups!;\n const delimiterIndex = depName.indexOf(':');\n const backend = depName.substring(0, delimiterIndex);\n const toolName = depName.substring(delimiterIndex + 1);\n const options = parseOptions(\n optionsInName,\n isNonEmptyObject(toolData) ? toolData : {},\n );\n const toolConfig =\n version === null\n ? null\n : getToolConfig(backend, toolName, version, options);\n return createDependency(depName, version, toolConfig, depType);\n}\n\nfunction createDependency(\n name: string,\n version: string | null,\n config: StaticTooling | BackendToolingConfig | null,\n depType: string,\n): PackageDependency {\n if (version === null) {\n return {\n depName: name,\n depType,\n skipReason: 'unspecified-version',\n };\n }\n if (config === null) {\n return {\n depName: name,\n depType,\n skipReason: 'unsupported-datasource',\n };\n }\n\n return {\n depName: name,\n depType,\n currentValue: version,\n // Spread the config last to override other properties\n ...config,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"extract.js","names":[],"sources":["../../../../lib/modules/manager/mise/extract.ts"],"sourcesContent":["import {\n isArray,\n isFunction,\n isNonEmptyObject,\n isNonEmptyString,\n isObject,\n isString,\n} from '@sindresorhus/is';\nimport { logger } from '../../../logger/index.ts';\nimport { readLocalFile } from '../../../util/fs/index.ts';\nimport { coerceObject } from '../../../util/object.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport type { StaticTooling } from '../asdf/types.ts';\nimport type { PackageDependency, PackageFileContent } from '../types.ts';\nimport {\n createAquaToolConfig,\n createCargoToolConfig,\n createDotnetToolConfig,\n createGemToolConfig,\n createGithubToolConfig,\n createGoToolConfig,\n createNpmToolConfig,\n createPipxToolConfig,\n createSpmToolConfig,\n createUbiToolConfig,\n} from './backends.ts';\nimport { getLockFileName, getLockedVersion } from './lockfile.ts';\nimport type { MiseTool, MiseToolOptions } from './schema.ts';\nimport { MiseLockFile } from './schema.ts';\nimport type { BackendToolingConfig, ToolingDefinition } from './types.ts';\nimport {\n asdfTooling,\n getOrderedMiseRegistryBackends,\n miseTooling,\n} from './upgradeable-tooling.ts';\nimport { parseTomlFile } from './utils.ts';\n\n// Tool names can have options in the tool name\n// e.g. ubi:tamasfe/taplo[matching=full,exe=taplo]\nconst optionInToolNameRegex = regEx(/^(?<name>.+?)(?:\\[(?<options>.+)\\])?$/);\n\n/**\n * Extracts mise tool dependencies from a mise configuration file.\n * Supports various backends (core, asdf, aqua, cargo, etc.) and\n * extracts locked versions when a corresponding lock file exists.\n */\nexport async function extractPackageFile(\n content: string,\n packageFile: string,\n): Promise<PackageFileContent | null> {\n logger.trace(`mise.extractPackageFile(${packageFile})`);\n\n const misefile = parseTomlFile(content, packageFile);\n if (!misefile) {\n return null;\n }\n\n const deps: PackageDependency[] = [];\n\n for (const [name, toolData] of Object.entries(misefile.tools)) {\n deps.push(extractToolEntry(name, toolData, 'tools'));\n }\n\n for (const [taskName, taskData] of Object.entries(misefile.tasks)) {\n for (const [name, toolData] of Object.entries(\n coerceObject(taskData.tools),\n )) {\n deps.push(extractToolEntry(name, toolData, `task-${taskName}-tools`));\n }\n }\n\n if (!deps.length) {\n return null;\n }\n\n const result: PackageFileContent = { deps };\n\n const lockFileName = getLockFileName(packageFile);\n const lockFileContent = await readLocalFile(lockFileName, 'utf8');\n\n if (lockFileContent) {\n const lockFileParsed = MiseLockFile.safeParse(lockFileContent);\n if (lockFileParsed.success) {\n result.lockFiles = [lockFileName];\n for (const dep of deps) {\n const lockedVersion = getLockedVersion(\n lockFileParsed.data,\n dep.depName!,\n );\n if (lockedVersion) {\n dep.lockedVersion = lockedVersion;\n }\n }\n } else {\n logger.debug(\n { lockFileName, err: lockFileParsed.error },\n 'Failed to parse mise lock file',\n );\n }\n }\n\n return result;\n}\n\nfunction parseVersion(toolData: MiseTool): string | null {\n if (isNonEmptyString(toolData)) {\n // Handle the string case\n // e.g. 'erlang = \"23.3\"'\n return toolData;\n }\n if (isArray(toolData, isString)) {\n // Handle the array case\n // e.g. 'erlang = [\"23.3\", \"24.0\"]'\n return toolData.length ? toolData[0] : null; // Get the first version in the array\n }\n if (isObject(toolData) && isNonEmptyString(toolData.version)) {\n // Handle the object case with a string version\n // e.g. 'python = { version = \"3.11.2\" }'\n return toolData.version;\n }\n return null; // Return null if no version is found\n}\n\nfunction parseOptions(\n optionsInName: string,\n toolOptions: MiseToolOptions,\n): MiseToolOptions {\n const options = isNonEmptyString(optionsInName)\n ? Object.fromEntries(\n optionsInName.split(',').map((option) => option.split('=', 2)),\n )\n : {};\n // Options in toolOptions will override options in the tool name\n return {\n ...options,\n ...toolOptions,\n };\n}\n\nfunction getToolConfig(\n backend: string,\n toolName: string,\n version: string,\n toolOptions: MiseToolOptions,\n): StaticTooling | BackendToolingConfig | null {\n switch (backend) {\n case '': {\n // If the tool name does not specify a backend, it should be a short name or an alias defined by users\n const staticResult = getRegistryToolConfig(toolName, version);\n if (staticResult) {\n return staticResult;\n }\n\n // Otherwise, see if we have any known short tool names that are in the `mise-registry.json` data file\n const backends = getOrderedMiseRegistryBackends(toolName);\n\n // prioritise the github backend as the best source for data\n if (backends.github) {\n const result = getToolConfig(\n 'github',\n backends.github,\n version,\n toolOptions,\n );\n // v8 ignore else -- TODO: add test #40625\n if (result !== null) {\n return result;\n }\n }\n\n for (const [backendType, backendName] of Object.entries(backends)) {\n const result = getToolConfig(\n backendType,\n backendName,\n version,\n toolOptions,\n );\n // v8 ignore else -- TODO: add test #40625\n if (result !== null) {\n return result;\n }\n }\n return null;\n }\n // We can specify core, asdf, vfox, aqua backends for tools in the default registry\n // e.g. 'core:rust', 'asdf:rust', 'vfox:clang', 'aqua:act'\n case 'core':\n return getConfigFromTooling(miseTooling, toolName, version);\n case 'asdf':\n return getConfigFromTooling(asdfTooling, toolName, version);\n case 'vfox':\n return getRegistryToolConfig(toolName, version);\n case 'aqua':\n return (\n getRegistryToolConfig(toolName, version) ??\n createAquaToolConfig(toolName, version)\n );\n case 'cargo':\n return createCargoToolConfig(toolName, version);\n case 'dotnet':\n return createDotnetToolConfig(toolName);\n case 'gem':\n return createGemToolConfig(toolName);\n case 'github':\n return createGithubToolConfig(toolName, version, toolOptions);\n case 'go':\n return createGoToolConfig(toolName);\n case 'npm':\n return createNpmToolConfig(toolName);\n case 'pipx':\n return createPipxToolConfig(toolName);\n case 'spm':\n return createSpmToolConfig(toolName);\n case 'ubi':\n return createUbiToolConfig(toolName, version, toolOptions);\n default:\n // Unsupported backend\n return null;\n }\n}\n\n/**\n * Get the tooling config for a short name defined in the default registry\n * @link https://mise.jdx.dev/registry.html\n */\nfunction getRegistryToolConfig(\n short: string,\n version: string,\n): StaticTooling | null {\n // Try to get the config from miseTooling first, then asdfTooling\n return (\n getConfigFromTooling(miseTooling, short, version) ??\n getConfigFromTooling(asdfTooling, short, version)\n );\n}\n\nfunction getConfigFromTooling(\n toolingSource: Record<string, ToolingDefinition>,\n name: string,\n version: string,\n): StaticTooling | null {\n const toolDefinition = toolingSource[name];\n if (!toolDefinition) {\n return null;\n } // Return null if no toolDefinition is found\n\n return (\n (isFunction(toolDefinition.config)\n ? toolDefinition.config(version)\n : toolDefinition.config) ?? null\n ); // Ensure null is returned instead of undefined\n}\n\nfunction extractToolEntry(\n name: string,\n toolData: MiseTool,\n depType: string,\n): PackageDependency {\n const version = parseVersion(toolData);\n const { name: depName, options: optionsInName } = optionInToolNameRegex.exec(\n name.trim(),\n )!.groups!;\n const delimiterIndex = depName.indexOf(':');\n const backend = depName.substring(0, delimiterIndex);\n const toolName = depName.substring(delimiterIndex + 1);\n const options = parseOptions(\n optionsInName,\n isNonEmptyObject(toolData) ? toolData : {},\n );\n const toolConfig =\n version === null\n ? null\n : getToolConfig(backend, toolName, version, options);\n return createDependency(depName, version, toolConfig, depType);\n}\n\nfunction createDependency(\n name: string,\n version: string | null,\n config: StaticTooling | BackendToolingConfig | null,\n depType: string,\n): PackageDependency {\n if (version === null) {\n return {\n depName: name,\n depType,\n skipReason: 'unspecified-version',\n };\n }\n if (config === null) {\n return {\n depName: name,\n depType,\n skipReason: 'unsupported-datasource',\n };\n }\n\n return {\n depName: name,\n depType,\n currentValue: version,\n // Spread the config last to override other properties\n ...config,\n };\n}\n"],"mappings":"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"}
@@ -17,7 +17,7 @@ async function extractPackageFile(content, packageFile, config) {
17
17
  if (!flakeLockParsed.success) {
18
18
  logger.debug({
19
19
  flakeLockFile,
20
- error: flakeLockParsed.error
20
+ err: flakeLockParsed.error
21
21
  }, `invalid flake.lock file`);
22
22
  return null;
23
23
  }
@@ -26,7 +26,7 @@ async function extractPackageFile(content, packageFile, config) {
26
26
  if (!rootInputs) {
27
27
  logger.debug({
28
28
  flakeLockFile,
29
- error: flakeLockParsed.error
29
+ err: flakeLockParsed.error
30
30
  }, `flake.lock is missing "root" node`);
31
31
  return null;
32
32
  }
@@ -1 +1 @@
1
- {"version":3,"file":"extract.js","names":["nixpkgsVersioning"],"sources":["../../../../lib/modules/manager/nix/extract.ts"],"sourcesContent":["import { logger } from '../../../logger/index.ts';\nimport { getSiblingFileName, readLocalFile } from '../../../util/fs/index.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { GitRefsDatasource } from '../../datasource/git-refs/index.ts';\nimport { id as gitRefVersioning } from '../../versioning/git/index.ts';\nimport { id as nixpkgsVersioning } from '../../versioning/nixpkgs/index.ts';\nimport type {\n ExtractConfig,\n PackageDependency,\n PackageFileContent,\n} from '../types.ts';\nimport { NixFlakeLock } from './schema.ts';\n\n// as documented upstream\n// https://github.com/NixOS/nix/blob/master/doc/manual/source/protocols/tarball-fetcher.md#gitea-and-forgejo-support\nconst lockableHTTPTarballProtocol = regEx(\n '^https://(?<domain>[^/]+)/(?<owner>[^/]+)/(?<repo>[^/]+)/archive/(?<rev>.+).tar.gz$',\n);\n\nconst lockableChannelOriginalUrl = regEx(\n '^https://(?:channels\\\\.nixos\\\\.org|nixos\\\\.org/channels)/(?<channel>[^/]+)/nixexprs\\\\.tar\\\\.xz$',\n);\n\nexport async function extractPackageFile(\n content: string,\n packageFile: string,\n config?: ExtractConfig,\n): Promise<PackageFileContent | null> {\n const flakeLockFile = getSiblingFileName(packageFile, 'flake.lock');\n const flakeLockContents = await readLocalFile(flakeLockFile, 'utf8');\n\n logger.trace(`nix.extractPackageFile(${flakeLockFile})`);\n\n const deps: PackageDependency[] = [];\n\n const flakeLockParsed = NixFlakeLock.safeParse(flakeLockContents);\n if (!flakeLockParsed.success) {\n logger.debug(\n { flakeLockFile, error: flakeLockParsed.error },\n `invalid flake.lock file`,\n );\n return null;\n }\n\n const flakeLock = flakeLockParsed.data;\n const rootInputs = flakeLock.nodes.root.inputs;\n\n if (!rootInputs) {\n logger.debug(\n { flakeLockFile, error: flakeLockParsed.error },\n `flake.lock is missing \"root\" node`,\n );\n return null;\n }\n\n for (const [depName, flakeInput] of Object.entries(flakeLock.nodes)) {\n // the root input is a magic string for the entrypoint and only references other flake inputs\n if (depName === 'root') {\n continue;\n }\n\n // skip all locked and transitivie nodes as they cannot be updated by regular means\n if (!(depName in rootInputs)) {\n continue;\n }\n\n // flakeLocked example: { rev: '56a49ffef2908dad1e9a8adef1f18802bc760962', type: 'github' }\n const flakeLocked = flakeInput.locked;\n // flakeOriginal example: { owner: 'NuschtOS', repo: 'search', type: 'github' }\n const flakeOriginal = flakeInput.original;\n\n if (flakeLocked === undefined) {\n logger.debug(\n { flakeLockFile, flakeInput },\n `input is missing locked, skipping`,\n );\n continue;\n }\n\n if (flakeOriginal === undefined) {\n logger.debug(\n { flakeLockFile, flakeInput },\n `input is missing original, skipping`,\n );\n continue;\n }\n\n // indirect inputs cannot be reliably updated because they depend on the flake registry\n if (flakeOriginal.type === 'indirect' || flakeLocked.type === 'indirect') {\n logger.debug(\n { flakeLockFile, flakeInput },\n `input is type indirect, skipping`,\n );\n continue;\n }\n\n // cannot update local path inputs\n if (flakeOriginal.type === 'path' || flakeLocked.type === 'path') {\n logger.debug(\n { flakeLockFile, flakeInput },\n `input is type path, skipping`,\n );\n continue;\n }\n\n // if no rev is being tracked, we cannot update this input\n if (flakeLocked.rev === undefined) {\n logger.debug(\n { flakeLockFile, flakeInput },\n `locked input is not tracking a rev, skipping`,\n );\n continue;\n }\n\n // if there's a new digest, set the corresponding digest in the lockfile so confirmations pass\n const currentDigest = config?.currentDigest;\n const newDigest = config?.newDigest;\n if (\n currentDigest &&\n newDigest &&\n flakeOriginal.rev &&\n flakeOriginal.rev === currentDigest && // currentDigest is the old digest\n content.includes(newDigest) // flake.nix contains the new digest\n ) {\n logger.debug(\n { flakeLockFile, flakeInput },\n `overriding rev ${flakeOriginal.rev} with new digest ${newDigest}`,\n );\n flakeOriginal.rev = newDigest;\n }\n\n const dep: PackageDependency = {\n depName,\n datasource: GitRefsDatasource.id,\n versioning: gitRefVersioning,\n };\n\n // if rev is set, the flake contains a digest and can be updated directly\n // otherwise set lockedVersion so it is updated during lock file maintenance\n if (flakeOriginal.rev) {\n dep.currentValue = flakeOriginal.ref;\n dep.currentDigest = flakeOriginal.rev;\n dep.replaceString = flakeOriginal.rev;\n } else {\n dep.lockedVersion = flakeLocked.rev;\n }\n\n switch (flakeLocked.type) {\n case 'github':\n // set to nixpkgs if it is a nixpkgs reference\n if (\n flakeOriginal.owner?.toLowerCase() === 'nixos' &&\n flakeOriginal.repo?.toLowerCase() === 'nixpkgs'\n ) {\n dep.packageName = 'https://github.com/NixOS/nixpkgs';\n dep.currentValue = flakeOriginal.ref;\n dep.versioning = nixpkgsVersioning;\n break;\n }\n\n dep.packageName = `https://${flakeOriginal.host ?? 'github.com'}/${flakeOriginal.owner}/${flakeOriginal.repo}`;\n break;\n\n case 'gitlab':\n dep.packageName = `https://${flakeOriginal.host ?? 'gitlab.com'}/${decodeURIComponent(flakeOriginal.owner!)}/${flakeOriginal.repo}`;\n break;\n\n case 'git':\n dep.packageName = flakeOriginal.url;\n break;\n\n case 'sourcehut':\n dep.packageName = `https://${flakeOriginal.host ?? 'git.sr.ht'}/${flakeOriginal.owner}/${flakeOriginal.repo}`;\n break;\n\n case 'tarball':\n // set to nixpkgs if it is a lockable channel URL\n if (\n flakeOriginal.url &&\n lockableChannelOriginalUrl.test(flakeOriginal.url)\n ) {\n dep.packageName = 'https://github.com/NixOS/nixpkgs';\n dep.currentValue = flakeOriginal.url.replace(\n lockableChannelOriginalUrl,\n '$<channel>',\n );\n dep.versioning = nixpkgsVersioning;\n break;\n }\n\n dep.packageName = flakeOriginal.url!.replace(\n lockableHTTPTarballProtocol,\n 'https://$<domain>/$<owner>/$<repo>',\n );\n break;\n }\n\n deps.push(dep);\n }\n\n if (deps.length) {\n return { deps };\n }\n\n return null;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"extract.js","names":["nixpkgsVersioning"],"sources":["../../../../lib/modules/manager/nix/extract.ts"],"sourcesContent":["import { logger } from '../../../logger/index.ts';\nimport { getSiblingFileName, readLocalFile } from '../../../util/fs/index.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { GitRefsDatasource } from '../../datasource/git-refs/index.ts';\nimport { id as gitRefVersioning } from '../../versioning/git/index.ts';\nimport { id as nixpkgsVersioning } from '../../versioning/nixpkgs/index.ts';\nimport type {\n ExtractConfig,\n PackageDependency,\n PackageFileContent,\n} from '../types.ts';\nimport { NixFlakeLock } from './schema.ts';\n\n// as documented upstream\n// https://github.com/NixOS/nix/blob/master/doc/manual/source/protocols/tarball-fetcher.md#gitea-and-forgejo-support\nconst lockableHTTPTarballProtocol = regEx(\n '^https://(?<domain>[^/]+)/(?<owner>[^/]+)/(?<repo>[^/]+)/archive/(?<rev>.+).tar.gz$',\n);\n\nconst lockableChannelOriginalUrl = regEx(\n '^https://(?:channels\\\\.nixos\\\\.org|nixos\\\\.org/channels)/(?<channel>[^/]+)/nixexprs\\\\.tar\\\\.xz$',\n);\n\nexport async function extractPackageFile(\n content: string,\n packageFile: string,\n config?: ExtractConfig,\n): Promise<PackageFileContent | null> {\n const flakeLockFile = getSiblingFileName(packageFile, 'flake.lock');\n const flakeLockContents = await readLocalFile(flakeLockFile, 'utf8');\n\n logger.trace(`nix.extractPackageFile(${flakeLockFile})`);\n\n const deps: PackageDependency[] = [];\n\n const flakeLockParsed = NixFlakeLock.safeParse(flakeLockContents);\n if (!flakeLockParsed.success) {\n logger.debug(\n { flakeLockFile, err: flakeLockParsed.error },\n `invalid flake.lock file`,\n );\n return null;\n }\n\n const flakeLock = flakeLockParsed.data;\n const rootInputs = flakeLock.nodes.root.inputs;\n\n if (!rootInputs) {\n logger.debug(\n { flakeLockFile, err: flakeLockParsed.error },\n `flake.lock is missing \"root\" node`,\n );\n return null;\n }\n\n for (const [depName, flakeInput] of Object.entries(flakeLock.nodes)) {\n // the root input is a magic string for the entrypoint and only references other flake inputs\n if (depName === 'root') {\n continue;\n }\n\n // skip all locked and transitivie nodes as they cannot be updated by regular means\n if (!(depName in rootInputs)) {\n continue;\n }\n\n // flakeLocked example: { rev: '56a49ffef2908dad1e9a8adef1f18802bc760962', type: 'github' }\n const flakeLocked = flakeInput.locked;\n // flakeOriginal example: { owner: 'NuschtOS', repo: 'search', type: 'github' }\n const flakeOriginal = flakeInput.original;\n\n if (flakeLocked === undefined) {\n logger.debug(\n { flakeLockFile, flakeInput },\n `input is missing locked, skipping`,\n );\n continue;\n }\n\n if (flakeOriginal === undefined) {\n logger.debug(\n { flakeLockFile, flakeInput },\n `input is missing original, skipping`,\n );\n continue;\n }\n\n // indirect inputs cannot be reliably updated because they depend on the flake registry\n if (flakeOriginal.type === 'indirect' || flakeLocked.type === 'indirect') {\n logger.debug(\n { flakeLockFile, flakeInput },\n `input is type indirect, skipping`,\n );\n continue;\n }\n\n // cannot update local path inputs\n if (flakeOriginal.type === 'path' || flakeLocked.type === 'path') {\n logger.debug(\n { flakeLockFile, flakeInput },\n `input is type path, skipping`,\n );\n continue;\n }\n\n // if no rev is being tracked, we cannot update this input\n if (flakeLocked.rev === undefined) {\n logger.debug(\n { flakeLockFile, flakeInput },\n `locked input is not tracking a rev, skipping`,\n );\n continue;\n }\n\n // if there's a new digest, set the corresponding digest in the lockfile so confirmations pass\n const currentDigest = config?.currentDigest;\n const newDigest = config?.newDigest;\n if (\n currentDigest &&\n newDigest &&\n flakeOriginal.rev &&\n flakeOriginal.rev === currentDigest && // currentDigest is the old digest\n content.includes(newDigest) // flake.nix contains the new digest\n ) {\n logger.debug(\n { flakeLockFile, flakeInput },\n `overriding rev ${flakeOriginal.rev} with new digest ${newDigest}`,\n );\n flakeOriginal.rev = newDigest;\n }\n\n const dep: PackageDependency = {\n depName,\n datasource: GitRefsDatasource.id,\n versioning: gitRefVersioning,\n };\n\n // if rev is set, the flake contains a digest and can be updated directly\n // otherwise set lockedVersion so it is updated during lock file maintenance\n if (flakeOriginal.rev) {\n dep.currentValue = flakeOriginal.ref;\n dep.currentDigest = flakeOriginal.rev;\n dep.replaceString = flakeOriginal.rev;\n } else {\n dep.lockedVersion = flakeLocked.rev;\n }\n\n switch (flakeLocked.type) {\n case 'github':\n // set to nixpkgs if it is a nixpkgs reference\n if (\n flakeOriginal.owner?.toLowerCase() === 'nixos' &&\n flakeOriginal.repo?.toLowerCase() === 'nixpkgs'\n ) {\n dep.packageName = 'https://github.com/NixOS/nixpkgs';\n dep.currentValue = flakeOriginal.ref;\n dep.versioning = nixpkgsVersioning;\n break;\n }\n\n dep.packageName = `https://${flakeOriginal.host ?? 'github.com'}/${flakeOriginal.owner}/${flakeOriginal.repo}`;\n break;\n\n case 'gitlab':\n dep.packageName = `https://${flakeOriginal.host ?? 'gitlab.com'}/${decodeURIComponent(flakeOriginal.owner!)}/${flakeOriginal.repo}`;\n break;\n\n case 'git':\n dep.packageName = flakeOriginal.url;\n break;\n\n case 'sourcehut':\n dep.packageName = `https://${flakeOriginal.host ?? 'git.sr.ht'}/${flakeOriginal.owner}/${flakeOriginal.repo}`;\n break;\n\n case 'tarball':\n // set to nixpkgs if it is a lockable channel URL\n if (\n flakeOriginal.url &&\n lockableChannelOriginalUrl.test(flakeOriginal.url)\n ) {\n dep.packageName = 'https://github.com/NixOS/nixpkgs';\n dep.currentValue = flakeOriginal.url.replace(\n lockableChannelOriginalUrl,\n '$<channel>',\n );\n dep.versioning = nixpkgsVersioning;\n break;\n }\n\n dep.packageName = flakeOriginal.url!.replace(\n lockableHTTPTarballProtocol,\n 'https://$<domain>/$<owner>/$<repo>',\n );\n break;\n }\n\n deps.push(dep);\n }\n\n if (deps.length) {\n return { deps };\n }\n\n return null;\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../../lib/modules/manager/npm/extract/index.ts"],"sourcesContent":["import {\n isArray,\n isNonEmptyObject,\n isNonEmptyStringAndNotWhitespace,\n isString,\n} from '@sindresorhus/is';\nimport upath from 'upath';\nimport { logger } from '../../../../logger/index.ts';\nimport {\n findLocalSiblingOrParent,\n getSiblingFileName,\n readLocalFile,\n} from '../../../../util/fs/index.ts';\nimport { NpmDatasource } from '../../../datasource/npm/index.ts';\n\nimport type {\n ExtractConfig,\n PackageFile,\n PackageFileContent,\n} from '../../types.ts';\nimport { resolveNpmrc } from '../npmrc.ts';\nimport { PnpmWorkspaceFile, type YarnConfig } from '../schema.ts';\nimport type { NpmLockFiles, NpmManagerData } from '../types.ts';\nimport { getExtractedConstraints } from './common/dependency.ts';\nimport {\n extractPackageJson,\n hasPackageManager,\n} from './common/package-file.ts';\nimport {\n applyPnpmWorkspaceRegistries,\n extractPnpmWorkspaceFile,\n} from './pnpm.ts';\nimport { postExtract } from './post/index.ts';\nimport type { NpmPackage } from './types.ts';\nimport { extractYarnCatalogs, isZeroInstall } from './yarn.ts';\nimport {\n loadConfigFromLegacyYarnrc,\n loadConfigFromYarnrcYml,\n resolveRegistryUrl,\n} from './yarnrc.ts';\n\nfunction hasMultipleLockFiles(lockFiles: NpmLockFiles): boolean {\n return Object.values(lockFiles).filter(isString).length > 1;\n}\n\nexport async function extractPackageFile(\n content: string,\n packageFile: string,\n config: ExtractConfig,\n): Promise<PackageFileContent<NpmManagerData> | null> {\n logger.trace(`npm.extractPackageFile(${packageFile})`);\n logger.trace({ content });\n let packageJson: NpmPackage;\n try {\n packageJson = JSON.parse(content);\n } catch {\n logger.debug({ packageFile }, `Invalid JSON`);\n return null;\n }\n\n const res = extractPackageJson(packageJson, packageFile);\n if (!res) {\n return null;\n }\n\n let workspacesPackages: string[] | undefined;\n if (isArray(packageJson.workspaces)) {\n workspacesPackages = packageJson.workspaces;\n } else {\n workspacesPackages = packageJson.workspaces?.packages;\n }\n\n const lockFiles: NpmLockFiles = {\n yarnLock: 'yarn.lock',\n packageLock: 'package-lock.json',\n shrinkwrapJson: 'npm-shrinkwrap.json',\n pnpmLockFile: 'pnpm-lock.yaml',\n };\n\n for (const [key, val] of Object.entries(lockFiles) as [\n 'yarnLock' | 'packageLock' | 'shrinkwrapJson' | 'pnpmLockFile',\n string,\n ][]) {\n const filePath = getSiblingFileName(packageFile, val);\n if (await readLocalFile(filePath, 'utf8')) {\n lockFiles[key] = filePath;\n } else {\n lockFiles[key] = undefined;\n }\n }\n lockFiles.npmLock = lockFiles.packageLock ?? lockFiles.shrinkwrapJson;\n delete lockFiles.packageLock;\n delete lockFiles.shrinkwrapJson;\n\n if (hasMultipleLockFiles(lockFiles)) {\n logger.warn(\n 'Updating multiple npm lock files is deprecated and support will be removed in future versions.',\n );\n }\n\n const { npmrc, npmrcFileName } = await resolveNpmrc(packageFile, config);\n\n const yarnrcYmlFileName = await findLocalSiblingOrParent(\n packageFile,\n '.yarnrc.yml',\n );\n const yarnZeroInstall = yarnrcYmlFileName\n ? await isZeroInstall(yarnrcYmlFileName)\n : false;\n\n let yarnrcConfig: YarnConfig | null = null;\n const repoYarnrcYml = yarnrcYmlFileName\n ? await readLocalFile(yarnrcYmlFileName, 'utf8')\n : null;\n if (isString(repoYarnrcYml) && repoYarnrcYml.trim().length > 0) {\n yarnrcConfig = loadConfigFromYarnrcYml(repoYarnrcYml);\n }\n\n const legacyYarnrcFileName = await findLocalSiblingOrParent(\n packageFile,\n '.yarnrc',\n );\n const repoLegacyYarnrc = legacyYarnrcFileName\n ? await readLocalFile(legacyYarnrcFileName, 'utf8')\n : null;\n if (isString(repoLegacyYarnrc) && repoLegacyYarnrc.trim().length > 0) {\n yarnrcConfig = loadConfigFromLegacyYarnrc(repoLegacyYarnrc);\n }\n\n let pnpmWorkspaceRegistry: string | undefined;\n let pnpmWorkspaceRegistries: Record<string, string> | undefined;\n const pnpmWorkspaceYamlFileName = await findLocalSiblingOrParent(\n packageFile,\n 'pnpm-workspace.yaml',\n );\n const repoPnpmWorkspaceYaml = pnpmWorkspaceYamlFileName\n ? await readLocalFile(pnpmWorkspaceYamlFileName, 'utf8')\n : null;\n if (isNonEmptyStringAndNotWhitespace(repoPnpmWorkspaceYaml)) {\n const parsed = await PnpmWorkspaceFile.safeParseAsync(\n repoPnpmWorkspaceYaml,\n );\n if (parsed.success) {\n pnpmWorkspaceRegistry = parsed.data.registry;\n pnpmWorkspaceRegistries = parsed.data.registries;\n } else {\n logger.debug(\n { packageFile: pnpmWorkspaceYamlFileName, err: parsed.error },\n 'Failed to parse pnpm-workspace.yaml',\n );\n }\n }\n\n if (res.deps.length === 0) {\n logger.debug('Package file has no deps');\n if (\n !(\n !!res.managerData?.packageJsonName ||\n !!res.packageFileVersion ||\n !!npmrc ||\n workspacesPackages\n )\n ) {\n logger.debug('Skipping file');\n return null;\n }\n }\n let skipInstalls = config.skipInstalls;\n if (skipInstalls === null) {\n const hasFancyRefs = !!res.deps.some(\n (dep) =>\n !!dep.currentValue?.startsWith('file:') ||\n !!dep.currentValue?.startsWith('npm:'),\n );\n if ((hasFancyRefs && !!lockFiles.npmLock) || yarnZeroInstall) {\n // https://github.com/npm/cli/issues/1432\n // Explanation:\n // - npm install --package-lock-only is buggy for transitive deps in file: and npm: references\n // - So we set skipInstalls to false if file: or npm: refs are found *and* the user hasn't explicitly set the value already\n // - Also, do not skip install if Yarn zero-install is used\n logger.debug('Automatically setting skipInstalls to false');\n skipInstalls = false;\n } else {\n skipInstalls = true;\n }\n }\n\n const extractedConstraints = getExtractedConstraints(res.deps);\n\n if (yarnrcConfig) {\n for (const dep of res.deps) {\n // v8 ignore else -- TODO: add tests #40625\n if (dep.depName) {\n const registryUrlFromYarnrcConfig = resolveRegistryUrl(\n dep.packageName ?? dep.depName,\n yarnrcConfig,\n );\n if (\n registryUrlFromYarnrcConfig &&\n dep.datasource === NpmDatasource.id\n ) {\n dep.registryUrls = [registryUrlFromYarnrcConfig];\n }\n }\n }\n }\n\n // Applied after the yarnrc resolution so pnpm-workspace.yaml wins in pnpm repos\n applyPnpmWorkspaceRegistries(\n res.deps,\n pnpmWorkspaceRegistries,\n pnpmWorkspaceRegistry,\n );\n\n return {\n ...res,\n npmrc,\n managerData: {\n ...res.managerData,\n ...lockFiles,\n yarnZeroInstall,\n hasPackageManager:\n isNonEmptyStringAndNotWhitespace(packageJson.packageManager) ||\n isNonEmptyObject(packageJson.devEngines?.packageManager),\n workspacesPackages,\n npmrcFileName, // store npmrc file name so we can later tell if it came from the workspace or not\n },\n skipInstalls,\n extractedConstraints,\n };\n}\n\nexport async function extractAllPackageFiles(\n config: ExtractConfig,\n packageFiles: string[],\n): Promise<PackageFile<NpmManagerData>[]> {\n const npmFiles: PackageFile<NpmManagerData>[] = [];\n for (const packageFile of packageFiles) {\n const content = await readLocalFile(packageFile, 'utf8');\n if (content) {\n // pnpm workspace files are their own package file, defined via managerFilePatterns.\n if (packageFile.endsWith('pnpm-workspace.yaml')) {\n logger.trace(\n { packageFile },\n `Extracting as a pnpm-workspace.yaml file`,\n );\n const parsedPnpmWorkspaceYaml =\n await PnpmWorkspaceFile.safeParseAsync(content);\n if (parsedPnpmWorkspaceYaml.success) {\n logger.trace(\n { packageFile },\n `Extracting file as a pnpm workspace YAML file`,\n );\n const deps = await extractPnpmWorkspaceFile(\n parsedPnpmWorkspaceYaml.data,\n packageFile,\n );\n // v8 ignore else -- TODO: add test #40625\n if (deps) {\n npmFiles.push({\n ...deps,\n packageFile,\n });\n }\n } else {\n logger.warn(\n { packageFile, err: parsedPnpmWorkspaceYaml.error },\n `Failed to parse pnpm-workspace.yaml file`,\n );\n }\n } else {\n if (packageFile.endsWith('json')) {\n logger.trace({ packageFile }, `Extracting as a package.json file`);\n\n const deps = await extractPackageFile(content, packageFile, config);\n // v8 ignore else -- TODO: add tests #40625\n if (deps) {\n npmFiles.push({\n ...deps,\n packageFile,\n });\n }\n } else {\n logger.trace({ packageFile }, `Extracting as a .yarnrc.yml file`);\n\n const yarnConfig = loadConfigFromYarnrcYml(content);\n\n // v8 ignore else -- TODO: add tests #40625\n if (yarnConfig?.catalogs || yarnConfig?.catalog) {\n const hasPackageManagerResult = await hasPackageManager(\n upath.dirname(packageFile),\n );\n const catalogsDeps = await extractYarnCatalogs(\n { catalog: yarnConfig.catalog, catalogs: yarnConfig.catalogs },\n packageFile,\n hasPackageManagerResult,\n );\n // v8 ignore else -- TODO: add tests #40625\n if (catalogsDeps) {\n npmFiles.push({\n ...catalogsDeps,\n packageFile,\n });\n }\n }\n }\n }\n } else {\n logger.debug({ packageFile }, `No content found`);\n }\n }\n\n await postExtract(npmFiles);\n return npmFiles;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../../lib/modules/manager/npm/extract/index.ts"],"sourcesContent":["import {\n isArray,\n isNonEmptyObject,\n isNonEmptyStringAndNotWhitespace,\n isString,\n} from '@sindresorhus/is';\nimport upath from 'upath';\nimport { logger } from '../../../../logger/index.ts';\nimport {\n findLocalSiblingOrParent,\n getSiblingFileName,\n readLocalFile,\n} from '../../../../util/fs/index.ts';\nimport { NpmDatasource } from '../../../datasource/npm/index.ts';\n\nimport type {\n ExtractConfig,\n PackageFile,\n PackageFileContent,\n} from '../../types.ts';\nimport { resolveNpmrc } from '../npmrc.ts';\nimport { PnpmWorkspaceFile, type YarnConfig } from '../schema.ts';\nimport type { NpmLockFiles, NpmManagerData } from '../types.ts';\nimport { getExtractedConstraints } from './common/dependency.ts';\nimport {\n extractPackageJson,\n hasPackageManager,\n} from './common/package-file.ts';\nimport {\n applyPnpmWorkspaceRegistries,\n extractPnpmWorkspaceFile,\n} from './pnpm.ts';\nimport { postExtract } from './post/index.ts';\nimport type { NpmPackage } from './types.ts';\nimport { extractYarnCatalogs, isZeroInstall } from './yarn.ts';\nimport {\n loadConfigFromLegacyYarnrc,\n loadConfigFromYarnrcYml,\n resolveRegistryUrl,\n} from './yarnrc.ts';\n\nfunction hasMultipleLockFiles(lockFiles: NpmLockFiles): boolean {\n return Object.values(lockFiles).filter(isString).length > 1;\n}\n\nexport async function extractPackageFile(\n content: string,\n packageFile: string,\n config: ExtractConfig,\n): Promise<PackageFileContent<NpmManagerData> | null> {\n logger.trace(`npm.extractPackageFile(${packageFile})`);\n logger.trace({ content });\n let packageJson: NpmPackage;\n try {\n packageJson = JSON.parse(content);\n } catch {\n logger.debug({ packageFile }, `Invalid JSON`);\n return null;\n }\n\n const res = extractPackageJson(packageJson, packageFile);\n if (!res) {\n return null;\n }\n\n let workspacesPackages: string[] | undefined;\n if (isArray(packageJson.workspaces)) {\n workspacesPackages = packageJson.workspaces;\n } else {\n workspacesPackages = packageJson.workspaces?.packages;\n }\n\n const lockFiles: NpmLockFiles = {\n yarnLock: 'yarn.lock',\n packageLock: 'package-lock.json',\n shrinkwrapJson: 'npm-shrinkwrap.json',\n pnpmLockFile: 'pnpm-lock.yaml',\n };\n\n for (const [key, val] of Object.entries(lockFiles) as [\n 'yarnLock' | 'packageLock' | 'shrinkwrapJson' | 'pnpmLockFile',\n string,\n ][]) {\n const filePath = getSiblingFileName(packageFile, val);\n if (await readLocalFile(filePath, 'utf8')) {\n lockFiles[key] = filePath;\n } else {\n lockFiles[key] = undefined;\n }\n }\n lockFiles.npmLock = lockFiles.packageLock ?? lockFiles.shrinkwrapJson;\n delete lockFiles.packageLock;\n delete lockFiles.shrinkwrapJson;\n\n if (hasMultipleLockFiles(lockFiles)) {\n logger.warn(\n 'Updating multiple npm lock files is deprecated and support will be removed in future versions.',\n );\n }\n\n const { npmrc, npmrcFileName } = await resolveNpmrc(packageFile, config);\n\n const yarnrcYmlFileName = await findLocalSiblingOrParent(\n packageFile,\n '.yarnrc.yml',\n );\n const yarnZeroInstall = yarnrcYmlFileName\n ? await isZeroInstall(yarnrcYmlFileName)\n : false;\n\n let yarnrcConfig: YarnConfig | null = null;\n const repoYarnrcYml = yarnrcYmlFileName\n ? await readLocalFile(yarnrcYmlFileName, 'utf8')\n : null;\n if (isString(repoYarnrcYml) && repoYarnrcYml.trim().length > 0) {\n yarnrcConfig = loadConfigFromYarnrcYml(repoYarnrcYml);\n }\n\n const legacyYarnrcFileName = await findLocalSiblingOrParent(\n packageFile,\n '.yarnrc',\n );\n const repoLegacyYarnrc = legacyYarnrcFileName\n ? await readLocalFile(legacyYarnrcFileName, 'utf8')\n : null;\n if (isString(repoLegacyYarnrc) && repoLegacyYarnrc.trim().length > 0) {\n yarnrcConfig = loadConfigFromLegacyYarnrc(repoLegacyYarnrc);\n }\n\n let pnpmWorkspaceRegistry: string | undefined;\n let pnpmWorkspaceRegistries: Record<string, string> | undefined;\n const pnpmWorkspaceYamlFileName = await findLocalSiblingOrParent(\n packageFile,\n 'pnpm-workspace.yaml',\n );\n const repoPnpmWorkspaceYaml = pnpmWorkspaceYamlFileName\n ? await readLocalFile(pnpmWorkspaceYamlFileName, 'utf8')\n : null;\n if (isNonEmptyStringAndNotWhitespace(repoPnpmWorkspaceYaml)) {\n const parsed = await PnpmWorkspaceFile.safeParseAsync(\n repoPnpmWorkspaceYaml,\n );\n if (parsed.success) {\n pnpmWorkspaceRegistry = parsed.data.registry;\n pnpmWorkspaceRegistries = parsed.data.registries;\n } else {\n logger.debug(\n { packageFile: pnpmWorkspaceYamlFileName, err: parsed.error },\n 'Failed to parse pnpm-workspace.yaml',\n );\n }\n }\n\n if (res.deps.length === 0) {\n logger.debug('Package file has no deps');\n if (!(\n !!res.managerData?.packageJsonName ||\n !!res.packageFileVersion ||\n !!npmrc ||\n workspacesPackages\n )) {\n logger.debug('Skipping file');\n return null;\n }\n }\n let skipInstalls = config.skipInstalls;\n if (skipInstalls === null) {\n const hasFancyRefs = !!res.deps.some(\n (dep) =>\n !!dep.currentValue?.startsWith('file:') ||\n !!dep.currentValue?.startsWith('npm:'),\n );\n if ((hasFancyRefs && !!lockFiles.npmLock) || yarnZeroInstall) {\n // https://github.com/npm/cli/issues/1432\n // Explanation:\n // - npm install --package-lock-only is buggy for transitive deps in file: and npm: references\n // - So we set skipInstalls to false if file: or npm: refs are found *and* the user hasn't explicitly set the value already\n // - Also, do not skip install if Yarn zero-install is used\n logger.debug('Automatically setting skipInstalls to false');\n skipInstalls = false;\n } else {\n skipInstalls = true;\n }\n }\n\n const extractedConstraints = getExtractedConstraints(res.deps);\n\n if (yarnrcConfig) {\n for (const dep of res.deps) {\n // v8 ignore else -- TODO: add tests #40625\n if (dep.depName) {\n const registryUrlFromYarnrcConfig = resolveRegistryUrl(\n dep.packageName ?? dep.depName,\n yarnrcConfig,\n );\n if (\n registryUrlFromYarnrcConfig &&\n dep.datasource === NpmDatasource.id\n ) {\n dep.registryUrls = [registryUrlFromYarnrcConfig];\n }\n }\n }\n }\n\n // Applied after the yarnrc resolution so pnpm-workspace.yaml wins in pnpm repos\n applyPnpmWorkspaceRegistries(\n res.deps,\n pnpmWorkspaceRegistries,\n pnpmWorkspaceRegistry,\n );\n\n return {\n ...res,\n npmrc,\n managerData: {\n ...res.managerData,\n ...lockFiles,\n yarnZeroInstall,\n hasPackageManager:\n isNonEmptyStringAndNotWhitespace(packageJson.packageManager) ||\n isNonEmptyObject(packageJson.devEngines?.packageManager),\n workspacesPackages,\n npmrcFileName, // store npmrc file name so we can later tell if it came from the workspace or not\n },\n skipInstalls,\n extractedConstraints,\n };\n}\n\nexport async function extractAllPackageFiles(\n config: ExtractConfig,\n packageFiles: string[],\n): Promise<PackageFile<NpmManagerData>[]> {\n const npmFiles: PackageFile<NpmManagerData>[] = [];\n for (const packageFile of packageFiles) {\n const content = await readLocalFile(packageFile, 'utf8');\n if (content) {\n // pnpm workspace files are their own package file, defined via managerFilePatterns.\n if (packageFile.endsWith('pnpm-workspace.yaml')) {\n logger.trace(\n { packageFile },\n `Extracting as a pnpm-workspace.yaml file`,\n );\n const parsedPnpmWorkspaceYaml =\n await PnpmWorkspaceFile.safeParseAsync(content);\n if (parsedPnpmWorkspaceYaml.success) {\n logger.trace(\n { packageFile },\n `Extracting file as a pnpm workspace YAML file`,\n );\n const deps = await extractPnpmWorkspaceFile(\n parsedPnpmWorkspaceYaml.data,\n packageFile,\n );\n // v8 ignore else -- TODO: add test #40625\n if (deps) {\n npmFiles.push({\n ...deps,\n packageFile,\n });\n }\n } else {\n logger.warn(\n { packageFile, err: parsedPnpmWorkspaceYaml.error },\n `Failed to parse pnpm-workspace.yaml file`,\n );\n }\n } else {\n if (packageFile.endsWith('json')) {\n logger.trace({ packageFile }, `Extracting as a package.json file`);\n\n const deps = await extractPackageFile(content, packageFile, config);\n // v8 ignore else -- TODO: add tests #40625\n if (deps) {\n npmFiles.push({\n ...deps,\n packageFile,\n });\n }\n } else {\n logger.trace({ packageFile }, `Extracting as a .yarnrc.yml file`);\n\n const yarnConfig = loadConfigFromYarnrcYml(content);\n\n // v8 ignore else -- TODO: add tests #40625\n if (yarnConfig?.catalogs || yarnConfig?.catalog) {\n const hasPackageManagerResult = await hasPackageManager(\n upath.dirname(packageFile),\n );\n const catalogsDeps = await extractYarnCatalogs(\n { catalog: yarnConfig.catalog, catalogs: yarnConfig.catalogs },\n packageFile,\n hasPackageManagerResult,\n );\n // v8 ignore else -- TODO: add tests #40625\n if (catalogsDeps) {\n npmFiles.push({\n ...catalogsDeps,\n packageFile,\n });\n }\n }\n }\n }\n } else {\n logger.debug({ packageFile }, `No content found`);\n }\n }\n\n await postExtract(npmFiles);\n return npmFiles;\n}\n"],"mappings":"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"}