~/bend-docscommunity

client.bend source

client.bend on the hub · documented module

import Baseimport ./http.bend as Himport ./json.bend as Jsonimport ./url.bend as Urltype Endpoint is Data:  Health{}  Register{}  Login{}  Refresh{}  Logout{}  Me{}  TemporaryKey{}  Wallet{}  Plans{}type Client is Data:  Client{base: String, token: String, org: String}type Session is Data:  Session{    accessToken: String,    refreshToken: String,    expiresIn: U32,    tokenType: String  }type User is Data:  User{id: String, email: String, displayName: String}type TempKey is Data:  TempKey{    id: String,    key: String,    expiresAt: String,    baseDomain: String,    stub: Bool  }def Endpoint.method(e: Endpoint) -> H.Method:  match e:    case Health{}:      H.GET{}    case Register{}:      H.POST{}    case Login{}:      H.POST{}    case Refresh{}:      H.POST{}    case Logout{}:      H.POST{}    case Me{}:      H.GET{}    case TemporaryKey{}:      H.POST{}    case Wallet{}:      H.GET{}    case Plans{}:      H.GET{}def Endpoint.path(e: Endpoint) -> String:  match e:    case Health{}:      "/health"    case Register{}:      "/v1/auth/register"    case Login{}:      "/v1/auth/login"    case Refresh{}:      "/v1/auth/refresh"    case Logout{}:      "/v1/auth/logout"    case Me{}:      "/v1/me"    case TemporaryKey{}:      "/v1/keys/temporary"    case Wallet{}:      "/v1/wallet"    case Plans{}:      "/v1/plans"def Endpoint.needs_bearer(e: Endpoint) -> Bool:  match e:    case Health{}:      False{}    case Register{}:      False{}    case Login{}:      False{}    case Refresh{}:      False{}    case Logout{}:      True{}    case Me{}:      True{}    case TemporaryKey{}:      True{}    case Wallet{}:      True{}    case Plans{}:      False{}def Client.default_base() -> String:  "http://127.0.0.1:8787"def Client.new(+base: String) -> Client:  Client{Url.rstrip(base), "", ""}def Client.local() -> Client:  Client.new(Client.default_base())def Client.with_token(c: Client, token: String) -> Client:  match c:    case Client{base, t, org}:      Client{base, token, org}def Client.with_org(c: Client, org: String) -> Client:  match c:    case Client{base, token, o}:      Client{base, token, org}def Client.auth_headers.token(+token: String, org_hs: List<&2, H.Hdr>) ->  List<&2, H.Hdr>:  match token:    case SNil{}:      org_hs    case SCon{h, t}:      H.Hdr.bearer(SCon{h, t}) <> org_hsdef Client.auth_headers.org(+org: String) -> List<&2, H.Hdr>:  match org:    case SNil{}:      Nil{}    case SCon{h, t}:      H.Hdr.org(SCon{h, t}) <> Nil{}def Client.auth_headers(+token: String, +org: String) -> List<&2, H.Hdr>:  Client.auth_headers.token(token, Client.auth_headers.org(org))def Client.headers.if(  json: Bool, bearer: Bool, +token: String, +org: String) -> List<&2, H.Hdr>:  match json bearer:    case True{} False{}:      H.Hdr.json() <> (H.Hdr.accept() <> Nil{})    case False{} False{}:      H.Hdr.accept() <> Nil{}    case True{} True{}:      H.Hdr.json() <> (H.Hdr.accept() <> Client.auth_headers(token, org))    case False{} True{}:      H.Hdr.accept() <> Client.auth_headers(token, org)def Client.headers(+c: Client, +e: Endpoint, json: Bool) -> List<&2, H.Hdr>:  match c:    case Client{base, +token, +org}:      Client.headers.if(json, Endpoint.needs_bearer(e), token, org)def Client.url(+c: Client, +e: Endpoint) -> String:  match c:    case Client{+base, token, org}:      Url.join(base, Endpoint.path(e))def Api.login_body(+email: String, +password: String) -> String:  Json.object2("email", email, "password", password)def Api.register_body(+displayName: String, +email: String, +password: String) ->  String:  match displayName:    case SNil{}:      Json.object2("email", email, "password", password)    case SCon{h, t}:      Json.object3("email", email, "password", password, "displayName",        SCon{h, t})def Api.refresh_body(+refreshToken: String) -> String:  Json.object1("refreshToken", refreshToken)def Api.request(+c: Client, +e: Endpoint, json: Bool, body: String) ->  IO(Result<&1, &1, U32 & String, H.Reply>):  match c:    case Client{+base, +token, +org}:      H.Http.call(        base,        Endpoint.method(e),        Endpoint.path(e),        Client.headers(Client{base, token, org}, e, json),        body      )def Api.health(+c: Client) -> IO(Result<&1, &1, U32 & String, H.Reply>):  Api.request(c, Health{}, False{}, "")def Api.plans(+c: Client) -> IO(Result<&1, &1, U32 & String, H.Reply>):  Api.request(c, Plans{}, False{}, "")def Api.login(+c: Client, +email: String, +password: String) ->  IO(Result<&1, &1, U32 & String, H.Reply>):  Api.request(c, Login{}, True{}, Api.login_body(email, password))def Api.register(+c: Client, +email: String, +password: String, +name: String) ->  IO(Result<&1, &1, U32 & String, H.Reply>):  Api.request(c, Register{}, True{}, Api.register_body(name, email, password))def Api.refresh(+c: Client, +refreshToken: String) ->  IO(Result<&1, &1, U32 & String, H.Reply>):  Api.request(c, Refresh{}, True{}, Api.refresh_body(refreshToken))def Api.logout(+c: Client) -> IO(Result<&1, &1, U32 & String, H.Reply>):  Api.request(c, Logout{}, False{}, "")def Api.me(+c: Client) -> IO(Result<&1, &1, U32 & String, H.Reply>):  Api.request(c, Me{}, False{}, "")def Api.wallet(+c: Client) -> IO(Result<&1, &1, U32 & String, H.Reply>):  Api.request(c, Wallet{}, False{}, "")def Api.temporary_key(+c: Client) -> IO(Result<&1, &1, U32 & String, H.Reply>):  Api.request(c, TemporaryKey{}, False{}, "")def Api.parse_session.exp(  exp: Maybe<&2, U32>, access: String, refresh: String, tokenType: String) -> Result<&2, &2, String, Session>:  match exp:    case None{}:      Fail{"session JSON missing expiresIn"}    case Some{n}:      Done{Session{access, refresh, n, tokenType}}def Api.parse_session.body(+body: String) -> Result<&2, &2, String, Session>:  a r t e =    Json.string_field(body, "accessToken")    Json.string_field(body, "refreshToken")    Json.string_field(body, "tokenType")    Json.u32_field(body, "expiresIn")  Result.bind(&2, &2, String, String, Session,    Json.need_string(a, "session JSON missing accessToken"),    access =>      Result.bind(&2, &2, String, String, Session,        Json.need_string(r, "session JSON missing refreshToken"),        refresh =>          Api.parse_session.exp(e, access, refresh, Json.or_empty(t))))def Api.parse_user.body(+body: String) -> Result<&2, &2, String, User>:  id e n =    Json.string_field(body, "id")    Json.string_field(body, "email")    Json.string_field(body, "displayName")  Result.bind(&2, &2, String, String, User,    Json.need_string(id, "me JSON missing user.id"),    uid =>      Result.bind(&2, &2, String, String, User,        Json.need_string(e, "me JSON missing user.email"),        email =>          Done{User{uid, email, Json.or_empty(n)}}))def Api.reject_stub.if(  id: String, k: String, exp: String, domain: String, stub: Bool) -> Result<&2, &2, String, TempKey>:  match stub:    case True{}:      Fail{"stub_key"}    case False{}:      Done{TempKey{id, k, exp, domain, False{}}}def Api.reject_stub(key: TempKey) -> Result<&2, &2, String, TempKey>:  match key:    case TempKey{id, k, exp, domain, stub}:      Api.reject_stub.if(id, k, exp, domain, stub)def Api.parse_temp.body(+body: String) -> Result<&2, &2, String, TempKey>:  k =    Json.string_field(body, "key")  Result.bind(&2, &2, String, String, TempKey,    Json.need_string(k, "temporary key JSON missing key"),    key =>      Api.reject_stub(TempKey{        Json.or_empty(Json.string_field(body, "id")),        key,        Json.or_empty(Json.string_field(body, "expiresAt")),        Json.or_empty(Json.string_field(body, "baseDomain")),        Json.or_false(Json.bool_field(body, "stub"))      }))def Api.realtime_url(+baseDomain: String) -> String:  "wss://stt-rt." ++ baseDomain ++ "/transcribe-websocket"def Api.show_reply(r: Result<&1, &1, U32 & String, H.Reply>) -> String:  match r:    case Fail{(code, message)}:      "NETWORK " ++ U32.show(code) ++ " " ++ message    case Done{H.Reply{status, headers, body}}:      U32.show(status) ++ " " ++ body