@iamnnort/request
Version:
Request handler for Node.js - Fast - Interactive - Simple
546 lines (539 loc) • 16.8 kB
JavaScript
// src/builder.ts
import { stringify } from "qs";
// src/types.ts
var HttpMethods = /* @__PURE__ */ ((HttpMethods2) => {
HttpMethods2["GET"] = "get";
HttpMethods2["POST"] = "post";
HttpMethods2["PUT"] = "put";
HttpMethods2["DELETE"] = "delete";
return HttpMethods2;
})(HttpMethods || {});
var HttpStatuses = /* @__PURE__ */ ((HttpStatuses2) => {
HttpStatuses2[HttpStatuses2["CONTINUE"] = 100] = "CONTINUE";
HttpStatuses2[HttpStatuses2["SWITCHING_PROTOCOLS"] = 101] = "SWITCHING_PROTOCOLS";
HttpStatuses2[HttpStatuses2["PROCESSING"] = 102] = "PROCESSING";
HttpStatuses2[HttpStatuses2["EARLYHINTS"] = 103] = "EARLYHINTS";
HttpStatuses2[HttpStatuses2["OK"] = 200] = "OK";
HttpStatuses2[HttpStatuses2["CREATED"] = 201] = "CREATED";
HttpStatuses2[HttpStatuses2["ACCEPTED"] = 202] = "ACCEPTED";
HttpStatuses2[HttpStatuses2["NON_AUTHORITATIVE_INFORMATION"] = 203] = "NON_AUTHORITATIVE_INFORMATION";
HttpStatuses2[HttpStatuses2["NO_CONTENT"] = 204] = "NO_CONTENT";
HttpStatuses2[HttpStatuses2["RESET_CONTENT"] = 205] = "RESET_CONTENT";
HttpStatuses2[HttpStatuses2["PARTIAL_CONTENT"] = 206] = "PARTIAL_CONTENT";
HttpStatuses2[HttpStatuses2["AMBIGUOUS"] = 300] = "AMBIGUOUS";
HttpStatuses2[HttpStatuses2["MOVED_PERMANENTLY"] = 301] = "MOVED_PERMANENTLY";
HttpStatuses2[HttpStatuses2["FOUND"] = 302] = "FOUND";
HttpStatuses2[HttpStatuses2["SEE_OTHER"] = 303] = "SEE_OTHER";
HttpStatuses2[HttpStatuses2["NOT_MODIFIED"] = 304] = "NOT_MODIFIED";
HttpStatuses2[HttpStatuses2["TEMPORARY_REDIRECT"] = 307] = "TEMPORARY_REDIRECT";
HttpStatuses2[HttpStatuses2["PERMANENT_REDIRECT"] = 308] = "PERMANENT_REDIRECT";
HttpStatuses2[HttpStatuses2["BAD_REQUEST"] = 400] = "BAD_REQUEST";
HttpStatuses2[HttpStatuses2["UNAUTHORIZED"] = 401] = "UNAUTHORIZED";
HttpStatuses2[HttpStatuses2["PAYMENT_REQUIRED"] = 402] = "PAYMENT_REQUIRED";
HttpStatuses2[HttpStatuses2["FORBIDDEN"] = 403] = "FORBIDDEN";
HttpStatuses2[HttpStatuses2["NOT_FOUND"] = 404] = "NOT_FOUND";
HttpStatuses2[HttpStatuses2["METHOD_NOT_ALLOWED"] = 405] = "METHOD_NOT_ALLOWED";
HttpStatuses2[HttpStatuses2["NOT_ACCEPTABLE"] = 406] = "NOT_ACCEPTABLE";
HttpStatuses2[HttpStatuses2["PROXY_AUTHENTICATION_REQUIRED"] = 407] = "PROXY_AUTHENTICATION_REQUIRED";
HttpStatuses2[HttpStatuses2["REQUEST_TIMEOUT"] = 408] = "REQUEST_TIMEOUT";
HttpStatuses2[HttpStatuses2["CONFLICT"] = 409] = "CONFLICT";
HttpStatuses2[HttpStatuses2["GONE"] = 410] = "GONE";
HttpStatuses2[HttpStatuses2["LENGTH_REQUIRED"] = 411] = "LENGTH_REQUIRED";
HttpStatuses2[HttpStatuses2["PRECONDITION_FAILED"] = 412] = "PRECONDITION_FAILED";
HttpStatuses2[HttpStatuses2["PAYLOAD_TOO_LARGE"] = 413] = "PAYLOAD_TOO_LARGE";
HttpStatuses2[HttpStatuses2["URI_TOO_LONG"] = 414] = "URI_TOO_LONG";
HttpStatuses2[HttpStatuses2["UNSUPPORTED_MEDIA_TYPE"] = 415] = "UNSUPPORTED_MEDIA_TYPE";
HttpStatuses2[HttpStatuses2["REQUESTED_RANGE_NOT_SATISFIABLE"] = 416] = "REQUESTED_RANGE_NOT_SATISFIABLE";
HttpStatuses2[HttpStatuses2["EXPECTATION_FAILED"] = 417] = "EXPECTATION_FAILED";
HttpStatuses2[HttpStatuses2["I_AM_A_TEAPOT"] = 418] = "I_AM_A_TEAPOT";
HttpStatuses2[HttpStatuses2["MISDIRECTED"] = 421] = "MISDIRECTED";
HttpStatuses2[HttpStatuses2["UNPROCESSABLE_ENTITY"] = 422] = "UNPROCESSABLE_ENTITY";
HttpStatuses2[HttpStatuses2["FAILED_DEPENDENCY"] = 424] = "FAILED_DEPENDENCY";
HttpStatuses2[HttpStatuses2["PRECONDITION_REQUIRED"] = 428] = "PRECONDITION_REQUIRED";
HttpStatuses2[HttpStatuses2["TOO_MANY_REQUESTS"] = 429] = "TOO_MANY_REQUESTS";
HttpStatuses2[HttpStatuses2["INTERNAL_SERVER_ERROR"] = 500] = "INTERNAL_SERVER_ERROR";
HttpStatuses2[HttpStatuses2["NOT_IMPLEMENTED"] = 501] = "NOT_IMPLEMENTED";
HttpStatuses2[HttpStatuses2["BAD_GATEWAY"] = 502] = "BAD_GATEWAY";
HttpStatuses2[HttpStatuses2["SERVICE_UNAVAILABLE"] = 503] = "SERVICE_UNAVAILABLE";
HttpStatuses2[HttpStatuses2["GATEWAY_TIMEOUT"] = 504] = "GATEWAY_TIMEOUT";
HttpStatuses2[HttpStatuses2["HTTP_VERSION_NOT_SUPPORTED"] = 505] = "HTTP_VERSION_NOT_SUPPORTED";
return HttpStatuses2;
})(HttpStatuses || {});
// src/builder.ts
var RequestBuilder = class {
baseConfig;
requestConfig;
config;
constructor(params) {
this.baseConfig = params.baseConfig;
this.requestConfig = params.requestConfig;
this.config = {
timeout: params.requestConfig.timeout || params.baseConfig.timeout,
responseType: params.requestConfig.responseType || params.baseConfig.responseType,
headers: {
Accept: "application/json",
"Content-Type": "application/json",
...params.baseConfig.headers,
...params.requestConfig.headers
}
};
}
makeContentType() {
if (this.requestConfig.multipart) {
this.config = {
...this.config,
headers: {
...this.config.headers,
"Content-Type": "multipart/form-data"
}
};
return this;
}
if (this.requestConfig.urlencoded) {
this.config = {
...this.config,
headers: {
...this.config.headers,
"Content-Type": "application/x-www-form-urlencoded"
}
};
return this;
}
if (this.requestConfig.xml) {
this.config = {
...this.config,
headers: {
...this.config.headers,
"Content-Type": "text/xml"
}
};
return this;
}
return this;
}
makeAuth() {
const auth = this.requestConfig.auth || this.baseConfig.auth;
if (auth) {
this.config = {
...this.config,
auth
};
return this;
}
const bearerToken = this.requestConfig.bearerToken || this.baseConfig.bearerToken;
if (bearerToken) {
this.config = {
...this.config,
headers: {
...this.config.headers,
Authorization: `Bearer ${bearerToken}`
}
};
return this;
}
const apiKey = this.requestConfig.apiKey || this.baseConfig.apiKey;
if (apiKey) {
this.config = {
...this.config,
headers: {
...this.config.headers,
"x-api-key": apiKey
}
};
return this;
}
return this;
}
makeUrl() {
const baseUrlMap = this.requestConfig.baseUrlMap || this.baseConfig.baseUrlMap;
const baseUrlName = this.requestConfig.baseUrlName || this.baseConfig.baseUrlName;
const urlParts = [
baseUrlMap && baseUrlName ? baseUrlMap[baseUrlName] : this.baseConfig.baseUrl,
this.baseConfig.url,
...this.baseConfig.urlParts || [],
this.requestConfig.baseUrl,
this.requestConfig.url,
...this.requestConfig.urlParts || []
].map((urlPart) => urlPart?.toString());
const isSecureProtocol = urlParts.some((urlPart) => urlPart?.includes("https"));
const protocol = isSecureProtocol ? "https" : "http";
const actualUrlParts = urlParts.filter((urlPart) => urlPart).map((urlPart) => {
return urlPart?.replace(/^(https?:\/\/|\/)?(.*?)(\/?)$/, "$2");
});
const url = `${protocol}://${actualUrlParts.join("/")}`;
this.config = {
...this.config,
url
};
return this;
}
makeMethod() {
this.config = {
...this.config,
method: this.requestConfig.method
};
return this;
}
makeData() {
if (this.requestConfig.method === "get" /* GET */) {
return this;
}
if (this.requestConfig.urlencoded) {
this.config = {
...this.config,
data: stringify(this.requestConfig.data)
};
return this;
}
this.config = {
...this.config,
data: this.requestConfig.data
};
return this;
}
makeParams() {
this.config = {
...this.config,
params: this.requestConfig.params
};
return this;
}
makeSerializer() {
this.config = {
...this.config,
paramsSerializer: (params) => {
return stringify(params, {
arrayFormat: this.baseConfig.serializer?.array || "brackets",
skipNulls: true
});
}
};
return this;
}
build() {
return this.config;
}
};
// src/data-source.ts
import axios from "axios";
// src/logger/builder.ts
import { stringify as stringify2 } from "qs";
var MessageBuilder = class {
printQueue;
request;
response;
error;
config;
constructor(config) {
this.printQueue = [];
this.config = config;
}
setRequest(request) {
this.request = request;
return this;
}
setResponse(response) {
this.response = response;
return this;
}
setError(error) {
this.error = error;
return this;
}
makeType(type) {
this.printQueue.push(`[${type}]`);
return this;
}
makeUrl() {
const url = this.request?.url || this.response?.config?.url || this.error?.response?.config.url;
const params = this.request?.params || this.response?.config?.params || this.error?.response?.config.params;
if (url) {
if (params) {
delete params["0"];
this.printQueue.push(
[
url,
stringify2(params, {
arrayFormat: this.config.serializer?.array || "brackets",
skipNulls: true
})
].filter((_) => _).join("?")
);
} else {
this.printQueue.push(url);
}
}
return this;
}
makeMethodText() {
const method = this.request?.method || this.response?.config?.method || this.error?.response?.config.method;
if (method) {
this.printQueue.push(method.toUpperCase());
}
return this;
}
makeRequestData() {
const data = this.request?.data || this.response?.config?.data || this.error?.response?.config.data;
if (data) {
if (typeof data === "string") {
this.printQueue.push(data);
return this;
}
if (Object.keys(data).length) {
this.printQueue.push(JSON.stringify(data));
return this;
}
}
return this;
}
makeResponseDataText() {
const data = this.response?.data || this.error?.response?.data;
if (data) {
if (typeof data === "string") {
this.printQueue.push(data);
return this;
}
if (Object.keys(data).length) {
this.printQueue.push(JSON.stringify(data));
return this;
}
}
return this;
}
makeStatusText() {
const status = this.response?.status || this.error?.response?.status;
if (status) {
this.printQueue.push(`${status}`);
const statusText = this.response?.statusText || this.error?.response?.statusText;
if (statusText) {
this.printQueue.push(statusText);
}
}
return this;
}
build() {
return this.printQueue.join(" ");
}
makeMethod() {
const method = this.request?.method || this.response?.config?.method || this.error?.response?.config.method;
if (!method) {
return "get" /* GET */;
}
return method.toLowerCase();
}
makeResponseData() {
const data = this.response?.data || this.error?.response?.data;
if (!data) {
return "";
}
if (typeof data === "string") {
return data;
}
return JSON.stringify(data);
}
makeStatus() {
const status = this.response?.status || this.error?.response?.status;
if (!status) {
return 500 /* INTERNAL_SERVER_ERROR */;
}
return status;
}
makeResponse() {
return {
success: this.error === void 0,
status: this.makeStatus(),
method: this.makeMethod(),
data: this.makeResponseData()
};
}
};
// src/logger/service.ts
var LoggerService = class {
config;
constructor(config) {
this.config = config;
}
log(message, context) {
const ctx = context || this.config.name || "";
if (ctx) {
return console.log(`[${ctx}] ${message}`);
}
return console.log(message);
}
logRequest(request) {
const loggerMessageBuilder = new MessageBuilder(this.config);
const message = loggerMessageBuilder.setRequest(request).makeType("Request").makeMethodText().makeUrl().makeRequestData().build();
return this.log(message);
}
logResponse(response) {
const loggerMessageBuilder = new MessageBuilder(this.config);
const message = loggerMessageBuilder.setResponse(response).makeType("Response").makeMethodText().makeUrl().makeRequestData().makeStatusText().makeResponseDataText().build();
return this.log(message);
}
logRequestError(error) {
const loggerMessageBuilder = new MessageBuilder(this.config);
const message = loggerMessageBuilder.setError(error).makeType("Error").makeMethodText().makeUrl().makeRequestData().makeStatusText().makeResponseDataText().build();
return this.log(message);
}
makeResponse(response) {
const loggerMessageBuilder = new MessageBuilder(this.config);
const responseData = loggerMessageBuilder.setResponse(response).makeResponse();
return responseData;
}
makeErrorResponse(error) {
const loggerMessageBuilder = new MessageBuilder(this.config);
const errorResponseData = loggerMessageBuilder.setError(error).makeResponse();
return errorResponseData;
}
};
// src/data-source.ts
var RequestDataSource = class {
baseRequestConfig;
constructor(baseRequestConfig) {
this.baseRequestConfig = baseRequestConfig;
}
common(requestConfig, responseConfig = {}) {
const loggerService = new LoggerService(this.baseRequestConfig);
const requestBuilder = new RequestBuilder({
baseConfig: this.baseRequestConfig,
requestConfig
});
const request = requestBuilder.makeContentType().makeAuth().makeUrl().makeMethod().makeParams().makeData().makeSerializer().build();
if (this.baseRequestConfig.logger) {
loggerService.logRequest(request);
}
return axios.request(request).then((response) => {
if (this.baseRequestConfig.logger) {
loggerService.logResponse(response);
}
if (responseConfig.raw) {
return loggerService.makeResponse(response);
}
return response.data;
}).catch((error) => {
if (this.baseRequestConfig.debug) {
console.log("Error:", error);
}
if (this.baseRequestConfig.logger) {
loggerService.logRequestError(error);
}
if (responseConfig.raw) {
return loggerService.makeErrorResponse(error);
}
throw error.response?.data || error.response || new Error(error.message);
});
}
async *bulkCommon(requestConfig, responseConfig = {}) {
const { params } = requestConfig;
const { bulkCallback } = responseConfig;
const { page, pageSize, bulkSize, ...searchDto } = params || {};
const paginationDto = {
page: page || 1,
pageSize: pageSize || 30
};
const maxPage = bulkSize ? paginationDto.page - 1 + bulkSize : null;
let pagination = {
total: 0,
currentPage: 0,
lastPage: 0,
from: 0,
to: 0,
pageSize: 0
};
do {
const response = await this.common({
...requestConfig,
params: {
...paginationDto,
...searchDto
}
});
pagination = response.pagination;
if (!response.data?.length) {
return;
}
yield response.data;
paginationDto.page += 1;
} while (pagination.currentPage !== pagination.lastPage && pagination.currentPage !== maxPage);
if (pagination.currentPage !== pagination.lastPage) {
if (bulkCallback) {
await bulkCallback(paginationDto.page);
}
}
}
search(config = {}) {
return this.common({
...config,
method: "get" /* GET */
});
}
bulkSearch(config = {}) {
return this.bulkCommon({
...config,
method: "get" /* GET */
});
}
get(id, config = {}) {
return this.common({
...config,
method: "get" /* GET */,
url: id
});
}
create(config) {
return this.common({
...config,
method: "post" /* POST */
});
}
bulkCreate(config) {
return this.common({
...config,
method: "post" /* POST */,
url: "/bulk",
data: {
bulk: config.data
}
});
}
update(id, config) {
return this.common({
...config,
method: "put" /* PUT */,
url: id
});
}
bulkUpdate(config) {
return this.common({
...config,
method: "put" /* PUT */,
url: "/bulk",
data: {
bulk: config.data
}
});
}
remove(id, config = {}) {
return this.common({
...config,
method: "delete" /* DELETE */,
url: id
});
}
};
// src/helper.ts
var RequestHelper = class {
static sleep(seconds) {
return new Promise((resolve) => {
setTimeout(resolve, seconds * 1e3);
});
}
};
export {
HttpMethods,
HttpStatuses,
RequestBuilder,
RequestDataSource,
RequestHelper
};
//# sourceMappingURL=index.mjs.map