diff --git a/http-client/index.ts b/http-client/index.ts index 7f30904a2..33c647300 100644 --- a/http-client/index.ts +++ b/http-client/index.ts @@ -7,6 +7,7 @@ import type { Remote, Repo, RepoListQuery, + SearchResult, TagInfo, Tree, TreeStats, @@ -46,7 +47,9 @@ import type { ZodSchema } from "zod"; import * as z from "zod"; import * as repo from "./lib/repo.js"; -import { Fetcher } from "./lib/fetcher.js"; +import { Fetcher, ResponseError } from "./lib/fetcher.js"; + +export { ResponseError }; import { nodeConfigSchema, scopeSchema, @@ -86,6 +89,7 @@ export type { RepoListQuery, Review, Revision, + SearchResult, SeedingPolicy, TagInfo, Tree, @@ -105,6 +109,15 @@ const nodeSchema = z.object({ description: z.string().optional(), }); +export type Info = z.infer; + +const infoSchema = z.object({ + node: nodeSchema, + httpd: z.object({ + searchAvailable: z.boolean(), + }), +}); + export type NodeIdentity = z.infer; const nodeIdentitySchema = z.object({ @@ -246,6 +259,17 @@ export class HttpdClient { ); } + public async getInfo(options?: RequestOptions): Promise { + return this.#fetcher.fetchOk( + { + method: "GET", + path: "info", + options, + }, + infoSchema, + ); + } + public async getNodeIdentity( nid: string, options?: RequestOptions, diff --git a/http-client/lib/fetcher.ts b/http-client/lib/fetcher.ts index eb14eb183..fa1d6f797 100644 --- a/http-client/lib/fetcher.ts +++ b/http-client/lib/fetcher.ts @@ -62,9 +62,9 @@ export class ResponseParseError extends Error { let description: string; if (!satisfies(nodeApiVersion, explorerRequiredApiVersion)) { - description = `The node you are fetching from (v${nodeApiVersion}) doesn't match the version requirements of radicle-explorer ${explorerRequiredApiVersion}.`; + description = `The node you are fetching from (v${nodeApiVersion}) doesn’t match the version requirements of radicle-explorer ${explorerRequiredApiVersion}.`; } else { - description = `The node (v${nodeApiVersion}) matches the version requirement of radicle-explorer (${explorerRequiredApiVersion}), but radicle-explorer isn't able to parse the response.`; + description = `The node (v${nodeApiVersion}) matches the version requirement of radicle-explorer (${explorerRequiredApiVersion}), but radicle-explorer isn’t able to parse the response.`; } this.apiVersion = apiVersion; this.description = @@ -72,7 +72,7 @@ export class ResponseParseError extends Error { description, config.deploymentId ? "" - : "
If you are self-hosting radicle-explorer and run into this error, try to clear the browser's localStorage and the cache.", + : "
If you are self-hosting radicle-explorer and run into this error, try to clear the browser’s localStorage and the cache.", ); this.method = method; diff --git a/http-client/lib/repo.ts b/http-client/lib/repo.ts index 7985cb765..e349fe1cc 100644 --- a/http-client/lib/repo.ts +++ b/http-client/lib/repo.ts @@ -87,6 +87,22 @@ const reposSchema = array(repoSchema); export type Repo = z.infer; +const searchResultSchema = object({ + rid: string(), + payloads: object({ + "xyz.radicle.project": object({ + name: string(), + description: string(), + defaultBranch: string(), + }).optional(), + }), + delegates: array(authorSchema), + seeds: number(), +}); +const searchResultsSchema = array(searchResultSchema); + +export type SearchResult = z.infer; + const activitySchema = object({ activity: array(number()), }); @@ -176,6 +192,7 @@ export type RepoListQuery = { page?: number; perPage?: number; show?: "pinned" | "all"; + sort?: "rid" | "activity" | "seeding"; }; export class Client { #fetcher: Fetcher; @@ -226,6 +243,21 @@ export class Client { ); } + public async search( + query: string, + options?: RequestOptions, + ): Promise { + return this.#fetcher.fetchOk( + { + method: "GET", + path: "repos/search", + query: { q: query }, + options, + }, + searchResultsSchema, + ); + } + public async getActivity( rid: string, options?: RequestOptions,