{
  "version": 3,
  "sources": ["../../../../src/packages/npm-resolver/pickPackageFromMeta.ts"],
  "sourcesContent": ["import { PnpmError } from '../error/index.ts';\nimport type { VersionSelectors } from '../resolver-base/index.ts';\nimport semver from 'semver';\nimport util from 'node:util';\nimport type { RegistryPackageSpec } from './parsePref.ts';\nimport type { PackageInRegistry, PackageMeta } from './pickPackage.ts';\n\nexport type PickVersionByVersionRange = (\n  meta: PackageMeta,\n  versionRange: string,\n  preferredVerSels?: VersionSelectors | undefined,\n  publishedBy?: Date | undefined\n) => string | undefined;\n\nexport function pickPackageFromMeta(\n  pickVersionByVersionRangeFn: PickVersionByVersionRange,\n  spec: RegistryPackageSpec,\n  preferredVersionSelectors: VersionSelectors | undefined,\n  meta: PackageMeta,\n  publishedBy?: Date | undefined\n): PackageInRegistry | undefined {\n  if (\n    (!meta.versions || Object.keys(meta.versions).length === 0) &&\n    !publishedBy\n  ) {\n    // Unfortunately, the npm registry doesn't return the time field in the abbreviated metadata.\n    // So we won't always know if the package was unpublished.\n    if ((meta.time?.unpublished?.versions.length ?? 0) > 0) {\n      throw new PnpmError(\n        'UNPUBLISHED_PKG',\n        `No versions available for ${spec.name} because it was unpublished`\n      );\n    }\n    throw new PnpmError(\n      'NO_VERSIONS',\n      `No versions available for ${spec.name}. The package may be unpublished.`\n    );\n  }\n  try {\n    let version!: string | undefined;\n    switch (spec.type) {\n      case 'version':\n        version = spec.fetchSpec;\n        break;\n      case 'tag':\n        version = meta['dist-tags'][spec.fetchSpec];\n        break;\n      case 'range':\n        version = pickVersionByVersionRangeFn(\n          meta,\n          spec.fetchSpec,\n          preferredVersionSelectors,\n          publishedBy\n        );\n        break;\n    }\n    if (typeof version === 'undefined') return undefined;\n    const manifest = meta.versions?.[version];\n\n    if (manifest && meta['name']) {\n      // Packages that are published to the GitHub registry are always published with a scope.\n      // However, the name in the package.json for some reason may omit the scope.\n      // So the package published to the GitHub registry will be published under @foo/bar\n      // but the name in package.json will be just bar.\n      // In order to avoid issues, we consider that the real name of the package is the one with the scope.\n      manifest.name = meta['name'];\n    }\n\n    return manifest;\n  } catch (err: unknown) {\n    if (\n      util.types.isNativeError(err) &&\n      'code' in err &&\n      typeof err.code === 'string' &&\n      err.code.startsWith('ERR_PNPM_')\n    ) {\n      throw err;\n    }\n    throw new PnpmError(\n      'MALFORMED_METADATA',\n      `Received malformed metadata for \"${spec.name}\"`,\n      {\n        hint: 'This might mean that the package was unpublished from the registry',\n      }\n    );\n  }\n}\n\nconst semverRangeCache = new Map<string, semver.Range | null>();\n\n// This is a performance optimization; working with string-ish semver\n// causes lots of allocations and repeated work, but caching the Range\n// and ensuring we give it a SemVer instance greatly speeds things up.\nfunction semverSatisfiesLoose(version: string, range: string): boolean {\n  let semverRange = semverRangeCache.get(range);\n  if (semverRange === undefined) {\n    try {\n      semverRange = new semver.Range(range, true);\n    } catch {\n      semverRange = null;\n    }\n    semverRangeCache.set(range, semverRange);\n  }\n\n  if (semverRange) {\n    try {\n      return semverRange.test(new semver.SemVer(version, true));\n    } catch {\n      return false;\n    }\n  }\n\n  return false;\n}\n\nexport function pickLowestVersionByVersionRange(\n  meta: PackageMeta,\n  versionRange: string,\n  preferredVerSels?: VersionSelectors | undefined\n): string | undefined {\n  if (preferredVerSels != null && Object.keys(preferredVerSels).length > 0) {\n    const prioritizedPreferredVersions = prioritizePreferredVersions(\n      meta,\n      versionRange,\n      preferredVerSels\n    );\n    for (const preferredVersions of prioritizedPreferredVersions) {\n      const preferredVersion = semver.minSatisfying(\n        preferredVersions,\n        versionRange,\n        true\n      );\n      if (typeof preferredVersion === 'string') {\n        return preferredVersion;\n      }\n    }\n  }\n\n  if (versionRange === '*') {\n    return Object.keys(meta.versions ?? {}).sort(semver.compare)[0] ?? '';\n  }\n\n  return (\n    semver.minSatisfying(\n      Object.keys(meta.versions ?? {}),\n      versionRange,\n      true\n    ) ?? undefined\n  );\n}\n\nexport function pickVersionByVersionRange(\n  meta: PackageMeta,\n  versionRange: string,\n  preferredVerSels?: VersionSelectors | undefined,\n  publishedBy?: Date | undefined\n): string | undefined {\n  let latest: string | undefined = meta['dist-tags'].latest;\n\n  if (preferredVerSels != null && Object.keys(preferredVerSels).length > 0) {\n    const prioritizedPreferredVersions = prioritizePreferredVersions(\n      meta,\n      versionRange,\n      preferredVerSels\n    );\n    for (const preferredVersions of prioritizedPreferredVersions) {\n      if (\n        typeof latest === 'string' &&\n        preferredVersions.includes(latest) &&\n        semverSatisfiesLoose(latest, versionRange)\n      ) {\n        return latest;\n      }\n\n      const preferredVersion = semver.maxSatisfying(\n        preferredVersions,\n        versionRange,\n        true\n      );\n\n      if (typeof preferredVersion === 'string') {\n        return preferredVersion;\n      }\n    }\n  }\n\n  let versions = Object.keys(meta.versions ?? {});\n\n  if (publishedBy) {\n    if (meta.time == null) {\n      throw new PnpmError(\n        'MISSING_TIME',\n        `The metadata of ${meta.name} is missing the \"time\" field`\n      );\n    }\n\n    versions = versions.filter(\n      (version) => new Date(meta.time?.[version] ?? 0) <= publishedBy\n    );\n    if (typeof latest !== 'string' || versions.includes(latest) !== true) {\n      latest = undefined;\n    }\n  }\n  if (\n    versionRange === '*' ||\n    (typeof latest === 'string' && semverSatisfiesLoose(latest, versionRange))\n  ) {\n    // Not using semver.satisfies in case of * because it does not select beta versions.\n    // E.g.: 1.0.0-beta.1. See issue: https://github.com/pnpm/pnpm/issues/865\n    return latest;\n  }\n\n  const maxVersion =\n    semver.maxSatisfying(versions, versionRange, true) ?? undefined;\n\n  // if the selected version is deprecated, try to find a non-deprecated one that satisfies the range\n  if (\n    typeof maxVersion === 'string' &&\n    typeof meta.versions?.[maxVersion]?.deprecated === 'string' &&\n    versions.length > 1\n  ) {\n    const nonDeprecatedVersions = versions\n      .map((version): PackageInRegistry | undefined => {\n        return meta.versions?.[version];\n      })\n      .filter((versionMeta): boolean => {\n        return typeof versionMeta?.deprecated !== 'string';\n      })\n      .map((versionMeta) => {\n        return versionMeta?.version;\n      })\n      .filter(Boolean);\n\n    const maxNonDeprecatedVersion = semver.maxSatisfying(\n      nonDeprecatedVersions,\n      versionRange,\n      true\n    );\n\n    if (typeof maxNonDeprecatedVersion === 'string') {\n      return maxNonDeprecatedVersion;\n    }\n  }\n\n  return maxVersion;\n}\n\nfunction prioritizePreferredVersions(\n  meta: PackageMeta,\n  versionRange: string,\n  preferredVerSelectors?: VersionSelectors\n): string[][] {\n  const preferredVerSelectorsArr = Object.entries(preferredVerSelectors ?? {});\n  const versionsPrioritizer = new PreferredVersionsPrioritizer();\n  for (const [\n    preferredSelector,\n    preferredSelectorType,\n  ] of preferredVerSelectorsArr) {\n    const { selectorType, weight } =\n      typeof preferredSelectorType === 'string'\n        ? { selectorType: preferredSelectorType, weight: 1 }\n        : preferredSelectorType;\n\n    if (preferredSelector === versionRange) {\n      continue;\n    }\n\n    switch (selectorType) {\n      case 'tag': {\n        versionsPrioritizer.add(\n          meta['dist-tags'][preferredSelector] ?? '',\n          weight\n        );\n\n        break;\n      }\n\n      case 'range': {\n        const versions = Object.keys(meta.versions ?? {});\n        for (const version of versions) {\n          if (semverSatisfiesLoose(version, preferredSelector)) {\n            versionsPrioritizer.add(version, weight);\n          }\n        }\n\n        break;\n      }\n\n      case 'version': {\n        if (typeof meta.versions?.[preferredSelector] !== 'undefined') {\n          versionsPrioritizer.add(preferredSelector, weight);\n        }\n        break;\n      }\n    }\n  }\n  return versionsPrioritizer.versionsByPriority();\n}\n\nclass PreferredVersionsPrioritizer {\n  private preferredVersions: Record<string, number> = {};\n\n  add(version: string, weight: number): void {\n    if (typeof this.preferredVersions[version] === 'undefined') {\n      this.preferredVersions[version] = weight;\n    } else {\n      this.preferredVersions[version] += weight;\n    }\n  }\n\n  versionsByPriority(): string[][] {\n    const versionsByWeight = Object.entries(this.preferredVersions).reduce(\n      (acc, [version, weight]) => {\n        acc[weight] = acc[weight] ?? [];\n        acc[weight].push(version);\n        return acc;\n      },\n      {} as Record<number, string[]>\n    );\n\n    return Object.keys(versionsByWeight)\n      .sort((a, b) => Number.parseInt(b, 10) - Number.parseInt(a, 10))\n      .map((weight) => versionsByWeight[Number.parseInt(weight, 10)])\n      .filter(Boolean);\n  }\n}\n"],
  "mappings": "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",
  "names": []
}
