106 lines
3.1 KiB
TypeScript
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
|
|
}
|