{"version":3,"sources":["../src/TwirpRPC.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { JsonValue } from '@bufbuild/protobuf';\n\n// twirp RPC adapter for client implementation\n\ntype Options = {\n  /** Prefix for the RPC requests */\n  prefix?: string;\n  /** Timeout for fetch requests, in seconds. Must be within the valid range for abort signal timeouts. */\n  requestTimeout?: number;\n};\n\nconst defaultPrefix = '/twirp';\nconst defaultTimeoutSeconds = 60;\n\nexport const livekitPackage = 'livekit';\nexport interface Rpc {\n  request(\n    service: string,\n    method: string,\n    data: JsonValue,\n    headers: any, // eslint-disable-line @typescript-eslint/no-explicit-any\n    timeout?: number,\n  ): Promise<string>;\n}\n\nexport class TwirpError extends Error {\n  status: number;\n  code?: string;\n  metadata?: Record<string, string>;\n\n  constructor(\n    name: string,\n    message: string,\n    status: number,\n    code?: string,\n    metadata?: Record<string, string>,\n  ) {\n    super(message);\n    this.name = name;\n    this.status = status;\n    this.code = code;\n    this.metadata = metadata;\n  }\n}\n\n/**\n * JSON based Twirp V7 RPC\n */\nexport class TwirpRpc {\n  host: string;\n\n  pkg: string;\n\n  prefix: string;\n\n  requestTimeout: number;\n\n  constructor(host: string, pkg: string, options?: Options) {\n    if (host.startsWith('ws')) {\n      host = host.replace('ws', 'http');\n    }\n    this.host = host;\n    this.pkg = pkg;\n    this.requestTimeout = options?.requestTimeout ?? defaultTimeoutSeconds;\n    this.prefix = options?.prefix || defaultPrefix;\n  }\n\n  async request(\n    service: string,\n    method: string,\n    data: any, // eslint-disable-line @typescript-eslint/no-explicit-any\n    headers: any, // eslint-disable-line @typescript-eslint/no-explicit-any\n    timeout = this.requestTimeout,\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  ): Promise<any> {\n    const path = `${this.prefix}/${this.pkg}.${service}/${method}`;\n    const url = new URL(path, this.host);\n    const init: RequestInit = {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/json;charset=UTF-8',\n        ...headers,\n      },\n      body: JSON.stringify(data),\n    };\n\n    if (timeout) {\n      init.signal = AbortSignal.timeout(timeout * 1000);\n    }\n\n    const response = await fetch(url, init);\n\n    if (!response.ok) {\n      const isJson = response.headers.get('content-type') === 'application/json';\n      let errorMessage = 'Unknown internal error';\n      let errorCode: string | undefined = undefined;\n      let metadata: Record<string, string> | undefined = undefined;\n      try {\n        if (isJson) {\n          const parsedError = (await response.json()) as Record<string, unknown>;\n          if ('msg' in parsedError) {\n            errorMessage = <string>parsedError.msg;\n          }\n          if ('code' in parsedError) {\n            errorCode = <string>parsedError.code;\n          }\n          if ('meta' in parsedError) {\n            metadata = <Record<string, string>>parsedError.meta;\n          }\n        } else {\n          errorMessage = await response.text();\n        }\n      } catch (e) {\n        // parsing went wrong, no op and we keep default error message\n        console.debug(`Error when trying to parse error message, using defaults`, e);\n      }\n\n      throw new TwirpError(response.statusText, errorMessage, response.status, errorCode, metadata);\n    }\n    const parsedResp = (await response.json()) as Record<string, unknown>;\n\n    const camelcaseKeys = await import('camelcase-keys').then((mod) => mod.default);\n    return camelcaseKeys(parsedResp, { deep: true });\n  }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAcA,MAAM,gBAAgB;AACtB,MAAM,wBAAwB;AAEvB,MAAM,iBAAiB;AAWvB,MAAM,mBAAmB,MAAM;AAAA,EAKpC,YACE,MACA,SACA,QACA,MACA,UACA;AACA,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,OAAO;AACZ,SAAK,WAAW;AAAA,EAClB;AACF;AAKO,MAAM,SAAS;AAAA,EASpB,YAAY,MAAc,KAAa,SAAmB;AACxD,QAAI,KAAK,WAAW,IAAI,GAAG;AACzB,aAAO,KAAK,QAAQ,MAAM,MAAM;AAAA,IAClC;AACA,SAAK,OAAO;AACZ,SAAK,MAAM;AACX,SAAK,kBAAiB,mCAAS,mBAAkB;AACjD,SAAK,UAAS,mCAAS,WAAU;AAAA,EACnC;AAAA,EAEA,MAAM,QACJ,SACA,QACA,MACA,SACA,UAAU,KAAK,gBAED;AACd,UAAM,OAAO,GAAG,KAAK,MAAM,IAAI,KAAK,GAAG,IAAI,OAAO,IAAI,MAAM;AAC5D,UAAM,MAAM,IAAI,IAAI,MAAM,KAAK,IAAI;AACnC,UAAM,OAAoB;AAAA,MACxB,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,GAAG;AAAA,MACL;AAAA,MACA,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B;AAEA,QAAI,SAAS;AACX,WAAK,SAAS,YAAY,QAAQ,UAAU,GAAI;AAAA,IAClD;AAEA,UAAM,WAAW,MAAM,MAAM,KAAK,IAAI;AAEtC,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,SAAS,SAAS,QAAQ,IAAI,cAAc,MAAM;AACxD,UAAI,eAAe;AACnB,UAAI,YAAgC;AACpC,UAAI,WAA+C;AACnD,UAAI;AACF,YAAI,QAAQ;AACV,gBAAM,cAAe,MAAM,SAAS,KAAK;AACzC,cAAI,SAAS,aAAa;AACxB,2BAAuB,YAAY;AAAA,UACrC;AACA,cAAI,UAAU,aAAa;AACzB,wBAAoB,YAAY;AAAA,UAClC;AACA,cAAI,UAAU,aAAa;AACzB,uBAAmC,YAAY;AAAA,UACjD;AAAA,QACF,OAAO;AACL,yBAAe,MAAM,SAAS,KAAK;AAAA,QACrC;AAAA,MACF,SAAS,GAAG;AAEV,gBAAQ,MAAM,4DAA4D,CAAC;AAAA,MAC7E;AAEA,YAAM,IAAI,WAAW,SAAS,YAAY,cAAc,SAAS,QAAQ,WAAW,QAAQ;AAAA,IAC9F;AACA,UAAM,aAAc,MAAM,SAAS,KAAK;AAExC,UAAM,gBAAgB,MAAM,OAAO,gBAAgB,EAAE,KAAK,CAAC,QAAQ,IAAI,OAAO;AAC9E,WAAO,cAAc,YAAY,EAAE,MAAM,KAAK,CAAC;AAAA,EACjD;AACF;","names":[]}