Skip to content

Instantly share code, notes, and snippets.

@rajivnarayana
Created January 20, 2022 11:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rajivnarayana/b59f110a83d137ab408004a795777919 to your computer and use it in GitHub Desktop.
Save rajivnarayana/b59f110a83d137ab408004a795777919 to your computer and use it in GitHub Desktop.
A No dependency NodeJS requests library.
import FormData from "form-data";
import { APIError } from "../utils/api-error";
const querystring = require("querystring");
function onRequestComplete(resolve, reject) {
return (res) => {
const contentType = res.headers.hasOwnProperty("content-type")
? { "application/json": "json", "text/xml": "xml" }[
res.headers["content-type"]
] || "binary"
: "unknown";
const success = res.statusCode < 300;
const data: Uint8Array[] = [];
res.on("data", (chunk) => data.push(chunk));
res.on("end", () => {
if (success) {
if (contentType == "xml") {
const { soap } = require("strong-soap");
const xmlHandler = new soap.XMLHandler();
return resolve(
xmlHandler.xmlToJson(null, Buffer.concat(data).toString(), null)
);
} else if (contentType == "json" || contentType == "unknown") {
const str = Buffer.concat(data).toString();
try {
return resolve(JSON.parse(str));
} catch (err) {
console.log("Could not parse JSON:", str);
return reject(
new APIError("JSON_PARSE_ERROR", "Error parsing JSON response")
);
}
} else {
return resolve(Buffer.concat(data));
}
} else {
const str = Buffer.concat(data).toString();
reject(new Error(str));
}
});
};
}
export async function post(
url: string,
{
body,
headers,
form,
bodyText,
}: {
body?: any;
headers?: Record<string, string>;
form?: Record<string, any>;
bodyText?: string;
}
) {
if (!url) {
throw new Error("URL is required to post data");
}
if (body) {
return await postJSONBody(url, headers, body);
} else if (form) {
return await postFormBody(url, headers, form);
} else if (bodyText) {
return await postStringBody(url, headers, bodyText);
}
throw new Error("No body or form provided");
}
async function postJSONBody(url, headers, body) {
const http = url.startsWith("http://") ? require("http") : require("https");
return new Promise((resolve, reject) => {
const data = JSON.stringify(body);
const options = {
method: "POST",
headers: {
"Content-Type": "application/json",
"Content-Length": Buffer.byteLength(data),
...headers,
},
};
const req = http.request(url, options, onRequestComplete(resolve, reject));
req.on("error", (error) => {
console.error(error);
reject(new Error(error.message));
});
req.write(data);
req.end();
});
}
async function postFormBody(url, headers, form) {
const http = url.startsWith("http://") ? require("http") : require("https");
return new Promise((resolve, reject) => {
let formData: FormData;
if (!(form instanceof FormData)) {
formData = new FormData();
for (const key in form) {
if (form.hasOwnProperty(key)) {
formData.append(key, form[key]);
}
}
} else {
formData = form;
}
const options = {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
...headers,
...formData.getHeaders(),
},
};
const req = http.request(url, options, onRequestComplete(resolve, reject));
req.on("error", (error) => {
console.error(error);
reject(new Error(error.message));
});
formData.pipe(req);
req.end();
// formData.submit(req);
});
}
async function postStringBody(url, headers, data) {
const http = url.startsWith("http://") ? require("http") : require("https");
return new Promise((resolve, reject) => {
const options = {
method: "POST",
headers: {
"Content-Type": "text/plain",
"Content-Length": Buffer.byteLength(data),
...headers,
},
};
const req = http.request(url, options, onRequestComplete(resolve, reject));
req.on("error", (error) => {
console.error(error);
reject(new Error(error.message));
});
req.write(data);
req.end();
});
}
export async function get(url: string, headers: any = {}, qs: any = null) {
let get_request_args = querystring.stringify(qs);
const http = url.startsWith("http://") ? require("http") : require("https");
return new Promise((resolve, reject) => {
const options = {
method: "GET",
headers: { ...headers },
};
const req = http.request(
`${url}?${get_request_args}`,
options,
onRequestComplete(resolve, reject)
);
req.on("error", (error) => {
console.error(error);
reject(new Error(error.message));
});
req.end();
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment