UNPKG

@iamnnort/request

Version:

Request handler for Node.js - Fast - Interactive - Simple

546 lines (539 loc) 16.8 kB
// 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