diff --git a/index.d.ts b/index.d.ts index 4048a71..837c3d5 100644 --- a/index.d.ts +++ b/index.d.ts @@ -32,6 +32,7 @@ export namespace sql { export { trimSql as trim }; } import parseCookies = require("./package-shared/utils/backend/parseCookies"); +import httpRequest = require("./package-shared/functions/backend/httpRequest"); import uploadImage = require("./utils/upload-image"); import uploadFile = require("./utils/upload-file"); import deleteFile = require("./utils/delete-file"); @@ -69,5 +70,6 @@ export declare namespace utils { }) => string; } export { parseCookies }; + export { httpRequest }; } export { get, post, getSchema, datasquirelClient as client }; diff --git a/index.js b/index.js index a23709a..927d3c1 100644 --- a/index.js +++ b/index.js @@ -32,6 +32,7 @@ const sqlInsertGenerator = require("./package-shared/functions/dsql/sql/sql-inse const sqlDeleteGenerator = require("./package-shared/functions/dsql/sql/sql-delete-generator"); const trimSql = require("./package-shared/utils/trim-sql"); const parseCookies = require("./package-shared/utils/backend/parseCookies"); +const httpRequest = require("./package-shared/functions/backend/httpRequest"); //////////////////////////////////////// //////////////////////////////////////// @@ -96,6 +97,7 @@ const datasquirel = { hash: require("./package-shared/functions/dsql/hashPassword"), }, parseCookies, + httpRequest, }, }; diff --git a/package-shared/functions/backend/httpRequest.d.ts b/package-shared/functions/backend/httpRequest.d.ts new file mode 100644 index 0000000..a2c6871 --- /dev/null +++ b/package-shared/functions/backend/httpRequest.d.ts @@ -0,0 +1,10 @@ +export type HttpRequestExtraParams = { + scheme?: "http" | "https"; + body?: { + [x: string]: any; + }; + query?: { + [x: string]: any; + }; + urlEncodedFormBody?: boolean; +}; diff --git a/package-shared/functions/backend/httpRequest.js b/package-shared/functions/backend/httpRequest.js new file mode 100644 index 0000000..f815ca1 --- /dev/null +++ b/package-shared/functions/backend/httpRequest.js @@ -0,0 +1,106 @@ +// @ts-check + +import http from "node:http"; +import https from "node:https"; +import querystring from "querystring"; +import serializeQuery from "../../utils/serialize-query"; +import _ from "lodash"; + +/** + * @typedef {object} HttpRequestExtraParams + * @property {"http" | "https"} [scheme] + * @property {Object} [body] + * @property {Object} [query] + * @property {boolean} [urlEncodedFormBody] + */ + +/** + * # Generate a http Request + * @param {import("node:https").RequestOptions & HttpRequestExtraParams} params + * + * @returns { Promise | string | null> } + */ +async function httpRequest(params) { + return new Promise((resolve, reject) => { + const isUrlEncodedFormBody = params.urlEncodedFormBody; + + const reqPayloadString = params.body + ? isUrlEncodedFormBody + ? querystring.stringify(params.body) + : JSON.stringify(params.body).replace(/\n|\r|\n\r/gm, "") + : undefined; + + const reqQueryString = params.query + ? serializeQuery(params.query) + : undefined; + + const paramScheme = params.scheme; + const finalScheme = paramScheme == "http" ? http : https; + + const finalPath = params.path + ? params.path + (reqQueryString ? reqQueryString : "") + : undefined; + + delete params.body; + delete params.scheme; + delete params.query; + delete params.urlEncodedFormBody; + + /** @type {import("node:https").RequestOptions} */ + const requestOptions = { + ...params, + headers: { + "Content-Type": isUrlEncodedFormBody + ? "application/x-www-form-urlencoded" + : "application/json", + "Content-Length": reqPayloadString + ? Buffer.from(reqPayloadString).length + : undefined, + ...params.headers, + }, + port: paramScheme == "https" ? 443 : params.port, + path: finalPath, + }; + + const httpsRequest = finalScheme.request( + requestOptions, + /** + * Callback Function + * + * @description https request callback + */ + (response) => { + var str = ""; + + response.on("data", function (chunk) { + str += chunk; + }); + + response.on("end", function () { + try { + resolve(JSON.parse(str)); + } catch (/** @type {any} */ error) { + console.log("Route ERROR:", error.message); + resolve(null); + } + }); + + response.on("error", (err) => { + resolve(null); + }); + } + ); + + if (reqPayloadString) { + httpsRequest.write(reqPayloadString); + } + + httpsRequest.on("error", (error) => { + console.log("HTTPS request ERROR =>", error); + }); + + httpsRequest.end(); + }); +} + +module.exports = httpRequest; diff --git a/package.json b/package.json index 622eebf..e5c4445 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@moduletrace/datasquirel", - "version": "3.3.0", + "version": "3.3.1", "description": "Cloud-based SQL data management tool", "main": "index.js", "bin": {