{"version":3,"file":"rubygems.mjs","names":[],"sources":["../../src/registries/rubygems.ts"],"sourcesContent":["import type { Client } from \"../core/client.ts\";\nimport type { Dependency, Maintainer, Package, URLBuilder, Version } from \"../core/types.ts\";\nimport { Registry } from \"../core/registry.ts\";\nimport { combineLicenses, normalizeLicense } from \"../core/license.ts\";\nimport { normalizeRepositoryURL } from \"../core/repository.ts\";\nimport { buildPURL } from \"../core/purl.ts\";\nimport { rethrowFetchError } from \"../core/errors.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\nfunction orEmpty(value: string | undefined): string {\n  return value || \"\";\n}\n\nfunction gemLicenses(licenses: readonly string[] | undefined): string {\n  return licenses ? combineLicenses(licenses.map((license) => normalizeLicense(license))) : \"\";\n}\n\nfunction gemRepositoryURL(\n  sourceCodeURI: string | undefined,\n  metadata: Readonly<Record<string, unknown>> | undefined,\n  homepageURI: string | undefined,\n): string {\n  const metadataURI = metadata?.[\"source_code_uri\"];\n  if (sourceCodeURI) return normalizeRepositoryURL(sourceCodeURI);\n  if (metadataURI) return normalizeRepositoryURL(metadataURI);\n  return normalizeRepositoryURL(homepageURI ?? \"\");\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      const licenses = gemLicenses(data.licenses);\n      const repository = gemRepositoryURL(data.source_code_uri, data.metadata, data.homepage_uri);\n\n      return {\n        name: data.name,\n        description: orEmpty(data.description),\n        homepage: orEmpty(data.homepage_uri),\n        documentation: orEmpty(data.documentation_uri),\n        repository,\n        licenses,\n        keywords: [],\n        namespace: \"\",\n        latestVersion: orEmpty(data.version),\n        metadata: data.metadata ?? {},\n      };\n    } catch (error) {\n      rethrowFetchError(error, this.ecosystem(), name);\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      rethrowFetchError(error, this.ecosystem(), name);\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      rethrowFetchError(error, this.ecosystem(), name, version);\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      rethrowFetchError(error, this.ecosystem(), name);\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"],"mappings":"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"}