@agntn/registries 0.2.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 (85) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +303 -0
  3. package/dist/_chunks/cached-registry.d.mts +35 -0
  4. package/dist/_chunks/cached-registry.d.mts.map +1 -0
  5. package/dist/_chunks/errors.d.mts +90 -0
  6. package/dist/_chunks/errors.d.mts.map +1 -0
  7. package/dist/_chunks/helpers.mjs +95 -0
  8. package/dist/_chunks/helpers.mjs.map +1 -0
  9. package/dist/_chunks/index.d.mts +142 -0
  10. package/dist/_chunks/index.d.mts.map +1 -0
  11. package/dist/_chunks/index2.d.mts +50 -0
  12. package/dist/_chunks/index2.d.mts.map +1 -0
  13. package/dist/_chunks/index3.d.mts +18 -0
  14. package/dist/_chunks/index3.d.mts.map +1 -0
  15. package/dist/_chunks/lockfile.d.mts +50 -0
  16. package/dist/_chunks/lockfile.d.mts.map +1 -0
  17. package/dist/_chunks/paths.d.mts +11 -0
  18. package/dist/_chunks/paths.d.mts.map +1 -0
  19. package/dist/_chunks/purl.mjs +192 -0
  20. package/dist/_chunks/purl.mjs.map +1 -0
  21. package/dist/_chunks/registries.mjs +1197 -0
  22. package/dist/_chunks/registries.mjs.map +1 -0
  23. package/dist/_chunks/registry.d.mts +39 -0
  24. package/dist/_chunks/registry.d.mts.map +1 -0
  25. package/dist/_chunks/registry.mjs +201 -0
  26. package/dist/_chunks/registry.mjs.map +1 -0
  27. package/dist/_chunks/storage.d.mts +22 -0
  28. package/dist/_chunks/storage.d.mts.map +1 -0
  29. package/dist/_chunks/types.d.mts +73 -0
  30. package/dist/_chunks/types.d.mts.map +1 -0
  31. package/dist/ai.d.mts +35 -0
  32. package/dist/ai.d.mts.map +1 -0
  33. package/dist/ai.mjs +50 -0
  34. package/dist/ai.mjs.map +1 -0
  35. package/dist/cache/cached-registry.d.mts +4 -0
  36. package/dist/cache/cached-registry.mjs +92 -0
  37. package/dist/cache/cached-registry.mjs.map +1 -0
  38. package/dist/cache/index.d.mts +8 -0
  39. package/dist/cache/index.mjs +12 -0
  40. package/dist/cache/index.mjs.map +1 -0
  41. package/dist/cache/lockfile.d.mts +2 -0
  42. package/dist/cache/lockfile.mjs +68 -0
  43. package/dist/cache/lockfile.mjs.map +1 -0
  44. package/dist/cache/paths.d.mts +2 -0
  45. package/dist/cache/paths.mjs +26 -0
  46. package/dist/cache/paths.mjs.map +1 -0
  47. package/dist/cache/storage.d.mts +2 -0
  48. package/dist/cache/storage.mjs +40 -0
  49. package/dist/cache/storage.mjs.map +1 -0
  50. package/dist/cli.d.mts +1 -0
  51. package/dist/cli.mjs +19 -0
  52. package/dist/cli.mjs.map +1 -0
  53. package/dist/commands/cache.d.mts +7 -0
  54. package/dist/commands/cache.d.mts.map +1 -0
  55. package/dist/commands/cache.mjs +80 -0
  56. package/dist/commands/cache.mjs.map +1 -0
  57. package/dist/commands/deps.d.mts +23 -0
  58. package/dist/commands/deps.d.mts.map +1 -0
  59. package/dist/commands/deps.mjs +72 -0
  60. package/dist/commands/deps.mjs.map +1 -0
  61. package/dist/commands/info.d.mts +26 -0
  62. package/dist/commands/info.d.mts.map +1 -0
  63. package/dist/commands/info.mjs +54 -0
  64. package/dist/commands/info.mjs.map +1 -0
  65. package/dist/commands/maintainers.d.mts +23 -0
  66. package/dist/commands/maintainers.d.mts.map +1 -0
  67. package/dist/commands/maintainers.mjs +46 -0
  68. package/dist/commands/maintainers.mjs.map +1 -0
  69. package/dist/commands/shared.d.mts +27 -0
  70. package/dist/commands/shared.d.mts.map +1 -0
  71. package/dist/commands/shared.mjs +69 -0
  72. package/dist/commands/shared.mjs.map +1 -0
  73. package/dist/commands/versions.d.mts +31 -0
  74. package/dist/commands/versions.d.mts.map +1 -0
  75. package/dist/commands/versions.mjs +58 -0
  76. package/dist/commands/versions.mjs.map +1 -0
  77. package/dist/core/index.d.mts +4 -0
  78. package/dist/core/index.mjs +3 -0
  79. package/dist/index.d.mts +11 -0
  80. package/dist/index.mjs +10 -0
  81. package/dist/registries/index.d.mts +4 -0
  82. package/dist/registries/index.mjs +4 -0
  83. package/dist/types.d.mts +3 -0
  84. package/dist/types.mjs +1 -0
  85. package/package.json +102 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registries.mjs","names":[],"sources":["../../src/registries/npm.ts","../../src/registries/cargo.ts","../../src/registries/pypi.ts","../../src/registries/rubygems.ts","../../src/registries/packagist.ts","../../src/registries/alpm.ts"],"sourcesContent":["import type { Client } from \"../core/client.ts\";\nimport type { Dependency, Maintainer, Package, URLBuilder, Version } from \"../core/types.ts\";\nimport { Registry, register } from \"../core/registry.ts\";\nimport { HTTPError, NotFoundError } from \"../core/errors.ts\";\nimport { normalizeLicense } from \"../core/license.ts\";\nimport { normalizeRepositoryURL } from \"../core/repository.ts\";\nimport { buildPURL } from \"../core/purl.ts\";\n\n/** npm registry API response for a single package. */\ninterface NpmPackageResponse {\n name: string;\n description?: string;\n homepage?: string;\n repository?:\n | {\n type?: string;\n url?: string;\n }\n | string;\n license?:\n | string\n | {\n type?: string;\n };\n keywords?: string[];\n \"dist-tags\": {\n latest: string;\n };\n versions: Record<string, NpmVersion>;\n maintainers?: Array<{\n name?: string;\n email?: string;\n url?: string;\n }>;\n time?: Record<string, string>;\n}\n\n/** npm version data. */\ninterface NpmVersion {\n name: string;\n version: string;\n description?: string;\n license?:\n | string\n | {\n type?: string;\n };\n keywords?: string[];\n author?: {\n name?: string;\n email?: string;\n url?: string;\n };\n contributors?: Array<{\n name?: string;\n email?: string;\n url?: string;\n }>;\n maintainers?: Array<{\n name?: string;\n email?: string;\n url?: string;\n }>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n optionalDependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n dist?: {\n integrity?: string;\n shasum?: string;\n tarball?: string;\n };\n deprecated?: boolean | string;\n}\n\n/** npm registry client. */\nexport class NpmRegistry extends Registry {\n constructor(baseURL: string, client: Client) {\n super();\n this.baseURL = baseURL;\n this.client = client;\n }\n\n readonly baseURL: string;\n readonly client: Client;\n\n ecosystem(): string {\n return \"npm\";\n }\n\n async fetchPackage(name: string, signal?: AbortSignal): Promise<Package> {\n const encodedName = this.encodeName(name);\n const url = `${this.baseURL}/${encodedName}`;\n\n try {\n const data = await this.client.getJSON<NpmPackageResponse>(url, signal);\n\n const latestVersion = data[\"dist-tags\"].latest;\n const latestVersionData = data.versions[latestVersion];\n\n const licenses = this.extractLicense(data.license || latestVersionData?.license);\n const namespace = this.extractNamespace(name);\n\n return {\n name: data.name,\n description: data.description || \"\",\n homepage: data.homepage || \"\",\n documentation: \"\",\n repository: normalizeRepositoryURL(data.repository || \"\"),\n licenses,\n keywords: data.keywords || [],\n namespace,\n latestVersion,\n metadata: {},\n };\n } catch (error) {\n if (error instanceof HTTPError && error.isNotFound()) {\n throw new NotFoundError(\"npm\", name);\n }\n throw error;\n }\n }\n\n async fetchVersions(name: string, signal?: AbortSignal): Promise<Version[]> {\n const encodedName = this.encodeName(name);\n const url = `${this.baseURL}/${encodedName}`;\n\n try {\n const data = await this.client.getJSON<NpmPackageResponse>(url, signal);\n const versions: Version[] = [];\n\n for (const [versionStr, versionData] of Object.entries(data.versions)) {\n const licenses = this.extractLicense(versionData.license);\n const publishedAt = data.time?.[versionStr] ? new Date(data.time[versionStr]) : null;\n\n const status = versionData.deprecated ? \"deprecated\" : \"\";\n\n const integrity = versionData.dist?.integrity\n ? versionData.dist.integrity\n : versionData.dist?.shasum\n ? `sha1-${versionData.dist.shasum}`\n : \"\";\n\n versions.push({\n number: versionStr,\n publishedAt,\n licenses,\n integrity,\n status,\n metadata: {},\n });\n }\n\n return versions;\n } catch (error) {\n if (error instanceof HTTPError && error.isNotFound()) {\n throw new NotFoundError(\"npm\", name);\n }\n throw error;\n }\n }\n\n async fetchDependencies(\n name: string,\n version: string,\n signal?: AbortSignal,\n ): Promise<Dependency[]> {\n const encodedName = this.encodeName(name);\n const url = `${this.baseURL}/${encodedName}/${version}`;\n\n try {\n const versionData = await this.client.getJSON<NpmVersion>(url, signal);\n\n const dependencies: Dependency[] = [];\n\n // Runtime dependencies\n if (versionData.dependencies) {\n for (const [depName, requirements] of Object.entries(versionData.dependencies)) {\n if (\n versionData.optionalDependencies &&\n Object.hasOwn(versionData.optionalDependencies, depName)\n ) {\n continue;\n }\n dependencies.push({\n name: depName,\n requirements,\n scope: \"runtime\",\n optional: false,\n });\n }\n }\n\n // Development dependencies\n if (versionData.devDependencies) {\n for (const [depName, requirements] of Object.entries(versionData.devDependencies)) {\n dependencies.push({\n name: depName,\n requirements,\n scope: \"development\",\n optional: false,\n });\n }\n }\n\n // Optional dependencies\n if (versionData.optionalDependencies) {\n for (const [depName, requirements] of Object.entries(versionData.optionalDependencies)) {\n dependencies.push({\n name: depName,\n requirements,\n scope: \"runtime\",\n optional: true,\n });\n }\n }\n\n // Peer dependencies\n if (versionData.peerDependencies) {\n for (const [depName, requirements] of Object.entries(versionData.peerDependencies)) {\n dependencies.push({\n name: depName,\n requirements,\n scope: \"runtime\",\n optional: false,\n });\n }\n }\n\n return dependencies;\n } catch (error) {\n if (error instanceof HTTPError && error.isNotFound()) {\n throw new NotFoundError(\"npm\", name, version);\n }\n throw error;\n }\n }\n\n async fetchMaintainers(name: string, signal?: AbortSignal): Promise<Maintainer[]> {\n const encodedName = this.encodeName(name);\n const url = `${this.baseURL}/${encodedName}`;\n\n try {\n const data = await this.client.getJSON<NpmPackageResponse>(url, signal);\n const maintainers: Maintainer[] = [];\n const seen = new Set<string>();\n\n // Use top-level maintainers (people with publish access)\n if (data.maintainers) {\n for (const maintainer of data.maintainers) {\n const key = this.maintainerKey(maintainer.name, maintainer.email);\n if (!key || seen.has(key)) continue;\n seen.add(key);\n maintainers.push({\n uuid: \"\",\n login: maintainer.email ? maintainer.email.split(\"@\")[0] : \"\",\n name: maintainer.name || \"\",\n email: maintainer.email || \"\",\n url: maintainer.url || \"\",\n role: \"\",\n });\n }\n }\n\n // Supplement with author and contributors from the latest version only\n const latestTag = data[\"dist-tags\"].latest;\n const latestVersion = data.versions[latestTag];\n\n if (latestVersion?.author) {\n const key = this.maintainerKey(latestVersion.author.name, latestVersion.author.email);\n if (key && !seen.has(key)) {\n seen.add(key);\n maintainers.push({\n uuid: \"\",\n login: latestVersion.author.email ? latestVersion.author.email.split(\"@\")[0] : \"\",\n name: latestVersion.author.name || \"\",\n email: latestVersion.author.email || \"\",\n url: latestVersion.author.url || \"\",\n role: \"author\",\n });\n }\n }\n\n if (latestVersion?.contributors) {\n for (const contributor of latestVersion.contributors) {\n const key = this.maintainerKey(contributor.name, contributor.email);\n if (key && !seen.has(key)) {\n seen.add(key);\n maintainers.push({\n uuid: \"\",\n login: contributor.email ? contributor.email.split(\"@\")[0] : \"\",\n name: contributor.name || \"\",\n email: contributor.email || \"\",\n url: contributor.url || \"\",\n role: \"contributor\",\n });\n }\n }\n }\n\n return maintainers;\n } catch (error) {\n if (error instanceof HTTPError && error.isNotFound()) {\n throw new NotFoundError(\"npm\", name);\n }\n throw error;\n }\n }\n\n urls(): URLBuilder {\n return {\n registry: (name: string, version?: string) => {\n const base = `https://www.npmjs.com/package/${name}`;\n return version ? `${base}/v/${version}` : base;\n },\n download: (name: string, version: string) => {\n const encodedName = this.encodeName(name);\n const tarballName = name.includes(\"/\") ? name.split(\"/\")[1] : name;\n return `https://registry.npmjs.org/${encodedName}/-/${tarballName}-${version}.tgz`;\n },\n documentation: (name: string, _version?: string) => {\n return `https://www.npmjs.com/package/${name}`;\n },\n readme: (name: string, version?: string) => {\n const ver = version ? `@${version}` : \"\";\n return `https://cdn.jsdelivr.net/npm/${name}${ver}/README.md`;\n },\n purl: (name: string, version?: string) => {\n const namespace = this.extractNamespace(name);\n const bareName = namespace ? name.slice(namespace.length + 1) : name;\n return buildPURL({ type: \"npm\", namespace, name: bareName, version });\n },\n };\n }\n\n /** Build a stable dedup key. Prefers email (unique per account), falls back to name. */\n private maintainerKey(name: string | undefined, email: string | undefined): string {\n if (email) return email;\n if (name) return name;\n return \"\";\n }\n\n /** Encode package name for URL (handle scoped packages). */\n private encodeName(name: string): string {\n if (name.startsWith(\"@\")) {\n return name.replace(\"/\", \"%2F\");\n }\n return name;\n }\n\n /** Extract namespace from scoped package name. */\n private extractNamespace(name: string): string {\n if (name.startsWith(\"@\")) {\n const parts = name.split(\"/\");\n return parts[0] || \"\";\n }\n return \"\";\n }\n\n /** Extract and normalize license. */\n private extractLicense(raw: string | { type?: string } | undefined): string {\n if (!raw) return \"\";\n\n if (typeof raw === \"string\") {\n return normalizeLicense(raw);\n }\n\n if (typeof raw === \"object\" && raw !== null) {\n const obj = raw as Record<string, unknown>;\n if (typeof obj[\"type\"] === \"string\") {\n return normalizeLicense(obj[\"type\"]);\n }\n }\n\n return \"\";\n }\n}\n\nregister(\"npm\", \"https://registry.npmjs.org\", NpmRegistry);\n","import type { Client } from \"../core/client.ts\";\nimport type { Dependency, Maintainer, Package, URLBuilder, Version } from \"../core/types.ts\";\nimport { Registry, register } from \"../core/registry.ts\";\nimport { HTTPError, NotFoundError } from \"../core/errors.ts\";\nimport { normalizeLicense } from \"../core/license.ts\";\nimport { normalizeRepositoryURL } from \"../core/repository.ts\";\nimport { buildPURL } from \"../core/purl.ts\";\n\n/** Crates.io API response for a single crate. */\ninterface CratesPackageResponse {\n crate: {\n id: number;\n name: string;\n updated_at: string;\n created_at: string;\n downloads: number;\n recent_downloads: number;\n max_version: string;\n max_stable_version: string;\n newest_version: string;\n description: string;\n homepage: string;\n documentation: string;\n repository: string;\n keywords: string[];\n categories: Array<{\n id: string;\n category: string;\n created_at: string;\n }>;\n badges: unknown[];\n links: Record<string, string>;\n };\n versions: CratesVersion[];\n}\n\n/** Crates.io version data. */\ninterface CratesVersion {\n id: number;\n num: string;\n dl_path: string;\n readme_path: string;\n created_at: string;\n updated_at: string;\n downloads: number;\n features: Record<string, string[]>;\n yanked: boolean;\n license: string;\n links: Record<string, string>;\n crate_size: number;\n published_by: {\n id: number;\n login: string;\n name: string;\n avatar: string;\n url: string;\n };\n checksum: string;\n}\n\n/** Crates.io dependencies response. */\ninterface CratesDependenciesResponse {\n dependencies: CratesDependency[];\n meta: {\n prelude: boolean;\n };\n}\n\n/** Crates.io dependency data. */\ninterface CratesDependency {\n id: number;\n version_id: number;\n crate_id: string;\n req: string;\n optional: boolean;\n default_features: boolean;\n features: string[];\n target: string | null;\n kind: string;\n downloads: number;\n}\n\n/** Crates.io maintainers response. */\ninterface CratesMaintainersResponse {\n users: CratesMaintainer[];\n}\n\n/** Crates.io maintainer data. */\ninterface CratesMaintainer {\n id: number;\n login: string;\n name: string;\n avatar: string;\n url: string;\n}\n\n/** Crates.io registry client. */\nexport class CargoRegistry extends Registry {\n constructor(baseURL: string, client: Client) {\n super();\n this.baseURL = baseURL;\n this.client = client;\n }\n\n readonly baseURL: string;\n readonly client: Client;\n\n ecosystem(): string {\n return \"cargo\";\n }\n\n async fetchPackage(name: string, signal?: AbortSignal): Promise<Package> {\n const url = `${this.baseURL}/api/v1/crates/${name}`;\n\n try {\n const data = await this.client.getJSON<CratesPackageResponse>(url, signal);\n const crateData = data.crate;\n const latestVersion = crateData.max_stable_version || crateData.max_version;\n const latestVersionData = data.versions.find((v) => v.num === latestVersion);\n\n return {\n name: crateData.name,\n description: crateData.description || \"\",\n homepage: crateData.homepage || \"\",\n documentation: crateData.documentation || \"\",\n repository: normalizeRepositoryURL(crateData.repository || \"\"),\n licenses: normalizeLicense(\n latestVersionData ? latestVersionData.license : (data.versions[0]?.license ?? \"\"),\n ),\n keywords: crateData.keywords,\n namespace: \"\",\n latestVersion,\n metadata: {\n downloads: crateData.downloads,\n recentDownloads: crateData.recent_downloads,\n categories: crateData.categories,\n newestVersion: crateData.newest_version,\n defaultVersion: crateData.max_version,\n updatedAt: crateData.updated_at,\n createdAt: crateData.created_at,\n },\n };\n } catch (error) {\n if (error instanceof HTTPError && error.isNotFound()) {\n throw new NotFoundError(\"cargo\", name);\n }\n throw error;\n }\n }\n\n async fetchVersions(name: string, signal?: AbortSignal): Promise<Version[]> {\n const url = `${this.baseURL}/api/v1/crates/${name}`;\n\n try {\n const data = await this.client.getJSON<CratesPackageResponse>(url, signal);\n const versions: Version[] = [];\n\n for (const versionData of data.versions) {\n const publishedAt = new Date(versionData.created_at);\n const status = versionData.yanked ? \"yanked\" : \"\";\n\n versions.push({\n number: versionData.num,\n publishedAt,\n licenses: normalizeLicense(versionData.license),\n integrity: `sha256-${versionData.checksum}`,\n status,\n metadata: {\n crateSize: versionData.crate_size,\n features: versionData.features,\n downloads: versionData.downloads,\n },\n });\n }\n\n return versions;\n } catch (error) {\n if (error instanceof HTTPError && error.isNotFound()) {\n throw new NotFoundError(\"cargo\", name);\n }\n throw error;\n }\n }\n\n async fetchDependencies(\n name: string,\n version: string,\n signal?: AbortSignal,\n ): Promise<Dependency[]> {\n const url = `${this.baseURL}/api/v1/crates/${name}/${version}/dependencies`;\n\n try {\n const data = await this.client.getJSON<CratesDependenciesResponse>(url, signal);\n const dependencies: Dependency[] = [];\n\n for (const dep of data.dependencies) {\n let scope: \"runtime\" | \"development\" | \"test\" | \"build\" | \"optional\";\n\n if (dep.kind === \"dev\") {\n scope = \"development\";\n } else if (dep.kind === \"build\") {\n scope = \"build\";\n } else {\n scope = \"runtime\";\n }\n\n dependencies.push({\n name: dep.crate_id,\n requirements: dep.req,\n scope,\n optional: dep.optional,\n });\n }\n\n return dependencies;\n } catch (error) {\n if (error instanceof HTTPError && error.isNotFound()) {\n throw new NotFoundError(\"cargo\", name, version);\n }\n throw error;\n }\n }\n\n async fetchMaintainers(name: string, signal?: AbortSignal): Promise<Maintainer[]> {\n const url = `${this.baseURL}/api/v1/crates/${name}/owner_user`;\n\n try {\n const data = await this.client.getJSON<CratesMaintainersResponse>(url, signal);\n const maintainers: Maintainer[] = [];\n\n for (const user of data.users) {\n maintainers.push({\n uuid: user.id.toString(),\n login: user.login,\n name: user.name,\n email: \"\",\n url: user.url,\n role: \"\",\n });\n }\n\n return maintainers;\n } catch (error) {\n if (error instanceof HTTPError && error.isNotFound()) {\n throw new NotFoundError(\"cargo\", name);\n }\n throw error;\n }\n }\n\n urls(): URLBuilder {\n return {\n registry: (name: string, version?: string) => {\n const base = `https://crates.io/crates/${name}`;\n return version ? `${base}/${version}` : base;\n },\n download: (name: string, version: string) => {\n return `https://crates.io/api/v1/crates/${name}/${version}/download`;\n },\n documentation: (name: string, version?: string) => {\n return version ? `https://docs.rs/${name}/${version}` : `https://docs.rs/${name}`;\n },\n readme: (name: string, version?: string) => {\n return version\n ? `https://crates.io/api/v1/crates/${name}/${version}/readme`\n : `https://crates.io/crates/${name}`;\n },\n purl: (name: string, version?: string) => {\n return buildPURL({ type: \"cargo\", name, version });\n },\n };\n }\n}\n\nregister(\"cargo\", \"https://crates.io\", CargoRegistry);\n","import type { Client } from \"../core/client.ts\";\nimport type { Dependency, Maintainer, Package, URLBuilder, Version } from \"../core/types.ts\";\nimport { Registry, register } from \"../core/registry.ts\";\nimport { HTTPError, NotFoundError } from \"../core/errors.ts\";\nimport { normalizeLicense } from \"../core/license.ts\";\nimport { normalizeRepositoryURL } from \"../core/repository.ts\";\nimport { buildPURL } from \"../core/purl.ts\";\n\nconst PYPI_FILENAME_SEPARATORS = [\"_\", \"-\", \".\"] as const;\n\n/** PyPI JSON API response for a package. */\ninterface PyPIPackageResponse {\n info: {\n name: string;\n version: string;\n summary: string;\n description: string;\n license: string;\n keywords: string;\n author: string;\n author_email: string;\n project_urls: Record<string, string>;\n requires_dist: string[] | null;\n };\n urls: PyPIFile[];\n}\n\n/** PyPI file information. */\ninterface PyPIFile {\n filename: string;\n url: string;\n upload_time_iso_8601: string;\n yanked: boolean;\n digests: {\n sha256: string;\n };\n}\n\n/** PyPI Simple API (PEP 691) response for a project. */\ninterface PyPISimpleResponse {\n meta: { \"api-version\": string };\n name: string;\n versions: string[];\n files: PyPISimpleFile[];\n}\n\n/** A single file entry in the Simple API response. */\ninterface PyPISimpleFile {\n filename: string;\n url: string;\n hashes: { sha256?: string };\n \"requires-python\"?: string;\n yanked?: string | false;\n \"upload-time\"?: string;\n}\n\n/** PyPI registry client. */\nexport class PyPIRegistry extends Registry {\n constructor(baseURL: string, client: Client) {\n super();\n this.baseURL = baseURL;\n this.client = client;\n }\n\n readonly baseURL: string;\n readonly client: Client;\n\n private readonly downloadUrls = new Map<string, string>();\n\n ecosystem(): string {\n return \"pypi\";\n }\n\n async fetchPackage(name: string, signal?: AbortSignal): Promise<Package> {\n const normalized = this.normalizeName(name);\n const url = `${this.baseURL}/pypi/${normalized}/json`;\n\n try {\n const data = await this.client.getJSON<PyPIPackageResponse>(url, signal);\n const info = data.info;\n\n const licenses = normalizeLicense(info.license);\n const repository = this.extractRepository(info.project_urls);\n const keywords = this.parseKeywords(info.keywords);\n\n return {\n name: info.name,\n description: info.summary || info.description || \"\",\n homepage: this.findProjectUrl(info.project_urls, [\"Homepage\"]),\n documentation: this.findProjectUrl(info.project_urls, [\"Documentation\"]),\n repository,\n licenses,\n keywords,\n namespace: \"\",\n latestVersion: info.version,\n metadata: {},\n };\n } catch (error) {\n if (error instanceof HTTPError && error.isNotFound()) {\n throw new NotFoundError(\"pypi\", name);\n }\n throw error;\n }\n }\n\n async fetchVersions(name: string, signal?: AbortSignal): Promise<Version[]> {\n const normalized = this.normalizeName(name);\n const url = `${this.baseURL}/simple/${normalized}/`;\n\n try {\n const data = await this.client.getJSON<PyPISimpleResponse>(url, signal, {\n Accept: \"application/vnd.pypi.simple.v1+json\",\n });\n\n const filesByVersion = new Map<string, PyPISimpleFile[]>();\n for (const version of data.versions) {\n filesByVersion.set(version, []);\n }\n\n for (const file of data.files) {\n const version = this.matchFileVersion(file.filename, normalized, data.versions);\n if (version) {\n filesByVersion.get(version)!.push(file);\n }\n }\n\n const versions: Version[] = [];\n for (const [versionStr, files] of filesByVersion) {\n if (files.length === 0) {\n versions.push({\n number: versionStr,\n publishedAt: null,\n licenses: \"\",\n integrity: \"\",\n status: \"\",\n metadata: {},\n });\n continue;\n }\n\n const sdist = files.find((f) => f.filename.endsWith(\".tar.gz\"));\n const file = sdist ?? files[0]!;\n const publishedAt = file[\"upload-time\"] ? new Date(file[\"upload-time\"]) : null;\n const integrity = file.hashes?.sha256 ? `sha256-${file.hashes.sha256}` : \"\";\n const status = file.yanked ? \"yanked\" : \"\";\n\n this.downloadUrls.set(`${normalized}@${versionStr}`, file.url);\n\n versions.push({\n number: versionStr,\n publishedAt,\n licenses: \"\",\n integrity,\n status,\n metadata: {},\n });\n }\n\n return versions;\n } catch (error) {\n if (error instanceof HTTPError && error.isNotFound()) {\n throw new NotFoundError(\"pypi\", name);\n }\n throw error;\n }\n }\n\n async fetchDependencies(\n name: string,\n version: string,\n signal?: AbortSignal,\n ): Promise<Dependency[]> {\n const normalized = this.normalizeName(name);\n const url = `${this.baseURL}/pypi/${normalized}/${version}/json`;\n\n try {\n const data = await this.client.getJSON<PyPIPackageResponse>(url, signal);\n const dependencies: Dependency[] = [];\n\n if (data.info.requires_dist) {\n for (const depStr of data.info.requires_dist) {\n const dep = this.parsePEP508(depStr);\n if (dep) {\n dependencies.push(dep);\n }\n }\n }\n\n return dependencies;\n } catch (error) {\n if (error instanceof HTTPError && error.isNotFound()) {\n throw new NotFoundError(\"pypi\", name, version);\n }\n throw error;\n }\n }\n\n async fetchMaintainers(name: string, signal?: AbortSignal): Promise<Maintainer[]> {\n const normalized = this.normalizeName(name);\n const url = `${this.baseURL}/pypi/${normalized}/json`;\n\n try {\n const data = await this.client.getJSON<PyPIPackageResponse>(url, signal);\n const maintainers: Maintainer[] = [];\n\n if (data.info.author || data.info.author_email) {\n maintainers.push({\n uuid: \"\",\n login: data.info.author_email ? data.info.author_email.split(\"@\")[0] : \"\",\n name: data.info.author || \"\",\n email: data.info.author_email || \"\",\n url: \"\",\n role: \"author\",\n });\n }\n\n return maintainers;\n } catch (error) {\n if (error instanceof HTTPError && error.isNotFound()) {\n throw new NotFoundError(\"pypi\", name);\n }\n throw error;\n }\n }\n\n urls(): URLBuilder {\n return {\n registry: (name: string, version?: string) => {\n const normalized = this.normalizeName(name);\n const base = `https://pypi.org/project/${normalized}`;\n return version ? `${base}/${version}` : base;\n },\n download: (name: string, version: string) => {\n const normalized = this.normalizeName(name);\n return (\n this.downloadUrls.get(`${normalized}@${version}`) ??\n `https://pypi.org/project/${normalized}/${version}/`\n );\n },\n documentation: (name: string, _version?: string) => {\n const normalized = this.normalizeName(name);\n return `https://pypi.org/project/${normalized}`;\n },\n readme: (name: string, version?: string) => {\n const normalized = this.normalizeName(name);\n return version\n ? `https://pypi.org/project/${normalized}/${version}/`\n : `https://pypi.org/project/${normalized}/`;\n },\n purl: (name: string, version?: string) => {\n return buildPURL({ type: \"pypi\", name: this.normalizeName(name), version });\n },\n };\n }\n\n /** Match a filename to a version from the known versions list. */\n private matchFileVersion(\n filename: string,\n normalizedName: string,\n versions: string[],\n ): string | undefined {\n const lower = filename.toLowerCase();\n let prefix: string | undefined;\n\n for (const separator of PYPI_FILENAME_SEPARATORS) {\n const candidate = normalizedName.replaceAll(\"-\", separator) + \"-\";\n if (lower.startsWith(candidate)) {\n prefix = candidate;\n break;\n }\n }\n\n if (!prefix) return undefined;\n\n const afterPrefix = filename.slice(prefix.length);\n\n // Wheel: {name}-{version}-{python}-{abi}-{platform}.whl\n // Version is before the first dash after the prefix\n const dashIdx = afterPrefix.indexOf(\"-\");\n if (dashIdx !== -1) {\n const candidate = afterPrefix.slice(0, dashIdx);\n if (versions.includes(candidate)) return candidate;\n }\n\n // Sdist: {name}-{version}.tar.gz / .zip / .tar.bz2\n const stripped = afterPrefix.replace(/\\.(tar\\.(gz|bz2|xz)|zip)$/i, \"\");\n if (versions.includes(stripped)) return stripped;\n\n return undefined;\n }\n\n /** Normalize package name per PEP 503. */\n private normalizeName(name: string): string {\n return name.toLowerCase().replace(/[-_.]+/g, \"-\");\n }\n\n /** Extract repository URL from project_urls. */\n private extractRepository(projectUrls: Record<string, string> | undefined): string {\n const url = this.findProjectUrl(projectUrls, [\n \"Repository\",\n \"Source\",\n \"Source Code\",\n \"GitHub\",\n \"Homepage\",\n ]);\n return normalizeRepositoryURL(url);\n }\n\n /** Find a project URL by key, case-insensitive. */\n private findProjectUrl(projectUrls: Record<string, string> | undefined, keys: string[]): string {\n if (!projectUrls) return \"\";\n\n const lowered = new Map<string, string>();\n for (const [k, v] of Object.entries(projectUrls)) {\n lowered.set(k.toLowerCase(), v);\n }\n\n for (const key of keys) {\n const value = lowered.get(key.toLowerCase());\n if (value) return value;\n }\n\n return \"\";\n }\n\n /** Parse comma-separated keywords. */\n private parseKeywords(keywords: string | undefined): string[] {\n if (!keywords) return [];\n return keywords\n .split(\",\")\n .map((k) => k.trim())\n .filter(Boolean);\n }\n\n /** Parse PEP 508 dependency string into a normalized Dependency. */\n private parsePEP508(depStr: string): Dependency | null {\n // PEP 508 format: name [extras] (version_spec) ; markers\n const semiIdx = depStr.indexOf(\";\");\n const mainPart = semiIdx === -1 ? depStr.trim() : depStr.slice(0, semiIdx).trim();\n const markerStr = semiIdx === -1 ? \"\" : depStr.slice(semiIdx + 1).trim();\n\n // Extract name, skip [extras] bracket group, capture version spec\n const match = mainPart.match(/^([a-zA-Z0-9._-]+)\\s*(?:\\[.*?\\])?\\s*(.*)$/);\n if (!match) return null;\n\n const depName = match[1]!;\n let versionSpec = match[2]!.trim();\n\n // Strip surrounding parentheses: \"(<4,>=2)\" -> \"<4,>=2\"\n if (versionSpec.startsWith(\"(\") && versionSpec.endsWith(\")\")) {\n versionSpec = versionSpec.slice(1, -1).trim();\n }\n\n // Only `extra == \"...\"` markers affect scope. Platform markers don't.\n let scope: \"runtime\" | \"development\" | \"test\" | \"build\" | \"optional\" = \"runtime\";\n let optional = false;\n\n if (markerStr) {\n const extraMatch = markerStr.match(/extra\\s*==\\s*[\"']([^\"']+)[\"']/);\n if (extraMatch) {\n optional = true;\n const extraName = extraMatch[1]!.toLowerCase();\n if (/^dev(elop(ment)?)?$/.test(extraName)) {\n scope = \"development\";\n } else if (/^test(s|ing)?$/.test(extraName)) {\n scope = \"test\";\n }\n }\n }\n\n return {\n name: this.normalizeName(depName),\n requirements: versionSpec,\n scope,\n optional,\n };\n }\n}\n\nregister(\"pypi\", \"https://pypi.org\", PyPIRegistry);\n","import type { Client } from \"../core/client.ts\";\nimport type { Dependency, Maintainer, Package, URLBuilder, Version } from \"../core/types.ts\";\nimport { Registry, register } from \"../core/registry.ts\";\nimport { HTTPError, NotFoundError } from \"../core/errors.ts\";\nimport { combineLicenses, normalizeLicense } from \"../core/license.ts\";\nimport { normalizeRepositoryURL } from \"../core/repository.ts\";\nimport { buildPURL } from \"../core/purl.ts\";\n\n/** RubyGems API response for a single gem. */\ninterface RubyGemsGemResponse {\n name: string;\n version?: string;\n description: string;\n homepage_uri?: string;\n documentation_uri?: string;\n source_code_uri?: string;\n licenses?: string[];\n metadata?: Record<string, unknown>;\n dependencies?: {\n runtime?: Array<{\n name: string;\n requirements: string;\n }>;\n development?: Array<{\n name: string;\n requirements: string;\n }>;\n };\n}\n\n/** RubyGems version data. */\ninterface RubyGemsVersionResponse {\n number: string;\n sha: string;\n created_at?: string;\n yanked?: boolean;\n}\n\n/** RubyGems owner data. */\ninterface RubyGemsOwnerResponse {\n handle: string;\n email?: string;\n}\n\n/** RubyGems registry client. */\nexport class RubyGemsRegistry extends Registry {\n constructor(baseURL: string, client: Client) {\n super();\n this.baseURL = baseURL;\n this.client = client;\n }\n\n readonly baseURL: string;\n readonly client: Client;\n\n ecosystem(): string {\n return \"gem\";\n }\n\n async fetchPackage(name: string, signal?: AbortSignal): Promise<Package> {\n const url = `${this.baseURL}/api/v1/gems/${name}.json`;\n\n try {\n const data = await this.client.getJSON<RubyGemsGemResponse>(url, signal);\n\n // Extract licenses\n const licenses = data.licenses\n ? combineLicenses(data.licenses.map((l) => normalizeLicense(l)))\n : \"\";\n\n // Extract repository URL\n const repository = normalizeRepositoryURL(\n data.source_code_uri ||\n (data.metadata?.source_code_uri as string) ||\n data.homepage_uri ||\n \"\",\n );\n\n return {\n name: data.name,\n description: data.description || \"\",\n homepage: data.homepage_uri || \"\",\n documentation: data.documentation_uri || \"\",\n repository,\n licenses,\n keywords: [],\n namespace: \"\",\n latestVersion: data.version || \"\",\n metadata: data.metadata || {},\n };\n } catch (error) {\n if (error instanceof HTTPError && error.isNotFound()) {\n throw new NotFoundError(\"gem\", name);\n }\n throw error;\n }\n }\n\n async fetchVersions(name: string, signal?: AbortSignal): Promise<Version[]> {\n const url = `${this.baseURL}/api/v1/versions/${name}.json`;\n\n try {\n const data = await this.client.getJSON<RubyGemsVersionResponse[]>(url, signal);\n const versions: Version[] = [];\n\n for (const versionData of data) {\n const publishedAt = versionData.created_at ? new Date(versionData.created_at) : null;\n const status = versionData.yanked ? \"yanked\" : \"\";\n\n versions.push({\n number: versionData.number,\n publishedAt,\n licenses: \"\",\n integrity: versionData.sha ? `sha256-${versionData.sha}` : \"\",\n status,\n metadata: {},\n });\n }\n\n return versions;\n } catch (error) {\n if (error instanceof HTTPError && error.isNotFound()) {\n throw new NotFoundError(\"gem\", name);\n }\n throw error;\n }\n }\n\n async fetchDependencies(\n name: string,\n version: string,\n signal?: AbortSignal,\n ): Promise<Dependency[]> {\n const url = `${this.baseURL}/api/v2/rubygems/${name}/versions/${version}.json`;\n\n try {\n const data = await this.client.getJSON<RubyGemsGemResponse>(url, signal);\n const dependencies: Dependency[] = [];\n\n // Runtime dependencies\n if (data.dependencies?.runtime) {\n for (const dep of data.dependencies.runtime) {\n dependencies.push({\n name: dep.name,\n requirements: dep.requirements,\n scope: \"runtime\",\n optional: false,\n });\n }\n }\n\n // Development dependencies\n if (data.dependencies?.development) {\n for (const dep of data.dependencies.development) {\n dependencies.push({\n name: dep.name,\n requirements: dep.requirements,\n scope: \"development\",\n optional: false,\n });\n }\n }\n\n return dependencies;\n } catch (error) {\n if (error instanceof HTTPError && error.isNotFound()) {\n throw new NotFoundError(\"gem\", name, version);\n }\n throw error;\n }\n }\n\n async fetchMaintainers(name: string, signal?: AbortSignal): Promise<Maintainer[]> {\n const url = `${this.baseURL}/api/v1/gems/${name}/owners.json`;\n\n try {\n const data = await this.client.getJSON<RubyGemsOwnerResponse[]>(url, signal);\n const maintainers: Maintainer[] = [];\n\n for (const owner of data) {\n maintainers.push({\n uuid: \"\",\n login: owner.handle,\n name: owner.handle,\n email: owner.email || \"\",\n url: \"\",\n role: \"\",\n });\n }\n\n return maintainers;\n } catch (error) {\n if (error instanceof HTTPError && error.isNotFound()) {\n throw new NotFoundError(\"gem\", name);\n }\n throw error;\n }\n }\n\n urls(): URLBuilder {\n return {\n registry: (name: string, version?: string) => {\n const base = `https://rubygems.org/gems/${name}`;\n return version ? `${base}/versions/${version}` : base;\n },\n download: (name: string, version: string) => {\n return `https://rubygems.org/downloads/${name}-${version}.gem`;\n },\n documentation: (name: string, version?: string) => {\n const versionSuffix = version ? `/${version}` : \"\";\n return `https://www.rubydoc.info/gems/${name}${versionSuffix}`;\n },\n readme: (name: string, version?: string) => {\n const base = `https://rubygems.org/gems/${name}`;\n return version ? `${base}/versions/${version}` : base;\n },\n purl: (name: string, version?: string) => {\n return buildPURL({ type: \"gem\", name, version });\n },\n };\n }\n}\n\nregister(\"gem\", \"https://rubygems.org\", RubyGemsRegistry);\n","import type { Client } from \"../core/client.ts\";\nimport type { Dependency, Maintainer, Package, URLBuilder, Version } from \"../core/types.ts\";\nimport { Registry, register } from \"../core/registry.ts\";\nimport { HTTPError, NotFoundError, InvalidPURLError } from \"../core/errors.ts\";\nimport { combineLicenses } from \"../core/license.ts\";\nimport { normalizeRepositoryURL } from \"../core/repository.ts\";\nimport { buildPURL } from \"../core/purl.ts\";\n\n/** Packagist API response for a single package. */\ninterface PackagistPackageResponse {\n package: {\n name: string;\n description: string;\n repository?: string;\n keywords?: string[];\n versions: Record<string, PackagistVersion>;\n };\n}\n\n/** Packagist version data. */\ninterface PackagistVersion {\n name: string;\n version: string;\n license?: string | string[];\n keywords?: string[];\n authors?: Array<{\n name?: string;\n email?: string;\n homepage?: string;\n role?: string;\n }>;\n require?: Record<string, string>;\n \"require-dev\"?: Record<string, string>;\n source?: {\n type?: string;\n url?: string;\n reference?: string;\n };\n dist?: {\n type?: string;\n url?: string;\n reference?: string;\n shasum?: string;\n };\n time?: string;\n}\n\n/** Packagist registry client. */\nexport class PackagistRegistry extends Registry {\n constructor(baseURL: string, client: Client) {\n super();\n this.baseURL = baseURL;\n this.client = client;\n }\n\n readonly baseURL: string;\n readonly client: Client;\n\n ecosystem(): string {\n return \"composer\";\n }\n\n async fetchPackage(name: string, signal?: AbortSignal): Promise<Package> {\n const [vendor, pkg] = this.parseName(name);\n const url = `${this.baseURL}/packages/${vendor}/${pkg}.json`;\n\n try {\n const data = await this.client.getJSON<PackagistPackageResponse>(url, signal);\n const packageData = data.package;\n\n // Find latest version\n const versions = Object.keys(packageData.versions);\n const latestVersion = this.findLatestVersion(versions);\n\n // Get license from latest version\n const latestVersionData = packageData.versions[latestVersion];\n const licenses = this.extractLicenses(latestVersionData.license);\n\n return {\n name: packageData.name,\n description: packageData.description || \"\",\n homepage: \"\",\n documentation: \"\",\n repository: normalizeRepositoryURL(\n packageData.repository || latestVersionData.source?.url || \"\",\n ),\n licenses,\n keywords: packageData.keywords || [],\n namespace: vendor,\n latestVersion,\n metadata: {},\n };\n } catch (error) {\n if (error instanceof HTTPError && error.isNotFound()) {\n throw new NotFoundError(\"composer\", name);\n }\n throw error;\n }\n }\n\n async fetchVersions(name: string, signal?: AbortSignal): Promise<Version[]> {\n const [vendor, pkg] = this.parseName(name);\n const url = `${this.baseURL}/packages/${vendor}/${pkg}.json`;\n\n try {\n const data = await this.client.getJSON<PackagistPackageResponse>(url, signal);\n const versions: Version[] = [];\n\n for (const [versionStr, versionData] of Object.entries(data.package.versions)) {\n const licenses = this.extractLicenses(versionData.license);\n const publishedAt = versionData.time ? new Date(versionData.time) : null;\n\n versions.push({\n number: versionStr,\n publishedAt,\n licenses,\n integrity: versionData.dist?.shasum ? `sha1-${versionData.dist.shasum}` : \"\",\n status: \"\",\n metadata: {},\n });\n }\n\n return versions;\n } catch (error) {\n if (error instanceof HTTPError && error.isNotFound()) {\n throw new NotFoundError(\"composer\", name);\n }\n throw error;\n }\n }\n\n async fetchDependencies(\n name: string,\n version: string,\n signal?: AbortSignal,\n ): Promise<Dependency[]> {\n const [vendor, pkg] = this.parseName(name);\n const url = `${this.baseURL}/packages/${vendor}/${pkg}.json`;\n\n try {\n const data = await this.client.getJSON<PackagistPackageResponse>(url, signal);\n const versionData = data.package.versions[version];\n\n if (!versionData) {\n throw new NotFoundError(\"composer\", name, version);\n }\n\n const dependencies: Dependency[] = [];\n\n // Runtime dependencies\n if (versionData.require) {\n for (const [depName, requirements] of Object.entries(versionData.require)) {\n if (!this.shouldSkipDependency(depName)) {\n dependencies.push({\n name: depName,\n requirements,\n scope: \"runtime\",\n optional: false,\n });\n }\n }\n }\n\n // Development dependencies\n if (versionData[\"require-dev\"]) {\n for (const [depName, requirements] of Object.entries(versionData[\"require-dev\"])) {\n if (!this.shouldSkipDependency(depName)) {\n dependencies.push({\n name: depName,\n requirements,\n scope: \"development\",\n optional: false,\n });\n }\n }\n }\n\n return dependencies;\n } catch (error) {\n if (error instanceof HTTPError && error.isNotFound()) {\n throw new NotFoundError(\"composer\", name, version);\n }\n throw error;\n }\n }\n\n async fetchMaintainers(name: string, signal?: AbortSignal): Promise<Maintainer[]> {\n const [vendor, pkg] = this.parseName(name);\n const url = `${this.baseURL}/packages/${vendor}/${pkg}.json`;\n\n try {\n const data = await this.client.getJSON<PackagistPackageResponse>(url, signal);\n const maintainers: Maintainer[] = [];\n const seen = new Set<string>();\n\n // Collect authors from all versions\n for (const versionData of Object.values(data.package.versions)) {\n if (versionData.authors) {\n for (const author of versionData.authors) {\n const key = `${author.name}:${author.email}`;\n if (!seen.has(key)) {\n seen.add(key);\n maintainers.push({\n uuid: \"\",\n login: author.email ? author.email.split(\"@\")[0] : \"\",\n name: author.name || \"\",\n email: author.email || \"\",\n url: author.homepage || \"\",\n role: author.role || \"\",\n });\n }\n }\n }\n }\n\n return maintainers;\n } catch (error) {\n if (error instanceof HTTPError && error.isNotFound()) {\n throw new NotFoundError(\"composer\", name);\n }\n throw error;\n }\n }\n\n urls(): URLBuilder {\n return {\n registry: (name: string, version?: string) => {\n const [vendor, pkg] = this.parseName(name);\n const base = `https://packagist.org/packages/${vendor}/${pkg}`;\n return version ? `${base}#${version}` : base;\n },\n download: (name: string, version: string) => {\n const [vendor, pkg] = this.parseName(name);\n return `https://repo.packagist.org/p/${vendor}/${pkg}/${version}.json`;\n },\n documentation: (name: string, _version?: string) => {\n const [vendor, pkg] = this.parseName(name);\n return `https://packagist.org/packages/${vendor}/${pkg}`;\n },\n readme: (name: string, _version?: string) => {\n const [vendor, pkg] = this.parseName(name);\n return `https://packagist.org/packages/${vendor}/${pkg}`;\n },\n purl: (name: string, version?: string) => {\n const [vendor, pkg] = this.parseName(name);\n return buildPURL({ type: \"composer\", namespace: vendor, name: pkg, version });\n },\n };\n }\n\n /** Parse \"vendor/package\" format. */\n private parseName(name: string): [string, string] {\n const parts = name.split(\"/\");\n if (parts.length !== 2 || !parts[0] || !parts[1]) {\n throw new InvalidPURLError(\n `pkg:composer/${name}`,\n 'invalid Composer package name, expected \"vendor/package\" format',\n );\n }\n return [parts[0]!, parts[1]!];\n }\n\n /** Find the highest non-dev version. */\n private findLatestVersion(versions: string[]): string {\n // Filter out dev versions\n const stable = versions.filter((v) => !v.startsWith(\"dev-\") && !v.endsWith(\"-dev\"));\n if (stable.length === 0) {\n return versions[0] || \"\";\n }\n\n // Sort by semantic versioning (simplified)\n return (\n stable.sort((a, b) => {\n // Remove 'v' prefix if present\n const aClean = a.replace(/^v/, \"\");\n const bClean = b.replace(/^v/, \"\");\n\n // Try numeric comparison for simple versions\n const aParts = aClean.split(\".\").map((p) => Number.parseInt(p, 10));\n const bParts = bClean.split(\".\").map((p) => Number.parseInt(p, 10));\n\n for (let i = 0; i < Math.max(aParts.length, bParts.length); i++) {\n const aPart = aParts[i] ?? 0;\n const bPart = bParts[i] ?? 0;\n if (aPart !== bPart) {\n return bPart - aPart;\n }\n }\n\n return 0;\n })[0] ||\n versions[0] ||\n \"\"\n );\n }\n\n /** Extract and normalize licenses. */\n private extractLicenses(raw: string | string[] | undefined): string {\n if (!raw) return \"\";\n\n const licenses = Array.isArray(raw) ? raw : [raw];\n return combineLicenses(licenses);\n }\n\n /** Skip PHP and extension dependencies. */\n private shouldSkipDependency(name: string): boolean {\n return name === \"php\" || name.startsWith(\"ext-\");\n }\n}\n\nregister(\"composer\", \"https://packagist.org\", PackagistRegistry);\n","import type { Client } from \"../core/client.ts\";\nimport type { Dependency, Maintainer, Package, URLBuilder, Version } from \"../core/types.ts\";\nimport { Registry, register } from \"../core/registry.ts\";\nimport { HTTPError, NotFoundError } from \"../core/errors.ts\";\nimport { combineLicenses } from \"../core/license.ts\";\nimport { buildPURL } from \"../core/purl.ts\";\n\nconst AUR_BASE_URL = \"https://aur.archlinux.org\";\n\n/** Arch Linux official package search response. */\ninterface ArchSearchResponse {\n results: ArchPackageResult[];\n}\n\n/** Arch Linux official package data from search/detail endpoints. */\ninterface ArchPackageResult {\n pkgname: string;\n pkgbase: string;\n repo: string;\n arch: string;\n pkgver: string;\n pkgrel: string;\n epoch: number;\n pkgdesc: string;\n url: string;\n filename: string;\n compressed_size: number;\n installed_size: number;\n build_date: string;\n last_update: string;\n flag_date: string | null;\n maintainers: string[];\n packager: string;\n groups: string[];\n licenses: string[];\n conflicts: string[];\n provides: string[];\n replaces: string[];\n depends: string[];\n optdepends: string[];\n makedepends: string[];\n checkdepends: string[];\n}\n\n/** AUR RPC v5 response wrapper. */\ninterface AurResponse {\n resultcount: number;\n results: AurPackageResult[];\n type: string;\n version: number;\n}\n\n/** AUR package data. */\ninterface AurPackageResult {\n ID: number;\n Name: string;\n PackageBase: string;\n PackageBaseID: number;\n Version: string;\n Description: string;\n URL: string;\n NumVotes: number;\n Popularity: number;\n OutOfDate: number | null;\n Maintainer: string | null;\n FirstSubmitted: number;\n LastModified: number;\n URLPath: string;\n Depends?: string[];\n OptDepends?: string[];\n MakeDepends?: string[];\n CheckDepends?: string[];\n License?: string[];\n Keywords?: string[];\n}\n\n/** ALPM registry client — routes to Arch Linux official repos or AUR based on namespace. */\nexport class AlpmRegistry extends Registry {\n constructor(baseURL: string, client: Client) {\n super();\n this.baseURL = baseURL;\n this.client = client;\n }\n\n readonly baseURL: string;\n readonly client: Client;\n\n ecosystem(): string {\n return \"alpm\";\n }\n\n async fetchPackage(name: string, signal?: AbortSignal): Promise<Package> {\n const { namespace, pkgName } = this.parseName(name);\n this.assertSupportedNamespace(namespace, name);\n\n if (namespace === \"aur\") {\n return this.fetchAurPackage(pkgName, signal);\n }\n\n return this.fetchOfficialPackage(pkgName, signal);\n }\n\n async fetchVersions(name: string, signal?: AbortSignal): Promise<Version[]> {\n const { namespace, pkgName } = this.parseName(name);\n this.assertSupportedNamespace(namespace, name);\n\n if (namespace === \"aur\") {\n return this.fetchAurVersions(pkgName, signal);\n }\n\n return this.fetchOfficialVersions(pkgName, signal);\n }\n\n async fetchDependencies(\n name: string,\n version: string,\n signal?: AbortSignal,\n ): Promise<Dependency[]> {\n const { namespace, pkgName } = this.parseName(name);\n this.assertSupportedNamespace(namespace, name);\n\n if (namespace === \"aur\") {\n return this.fetchAurDependencies(pkgName, version, signal);\n }\n\n return this.fetchOfficialDependencies(pkgName, version, signal);\n }\n\n async fetchMaintainers(name: string, signal?: AbortSignal): Promise<Maintainer[]> {\n const { namespace, pkgName } = this.parseName(name);\n this.assertSupportedNamespace(namespace, name);\n\n if (namespace === \"aur\") {\n return this.fetchAurMaintainers(pkgName, signal);\n }\n\n return this.fetchOfficialMaintainers(pkgName, signal);\n }\n\n urls(): URLBuilder {\n return {\n registry: (name: string, _version?: string) => {\n const { namespace, pkgName } = this.parseName(name);\n if (namespace === \"aur\") {\n return `https://aur.archlinux.org/packages/${pkgName}`;\n }\n return `https://archlinux.org/packages/?name=${pkgName}`;\n },\n download: (name: string, _version: string) => {\n const { namespace, pkgName } = this.parseName(name);\n if (namespace === \"aur\") {\n return `https://aur.archlinux.org/cgit/aur.git/snapshot/${pkgName}.tar.gz`;\n }\n const letter = pkgName.charAt(0);\n return `https://archive.archlinux.org/packages/${letter}/${pkgName}/`;\n },\n documentation: (name: string, _version?: string) => {\n const { namespace, pkgName } = this.parseName(name);\n if (namespace === \"aur\") {\n return `https://aur.archlinux.org/packages/${pkgName}`;\n }\n return `https://wiki.archlinux.org/title/${pkgName}`;\n },\n readme: (_name: string, _version?: string) => {\n return \"\";\n },\n purl: (name: string, version?: string) => {\n const { namespace, pkgName } = this.parseName(name);\n return buildPURL({ type: \"alpm\", namespace, name: pkgName, version });\n },\n };\n }\n\n // --- Official Arch Linux API ---\n\n private async fetchOfficialPackage(name: string, signal?: AbortSignal): Promise<Package> {\n const result = await this.searchOfficial(name, signal);\n\n return {\n name: result.pkgname,\n description: result.pkgdesc || \"\",\n homepage: result.url || \"\",\n documentation: \"\",\n repository: \"\",\n licenses: combineLicenses(result.licenses),\n keywords: result.groups,\n namespace: \"arch\",\n latestVersion: this.formatVersion(result),\n metadata: {\n repo: result.repo,\n arch: result.arch,\n pkgbase: result.pkgbase,\n compressedSize: result.compressed_size,\n installedSize: result.installed_size,\n buildDate: result.build_date,\n lastUpdate: result.last_update,\n flagDate: result.flag_date,\n packager: result.packager,\n provides: result.provides,\n conflicts: result.conflicts,\n replaces: result.replaces,\n },\n };\n }\n\n private async fetchOfficialVersions(name: string, signal?: AbortSignal): Promise<Version[]> {\n const result = await this.searchOfficial(name, signal);\n\n return [\n {\n number: this.formatVersion(result),\n publishedAt: result.last_update ? new Date(result.last_update) : null,\n licenses: combineLicenses(result.licenses),\n integrity: \"\",\n status: result.flag_date ? \"deprecated\" : \"\",\n metadata: {\n repo: result.repo,\n arch: result.arch,\n },\n },\n ];\n }\n\n private async fetchOfficialDependencies(\n name: string,\n version: string,\n signal?: AbortSignal,\n ): Promise<Dependency[]> {\n const result = await this.searchOfficial(name, signal);\n const currentVersion = this.formatVersion(result);\n this.assertVersionMatches(name, version, currentVersion);\n\n return this.buildDependencies(\n result.depends,\n result.makedepends,\n result.optdepends,\n result.checkdepends,\n );\n }\n\n private async fetchOfficialMaintainers(\n name: string,\n signal?: AbortSignal,\n ): Promise<Maintainer[]> {\n const result = await this.searchOfficial(name, signal);\n\n return result.maintainers.map((m) => ({\n uuid: \"\",\n login: m,\n name: m,\n email: \"\",\n url: \"\",\n role: \"maintainer\",\n }));\n }\n\n /** Search official repos by exact package name. Prefers x86_64 results. */\n private async searchOfficial(name: string, signal?: AbortSignal): Promise<ArchPackageResult> {\n const url = `${this.baseURL}/packages/search/json/?name=${encodeURIComponent(name)}`;\n\n try {\n const data = await this.client.getJSON<ArchSearchResponse>(url, signal);\n\n if (!data.results || data.results.length === 0) {\n throw new NotFoundError(\"alpm\", name);\n }\n\n // Prefer x86_64 arch, fall back to first result\n return data.results.find((r) => r.arch === \"x86_64\") || data.results[0]!;\n } catch (error) {\n if (error instanceof NotFoundError) throw error;\n if (error instanceof HTTPError && error.isNotFound()) {\n throw new NotFoundError(\"alpm\", name);\n }\n throw error;\n }\n }\n\n // --- AUR API ---\n\n private async fetchAurPackage(name: string, signal?: AbortSignal): Promise<Package> {\n const result = await this.fetchAurInfo(name, signal);\n\n return {\n name: result.Name,\n description: result.Description || \"\",\n homepage: result.URL || \"\",\n documentation: \"\",\n repository: \"\",\n licenses: combineLicenses(result.License || []),\n keywords: result.Keywords || [],\n namespace: \"aur\",\n latestVersion: result.Version,\n metadata: {\n votes: result.NumVotes,\n popularity: result.Popularity,\n outOfDate: result.OutOfDate,\n pkgbase: result.PackageBase,\n firstSubmitted: result.FirstSubmitted,\n lastModified: result.LastModified,\n },\n };\n }\n\n private async fetchAurVersions(name: string, signal?: AbortSignal): Promise<Version[]> {\n const result = await this.fetchAurInfo(name, signal);\n\n return [\n {\n number: result.Version,\n publishedAt: result.LastModified ? new Date(result.LastModified * 1000) : null,\n licenses: combineLicenses(result.License || []),\n integrity: \"\",\n status: result.OutOfDate ? \"deprecated\" : \"\",\n metadata: {\n votes: result.NumVotes,\n popularity: result.Popularity,\n },\n },\n ];\n }\n\n private async fetchAurDependencies(\n name: string,\n version: string,\n signal?: AbortSignal,\n ): Promise<Dependency[]> {\n const result = await this.fetchAurInfo(name, signal);\n this.assertVersionMatches(`aur/${name}`, version, result.Version);\n\n return this.buildDependencies(\n result.Depends || [],\n result.MakeDepends || [],\n result.OptDepends || [],\n result.CheckDepends || [],\n );\n }\n\n private async fetchAurMaintainers(name: string, signal?: AbortSignal): Promise<Maintainer[]> {\n const result = await this.fetchAurInfo(name, signal);\n\n if (!result.Maintainer) return [];\n\n return [\n {\n uuid: \"\",\n login: result.Maintainer,\n name: result.Maintainer,\n email: \"\",\n url: \"\",\n role: \"maintainer\",\n },\n ];\n }\n\n /** Fetch package info from AUR RPC v5. */\n private async fetchAurInfo(name: string, signal?: AbortSignal): Promise<AurPackageResult> {\n const url = `${AUR_BASE_URL}/rpc/v5/info/${encodeURIComponent(name)}`;\n\n try {\n const data = await this.client.getJSON<AurResponse>(url, signal);\n\n if (!data.results || data.results.length === 0) {\n throw new NotFoundError(\"alpm\", `aur/${name}`);\n }\n\n return data.results[0]!;\n } catch (error) {\n if (error instanceof NotFoundError) throw error;\n if (error instanceof HTTPError && error.isNotFound()) {\n throw new NotFoundError(\"alpm\", `aur/${name}`);\n }\n throw error;\n }\n }\n\n // --- Shared helpers ---\n\n /** Parse \"namespace/name\" into components. Defaults to \"arch\" namespace. */\n private parseName(fullName: string): { namespace: string; pkgName: string } {\n const normalized = fullName.trim().toLowerCase();\n const slashIdx = normalized.indexOf(\"/\");\n if (slashIdx === -1) {\n return { namespace: \"arch\", pkgName: normalized };\n }\n return {\n namespace: normalized.slice(0, slashIdx),\n pkgName: normalized.slice(slashIdx + 1),\n };\n }\n\n private assertSupportedNamespace(namespace: string, requestedName: string): void {\n if (namespace !== \"arch\" && namespace !== \"aur\") {\n throw new NotFoundError(\"alpm\", requestedName);\n }\n }\n\n private assertVersionMatches(name: string, requested: string, current: string): void {\n if (requested && requested !== current) {\n throw new NotFoundError(\"alpm\", name, requested);\n }\n }\n\n /** Format ALPM version: epoch:pkgver-pkgrel (epoch omitted when 0). */\n private formatVersion(result: ArchPackageResult): string {\n const epoch = result.epoch && result.epoch > 0 ? `${result.epoch}:` : \"\";\n return `${epoch}${result.pkgver}-${result.pkgrel}`;\n }\n\n /** Build normalized dependency list from ALPM dependency arrays. */\n private buildDependencies(\n depends: string[],\n makedepends: string[],\n optdepends: string[],\n checkdepends: string[],\n ): Dependency[] {\n const dependencies: Dependency[] = [];\n\n for (const dep of depends) {\n const parsed = this.parseDep(dep);\n dependencies.push({\n name: parsed.name,\n requirements: parsed.requirements,\n scope: \"runtime\",\n optional: false,\n });\n }\n\n for (const dep of makedepends) {\n const parsed = this.parseDep(dep);\n dependencies.push({\n name: parsed.name,\n requirements: parsed.requirements,\n scope: \"build\",\n optional: false,\n });\n }\n\n for (const dep of optdepends) {\n const parsed = this.parseOptDep(dep);\n dependencies.push({\n name: parsed.name,\n requirements: parsed.requirements,\n scope: \"optional\",\n optional: true,\n });\n }\n\n for (const dep of checkdepends) {\n const parsed = this.parseDep(dep);\n dependencies.push({\n name: parsed.name,\n requirements: parsed.requirements,\n scope: \"test\",\n optional: false,\n });\n }\n\n return dependencies;\n }\n\n /** Parse a dependency string like \"glibc>=2.33\" or \"bash\". */\n private parseDep(dep: string): { name: string; requirements: string } {\n const match = dep.match(/^([a-zA-Z0-9@._+-]+)(.*)$/);\n if (!match) return { name: dep, requirements: \"\" };\n return {\n name: match[1]!,\n requirements: match[2]!.trim(),\n };\n }\n\n /** Parse optional dependency like \"perl-locale-gettext: translation support\". */\n private parseOptDep(dep: string): { name: string; requirements: string; description: string } {\n const colonIdx = dep.indexOf(\":\");\n if (colonIdx === -1) {\n const parsed = this.parseDep(dep.trim());\n return { name: parsed.name, requirements: parsed.requirements, description: \"\" };\n }\n const parsed = this.parseDep(dep.slice(0, colonIdx).trim());\n\n return {\n name: parsed.name,\n requirements: parsed.requirements,\n description: dep.slice(colonIdx + 1).trim(),\n };\n }\n}\n\nregister(\"alpm\", \"https://archlinux.org\", AlpmRegistry);\n"],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import { c as URLBuilder, i as Package, l as Version, n as Dependency, r as Maintainer, t as ClientOptions } from "./types.mjs";
