{"version":3,"sources":["../core/registry/utils/ModuleNeeds.ts"],"names":["existing"],"mappings":"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","file":"chunk-R42WGS45.mjs","sourcesContent":["import type {\n  ModuleNeeds,\n  ModuleNeedsNormalized,\n  PackageRequirement,\n  PackageRequirementMap,\n  RuntimeRequirement,\n  ToolRequirement,\n  VersionSpecifier\n} from '../types';\n\ntype LegacyRuntimeDetail = {\n  node?: string;\n  python?: string;\n  shell?: string;\n  packages?: string[];\n  commands?: string[];\n};\n\ntype LegacyNeedsDetails = {\n  js?: LegacyRuntimeDetail;\n  node?: LegacyRuntimeDetail;\n  py?: LegacyRuntimeDetail;\n  sh?: LegacyRuntimeDetail;\n};\n\nexport function normalizeModuleNeeds(\n  rawNeeds: unknown,\n  legacyDetails?: LegacyNeedsDetails\n): ModuleNeedsNormalized {\n  const normalized: ModuleNeedsNormalized = {\n    runtimes: [],\n    tools: [],\n    packages: {}\n  };\n\n  const addRuntime = (candidate: RuntimeRequirement): void => {\n    if (!candidate.name) {\n      return;\n    }\n\n    if (!normalized.runtimes.find(existing => existing.name === candidate.name)) {\n      normalized.runtimes.push(candidate);\n      return;\n    }\n\n    const existing = normalized.runtimes.find(existing => existing.name === candidate.name);\n    if (existing && !existing.specifier && candidate.specifier) {\n      existing.specifier = candidate.specifier;\n      existing.raw = candidate.raw;\n    }\n  };\n\n  const addTool = (candidate: ToolRequirement): void => {\n    if (!candidate.name) {\n      return;\n    }\n\n    if (!normalized.tools.find(existing => existing.name === candidate.name)) {\n      normalized.tools.push(candidate);\n      return;\n    }\n\n    const existing = normalized.tools.find(existing => existing.name === candidate.name);\n    if (existing && !existing.specifier && candidate.specifier) {\n      existing.specifier = candidate.specifier;\n      existing.raw = candidate.raw;\n    }\n  };\n\n  const addPackages = (ecosystem: string, packages: PackageRequirement[]): void => {\n    if (!ecosystem) {\n      return;\n    }\n\n    const bucket = normalized.packages[ecosystem] || [];\n    for (const pkg of packages) {\n      if (!pkg.name) {\n        continue;\n      }\n      if (!bucket.find(existing => existing.name === pkg.name && existing.specifier === pkg.specifier)) {\n        bucket.push(pkg);\n      }\n    }\n    normalized.packages[ecosystem] = bucket;\n  };\n\n  const handleRuntimeEntry = (entry: unknown): void => {\n    if (typeof entry === 'string') {\n      addRuntime(parseVersionSpecifier(entry));\n    } else if (entry && typeof entry === 'object') {\n      const name = String((entry as any).name || '');\n      const specifier = (entry as any).specifier ?? (entry as any).version;\n      if (name) {\n        addRuntime({\n          name,\n          specifier: typeof specifier === 'string' && specifier.length > 0 ? specifier : undefined,\n          raw: formatVersionSpecifier(name, specifier)\n        });\n      }\n    }\n  };\n\n  const handleToolEntry = (entry: unknown): void => {\n    if (typeof entry === 'string') {\n      addTool(parseVersionSpecifier(entry));\n    } else if (entry && typeof entry === 'object') {\n      const name = String((entry as any).name || '');\n      const specifier = (entry as any).specifier ?? (entry as any).version;\n      if (name) {\n        addTool({\n          name,\n          specifier: typeof specifier === 'string' && specifier.length > 0 ? specifier : undefined,\n          raw: formatVersionSpecifier(name, specifier)\n        });\n      }\n    }\n  };\n\n  const handlePackageList = (ecosystem: string, value: unknown): void => {\n    if (Array.isArray(value)) {\n      const packages = value.map(item => parseVersionSpecifier(String(item)));\n      addPackages(ecosystem, packages);\n      return;\n    }\n\n    if (value && typeof value === 'object') {\n      const packages = Object.values(value as Record<string, unknown>).map(item => parseVersionSpecifier(String(item)));\n      addPackages(ecosystem, packages);\n    }\n  };\n\n  if (Array.isArray(rawNeeds)) {\n    for (const entry of rawNeeds) {\n      handleRuntimeEntry(entry);\n    }\n  } else if (typeof rawNeeds === 'string') {\n    handleRuntimeEntry(rawNeeds);\n  } else if (rawNeeds && typeof rawNeeds === 'object') {\n    const structuredNeeds = rawNeeds as ModuleNeeds;\n\n    if (structuredNeeds.runtimes) {\n      for (const runtime of structuredNeeds.runtimes) {\n        handleRuntimeEntry(runtime);\n      }\n    }\n\n    if (structuredNeeds.tools) {\n      for (const tool of structuredNeeds.tools) {\n        handleToolEntry(tool);\n      }\n    }\n\n    if (structuredNeeds.packages) {\n      for (const [ecosystem, packageList] of Object.entries(structuredNeeds.packages)) {\n        handlePackageList(ecosystem, packageList);\n      }\n    }\n  }\n\n  if (legacyDetails) {\n    if (legacyDetails.js) {\n      inheritLegacyRuntimeDetail('js', legacyDetails.js, addRuntime, addPackages, addTool);\n    }\n    if (legacyDetails.node) {\n      inheritLegacyRuntimeDetail('node', legacyDetails.node, addRuntime, addPackages, addTool);\n    }\n    if (legacyDetails.py) {\n      inheritLegacyRuntimeDetail('python', legacyDetails.py, addRuntime, addPackages, addTool);\n    }\n    if (legacyDetails.sh) {\n      inheritLegacyRuntimeDetail('sh', legacyDetails.sh, addRuntime, addPackages, addTool);\n    }\n  }\n\n  return normalized;\n}\n\nexport function moduleNeedsToRuntimeNames(needs?: ModuleNeeds | ModuleNeedsNormalized): string[] {\n  if (!needs) {\n    return [];\n  }\n\n  const source = Array.isArray((needs as ModuleNeeds).runtimes) ? (needs as ModuleNeeds).runtimes : (needs as ModuleNeedsNormalized).runtimes;\n  if (!source) {\n    return [];\n  }\n\n  return source.map(entry => entry.name);\n}\n\nexport function parseVersionSpecifier(raw: string): VersionSpecifier {\n  const trimmed = raw.trim();\n  if (!trimmed) {\n    return { name: '', raw: '' };\n  }\n\n  if (trimmed.startsWith('@')) {\n    const parts = trimmed.split('@');\n    if (parts.length > 2) {\n      const spec = parts.pop();\n      const scopedName = parts.join('@');\n      if (spec) {\n        return {\n          name: scopedName,\n          specifier: spec,\n          raw: trimmed\n        };\n      }\n    }\n  }\n\n  const atIndex = trimmed.lastIndexOf('@');\n  if (atIndex > 0 && atIndex < trimmed.length - 1) {\n    const name = trimmed.slice(0, atIndex);\n    const specifier = trimmed.slice(atIndex + 1);\n    return { name, specifier, raw: trimmed };\n  }\n\n  return { name: trimmed, raw: trimmed };\n}\n\nexport function formatVersionSpecifier(name: string, specifier?: unknown): string {\n  if (!name) {\n    return '';\n  }\n\n  if (typeof specifier === 'string' && specifier.length > 0) {\n    return `${name}@${specifier}`;\n  }\n\n  return name;\n}\n\nexport function moduleNeedsToSerializable(needs: ModuleNeedsNormalized): ModuleNeeds {\n  const result: ModuleNeeds = {};\n\n  if (needs.runtimes.length > 0) {\n    result.runtimes = needs.runtimes.map(runtime => ({\n      name: runtime.name,\n      specifier: runtime.specifier,\n      raw: runtime.raw\n    }));\n  }\n\n  if (needs.tools.length > 0) {\n    result.tools = needs.tools.map(tool => ({\n      name: tool.name,\n      specifier: tool.specifier,\n      raw: tool.raw\n    }));\n  }\n\n  const packageEntries = Object.entries(needs.packages);\n  if (packageEntries.length > 0) {\n    result.packages = packageEntries.reduce<PackageRequirementMap>((acc, [ecosystem, packages]) => {\n      acc[ecosystem] = packages.map(pkg => ({\n        name: pkg.name,\n        specifier: pkg.specifier,\n        raw: pkg.raw\n      }));\n      return acc;\n    }, {});\n  }\n\n  return result;\n}\n\nexport function stringifyRequirementList(requirements: VersionSpecifier[]): string[] {\n  return requirements.map(req => formatVersionSpecifier(req.name, req.specifier));\n}\n\nexport function stringifyPackageMap(packages: PackageRequirementMap): Record<string, string[]> {\n  const entries: [string, string[]][] = Object.entries(packages).map(([ecosystem, list]) => [\n    ecosystem,\n    list.map(pkg => formatVersionSpecifier(pkg.name, pkg.specifier))\n  ]);\n  return Object.fromEntries(entries);\n}\n\nfunction inheritLegacyRuntimeDetail(\n  name: string,\n  detail: LegacyRuntimeDetail,\n  addRuntime: (candidate: RuntimeRequirement) => void,\n  addPackages: (ecosystem: string, packages: PackageRequirement[]) => void,\n  addTool: (candidate: ToolRequirement) => void\n): void {\n  if (detail.node && (name === 'node' || name === 'js')) {\n    addRuntime({ name: 'node', specifier: detail.node, raw: formatVersionSpecifier('node', detail.node) });\n  }\n\n  if (detail.python && name === 'python') {\n    addRuntime({ name: 'python', specifier: detail.python, raw: formatVersionSpecifier('python', detail.python) });\n  }\n\n  if (detail.shell && name === 'sh') {\n    addTool({ name: detail.shell, raw: detail.shell });\n  }\n\n  if (detail.packages && detail.packages.length > 0) {\n    addPackages(name, detail.packages.map(pkg => parseVersionSpecifier(pkg)));\n  }\n\n  if (detail.commands && detail.commands.length > 0) {\n    for (const command of detail.commands) {\n      addTool(parseVersionSpecifier(command));\n    }\n  }\n}\n"]}