2025-03-03 15:42:34 +05:30

106 lines
3.1 KiB
TypeScript

import request, { Agent } from "superagent";
import prefix from "superagent-prefix";
export function customErrorHandler(err: Error): request.Response {
// optional chaining doesn't work in repos that don't use node-ts yet.
const errMsg = (err as any) && (err as any).response && (err as any).response.text? (err as any).response.text: err.message;
throw new Error(errMsg);
}
export abstract class BaseCaller {
/**
* Makes the request after prefixing the apiUrl to the request path
* https://visionmedia.github.io/superagent/#get-requests
*/
protected agent: Agent;
/**
* base API url
*/
protected apiUrl: string;
/**
* Used in case we use the default token used at the time this class was initialized
*/
private authTokenString: string | undefined;
/**
* In case the caller decides to pass a function to use to get the authToken
*/
private authTokenFunction: (() => string) | undefined;
protected useBearerToken = true;
/**
* Used in case we pass a function to resolve the authToken at realTime
* By default, this simply returns the passed authToken
*/
protected getAuthToken = (): string => {
if (this.authTokenString !== undefined) {
if(this.useBearerToken) {
if(!this.authTokenString.startsWith("Bearer ")){
return `Bearer ${this.authTokenString}`
}
}
return `${this.authTokenString}`;
} else if (this.authTokenFunction !== undefined) {
return this.authTokenFunction();
} else {
console.log(`Error from BaseCaller: no auth token set`);
return "";
}
}
/**
* Used for callers where the only option is to use API token
* Can be used in the Caller code instead of calling callerInstance.setUseBearerToken(false) in the implementation file
* which would set the Bearer option globally for this callerInstance
*/
protected getApiToken = (): string => {
if (this.authTokenString !== undefined) {
return `${this.authTokenString}`;
} else {
console.log(`Error from BaseCaller: no auth token set`);
return "";
}
}
private setAuthToken(authToken: string | (() => string)) {
if(typeof authToken === "string") {
this.authTokenString = authToken;
} else {
this.authTokenFunction = authToken;
}
}
/**
* authToken accepts either a string or a function.
*/
constructor(apiUrl: string, authToken?: string | (() => string), useBearerToken?: boolean) {
this.apiUrl = apiUrl;
if(authToken !== undefined) {
this.setAuthToken(authToken);
}
if(useBearerToken !== undefined) {
this.setUseBearerToken(useBearerToken);
}
this.agent = request.agent().use(prefix(apiUrl));
/**
* !IMPORTANT: DO NOT ADD ERROR HANDLING. API ALWAYS RETURNS RESPONSES AND ERRORS.
*/
/*.on("error", (err) => {
console.log(`Error while making request. Status: ${err.status}, Text: ${err.response?.text}`);
throw err;
});*/
}
public setUseBearerToken(value = true): void {
this.useBearerToken = value;
}
/**
* @example
* return new ExampleCaller(this.apiUrl, token);
*/
abstract withToken(token: string): BaseCaller
}