2
+
3
+ //#region src/core/client.d.ts
4
+ /** HTTP client with retry, backoff, rate limiting, and timeout. */
5
+ declare class Client {
6
+ readonly maxRetries: number;
7
+ readonly baseDelay: number;
8
+ readonly timeout: number;
9
+ readonly userAgent: string;
10
+ private readonly rateLimiter;
11
+ private readonly fetch;
12
+ constructor(options?: ClientOptions);
13
+ /** Fetch JSON from a URL with retry and rate limiting. */
14
+ getJSON<T>(url: string, signal?: AbortSignal, headers?: Record<string, string>): Promise<T>;
15
+ }
16
+ /** Get or create the shared default client. */
17
+ declare function defaultClient(): Client;
18
+ //#endregion
19
+ //#region src/core/registry.d.ts
20
+ /** Common base for package registries and registry decorators. */
21
+ declare abstract class Registry {
22
+ abstract ecosystem(): string;
23
+ abstract fetchPackage(name: string, signal?: AbortSignal): Promise<Package>;
24
+ abstract fetchVersions(name: string, signal?: AbortSignal): Promise<Version[]>;
25
+ abstract fetchDependencies(name: string, version: string, signal?: AbortSignal): Promise<Dependency[]>;
26
+ abstract fetchMaintainers(name: string, signal?: AbortSignal): Promise<Maintainer[]>;
27
+ abstract urls(): URLBuilder;
28
+ }
29
+ /** Register an ecosystem class. Called by each registry module on import. */
30
+ declare function register(ecosystem: string, defaultURL: string, RegistryClass: new (baseURL: string, client: Client) => Registry): void;
31
+ /** Create a registry instance for the given ecosystem. */
32
+ declare function create(ecosystem: string, baseURL?: string, client?: Client): Registry;
33
+ /** List all registered ecosystem names. */
34
+ declare function ecosystems(): string[];
35
+ /** Check if an ecosystem is registered. */
36
+ declare function has(ecosystem: string): boolean;
37
+ //#endregion
38
+ export { register as a, has as i, create as n, Client as o, ecosystems as r, defaultClient as s, Registry as t };
39
+ //# sourceMappingURL=registry.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.mts","names":[],"sources":["../../src/core/client.ts","../../src/core/registry.ts"],"mappings":";;;;cAsDa,MAAA;EAAA,SACF,UAAA;EAAA,SACA,SAAA;EAAA,SACA,OAAA;EAAA,SACA,SAAA;EAAA,iBACQ,WAAA;EAAA,iBACA,KAAA;cAEL,OAAA,GAAS,aAAA;EAqCf;EAAA,OAAA,GAAA,CACJ,GAAA,UACA,MAAA,GAAS,WAAA,EACT,OAAA,GAAU,MAAA,mBACT,OAAA,CAAQ,CAAA;AAAA;;iBAyBG,aAAA,CAAA,GAAiB,MAAA;;;;uBC1HX,QAAA;EAAA,SACX,SAAA,CAAA;EAAA,SACA,YAAA,CAAa,IAAA,UAAc,MAAA,GAAS,WAAA,GAAc,OAAA,CAAQ,OAAA;EAAA,SAC1D,aAAA,CAAc,IAAA,UAAc,MAAA,GAAS,WAAA,GAAc,OAAA,CAAQ,OAAA;EAAA,SAC3D,iBAAA,CACP,IAAA,UACA,OAAA,UACA,MAAA,GAAS,WAAA,GACR,OAAA,CAAQ,UAAA;EAAA,SACF,gBAAA,CAAiB,IAAA,UAAc,MAAA,GAAS,WAAA,GAAc,OAAA,CAAQ,UAAA;EAAA,SAC9D,IAAA,CAAA,GAAQ,UAAA;AAAA;;iBAOH,QAAA,CACd,SAAA,UACA,UAAA,UACA,aAAA,OAAoB,OAAA,UAAiB,MAAA,EAAQ,MAAA,KAAW,QAAA;;iBAO1C,MAAA,CAAO,SAAA,UAAmB,OAAA,WAAkB,MAAA,GAAS,MAAA,GAAS,QAAA;;iBAS9D,UAAA,CAAA;;iBAKA,GAAA,CAAI,SAAA"}
@@ -0,0 +1,201 @@
1
+ import { FetchError, ofetch } from "ofetch";
2
+ /** Custom error types for registry operations. */
3
+ var PkioError = class extends Error {
4
+ constructor(message, options) {
5
+ super(message, options);
6
+ this.name = "PkioError";
7
+ }
8
+ };
9
+ var HTTPError = class extends PkioError {
10
+ statusCode;
11
+ url;
12
+ body;
13
+ constructor(statusCode, url, body) {
14
+ super(`HTTP ${statusCode}: ${url}`);
15
+ this.name = "HTTPError";
16
+ this.statusCode = statusCode;
17
+ this.url = url;
18
+ this.body = body;
19
+ }
20
+ isNotFound() {
21
+ return this.statusCode === 404;
22
+ }
23
+ isRateLimit() {
24
+ return this.statusCode === 429;
25
+ }
26
+ isServerError() {
27
+ return this.statusCode >= 500;
28
+ }
29
+ };
30
+ var NotFoundError = class extends PkioError {
31
+ ecosystem;
32
+ packageName;
33
+ version;
34
+ constructor(ecosystem, packageName, version = "") {
35
+ const versionSuffix = version ? `@${version}` : "";
36
+ super(`Package not found: ${ecosystem}/${packageName}${versionSuffix}`);
37
+ this.name = "NotFoundError";
38
+ this.ecosystem = ecosystem;
39
+ this.packageName = packageName;
40
+ this.version = version;
41
+ }
42
+ };
43
+ var RateLimitError = class extends PkioError {
44
+ retryAfter;
45
+ constructor(retryAfter) {
46
+ super(`Rate limited. Retry after ${retryAfter}s`);
47
+ this.name = "RateLimitError";
48
+ this.retryAfter = retryAfter;
49
+ }
50
+ };
51
+ var UnknownEcosystemError = class extends PkioError {
52
+ ecosystem;
53
+ constructor(ecosystem) {
54
+ super(`Unknown ecosystem: ${ecosystem}`);
55
+ this.name = "UnknownEcosystemError";
56
+ this.ecosystem = ecosystem;
57
+ }
58
+ };
59
+ var InvalidPURLError = class extends PkioError {
60
+ purl;
61
+ constructor(purl, reason) {
62
+ super(`Invalid PURL "${purl}": ${reason}`);
63
+ this.name = "InvalidPURLError";
64
+ this.purl = purl;
65
+ }
66
+ };
67
+ const DEFAULT_MAX_RETRIES = 5;
68
+ const DEFAULT_BASE_DELAY = 50;
69
+ const DEFAULT_TIMEOUT = 3e4;
70
+ const DEFAULT_USER_AGENT = "registries/0.1.0";
71
+ const MAX_TIMER_DELAY = 2147483647;
72
+ function parseRetryAfterValue(header) {
73
+ if (!header) return void 0;
74
+ const trimmed = header.trim();
75
+ if (!trimmed) return void 0;
76
+ if (/^\d+$/.test(trimmed)) {
77
+ const seconds = Number(trimmed);
78
+ return Number.isNaN(seconds) ? void 0 : seconds;
79
+ }
80
+ const timestamp = /[a-z]/i.test(trimmed) ? Date.parse(trimmed) : NaN;
81
+ if (Number.isNaN(timestamp)) return void 0;
82
+ const seconds = Math.ceil((timestamp - Date.now()) / 1e3);
83
+ return Math.max(seconds, 0);
84
+ }
85
+ /**
86
+ * Parse a `Retry-After` header into seconds.
87
+ *
88
+ * Handles two formats (RFC 7231 §7.1.3):
89
+ * - **Numeric**: `"120"` → 120
90
+ * - **HTTP-date**: `"Wed, 21 Oct 2025 07:28:00 GMT"` → seconds until that time
91
+ *
92
+ * Returns 60 when the header is absent, empty, or unparseable.
93
+ */
94
+ function parseRetryAfter(header) {
95
+ return parseRetryAfterValue(header) ?? 60;
96
+ }
97
+ /** Apply a valid, timer-safe `Retry-After` value or reject an unschedulable delay. */
98
+ function retryDelayFor(header, fallbackDelay) {
99
+ const retryAfter = parseRetryAfterValue(header);
100
+ if (retryAfter === void 0) return fallbackDelay;
101
+ const retryAfterDelay = retryAfter * 1e3;
102
+ if (!Number.isFinite(retryAfterDelay) || retryAfterDelay > MAX_TIMER_DELAY) throw new RateLimitError(retryAfter);
103
+ return Math.max(fallbackDelay, retryAfterDelay);
104
+ }
105
+ /** HTTP client with retry, backoff, rate limiting, and timeout. */
106
+ var Client = class {
107
+ maxRetries;
108
+ baseDelay;
109
+ timeout;
110
+ userAgent;
111
+ rateLimiter;
112
+ fetch;
113
+ constructor(options = {}) {
114
+ this.maxRetries = options.maxRetries ?? DEFAULT_MAX_RETRIES;
115
+ this.baseDelay = options.baseDelay ?? DEFAULT_BASE_DELAY;
116
+ this.timeout = options.timeout ?? DEFAULT_TIMEOUT;
117
+ this.userAgent = options.userAgent ?? DEFAULT_USER_AGENT;
118
+ this.rateLimiter = options.rateLimiter ?? null;
119
+ const maxRetries = this.maxRetries;
120
+ const baseDelay = this.baseDelay;
121
+ this.fetch = ofetch.create({
122
+ retry: this.maxRetries,
123
+ retryDelay(context) {
124
+ const attempt = maxRetries - (typeof context.options.retry === "number" ? context.options.retry : 0);
125
+ const delay = baseDelay * Math.pow(2, attempt - 1);
126
+ const jitteredDelay = delay + delay * Math.random() * .1;
127
+ const retryAfter = context.response?.headers.get("Retry-After");
128
+ try {
129
+ return retryDelayFor(retryAfter, jitteredDelay);
130
+ } catch (error) {
131
+ if (error instanceof RateLimitError && context.response?.status !== 429) throw new HTTPError(context.response?.status ?? 0, String(context.request), "");
132
+ throw error;
133
+ }
134
+ },
135
+ retryStatusCodes: [
136
+ 408,
137
+ 409,
138
+ 425,
139
+ 429,
140
+ 500,
141
+ 502,
142
+ 503,
143
+ 504
144
+ ],
145
+ timeout: this.timeout,
146
+ headers: {
147
+ Accept: "application/json",
148
+ "User-Agent": this.userAgent
149
+ }
150
+ });
151
+ }
152
+ /** Fetch JSON from a URL with retry and rate limiting. */
153
+ async getJSON(url, signal, headers) {
154
+ if (this.rateLimiter) await this.rateLimiter.wait(signal);
155
+ try {
156
+ return await this.fetch(url, {
157
+ signal,
158
+ headers
159
+ });
160
+ } catch (error) {
161
+ if (error instanceof FetchError) {
162
+ if (error.statusCode === 429) throw new RateLimitError(parseRetryAfter(error.response?.headers.get("Retry-After")));
163
+ const body = typeof error.data === "string" ? error.data : JSON.stringify(error.data ?? "");
164
+ throw new HTTPError(error.statusCode ?? 0, url, body);
165
+ }
166
+ throw error;
167
+ }
168
+ }
169
+ };
170
+ let _defaultClient;
171
+ /** Get or create the shared default client. */
172
+ function defaultClient() {
173
+ if (!_defaultClient) _defaultClient = new Client();
174
+ return _defaultClient;
175
+ }
176
+ /** Common base for package registries and registry decorators. */
177
+ var Registry = class {};
178
+ const constructors = /* @__PURE__ */ new Map();
179
+ const defaults = /* @__PURE__ */ new Map();
180
+ /** Register an ecosystem class. Called by each registry module on import. */
181
+ function register(ecosystem, defaultURL, RegistryClass) {
182
+ constructors.set(ecosystem, RegistryClass);
183
+ defaults.set(ecosystem, defaultURL);
184
+ }
185
+ /** Create a registry instance for the given ecosystem. */
186
+ function create(ecosystem, baseURL, client) {
187
+ const RegistryClass = constructors.get(ecosystem);
188
+ if (!RegistryClass) throw new UnknownEcosystemError(ecosystem);
189
+ return new RegistryClass(baseURL || defaults.get(ecosystem), client ?? defaultClient());
190
+ }
191
+ /** List all registered ecosystem names. */
192
+ function ecosystems() {
193
+ return [...constructors.keys()];
194
+ }
195
+ /** Check if an ecosystem is registered. */
196
+ function has(ecosystem) {
197
+ return constructors.has(ecosystem);
198
+ }
199
+ export { register as a, HTTPError as c, PkioError as d, RateLimitError as f, has as i, InvalidPURLError as l, create as n, Client as o, UnknownEcosystemError as p, ecosystems as r, defaultClient as s, Registry as t, NotFoundError as u };
200
+
201
+ //# sourceMappingURL=registry.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.mjs","names":[],"sources":["../../src/core/errors.ts","../../src/core/client.ts","../../src/core/registry.ts"],"sourcesContent":["/** Custom error types for registry operations. */\n\nexport class PkioError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"PkioError\";\n }\n}\n\nexport class HTTPError extends PkioError {\n readonly statusCode: number;\n readonly url: string;\n readonly body: string;\n\n constructor(statusCode: number, url: string, body: string) {\n super(`HTTP ${statusCode}: ${url}`);\n this.name = \"HTTPError\";\n this.statusCode = statusCode;\n this.url = url;\n this.body = body;\n }\n\n isNotFound(): boolean {\n return this.statusCode === 404;\n }\n\n isRateLimit(): boolean {\n return this.statusCode === 429;\n }\n\n isServerError(): boolean {\n return this.statusCode >= 500;\n }\n}\n\nexport class NotFoundError extends PkioError {\n readonly ecosystem: string;\n readonly packageName: string;\n readonly version: string;\n\n constructor(ecosystem: string, packageName: string, version = \"\") {\n const versionSuffix = version ? `@${version}` : \"\";\n super(`Package not found: ${ecosystem}/${packageName}${versionSuffix}`);\n this.name = \"NotFoundError\";\n this.ecosystem = ecosystem;\n this.packageName = packageName;\n this.version = version;\n }\n}\n\nexport class RateLimitError extends PkioError {\n readonly retryAfter: number;\n\n constructor(retryAfter: number) {\n super(`Rate limited. Retry after ${retryAfter}s`);\n this.name = \"RateLimitError\";\n this.retryAfter = retryAfter;\n }\n}\n\nexport class UnknownEcosystemError extends PkioError {\n readonly ecosystem: string;\n\n constructor(ecosystem: string) {\n super(`Unknown ecosystem: ${ecosystem}`);\n this.name = \"UnknownEcosystemError\";\n this.ecosystem = ecosystem;\n }\n}\n\nexport class InvalidPURLError extends PkioError {\n readonly purl: string;\n\n constructor(purl: string, reason: string) {\n super(`Invalid PURL \"${purl}\": ${reason}`);\n this.name = \"InvalidPURLError\";\n this.purl = purl;\n }\n}\n","import { ofetch, FetchError } from \"ofetch\";\nimport type { $Fetch } from \"ofetch\";\nimport type { ClientOptions, RateLimiter } from \"./types.ts\";\nimport { HTTPError, RateLimitError } from \"./errors.ts\";\n\nconst DEFAULT_MAX_RETRIES = 5;\nconst DEFAULT_BASE_DELAY = 50;\nconst DEFAULT_TIMEOUT = 30_000;\nconst DEFAULT_USER_AGENT = \"registries/0.1.0\";\nconst MAX_TIMER_DELAY = 2_147_483_647;\n\nfunction parseRetryAfterValue(header: string | null | undefined): number | undefined {\n if (!header) return undefined;\n const trimmed = header.trim();\n if (!trimmed) return undefined;\n\n if (/^\\d+$/.test(trimmed)) {\n const seconds = Number(trimmed);\n return Number.isNaN(seconds) ? undefined : seconds;\n }\n\n const timestamp = /[a-z]/i.test(trimmed) ? Date.parse(trimmed) : NaN;\n if (Number.isNaN(timestamp)) return undefined;\n\n const seconds = Math.ceil((timestamp - Date.now()) / 1000);\n return Math.max(seconds, 0);\n}\n\n/**\n * Parse a `Retry-After` header into seconds.\n *\n * Handles two formats (RFC 7231 §7.1.3):\n * - **Numeric**: `\"120\"` → 120\n * - **HTTP-date**: `\"Wed, 21 Oct 2025 07:28:00 GMT\"` → seconds until that time\n *\n * Returns 60 when the header is absent, empty, or unparseable.\n */\nexport function parseRetryAfter(header: string | null | undefined): number {\n return parseRetryAfterValue(header) ?? 60;\n}\n\n/** Apply a valid, timer-safe `Retry-After` value or reject an unschedulable delay. */\nexport function retryDelayFor(header: string | null | undefined, fallbackDelay: number): number {\n const retryAfter = parseRetryAfterValue(header);\n if (retryAfter === undefined) return fallbackDelay;\n\n const retryAfterDelay = retryAfter * 1000;\n if (!Number.isFinite(retryAfterDelay) || retryAfterDelay > MAX_TIMER_DELAY) {\n throw new RateLimitError(retryAfter);\n }\n return Math.max(fallbackDelay, retryAfterDelay);\n}\n\n/** HTTP client with retry, backoff, rate limiting, and timeout. */\nexport class Client {\n readonly maxRetries: number;\n readonly baseDelay: number;\n readonly timeout: number;\n readonly userAgent: string;\n private readonly rateLimiter: RateLimiter | null;\n private readonly fetch: $Fetch;\n\n constructor(options: ClientOptions = {}) {\n this.maxRetries = options.maxRetries ?? DEFAULT_MAX_RETRIES;\n this.baseDelay = options.baseDelay ?? DEFAULT_BASE_DELAY;\n this.timeout = options.timeout ?? DEFAULT_TIMEOUT;\n this.userAgent = options.userAgent ?? DEFAULT_USER_AGENT;\n this.rateLimiter = options.rateLimiter ?? null;\n\n const maxRetries = this.maxRetries;\n const baseDelay = this.baseDelay;\n\n this.fetch = ofetch.create({\n retry: this.maxRetries,\n retryDelay(context) {\n const remaining = typeof context.options.retry === \"number\" ? context.options.retry : 0;\n const attempt = maxRetries - remaining;\n const delay = baseDelay * Math.pow(2, attempt - 1);\n const jitteredDelay = delay + delay * Math.random() * 0.1;\n const retryAfter = context.response?.headers.get(\"Retry-After\");\n try {\n return retryDelayFor(retryAfter, jitteredDelay);\n } catch (error) {\n if (error instanceof RateLimitError && context.response?.status !== 429) {\n throw new HTTPError(context.response?.status ?? 0, String(context.request), \"\");\n }\n throw error;\n }\n },\n retryStatusCodes: [408, 409, 425, 429, 500, 502, 503, 504],\n timeout: this.timeout,\n headers: {\n Accept: \"application/json\",\n \"User-Agent\": this.userAgent,\n },\n });\n }\n\n /** Fetch JSON from a URL with retry and rate limiting. */\n async getJSON<T>(\n url: string,\n signal?: AbortSignal,\n headers?: Record<string, string>,\n ): Promise<T> {\n if (this.rateLimiter) {\n await this.rateLimiter.wait(signal);\n }\n\n try {\n return await this.fetch<T>(url, { signal, headers });\n } catch (error) {\n if (error instanceof FetchError) {\n if (error.statusCode === 429) {\n throw new RateLimitError(parseRetryAfter(error.response?.headers.get(\"Retry-After\")));\n }\n\n const body = typeof error.data === \"string\" ? error.data : JSON.stringify(error.data ?? \"\");\n\n throw new HTTPError(error.statusCode ?? 0, url, body);\n }\n throw error;\n }\n }\n}\n\nlet _defaultClient: Client | undefined;\n\n/** Get or create the shared default client. */\nexport function defaultClient(): Client {\n if (!_defaultClient) {\n _defaultClient = new Client();\n }\n return _defaultClient;\n}\n","import type { Client } from \"./client.ts\";\nimport { defaultClient } from \"./client.ts\";\nimport { UnknownEcosystemError } from \"./errors.ts\";\nimport type { Dependency, Maintainer, Package, URLBuilder, Version } from \"./types.ts\";\n\n/** Common base for package registries and registry decorators. */\nexport abstract class Registry {\n abstract ecosystem(): string;\n abstract fetchPackage(name: string, signal?: AbortSignal): Promise<Package>;\n abstract fetchVersions(name: string, signal?: AbortSignal): Promise<Version[]>;\n abstract fetchDependencies(\n name: string,\n version: string,\n signal?: AbortSignal,\n ): Promise<Dependency[]>;\n abstract fetchMaintainers(name: string, signal?: AbortSignal): Promise<Maintainer[]>;\n abstract urls(): URLBuilder;\n}\n\nconst constructors = new Map<string, new (baseURL: string, client: Client) => Registry>();\nconst defaults = new Map<string, string>();\n\n/** Register an ecosystem class. Called by each registry module on import. */\nexport function register(\n ecosystem: string,\n defaultURL: string,\n RegistryClass: new (baseURL: string, client: Client) => Registry,\n): void {\n constructors.set(ecosystem, RegistryClass);\n defaults.set(ecosystem, defaultURL);\n}\n\n/** Create a registry instance for the given ecosystem. */\nexport function create(ecosystem: string, baseURL?: string, client?: Client): Registry {\n const RegistryClass = constructors.get(ecosystem);\n if (!RegistryClass) {\n throw new UnknownEcosystemError(ecosystem);\n }\n return new RegistryClass(baseURL || defaults.get(ecosystem)!, client ?? defaultClient());\n}\n\n/** List all registered ecosystem names. */\nexport function ecosystems(): string[] {\n return [...constructors.keys()];\n}\n\n/** Check if an ecosystem is registered. */\nexport function has(ecosystem: string): boolean {\n return constructors.has(ecosystem);\n}\n"],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { Storage } from "unstorage";
2
+
3
+ //#region src/cache/storage.d.ts
4
+ /**
5
+ * Configure a custom unstorage instance for @agntn/registries.
6
+ * Call this before any cache operations to use a non-default driver
7
+ * (e.g. Cloudflare KV, Redis, memory).
8
+ */
9
+ declare function configureStorage(storage: Storage): void;
10
+ /** Get or create the shared storage instance. Uses configured storage or falls back to fs driver. */
11
+ declare function getStorage(): Storage;
12
+ /** Get a namespaced storage for a specific ecosystem (e.g. 'npm', 'cargo'). */
13
+ declare function getEcosystemStorage(ecosystem: string): Storage;
14
+ /** Compute a sha256 integrity hash of a JSON-serializable value. */
15
+ declare function computeIntegrity(value: unknown): string;
16
+ /** Dispose the storage instance. Call on process exit. */
17
+ declare function disposeStorage(): Promise<void>;
18
+ /** Clear all cached data. */
19
+ declare function clearStorage(): Promise<void>;
20
+ //#endregion
21
+ export { getEcosystemStorage as a, disposeStorage as i, computeIntegrity as n, getStorage as o, configureStorage as r, clearStorage as t };
22
+ //# sourceMappingURL=storage.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.mts","names":[],"sources":["../../src/cache/storage.ts"],"mappings":";;;;;AAaA;;;iBAAgB,gBAAA,CAAiB,OAAA,EAAS,OAAA;;iBAK1B,UAAA,CAAA,GAAc,OAAA;;iBAUd,mBAAA,CAAoB,SAAA,WAAoB,OAAA;;iBAKxC,gBAAA,CAAiB,KAAA;AALjC;AAAA,iBAUsB,cAAA,CAAA,GAAkB,OAAA;;iBAQlB,YAAA,CAAA,GAAgB,OAAA"}
@@ -0,0 +1,73 @@
1
+ //#region src/core/types.d.ts
2
+ /** Normalized package metadata returned by any registry. */
3
+ interface Package {
4
+ name: string;
5
+ description: string;
6
+ homepage: string;
7
+ documentation: string;
8
+ repository: string;
9
+ licenses: string;
10
+ keywords: string[];
11
+ namespace: string;
12
+ latestVersion: string;
13
+ metadata: Record<string, unknown>;
14
+ }
15
+ /** A single version entry of a package. */
16
+ interface Version {
17
+ number: string;
18
+ publishedAt: Date | null;
19
+ licenses: string;
20
+ integrity: string;
21
+ status: VersionStatus;
22
+ metadata: Record<string, unknown>;
23
+ }
24
+ /** Dependency of a package version. */
25
+ interface Dependency {
26
+ name: string;
27
+ requirements: string;
28
+ scope: Scope;
29
+ optional: boolean;
30
+ }
31
+ /** Maintainer / author of a package. */
32
+ interface Maintainer {
33
+ uuid: string;
34
+ login: string;
35
+ name: string;
36
+ email: string;
37
+ url: string;
38
+ role: string;
39
+ }
40
+ type VersionStatus = "" | "yanked" | "deprecated" | "retracted";
41
+ type Scope = "runtime" | "development" | "test" | "build" | "optional";
42
+ /** URL builder for a specific registry. */
43
+ interface URLBuilder {
44
+ registry(name: string, version?: string): string;
45
+ download(name: string, version: string): string;
46
+ documentation(name: string, version?: string): string;
47
+ readme(name: string, version?: string): string;
48
+ purl(name: string, version?: string): string;
49
+ }
50
+ /** Options for the HTTP client. */
51
+ interface ClientOptions {
52
+ maxRetries?: number;
53
+ baseDelay?: number;
54
+ timeout?: number;
55
+ rateLimiter?: RateLimiter;
56
+ userAgent?: string;
57
+ }
58
+ /** Rate limiter interface — bring your own implementation. */
59
+ interface RateLimiter {
60
+ wait(signal?: AbortSignal): Promise<void>;
61
+ }
62
+ /** Parsed PURL components. */
63
+ interface ParsedPURL {
64
+ type: string;
65
+ namespace: string;
66
+ name: string;
67
+ version: string;
68
+ qualifiers: Record<string, string>;
69
+ subpath: string;
70
+ }
71
+ //#endregion
72
+ export { ParsedPURL as a, URLBuilder as c, Package as i, Version as l, Dependency as n, RateLimiter as o, Maintainer as r, Scope as s, ClientOptions as t, VersionStatus as u };
73
+ //# sourceMappingURL=types.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.mts","names":[],"sources":["../../src/core/types.ts"],"mappings":";;UACiB,OAAA;EACf,IAAA;EACA,WAAA;EACA,QAAA;EACA,aAAA;EACA,UAAA;EACA,QAAA;EACA,QAAA;EACA,SAAA;EACA,aAAA;EACA,QAAA,EAAU,MAAA;AAAA;;UAIK,OAAA;EACf,MAAA;EACA,WAAA,EAAa,IAAA;EACb,QAAA;EACA,SAAA;EACA,MAAA,EAAQ,aAAA;EACR,QAAA,EAAU,MAAA;AAAA;;UAIK,UAAA;EACf,IAAA;EACA,YAAA;EACA,KAAA,EAAO,KAAA;EACP,QAAA;AAAA;;UAIe,UAAA;EACf,IAAA;EACA,KAAA;EACA,IAAA;EACA,KAAA;EACA,GAAA;EACA,IAAA;AAAA;AAAA,KAGU,aAAA;AAAA,KACA,KAAA;;UAGK,UAAA;EACf,QAAA,CAAS,IAAA,UAAc,OAAA;EACvB,QAAA,CAAS,IAAA,UAAc,OAAA;EACvB,aAAA,CAAc,IAAA,UAAc,OAAA;EAC5B,MAAA,CAAO,IAAA,UAAc,OAAA;EACrB,IAAA,CAAK,IAAA,UAAc,OAAA;AAAA;AAlBrB;AAAA,UAsBiB,aAAA;EACf,UAAA;EACA,SAAA;EACA,OAAA;EACA,WAAA,GAAc,WAAA;EACd,SAAA;AAAA;;UAIe,WAAA;EACf,IAAA,CAAK,MAAA,GAAS,WAAA,GAAc,OAAA;AAAA;AAvB9B;AAAA,UA2BiB,UAAA;EACf,IAAA;EACA,SAAA;EACA,IAAA;EACA,OAAA;EACA,UAAA,EAAY,MAAA;EACZ,OAAA;AAAA"}
package/dist/ai.d.mts ADDED
@@ -0,0 +1,35 @@
1
+ import { i as Package, l as Version, n as Dependency, r as Maintainer } from "./_chunks/types.mjs";
2
+ import "./_chunks/registry.mjs";
3
+ import "./_chunks/index.mjs";
4
+ import "./_chunks/errors.mjs";
5
+ import "./_chunks/index2.mjs";
6
+ import "./_chunks/paths.mjs";
7
+ import "./_chunks/storage.mjs";
8
+ import "./_chunks/cached-registry.mjs";
9
+ import "./_chunks/lockfile.mjs";
10
+ import "./_chunks/index3.mjs";
11
+ import * as ai from "ai";
12
+
13
+ //#region src/ai.d.ts
14
+ declare const packageTool: ai.Tool<{
15
+ operation: "package";
16
+ purl: string;
17
+ } | {
18
+ operation: "versions";
19
+ purl: string;
20
+ } | {
21
+ operation: "dependencies";
22
+ purl: string;
23
+ } | {
24
+ operation: "maintainers";
25
+ purl: string;
26
+ } | {
27
+ operation: "bulk-packages";
28
+ purls: string[];
29
+ concurrency?: number | undefined;
30
+ }, Package | Version[] | Dependency[] | Maintainer[] | {
31
+ [k: string]: Package;
32
+ }>;
33
+ //#endregion
34
+ export { packageTool };
35
+ //# sourceMappingURL=ai.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai.d.mts","names":[],"sources":["../src/ai.ts"],"mappings":";;;;;;;;;;;;;cAWa,WAAA,KAAW,IAAA;;;;;;;;;;;;;;;;GAuDtB,OAAA"}