All files / app/service client.ts

90.56% Statements 48/53
92.3% Branches 12/13
60% Functions 3/5
90.19% Lines 46/51

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142183x 183x 183x 183x 183x 183x 183x 183x 183x 183x 183x 183x 183x 183x 183x 183x 183x 183x 183x 183x 183x 183x 183x 183x   183x   183x     183x     183x       183x 1094x     1090x     7x     3x 3x   2x 1x   1x     2x                                 183x 183x   183x             183x                                                   183x   183x   183x                                                     183x  
import { Request, RpcError, StatusCode } from "grpc-web";
import { AccountPromiseClient } from "proto/account_grpc_web_pb";
import { AdminPromiseClient } from "proto/admin_grpc_web_pb";
import { APIPromiseClient } from "proto/api_grpc_web_pb";
import { AuthPromiseClient } from "proto/auth_grpc_web_pb";
import { BlockingPromiseClient } from "proto/blocking_grpc_web_pb";
import { BugsPromiseClient } from "proto/bugs_grpc_web_pb";
import { CommunitiesPromiseClient } from "proto/communities_grpc_web_pb";
import { ConversationsPromiseClient } from "proto/conversations_grpc_web_pb";
import { DiscussionsPromiseClient } from "proto/discussions_grpc_web_pb";
import { DonationsPromiseClient } from "proto/donations_grpc_web_pb";
import { EventsPromiseClient } from "proto/events_grpc_web_pb";
import { GalleriesPromiseClient } from "proto/galleries_grpc_web_pb";
import { GroupsPromiseClient } from "proto/groups_grpc_web_pb";
import { JailPromiseClient } from "proto/jail_grpc_web_pb";
import { NotificationsPromiseClient } from "proto/notifications_grpc_web_pb";
import { PagesPromiseClient } from "proto/pages_grpc_web_pb";
import { PublicPromiseClient } from "proto/public_grpc_web_pb";
import { ReferencesPromiseClient } from "proto/references_grpc_web_pb";
import { ReportingPromiseClient } from "proto/reporting_grpc_web_pb";
import { RequestsPromiseClient } from "proto/requests_grpc_web_pb";
import { ResourcesPromiseClient } from "proto/resources_grpc_web_pb";
import { SearchPromiseClient } from "proto/search_grpc_web_pb";
import { ThreadsPromiseClient } from "proto/threads_grpc_web_pb";
 
import isGrpcError from "./utils/isGrpcError";
 
const URL = (process.env.NEXT_PUBLIC_API_BASE_URL ||
  process.env.EXPO_PUBLIC_API_BASE_URL)!;
const IS_PROD =
  (process.env.NEXT_PUBLIC_COUCHERS_ENV ||
    process.env.EXPO_PUBLIC_COUCHERS_ENV)! === "prod";
 
const grpcTimeout = 10000; //milliseconds
 
let _unauthenticatedErrorHandler: (
  e: RpcError,
) => Promise<void> = async () => {};
export const setUnauthenticatedErrorHandler = (
  f: (e: RpcError) => Promise<void>,
) => {
  _unauthenticatedErrorHandler = f;
};
 
export class AuthInterceptor {
  async intercept(request: unknown, invoker: (request: unknown) => unknown) {
    let response;
    try {
      response = await invoker(request);
    } catch (e) {
      if (isGrpcError(e) && e.code === StatusCode.UNAUTHENTICATED) {
        _unauthenticatedErrorHandler(e);
      } else {
        throw e;
      }
    }
    return response;
  }
}
 
class TimeoutInterceptor {
  async intercept(
    request: Request<unknown, unknown>,
    invoker: (request: unknown) => unknown,
  ) {
    const deadline = Date.now() + grpcTimeout;
    const metadata = request.getMetadata();
    metadata.deadline = deadline.toString();
    const response = await invoker(request);
    return response;
  }
}
 
const authInterceptor = new AuthInterceptor();
const timeoutInterceptor = new TimeoutInterceptor();
 
const opts = {
  unaryInterceptors: [authInterceptor, timeoutInterceptor],
  // this modifies the behaviour on the API so that it will send cookies on the requests
  withCredentials: true,
  /// TODO: streaming interceptor for auth https://grpc.io/blog/grpc-web-interceptor/
};
 
const client = {
  account: new AccountPromiseClient(URL, null, opts),
  admin: new AdminPromiseClient(URL, null, opts),
  api: new APIPromiseClient(URL, null, opts),
  auth: new AuthPromiseClient(URL, null, opts),
  blocking: new BlockingPromiseClient(URL, null, opts),
  bugs: new BugsPromiseClient(URL, null, opts),
  communities: new CommunitiesPromiseClient(URL, null, opts),
  conversations: new ConversationsPromiseClient(URL, null, opts),
  discussions: new DiscussionsPromiseClient(URL, null, opts),
  donations: new DonationsPromiseClient(URL, null, opts),
  events: new EventsPromiseClient(URL, null, opts),
  galleries: new GalleriesPromiseClient(URL, null, opts),
  groups: new GroupsPromiseClient(URL, null, opts),
  jail: new JailPromiseClient(URL, null, opts),
  notifications: new NotificationsPromiseClient(URL, null, opts),
  pages: new PagesPromiseClient(URL, null, opts),
  public: new PublicPromiseClient(URL, null, opts),
  references: new ReferencesPromiseClient(URL, null, opts),
  reporting: new ReportingPromiseClient(URL, null, opts),
  requests: new RequestsPromiseClient(URL, null, opts),
  resources: new ResourcesPromiseClient(URL, null, opts),
  search: new SearchPromiseClient(URL, null, opts),
  threads: new ThreadsPromiseClient(URL, null, opts),
};
 
if (!IS_PROD && typeof window !== "undefined") {
  // @ts-ignore
  const grpcWebTools = window.__GRPCWEB_DEVTOOLS__ || (() => {});
 
  grpcWebTools([
    client.account,
    client.admin,
    client.api,
    client.auth,
    client.blocking,
    client.bugs,
    client.communities,
    client.conversations,
    client.discussions,
    client.donations,
    client.events,
    client.galleries,
    client.groups,
    client.jail,
    client.notifications,
    client.pages,
    client.public,
    client.references,
    client.reporting,
    client.requests,
    client.resources,
    client.search,
    client.threads,
  ]);
}
 
export default client;