{"version":3,"file":"tool-operations.mjs","names":[],"sources":["../../src/tool-operations.ts"],"sourcesContent":["import type { Client } from \"./core/client.ts\";\nimport { InvalidPURLError, PkioError } from \"./core/errors.ts\";\nimport { parsePURL } from \"./core/purl.ts\";\nimport { ecosystems } from \"./core/registry.ts\";\nimport type { Package } from \"./core/types.ts\";\nimport {\n  bulkFetchPackages,\n  fetchDependenciesFromPURL,\n  fetchMaintainersFromPURL,\n  fetchPackageFromPURL,\n  fetchVersionsFromPURL,\n} from \"./helpers.ts\";\n\nexport const MAX_PURL_LENGTH = 2_048;\nexport const MAX_BULK_PACKAGES = 50;\nexport const DEFAULT_BULK_CONCURRENCY = 15;\nexport const MAX_BULK_CONCURRENCY = 50;\n\nexport interface ToolResult<T> {\n  content: Array<{ type: \"text\"; text: string }>;\n  details: T;\n  isError?: boolean;\n}\n\nexport interface PURLParams {\n  readonly purl: string;\n}\n\nexport interface BulkPackagesParams {\n  readonly purls: readonly string[];\n  readonly concurrency?: number;\n}\n\nfunction jsonResult<T>(details: T): ToolResult<T> {\n  return {\n    content: [{ type: \"text\", text: JSON.stringify(details, null, 2) }],\n    details,\n  };\n}\n\nfunction assertPURL(purl: string): void {\n  if (typeof purl !== \"string\" || purl.length === 0) {\n    throw new InvalidPURLError(String(purl), \"must be a non-empty string\");\n  }\n  if (purl.length > MAX_PURL_LENGTH) {\n    throw new InvalidPURLError(\n      purl.slice(0, MAX_PURL_LENGTH),\n      `must not exceed ${MAX_PURL_LENGTH} characters`,\n    );\n  }\n\n  const parsed = parsePURL(purl);\n  if (Object.hasOwn(parsed.qualifiers, \"repository_url\")) {\n    throw new InvalidPURLError(purl, \"repository_url is not allowed in agent tools\");\n  }\n}\n\nfunction isPURLArray(value: unknown): value is readonly string[] {\n  return Array.isArray(value) && value.every((item: unknown) => typeof item === \"string\");\n}\n\nfunction assertBulkParams(params: Readonly<BulkPackagesParams>): void {\n  if (!isPURLArray(params.purls) || params.purls.length === 0) {\n    throw new PkioError(\"Bulk package lookup needs at least one PURL\");\n  }\n  if (params.purls.length > MAX_BULK_PACKAGES) {\n    throw new PkioError(`Bulk package lookup accepts at most ${MAX_BULK_PACKAGES} PURLs`);\n  }\n  for (const purl of params.purls) assertPURL(purl);\n\n  const concurrency = params.concurrency ?? DEFAULT_BULK_CONCURRENCY;\n  if (!Number.isInteger(concurrency) || concurrency < 1 || concurrency > MAX_BULK_CONCURRENCY) {\n    throw new PkioError(`Concurrency must be an integer from 1 through ${MAX_BULK_CONCURRENCY}`);\n  }\n}\n\nexport async function packageOperation(\n  params: Readonly<PURLParams>,\n  signal?: AbortSignal,\n  client?: Client,\n): Promise<ToolResult<Package>> {\n  assertPURL(params.purl);\n  return jsonResult(await fetchPackageFromPURL(params.purl, signal, client));\n}\n\nexport async function versionsOperation(\n  params: Readonly<PURLParams>,\n  signal?: AbortSignal,\n  client?: Client,\n) {\n  assertPURL(params.purl);\n  return jsonResult(await fetchVersionsFromPURL(params.purl, signal, client));\n}\n\nexport async function dependenciesOperation(\n  params: Readonly<PURLParams>,\n  signal?: AbortSignal,\n  client?: Client,\n) {\n  assertPURL(params.purl);\n  return jsonResult(await fetchDependenciesFromPURL(params.purl, signal, client));\n}\n\nexport async function maintainersOperation(\n  params: Readonly<PURLParams>,\n  signal?: AbortSignal,\n  client?: Client,\n) {\n  assertPURL(params.purl);\n  return jsonResult(await fetchMaintainersFromPURL(params.purl, signal, client));\n}\n\nexport async function bulkPackagesOperation(\n  params: Readonly<BulkPackagesParams>,\n  signal?: AbortSignal,\n  client?: Client,\n): Promise<ToolResult<Record<string, Package>>> {\n  assertBulkParams(params);\n  const packages = await bulkFetchPackages(params.purls, {\n    concurrency: params.concurrency ?? DEFAULT_BULK_CONCURRENCY,\n    signal,\n    client,\n  });\n  return jsonResult(Object.fromEntries(packages));\n}\n\nexport async function ecosystemsOperation(): Promise<ToolResult<{ ecosystems: string[] }>> {\n  return jsonResult({ ecosystems: ecosystems().sort() });\n}\n"],"mappings":";;;AAaA,MAAa,kBAAkB;AAC/B,MAAa,oBAAoB;AACjC,MAAa,2BAA2B;AACxC,MAAa,uBAAuB;AAiBpC,SAAS,WAAc,SAA2B;AAChD,QAAO;EACL,SAAS,CAAC;GAAE,MAAM;GAAQ,MAAM,KAAK,UAAU,SAAS,MAAM,EAAA;GAAI,CAAC;EACnE;EACD;;AAGH,SAAS,WAAW,MAAoB;AACtC,KAAI,OAAO,SAAS,YAAY,KAAK,WAAW,EAC9C,OAAM,IAAI,iBAAiB,OAAO,KAAK,EAAE,6BAA6B;AAExE,KAAI,KAAK,SAAS,gBAChB,OAAM,IAAI,iBACR,KAAK,MAAM,GAAG,gBAAgB,EAC9B,mBAAmB,gBAAgB,aACpC;CAGH,MAAM,SAAS,UAAU,KAAK;AAC9B,KAAI,OAAO,OAAO,OAAO,YAAY,iBAAiB,CACpD,OAAM,IAAI,iBAAiB,MAAM,+CAA+C;;AAIpF,SAAS,YAAY,OAA4C;AAC/D,QAAO,MAAM,QAAQ,MAAM,IAAI,MAAM,OAAO,SAAkB,OAAO,SAAS,SAAS;;AAGzF,SAAS,iBAAiB,QAA4C;AACpE,KAAI,CAAC,YAAY,OAAO,MAAM,IAAI,OAAO,MAAM,WAAW,EACxD,OAAM,IAAI,UAAU,8CAA8C;AAEpE,KAAI,OAAO,MAAM,SAAS,kBACxB,OAAM,IAAI,UAAU,uCAAuC,kBAAkB,QAAQ;AAEvF,MAAK,MAAM,QAAQ,OAAO,MAAO,YAAW,KAAK;CAEjD,MAAM,cAAc,OAAO,eAAe;AAC1C,KAAI,CAAC,OAAO,UAAU,YAAY,IAAI,cAAc,KAAK,cAAc,qBACrE,OAAM,IAAI,UAAU,iDAAiD,uBAAuB;;AAIhG,eAAsB,iBACpB,QACA,QACA,QAC8B;AAC9B,YAAW,OAAO,KAAK;AACvB,QAAO,WAAW,MAAM,qBAAqB,OAAO,MAAM,QAAQ,OAAO,CAAC;;AAG5E,eAAsB,kBACpB,QACA,QACA,QACA;AACA,YAAW,OAAO,KAAK;AACvB,QAAO,WAAW,MAAM,sBAAsB,OAAO,MAAM,QAAQ,OAAO,CAAC;;AAG7E,eAAsB,sBACpB,QACA,QACA,QACA;AACA,YAAW,OAAO,KAAK;AACvB,QAAO,WAAW,MAAM,0BAA0B,OAAO,MAAM,QAAQ,OAAO,CAAC;;AAGjF,eAAsB,qBACpB,QACA,QACA,QACA;AACA,YAAW,OAAO,KAAK;AACvB,QAAO,WAAW,MAAM,yBAAyB,OAAO,MAAM,QAAQ,OAAO,CAAC;;AAGhF,eAAsB,sBACpB,QACA,QACA,QAC8C;AAC9C,kBAAiB,OAAO;CACxB,MAAM,WAAW,MAAM,kBAAkB,OAAO,OAAO;EACrD,aAAa,OAAO,eAAe;EACnC;EACA;EACD,CAAC;AACF,QAAO,WAAW,OAAO,YAAY,SAAS,CAAC;;AAGjD,eAAsB,sBAAqE;AACzF,QAAO,WAAW,EAAE,YAAY,YAAY,CAAC,MAAM,EAAE,CAAC"}