diff --git a/packages/registry/src/version-check.test.ts b/packages/registry/src/version-check.test.ts index 5ba49e0..0312bd7 100644 --- a/packages/registry/src/version-check.test.ts +++ b/packages/registry/src/version-check.test.ts @@ -137,6 +137,33 @@ describe("discoverVersions", () => { ); }); + it("fetches hex versions and filters to defined ranges", async () => { + const hexDef: VersionedDefinition = { + ...mockDefinition, + name: "phoenix", + registry: "hex", + }; + + const mockFetch = vi.mocked(fetch); + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => ({ + releases: [ + { version: "1.7.0", inserted_at: "2024-06-01T00:00:00Z" }, + { version: "1.6.0", inserted_at: "2024-03-01T00:00:00Z" }, + { version: "1.5.0", inserted_at: "2024-01-01T00:00:00Z" }, + ], + }), + } as Response); + + const versions = await discoverVersions(hexDef); + + expect(versions.map((v) => v.version)).toEqual(["1.7.0", "1.6.0", "1.5.0"]); + expect(mockFetch).toHaveBeenCalledWith( + expect.stringContaining("hex.pm/api/packages/phoenix"), + ); + }); + it("throws for unsupported registry", async () => { const def = { ...mockDefinition, registry: "cargo" }; await expect(discoverVersions(def)).rejects.toThrow( diff --git a/packages/registry/src/version-check.ts b/packages/registry/src/version-check.ts index ce3bf34..ace0b17 100644 --- a/packages/registry/src/version-check.ts +++ b/packages/registry/src/version-check.ts @@ -1,5 +1,5 @@ /** - * Version discovery from package registry APIs (npm, pip, maven). + * Version discovery from package registry APIs (npm, pip, maven, hex). * * Queries public registry APIs to find available versions, * filters to defined ranges, and deduplicates to latest-patch-per-minor. @@ -32,6 +32,7 @@ const registryFetchers: Record = { npm: fetchNpmVersions, pip: fetchPipVersions, maven: fetchMavenVersions, + hex: fetchHexVersions, }; /** @@ -196,6 +197,29 @@ async function fetchMavenVersions(packageName: string): Promise { })); } +/** + * Fetch versions from Hex.pm API. + * Package names are lowercase with underscores (e.g., "phoenix", "phoenix_live_view"). + */ +async function fetchHexVersions(packageName: string): Promise { + const res = await fetchWithRetry( + `https://hex.pm/api/packages/${encodeURIComponent(packageName)}`, + `Hex`, + packageName, + ); + + const data = (await res.json()) as { + releases?: Array<{ version?: string; inserted_at?: string }>; + }; + + const releases = data.releases ?? []; + + return releases.map((r) => ({ + version: r.version ?? "", + publishedAt: r.inserted_at, + })); +} + /** * Public registries occasionally return 504/503 under load. Retry 5xx and * network errors with exponential backoff; 4xx aborts immediately. diff --git a/registry/hex/elixir.yaml b/registry/hex/elixir.yaml new file mode 100644 index 0000000..3f729f7 --- /dev/null +++ b/registry/hex/elixir.yaml @@ -0,0 +1,8 @@ +name: elixir +description: "A dynamic, functional language for building scalable and maintainable applications" +repository: https://github.com/elixir-lang/elixir + +source: + type: git + url: https://github.com/elixir-lang/elixir + docs_path: lib/elixir/pages diff --git a/registry/hex/phoenix.yaml b/registry/hex/phoenix.yaml new file mode 100644 index 0000000..fe4a64c --- /dev/null +++ b/registry/hex/phoenix.yaml @@ -0,0 +1,11 @@ +name: phoenix +description: "A productive web framework for building modern web applications in Elixir" +repository: https://github.com/phoenixframework/phoenix + +versions: + - min_version: "1.5.0" + source: + type: git + url: https://github.com/phoenixframework/phoenix + docs_path: guides + tag_pattern: "v{version}" diff --git a/registry/hex/phoenix_live_view.yaml b/registry/hex/phoenix_live_view.yaml new file mode 100644 index 0000000..311676c --- /dev/null +++ b/registry/hex/phoenix_live_view.yaml @@ -0,0 +1,11 @@ +name: phoenix_live_view +description: "Rich, real-time user experiences with server-rendered HTML in Elixir" +repository: https://github.com/phoenixframework/phoenix_live_view + +versions: + - min_version: "0.17.0" + source: + type: git + url: https://github.com/phoenixframework/phoenix_live_view + docs_path: guides + tag_pattern: "v{version}"