g1t/packages/contracts/src/clients.ts

50 lines2,146 bytesCodeBlame
1import type { IdentityApi } from "./identity";
2
3/** A service binding, as far as these clients need it. */
4export type ServiceBinding = {
5 fetch(input: string, init?: RequestInit): Promise<Response>;
6};
7
8/**
9 * Calls a method on a service that speaks the JSON protocol used by the
10 * Rust services: `POST /rpc/<method>` with the arguments as the body.
11 */
12async function rpc<T>(
13 service: ServiceBinding,
14 method: string,
15 args: object,
16): Promise<T> {
17 // The hostname is ignored; a service binding always reaches its service.
18 const response = await service.fetch(`https://service/rpc/${method}`, {
19 method: "POST",
20 headers: { "content-type": "application/json" },
21 body: JSON.stringify(args),
22 });
23 if (!response.ok) {
24 throw new Error(`${method} failed with status ${response.status}`);
25 }
26 return response.json();
27}
28
29export function identityClient(service: ServiceBinding): IdentityApi {
30 const call = <T>(method: string, args: object) => rpc<T>(service, method, args);
31 return {
32 register: (username, email, password) =>
33 call("register", { username, email, password }),
34 signIn: (username, password) => call("sign_in", { username, password }),
35 signOut: (sessionToken) => call("sign_out", { sessionToken }),
36 userForSession: (sessionToken) => call("user_for_session", { sessionToken }),
37 userForGitCredentials: (username, secret) =>
38 call("user_for_git_credentials", { username, secret }),
39 userForAccessToken: (token) => call("user_for_access_token", { token }),
40 userForSshKey: (fingerprint) => call("user_for_ssh_key", { fingerprint }),
41 userByUsername: (username) => call("user_by_username", { username }),
42 listSshKeys: (user) => call("list_ssh_keys", { user }),
43 addSshKey: (user, title, publicKey) =>
44 call("add_ssh_key", { user, title, publicKey }),
45 removeSshKey: (user, id) => call("remove_ssh_key", { user, id }),
46 listAccessTokens: (user) => call("list_access_tokens", { user }),
47 createAccessToken: (user, name) => call("create_access_token", { user, name }),
48 removeAccessToken: (user, id) => call("remove_access_token", { user, id }),
49 };
50}