This commit is contained in:
Sahil Ahuja 2025-03-03 15:19:59 +05:30
parent 54e7a01dfd
commit 926a9f858f
4 changed files with 113 additions and 3 deletions

View File

@ -2,8 +2,8 @@
"name": "@gmetrivr/definitions",
"version": "1.0.163",
"description": "GMetri Definitions",
"types": "./lib/esm/index.d.ts",
"@comment main": "This key is still kept around until older version of node that don't understand exports key are used",
"types": "./lib/esm/index.d.ts",
"main": "./lib/cjs/index.js",
"exports": {
"require": "./lib/cjs/index.js",
@ -14,6 +14,7 @@
"license": "UNLICENSED",
"sideEffects": false,
"type": "module",
"@comment files": "Files dictate what goes to npm",
"files": [
"lib/*"
],
@ -39,8 +40,8 @@
"@gmetrixr/gdash": "1.*.*"
},
"dependencies": {
"@types/superagent": "^8.1.9",
"superagent": "^10.1.1"
"superagent": "^10.1.1",
"superagent-prefix": "^0.0.2"
},
"devDependencies": {
"@eslint/js": "^9.20.0",

View File

@ -0,0 +1,106 @@
import request, { SuperAgent } 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: SuperAgent<request.SuperAgentRequest>;
/**
* 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
}

View File

@ -0,0 +1,3 @@
import { BaseCaller } from "./callerUtils.js";
export { BaseCaller };