export declare const grpcGateway = "\n\n/**\n * base64 encoder and decoder\n * Copied and adapted from https://github.com/protobufjs/protobuf.js/blob/master/lib/base64/index.js\n */\n// Base64 encoding table\nconst b64 = new Array(64);\n\n// Base64 decoding table\nconst s64 = new Array(123);\n\n// 65..90, 97..122, 48..57, 43, 47\nfor (let i = 0; i < 64;)\n s64[b64[i] = i < 26 ? i + 65 : i < 52 ? i + 71 : i < 62 ? i - 4 : i - 59 | 43] = i++;\n\nexport function b64Encode(buffer: Uint8Array, start: number, end: number): string {\n\tlet parts: string[] = null;\n const chunk = [];\n let i = 0, // output index\n j = 0, // goto index\n t; // temporary\n while (start < end) {\n const b = buffer[start++];\n switch (j) {\n case 0:\n chunk[i++] = b64[b >> 2];\n t = (b & 3) << 4;\n j = 1;\n break;\n case 1:\n chunk[i++] = b64[t | b >> 4];\n t = (b & 15) << 2;\n j = 2;\n break;\n case 2:\n chunk[i++] = b64[t | b >> 6];\n chunk[i++] = b64[b & 63];\n j = 0;\n break;\n }\n if (i > 8191) {\n (parts || (parts = [])).push(String.fromCharCode.apply(String, chunk));\n i = 0;\n }\n }\n if (j) {\n chunk[i++] = b64[t];\n chunk[i++] = 61;\n if (j === 1)\n chunk[i++] = 61;\n }\n if (parts) {\n if (i)\n parts.push(String.fromCharCode.apply(String, chunk.slice(0, i)));\n return parts.join(\"\");\n }\n return String.fromCharCode.apply(String, chunk.slice(0, i));\n}\n\nconst invalidEncoding = \"invalid encoding\";\n\nexport function b64Decode(s: string): Uint8Array {\n\tconst buffer = [];\n\tlet offset = 0;\n let j = 0, // goto index\n t; // temporary\n for (let i = 0; i < s.length;) {\n let c = s.charCodeAt(i++);\n if (c === 61 && j > 1)\n break;\n if ((c = s64[c]) === undefined)\n throw Error(invalidEncoding);\n switch (j) {\n case 0:\n t = c;\n j = 1;\n break;\n case 1:\n buffer[offset++] = t << 2 | (c & 48) >> 4;\n t = c;\n j = 2;\n break;\n case 2:\n buffer[offset++] = (t & 15) << 4 | (c & 60) >> 2;\n t = c;\n j = 3;\n break;\n case 3:\n buffer[offset++] = (t & 3) << 6 | c;\n j = 0;\n break;\n }\n }\n if (j === 1)\n throw Error(invalidEncoding);\n return new Uint8Array(buffer);\n}\n\nfunction b64Test(s: string): boolean {\n\treturn /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(s);\n}\n\nexport interface InitReq extends RequestInit {\n pathPrefix?: string\n}\n\nexport function replacer(key: any, value: any): any {\n if(value && value.constructor === Uint8Array) {\n return b64Encode(value, 0, value.length);\n }\n\n return value;\n}\n\nexport function fetchReq(path: string, init?: InitReq): Promise {\n const {pathPrefix, ...req} = init || {}\n\n const url = pathPrefix ? `${pathPrefix}${path}` : path\n\n return fetch(url, req).then(r => r.json().then((body: O) => {\n if (!r.ok) { throw body; }\n return body;\n })) as Promise\n}\n\n// NotifyStreamEntityArrival is a callback that will be called on streaming entity arrival\nexport type NotifyStreamEntityArrival = (resp: T) => void\n\n/**\n * fetchStreamingRequest is able to handle grpc-gateway server side streaming call\n * it takes NotifyStreamEntityArrival that lets users respond to entity arrival during the call\n * all entities will be returned as an array after the call finishes.\n **/\nexport async function fetchStreamingRequest(path: string, callback?: NotifyStreamEntityArrival, init?: InitReq) {\n const {pathPrefix, ...req} = init || {}\n const url = pathPrefix ? `${pathPrefix}${path}` : path\n const result = await fetch(url, req)\n // needs to use the .ok to check the status of HTTP status code\n // http other than 200 will not throw an error, instead the .ok will become false.\n // see https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#\n if (!result.ok) {\n const resp = await result.json()\n const errMsg = resp.error && resp.error.message ? resp.error.message : \"\"\n throw new Error(errMsg)\n }\n\n if (!result.body) {\n throw new Error(\"response doesnt have a body\")\n }\n\n await result.body\n .pipeThrough(new TextDecoderStream())\n .pipeThrough(getNewLineDelimitedJSONDecodingStream())\n .pipeTo(getNotifyEntityArrivalSink((e: R) => {\n if (callback) {\n callback(e)\n }\n }))\n\n // wait for the streaming to finish and return the success respond\n return\n}\n\n/**\n * JSONStringStreamController represents the transform controller that's able to transform the incoming\n * new line delimited json content stream into entities and able to push the entity to the down stream\n */\ninterface JSONStringStreamController extends TransformStreamDefaultController {\n buf?: string\n pos?: number\n enqueue: (s: T) => void\n}\n\n/**\n * getNewLineDelimitedJSONDecodingStream returns a TransformStream that's able to handle new line delimited json stream content into parsed entities\n */\nfunction getNewLineDelimitedJSONDecodingStream(): TransformStream {\n return new TransformStream({\n start(controller: JSONStringStreamController) {\n controller.buf = ''\n controller.pos = 0\n },\n\n transform(chunk: string, controller: JSONStringStreamController) {\n if (controller.buf === undefined) {\n controller.buf = ''\n }\n if (controller.pos === undefined) {\n controller.pos = 0\n }\n controller.buf += chunk\n while (controller.pos < controller.buf.length) {\n if (controller.buf[controller.pos] === '\\n') {\n const line = controller.buf.substring(0, controller.pos)\n const response = JSON.parse(line)\n controller.enqueue(response.result)\n controller.buf = controller.buf.substring(controller.pos + 1)\n controller.pos = 0\n } else {\n ++controller.pos\n }\n }\n }\n })\n\n}\n\n/**\n * getNotifyEntityArrivalSink takes the NotifyStreamEntityArrival callback and return\n * a sink that will call the callback on entity arrival\n * @param notifyCallback\n */\nfunction getNotifyEntityArrivalSink(notifyCallback: NotifyStreamEntityArrival) {\n return new WritableStream({\n write(entity: T) {\n notifyCallback(entity)\n }\n })\n}\n\ntype Primitive = string | boolean | number;\ntype RequestPayload = Record;\ntype FlattenedRequestPayload = Record>;\n\n/**\n * Checks if given value is a plain object\n * Logic copied and adapted from below source: \n * https://github.com/char0n/ramda-adjunct/blob/master/src/isPlainObj.js\n * @param {unknown} value\n * @return {boolean}\n */\nfunction isPlainObject(value: unknown): boolean {\n const isObject =\n Object.prototype.toString.call(value).slice(8, -1) === \"Object\";\n const isObjLike = value !== null && isObject;\n\n if (!isObjLike || !isObject) {\n return false;\n }\n\n const proto = Object.getPrototypeOf(value);\n\n const hasObjectConstructor =\n typeof proto === \"object\" &&\n proto.constructor === Object.prototype.constructor;\n\n return hasObjectConstructor;\n}\n\n/**\n * Checks if given value is of a primitive type\n * @param {unknown} value\n * @return {boolean}\n */\nfunction isPrimitive(value: unknown): boolean {\n return [\"string\", \"number\", \"boolean\"].some(t => typeof value === t);\n}\n\n/**\n * Checks if given primitive is zero-value\n * @param {Primitive} value\n * @return {boolean}\n */\nfunction isZeroValuePrimitive(value: Primitive): boolean {\n return value === false || value === 0 || value === \"\";\n}\n\n/**\n * Flattens a deeply nested request payload and returns an object\n * with only primitive values and non-empty array of primitive values\n * as per https://github.com/googleapis/googleapis/blob/master/google/api/http.proto\n * @param {RequestPayload} requestPayload\n * @param {String} path\n * @return {FlattenedRequestPayload>}\n */\nfunction flattenRequestPayload(\n requestPayload: T,\n path: string = \"\"\n): FlattenedRequestPayload {\n return Object.keys(requestPayload).reduce(\n (acc: T, key: string): T => {\n const value = requestPayload[key];\n const newPath = path ? [path, key].join(\".\") : key;\n\n const isNonEmptyPrimitiveArray =\n Array.isArray(value) &&\n value.every(v => isPrimitive(v)) &&\n value.length > 0;\n\n const isNonZeroValuePrimitive =\n isPrimitive(value) && !isZeroValuePrimitive(value as Primitive);\n\n let objectToMerge = {};\n\n if (isPlainObject(value)) {\n objectToMerge = flattenRequestPayload(value as RequestPayload, newPath);\n } else if (value && value.constructor === Uint8Array) {\n objectToMerge = {\n [newPath]: b64Encode(value, 0, value.length),\n };\n } else if (isNonZeroValuePrimitive || isNonEmptyPrimitiveArray) {\n objectToMerge = { [newPath]: value };\n }\n\n return { ...acc, ...objectToMerge };\n },\n {} as T\n ) as FlattenedRequestPayload;\n}\n\n/**\n * Renders a deeply nested request payload into a string of URL search\n * parameters by first flattening the request payload and then removing keys\n * which are already present in the URL path.\n * @param {RequestPayload} requestPayload\n * @param {string[]} urlPathParams\n * @return {string}\n */\nexport function renderURLSearchParams(\n requestPayload: T,\n urlPathParams: string[] = []\n): string {\n const flattenedRequestPayload = flattenRequestPayload(requestPayload);\n\n const urlSearchParams = Object.keys(flattenedRequestPayload).reduce(\n (acc: string[][], key: string): string[][] => {\n // key should not be present in the url path as a parameter\n const value = flattenedRequestPayload[key];\n if (urlPathParams.find(f => f === key)) {\n return acc;\n }\n return Array.isArray(value)\n ? [...acc, ...value.map(m => [key, m.toString()])]\n : (acc = [...acc, [key, value.toString()]]);\n },\n [] as string[][]\n );\n\n // react-native's URLSearchParams doesn't like working with array of arrays\n return urlSearchParams\n .map((x) => new URLSearchParams({ [x[0]]: x[1] }).toString())\n .join(\"&\");\n}\n";