pr_01m47d15m3e54sn21z27rpy5n9/packages/contracts/src/clients.ts

55 lines2,451 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 resendVerification: (user) => call("resend_verification", { user }),
37 verifyEmail: (token) => call("verify_email", { token }),
38 requestPasswordReset: (email) => call("request_password_reset", { email }),
39 resetPassword: (token, password) =>
40 call("reset_password", { token, password }),
41 userForSession: (sessionToken) => call("user_for_session", { sessionToken }),
42 userForGitCredentials: (username, secret) =>
43 call("user_for_git_credentials", { username, secret }),
44 userForAccessToken: (token) => call("user_for_access_token", { token }),
45 userForSshKey: (fingerprint) => call("user_for_ssh_key", { fingerprint }),
46 userByUsername: (username) => call("user_by_username", { username }),
47 listSshKeys: (user) => call("list_ssh_keys", { user }),
48 addSshKey: (user, title, publicKey) =>
49 call("add_ssh_key", { user, title, publicKey }),
50 removeSshKey: (user, id) => call("remove_ssh_key", { user, id }),
51 listAccessTokens: (user) => call("list_access_tokens", { user }),
52 createAccessToken: (user, name) => call("create_access_token", { user, name }),
53 removeAccessToken: (user, id) => call("remove_access_token", { user, id }),
54 };
55}