@gray-adeyi/korapay-sdk
Version:
A korapay client SDK for the javascript runtime.
222 lines (221 loc) • 8 kB
JavaScript
import * as dntShim from "../_dnt.shims.js";
import { KorapayClientError } from "./errors.js";
import axios from "axios";
import { camelCase, snakeCase } from "lodash-es";
import { encryptAes256 } from "./utils.js";
import { HTTPMethod } from "./enums.js";
class RestClient {
constructor(publicKey, secretKey, encryptionKey) {
Object.defineProperty(this, "publicKey", {
enumerable: true,
configurable: true,
writable: true,
value: ""
});
Object.defineProperty(this, "secretKey", {
enumerable: true,
configurable: true,
writable: true,
value: ""
});
Object.defineProperty(this, "encryptionKey", {
enumerable: true,
configurable: true,
writable: true,
value: ""
});
Object.defineProperty(this, "secureClient", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "openClient", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
this.loadKey("public key", RestClient.ENV_PUBLIC_KEY_NAME, publicKey);
this.loadKey("secret key", RestClient.ENV_SECRET_KEY_NAME, secretKey);
this.loadKey("encryption key", RestClient.ENV_ENCRYPTION_KEY_NAME, encryptionKey);
this.secureClient = axios.create({
baseURL: RestClient.BASE_URL,
headers: this.secureHeaders,
});
this.secureClient.interceptors.request.use(this.requestPayloadTransformerInterceptor, this.handleRequestError);
this.secureClient.interceptors.response.use(this.responsePayloadTransformerInterceptor, this.handleResponseError);
this.openClient = axios.create({
baseURL: RestClient.BASE_URL,
headers: this.openHeaders,
});
this.openClient.interceptors.request.use(this.requestPayloadTransformerInterceptor, this.handleRequestError);
this.openClient.interceptors.response.use(this.responsePayloadTransformerInterceptor, this.handleResponseError);
}
// deno-lint-ignore no-explicit-any
async call(endpoint, method,
// deno-lint-ignore no-explicit-any
data, noAuth = false) {
const handler = this.getMethodHandler(method, noAuth);
let response;
if ([HTTPMethod.GET, HTTPMethod.DELETE].includes(method)) {
response = await handler(endpoint);
}
else {
response = await handler(endpoint, data);
}
return this.deserializeResponse(response);
}
// deno-lint-ignore no-explicit-any
encryptData(data) {
return encryptAes256(this.encryptionKey, data);
}
get baseHeaders() {
return {
"User-Agent": "@gray-adeyi/korapay-sdk 0.2.1",
Accept: "application/json",
"Content-Type": "application/json",
};
}
get openHeaders() {
return {
...this.baseHeaders,
Authorization: `Bearer ${this.publicKey}`,
};
}
get secureHeaders() {
return {
...this.baseHeaders,
Authorization: `Bearer ${this.secretKey}`,
};
}
getMethodHandler(method, noAuth) {
// deno-lint-ignore no-explicit-any
const secureClientHandlerMapping = {
[HTTPMethod.GET]: this.secureClient.get,
[HTTPMethod.POST]: this.secureClient.post,
[HTTPMethod.PATCH]: this.secureClient.patch,
[HTTPMethod.PUT]: this.secureClient.put,
[HTTPMethod.DELETE]: this.secureClient.delete,
};
const openClientHandlerMapping = {
[HTTPMethod.GET]: this.openClient.get,
[HTTPMethod.POST]: this.openClient.post,
[HTTPMethod.PATCH]: this.openClient.patch,
[HTTPMethod.PUT]: this.openClient.put,
[HTTPMethod.DELETE]: this.openClient.delete,
};
const mapping = noAuth
? openClientHandlerMapping
: secureClientHandlerMapping;
return mapping[method];
}
deserializeResponse(response) {
return {
statusCode: response.status,
status: response.data["status"] || false,
message: response.data["message"],
data: response.data["data"],
};
}
requestPayloadTransformerInterceptor(config) {
config.data = RestClient.camelToSnakeCaseTransformer(config.data);
return config;
}
responsePayloadTransformerInterceptor(response) {
response.data = RestClient.snakeToCamelCaseTransformer(response.data);
return response;
}
// deno-lint-ignore no-explicit-any
static camelToSnakeCaseTransformer(data) {
if (Array.isArray(data)) {
return data.map(RestClient.camelToSnakeCaseTransformer);
}
else if (data !== null && typeof data === "object") {
// deno-lint-ignore no-explicit-any
return Object.keys(data).reduce((acc, key) => {
const snakeKey = snakeCase(key);
acc[snakeKey] = RestClient.camelToSnakeCaseTransformer(data[key]);
return acc;
}, {});
}
return data;
}
// deno-lint-ignore no-explicit-any
static snakeToCamelCaseTransformer(data) {
if (Array.isArray(data)) {
return data.map(RestClient.snakeToCamelCaseTransformer);
}
else if (data !== null && typeof data === "object") {
// deno-lint-ignore no-explicit-any
return Object.keys(data).reduce((acc, key) => {
const camelKey = camelCase(key);
acc[camelKey] = RestClient.snakeToCamelCaseTransformer(data[key]);
return acc;
}, {});
}
return data;
}
handleRequestError(error) {
return Promise.reject(new KorapayClientError(error.message, error.status, error.code));
}
handleResponseError(error) {
return Promise.reject(new KorapayClientError(error.message, error.status, error.code, error));
}
loadKey(keyName, keyEnvName, value) {
if (value) {
switch (keyName) {
case "public key":
this.publicKey = value;
break;
case "secret key":
this.secretKey = value;
break;
case "encryption key":
this.encryptionKey = value;
break;
}
return;
}
if (!dntShim.Deno.env.has(keyEnvName)) {
throw new KorapayClientError(`${keyName} was not provided on instantiation or set in environmental variables as ${keyEnvName}`);
}
const envValue = dntShim.Deno.env.get(keyEnvName);
switch (keyName) {
case "public key":
this.publicKey = envValue;
break;
case "secret key":
this.secretKey = envValue;
break;
case "encryption key":
this.encryptionKey = envValue;
break;
}
}
}
Object.defineProperty(RestClient, "BASE_URL", {
enumerable: true,
configurable: true,
writable: true,
value: "https://api.korapay.com"
});
Object.defineProperty(RestClient, "ENV_PUBLIC_KEY_NAME", {
enumerable: true,
configurable: true,
writable: true,
value: "KORAPAY_PUBLIC_KEY"
});
Object.defineProperty(RestClient, "ENV_SECRET_KEY_NAME", {
enumerable: true,
configurable: true,
writable: true,
value: "KORAPAY_SECRET_KEY"
});
Object.defineProperty(RestClient, "ENV_ENCRYPTION_KEY_NAME", {
enumerable: true,
configurable: true,
writable: true,
value: "KORAPAY_ENCRYPTION_KEY"
});
export default RestClient;