Skip to content

Commit

Permalink
feat: add support for stream
Browse files Browse the repository at this point in the history
  • Loading branch information
tbnritzdoge committed Mar 25, 2021
1 parent 3c99e74 commit c706801
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 15 deletions.
61 changes: 47 additions & 14 deletions src/lib/PetitioRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import type ClientType from "undici/types/client";
import type { IncomingHttpHeaders } from "http";
import type { ParsedUrlQueryInput } from "querystring";
import { PetitioResponse } from "./PetitioResponse";
import Stream from "stream";
import { URL } from "url";
import { join } from "path";
import { stringify } from "querystring"; // eslint-disable-line no-duplicate-imports

/**
* Accepted HTTP methods (currently only supports up to HTTP/1.1).
*/
Expand All @@ -34,7 +34,7 @@ export class PetitioRequest {
/**
* The data to be sent as the request body.
*/
public data?: string | Buffer;
public data?: Buffer | string | Stream.Readable;
/**
* @see [[HTTPMethod]]
*/
Expand Down Expand Up @@ -142,16 +142,49 @@ export class PetitioRequest {
* set to the URL encoded version of the query string.
*/
public body(data: ParsedUrlQueryInput | string, sendAs: "form"): this
public body(data: any, sendAs?: "json" | "form"): this {
if (sendAs === "json" || (typeof data === "object" && !Buffer.isBuffer(data))) {
this.reqHeaders["content-type"] = "application/json";
this.data = JSON.stringify(data);
} else if (sendAs === "form") {
this.reqHeaders["content-type"] = "application/x-www-form-urlencoded";
this.data = stringify(data);
} else this.data = data;
this.reqHeaders["content-length"] = Buffer.byteLength(this.data as string | Buffer).toString();

/**
* @param {*} data The data to be set for the request body.
* @param {*} sendAs If data is a stream *AND* this is set to `stream`,
* the body will be sent as is with no modifications such as stringification
* or otherwise.
*/
public body(data: Stream.Readable, sendAs: "stream"): this
public body(data: any, sendAs?: "json" | "form" | "stream"): this {
switch (sendAs) {
case "json": {
this.data = JSON.stringify(data);
this.header({
"content-type": "application/json",
"content-length": Buffer.byteLength(this.data as string | Buffer).toString()
});
break;
}
case "form": {
this.data = stringify(data);
this.header({
"content-type": "application/x-www-form-urlencoded",
"content-length": Buffer.byteLength(this.data as string | Buffer).toString()
});
break;
}
case "stream": {
this.data = data;
break;
}
default: {
if (typeof data === "object" && !Buffer.isBuffer(data)) {
this.data = JSON.stringify(data);
this.header({
"content-type": "application/json",
"content-length": Buffer.byteLength(this.data as string).toString()
});
} else {
this.data = data;
this.header("content-length", Buffer.byteLength(this.data as string | Buffer).toString());
}
break;
}
}
return this;
}

Expand Down Expand Up @@ -215,7 +248,7 @@ export class PetitioRequest {
*/
public option<T extends keyof ClientType.Options>(key: T, value: ClientType.Options[T]): this
public option(key: keyof ClientType.Options | ClientType.Options, value?: any) {
if (typeof key === "object") this.coreOptions = {...this.coreOptions, ...key};
if (typeof key === "object") this.coreOptions = { ...this.coreOptions, ...key };
else this.coreOptions[key] = value;

return this;
Expand Down Expand Up @@ -253,7 +286,7 @@ export class PetitioRequest {
*/
public send(): Promise<PetitioResponse> {
return new Promise((resolve, reject) => {
const options: Client.RequestOptions = {
const options: ClientType.RequestOptions = {
path: this.url.pathname + this.url.search,
method: this.httpMethod,
headers: this.reqHeaders,
Expand Down
37 changes: 36 additions & 1 deletion tests/PetitioRequest.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Client } from "undici";
import { URL as NURL } from "url";
import { PetitioRequest } from "../src/lib/PetitioRequest";
import { Readable } from "stream";
import qs from "querystring";

describe("PetitioRequest", () => {
Expand Down Expand Up @@ -41,11 +42,14 @@ describe("PetitioRequest", () => {

describe("Body", () => {
const body = { hi: "hello" };
const text = "hi";

const bodyString = JSON.stringify(body);
const bodyString2 = qs.stringify(body);
const bodyBuffer = Buffer.from(bodyString);

const bodyStream = Readable.from(text, { objectMode: false });

test("CHECK THAT passed body MATCH RECIEVED stringified body", () => {
expect.assertions(1);

Expand All @@ -58,6 +62,29 @@ describe("PetitioRequest", () => {
expect(response.data).toEqual(bodyString);
});

test("CHECK THAT passed body MATCH RECIEVED stringified body", () => {
expect.assertions(1);

const URL = "https://postman-echo.com/get";

const request = new PetitioRequest(URL);
const response = request
.body(body, "json");

expect(response.data).toEqual(bodyString);
});

test("CHECK THAT passed stream MATCH RECIEVED passed body", () => {
expect.assertions(1);

const URL = "https://postman-echo.com/get";

const request = new PetitioRequest(URL)
.body(bodyStream, "stream");

expect(request.data).toEqual(bodyStream);
});

test("CHECK THAT passed form MATCH RECIEVED form body", () => {
expect.assertions(1);

Expand Down Expand Up @@ -163,12 +190,20 @@ describe("PetitioRequest", () => {
describe("OPTION", () => {
const key = "pipelining";
const val = 10;
test("CHECK THAT post MATCHED SENT post", () => {
const options = { "pipelining": val };
test("CHECK THAT key/val MATCHED SENT key/val", () => {
const req = new PetitioRequest("https://helper.wtf")
.option(key, val);

expect(req.coreOptions[key]).toEqual(val);
});

test("CHECK THAT k/v object MATCHED SENT k/v object", () => {
const req = new PetitioRequest("https://helper.wtf")
.option(options);

expect(req.coreOptions[key]).toEqual(val);
});
});
describe("RAW", () => {
const obj = { test: "test1", test1: "test" };
Expand Down

0 comments on commit c706801

Please sign in to comment.