bc-node-sdk
Version:
BetterCommerce's NodeJS SDK encapsulates the base framework for all the Next.js applications.
268 lines (267 loc) • 14.2 kB
JavaScript
"use strict";
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
// Package Imports
const axios_1 = require("axios");
const server_1 = require("next/server");
const api_util_1 = __importDefault(require("../../utils/api-util"));
const app_util_1 = __importDefault(require("../../utils/app-util"));
const parse_util_1 = __importDefault(require("../../utils/parse-util"));
const constants_1 = require("../../domain/constants");
const BaseApiController_1 = __importDefault(require("./BaseApiController"));
const RequestMethod_1 = require("../../domain/enums/api/RequestMethod");
/**
* Class {@link ApiController} is a concrete implementation of the {@link IApiRequestHandler} interface and extends the behavior of {@link BaseApiController}.
* It delegates API requests to the appropriate HTTP method handler and returns
* the result of the API call or a JSON response in case of an error.
*/
class ApiController extends BaseApiController_1.default {
/**
* Constructs an instance of the ApiController class, extending the BaseApiController.
* Initializes an ApiService instance if client secret authentication is enabled.
*
* @param cacheManager - The cache manager instance used for caching operations.
*/
constructor(cacheManager) {
super(cacheManager);
this._apiInstance = null;
if (process.env.ENABLE_CLIENT_SECRET_AUTH) {
this._apiInstance = this.serviceInstance(process.env.API_BASE_URL);
}
}
/**
* Handles API requests by delegating them to the appropriate HTTP method handler.
*
* @param request - The IApiParams object containing request details such as endpoint, data, params, headers, and cookies.
* @param method - The HTTP request method as a string (e.g., GET, POST, PUT, DELETE, PATCH).
* @returns A Promise that resolves to the result of the API call or a JSON response indicating the method is not allowed.
*/
async handleRequest(request, method) {
switch (method) {
case RequestMethod_1.RequestMethod.GET:
return this.get(request);
case RequestMethod_1.RequestMethod.POST:
return await this.post(request);
case RequestMethod_1.RequestMethod.PUT:
return this.put(request);
case RequestMethod_1.RequestMethod.DELETE:
return this.delete(request);
case RequestMethod_1.RequestMethod.PATCH:
return this.patch(request);
default:
return server_1.NextResponse.json({ message: 'Method not allowed' }, { status: 405 });
}
}
/**
* GET request handler
* @param request - The IApiParams object containing request details such as endpoint, data, params, headers, and cookies.
* @returns A Promise that resolves to the result of the API call.
* @throws An error if client ID or secret is missing when client secret authentication is enabled.
*/
async get(request) {
//const requestHeaders: any = request.headers || Defaults.Object.Value
const headers = await this.authorizationHeaderFromRequestCookies(request.cookies, request.headers, this.cacheManager);
let config = {
url: request.endpoint,
method: RequestMethod_1.RequestMethod.GET,
headers: Object.assign({}, headers),
};
if (request.params) {
config = Object.assign(Object.assign({}, config), { params: request.params || constants_1.Defaults.Object.Value });
}
if (!process.env.ENABLE_CLIENT_SECRET_AUTH) {
//logInfo({ url, config }, '--- serviceInstanceApi ---')
const { data } = await api_util_1.default.callApi(config);
return data;
}
if (!this._apiInstance) {
throw new Error("client id or secret missing");
}
if (request === null || request === void 0 ? void 0 : request.baseUrl) {
config = Object.assign(Object.assign({}, config), { baseURL: request === null || request === void 0 ? void 0 : request.baseUrl });
}
const { url } = config, rest = __rest(config, ["url"]);
app_util_1.default.logInfo(config, '--- config ---');
const { data } = await this._apiInstance.get(url, Object.assign({}, rest));
return data;
}
/**
* POST request handler
* @param request - The IApiParams object containing request details such as endpoint, data, params, headers, and cookies.
* @returns A Promise that resolves to the result of the API call.
* @throws An error if client ID or secret is missing when client secret authentication is enabled.
*/
async post(request) {
//const requestHeaders: any = request.headers || Defaults.Object.Value
const headers = await this.authorizationHeaderFromRequestCookies(request.cookies, request.headers, this.cacheManager);
let config = {
url: request.endpoint,
method: RequestMethod_1.RequestMethod.POST,
data: request.data || constants_1.Defaults.Object.Value,
// params: request.params || Defaults.Object.Value,
headers: Object.assign({}, headers),
};
if (!process.env.ENABLE_CLIENT_SECRET_AUTH) {
// logInfo({ url, config }, '--- serviceInstanceApi ---')
const { data } = await api_util_1.default.callApi(config);
return data;
}
if (!this._apiInstance) {
throw new Error("client id or secret missing");
}
if (request === null || request === void 0 ? void 0 : request.baseUrl) {
config = Object.assign(Object.assign({}, config), { baseURL: request === null || request === void 0 ? void 0 : request.baseUrl });
}
if (request === null || request === void 0 ? void 0 : request.responseType) {
config = Object.assign(Object.assign({}, config), { responseType: request === null || request === void 0 ? void 0 : request.responseType });
}
const { url, data: payload } = config, rest = __rest(config, ["url", "data"]);
const newConfig = Object.assign({}, rest);
const response = await this._apiInstance.post(url, payload, newConfig);
if ((request === null || request === void 0 ? void 0 : request.responseType) === 'arraybuffer') { // To handle response returning bytes stream.
return { data: response === null || response === void 0 ? void 0 : response.data, headers: response === null || response === void 0 ? void 0 : response.headers };
}
return response === null || response === void 0 ? void 0 : response.data;
}
/**
* PUT request handler
* Handles a PUT request using the provided API parameters.
*
* @param request - The IApiParams object containing request details such as endpoint, data, headers, and cookies.
* @returns A Promise that resolves to the result of the API call.
* @throws An error if client ID or secret is missing when client secret authentication is enabled.
*/
async put(request) {
//const requestHeaders: any = request.headers || Defaults.Object.Value
const headers = await this.authorizationHeaderFromRequestCookies(request.cookies, request.headers, this.cacheManager);
let config = {
url: request.endpoint,
method: RequestMethod_1.RequestMethod.PUT,
data: request.data || constants_1.Defaults.Object.Value,
// params: request.params || Defaults.Object.Value,
headers: Object.assign({}, headers),
};
if (!process.env.ENABLE_CLIENT_SECRET_AUTH) {
// logInfo({ url, config }, '--- serviceInstanceApi ---')
const { data } = await api_util_1.default.callApi(config);
return data;
}
if (!this._apiInstance) {
throw new Error("client id or secret missing");
}
if (request === null || request === void 0 ? void 0 : request.baseUrl) {
config = Object.assign(Object.assign({}, config), { baseURL: request === null || request === void 0 ? void 0 : request.baseUrl });
}
const { url, data: payload } = config, rest = __rest(config, ["url", "data"]);
const { data } = await this._apiInstance.put(url, payload, Object.assign({}, rest));
return data;
}
/**
* Handles a DELETE request using the provided API parameters.
*
* @param request - The IApiParams object containing request details such as endpoint, data, headers, and cookies.
* @returns A Promise that resolves to the result of the API call.
* @throws An error if client ID or secret is missing when client secret authentication is enabled.
*/
async delete(request) {
//const requestHeaders: any = request.headers || Defaults.Object.Value
const headers = await this.authorizationHeaderFromRequestCookies(request.cookies, request.headers, this.cacheManager);
let config = {
url: request.endpoint,
method: RequestMethod_1.RequestMethod.DELETE,
data: request.data || constants_1.Defaults.Object.Value,
// params: request.params || Defaults.Object.Value,
headers: Object.assign({}, headers),
};
if (!process.env.ENABLE_CLIENT_SECRET_AUTH) {
// logInfo({ url, config }, '--- serviceInstanceApi ---')
const { data } = await api_util_1.default.callApi(config);
return data;
}
if (!this._apiInstance) {
throw new Error("client id or secret missing");
}
if (request === null || request === void 0 ? void 0 : request.baseUrl) {
config = Object.assign(Object.assign({}, config), { baseURL: request === null || request === void 0 ? void 0 : request.baseUrl });
}
const { url, data: payload } = config, rest = __rest(config, ["url", "data"]);
const newConfig = Object.assign({}, rest);
const { data } = await this._apiInstance.delete(url, config);
return data;
}
/**
* PATCH request handler
* Handles a PATCH request using the provided API parameters.
*
* @param request - The IApiParams object containing request details such as endpoint, data, headers, and cookies.
* @returns A Promise that resolves to the result of the API call.
* @throws An error if client ID or secret is missing when client secret authentication is enabled.
*/
async patch(request) {
//const requestHeaders: any = request.headers || Defaults.Object.Value
const headers = await this.authorizationHeaderFromRequestCookies(request.cookies, request.headers, this.cacheManager);
let config = {
url: request.endpoint,
method: RequestMethod_1.RequestMethod.PATCH,
data: request.data || constants_1.Defaults.Object.Value,
// params: request.params || Defaults.Object.Value,
headers: Object.assign({}, headers),
};
if (!process.env.ENABLE_CLIENT_SECRET_AUTH) {
// logInfo({ url, config }, '--- serviceInstanceApi ---')
const { data } = await api_util_1.default.callApi(config);
return data;
}
if (!this._apiInstance) {
throw new Error("client id or secret missing");
}
if (request === null || request === void 0 ? void 0 : request.baseUrl) {
config = Object.assign(Object.assign({}, config), { baseURL: request === null || request === void 0 ? void 0 : request.baseUrl });
}
const { url, data: payload } = config, rest = __rest(config, ["url", "data"]);
const { data } = await this._apiInstance.put(url, payload, Object.assign({}, rest));
return data;
}
/**
* Handles errors by logging them and returning the error response to the caller.
* If the error is an HTTP 401, it also clears the site data (cookies, storage, and cache).
* @param error The error to be handled.
*/
errorResponse(error) {
var _a;
console.log('---errorResponse---', parse_util_1.default.jsonStringify(error));
app_util_1.default.logError(error);
if (error === null || error === void 0 ? void 0 : error.response) {
const { status, data } = (_a = error === null || error === void 0 ? void 0 : error.response) !== null && _a !== void 0 ? _a : constants_1.Defaults.Object.Value;
let response = server_1.NextResponse.json({ error: data }, { status, });
// If HTTP 401 is returned, clear site data (cookies, storage, and cache)
if (status === axios_1.HttpStatusCode.Unauthorized) {
response.headers.set('Clear-Site-Data', '"cookies", "storage", "cache"'); // Clear site data (cookies, storage, and cache)
return response;
}
return response;
}
return server_1.NextResponse.json({ error }, { status: axios_1.HttpStatusCode.InternalServerError, });
//return this.nullResponse()
}
/**
* Returns a 200 response with a null body.
*/
nullResponse() {
return server_1.NextResponse.json(null);
}
}
exports.default = ApiController;