{"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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"}