Skip to content

Commit

Permalink
Fix response body type for parse: none
Browse files Browse the repository at this point in the history
Fixes # 62

Fix response body type for parse: none to be Buffer
Add parse: string to explicitly ask for body as a string
Add types for string parsing
Add tests for Buffer and string bodies
Regenerate documentation
  • Loading branch information
jdforsythe committed Mar 2, 2021
1 parent 545c98d commit d4d0a74
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 36 deletions.
4 changes: 2 additions & 2 deletions docs/global.html
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ <h5 class="subsection-title">Properties:</h5>
</td>


<td class="description last">Response parsing. Errors will be given if the response can't be parsed. ('none', 'json')</td>
<td class="description last">Response parsing. Errors will be given if the response can't be parsed. 'none' returns body as a `Buffer`, 'json' attempts to parse the body as JSON, and 'string' attempts to parse the body as a string</td>
</tr>


Expand Down Expand Up @@ -1084,7 +1084,7 @@ <h2><a href="index.html">Home</a></h2><h3>Global</h3><ul><li><a href="global.htm
<br class="clear">

<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Mon Jun 03 2019 19:40:29 GMT-0700 (Pacific Daylight Time)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Mon Mar 01 2021 20:21:46 GMT-0500 (EST)
</footer>

<script> prettyPrint(); </script>
Expand Down
33 changes: 14 additions & 19 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,16 @@ <h3> </h3>

<hr>
<blockquote>
<p>The ultra-lightweight Node.js HTTP client</p>
<p>The lightweight Node.js HTTP client</p>
</blockquote>
<p><a href="https://ethanent.github.io/phin/">Full documentation</a> | <a href="https://github.com/ethanent/phin">GitHub</a> | <a href="https://www.npmjs.com/package/phin">NPM</a></p>
<p><a href="https://ethanent.github.io/phin/global.html">Full documentation</a> | <a href="https://github.com/ethanent/phin">GitHub</a> | <a href="https://www.npmjs.com/package/phin">NPM</a></p>
<h2>Simple Usage</h2><pre class="prettyprint source lang-javascript"><code>const p = require('phin')

const res = await p('https://ethanent.me')

console.log(res.body)</code></pre><p>Note that the above should be in an async context! phin also provides an unpromisified version of the library.</p>
<h2>Install</h2><pre class="prettyprint source"><code>npm install phin</code></pre><h2>Why phin?</h2><p>phin is <strong>trusted</strong> by some really important projects. The hundreds of contributors at <a href="https://github.com/less/less.js">Less</a>, for example, depend on phin as part of their development process.</p>
<p>Also, phin is super <strong>lightweight</strong>. Like <strong>99.8% smaller than request</strong> lightweight. To compare to other libraries, see <a href="https://github.com/ethanent/phin/blob/master/README.md#phin-vs-the-competition">phin vs. the Competition</a>.</p>
<p><img src="https://pbs.twimg.com/media/DSPF9TaUQAA0tIe.jpg:large" alt="phin became 33% lighter with release 2.7.0!"/></p>
console.log(res.body)</code></pre><p>Note that the above should be in an async context! Phin also provides an unpromisified version of the library.</p>
<h2>Install</h2><pre class="prettyprint source"><code>npm install phin</code></pre><h2>Why Phin?</h2><p>Phin is relied upon by important projects and large companies. The hundreds of contributors at <a href="https://github.com/less/less.js">Less</a>, for example, depend on Phin as part of their development process.</p>
<p>Also, Phin is very lightweight. To compare to other libraries, see <a href="https://github.com/ethanent/phin/blob/master/README.md#phin-vs-the-competition">Phin vs. the Competition</a>.</p>
<h2>Quick Demos</h2><p>Simple POST:</p>
<pre class="prettyprint source lang-js"><code>await p({
url: 'https://ethanent.me',
Expand Down Expand Up @@ -88,15 +87,15 @@ <h2>Quick Demos</h2><p>Simple POST:</p>
const res = await ppostjson('https://ethanent.me/somejson')
// ^ An options object could also be used here to set other options.

// Do things with res.body?</code></pre><h3>Custom Core HTTP Options</h3><p>phin allows you to set <a href="https://nodejs.org/api/http.html#http_http_request_url_options_callback">core HTTP options</a>.</p>
// Do things with res.body?</code></pre><h3>Custom Core HTTP Options</h3><p>Phin allows you to set <a href="https://nodejs.org/api/http.html#http_http_request_url_options_callback">core HTTP options</a>.</p>
<pre class="prettyprint source lang-js"><code>await p({
'url': 'https://ethanent.me/name',
'core': {
'agent': myAgent // Assuming you'd already created myAgent earlier.
}
})</code></pre><h2>Full Documentation</h2><p>There's a lot more which can be done with the phin library.</p>
<p>See <a href="https://ethanent.github.io/phin/">the phin documentation</a>.</p>
<h2>phin vs. the Competition</h2><p>phin is a very lightweight library, yet it contains all of the common HTTP client features included in competing libraries!</p>
})</code></pre><h2>Full Documentation</h2><p>There's a lot more which can be done with the Phin library.</p>
<p>See <a href="https://ethanent.github.io/phin/global.html">the Phin documentation</a>.</p>
<h2>Phin vs. the Competition</h2><p>Phin is a very lightweight library, yet it contains all of the common HTTP client features included in competing libraries!</p>
<p>Here's a size comparison table:</p>
<table>
<thead>
Expand All @@ -115,16 +114,16 @@ <h2>phin vs. the Competition</h2><p>phin is a very lightweight library, yet it c
<td><a href="https://packagephobia.now.sh/result?p=superagent"><img src="https://packagephobia.now.sh/badge?p=superagent" alt="superagent package size"></a></td>
</tr>
<tr>
<td>isomorphic-fetch</td>
<td><a href="https://packagephobia.now.sh/result?p=isomorphic-fetch"><img src="https://packagephobia.now.sh/badge?p=isomorphic-fetch" alt="isomorphic-fetch package size"></a></td>
<td>got</td>
<td><a href="https://packagephobia.now.sh/result?p=got"><img src="https://packagephobia.now.sh/badge?p=got" alt="got package size"></a></td>
</tr>
<tr>
<td>axios</td>
<td><a href="https://packagephobia.now.sh/result?p=axios"><img src="https://packagephobia.now.sh/badge?p=axios" alt="axios package size"></a></td>
</tr>
<tr>
<td>got</td>
<td><a href="https://packagephobia.now.sh/result?p=got"><img src="https://packagephobia.now.sh/badge?p=got" alt="got package size"></a></td>
<td>isomorphic-fetch</td>
<td><a href="https://packagephobia.now.sh/result?p=isomorphic-fetch"><img src="https://packagephobia.now.sh/badge?p=isomorphic-fetch" alt="isomorphic-fetch package size"></a></td>
</tr>
<tr>
<td>r2</td>
Expand All @@ -135,10 +134,6 @@ <h2>phin vs. the Competition</h2><p>phin is a very lightweight library, yet it c
<td><a href="https://packagephobia.now.sh/result?p=node-fetch"><img src="https://packagephobia.now.sh/badge?p=node-fetch" alt="node-fetch package size"></a></td>
</tr>
<tr>
<td>snekfetch</td>
<td><a href="https://packagephobia.now.sh/result?p=snekfetch"><img src="https://packagephobia.now.sh/badge?p=snekfetch" alt="snekfetch package size"></a></td>
</tr>
<tr>
<td>phin</td>
<td><a href="https://packagephobia.now.sh/result?p=phin"><img src="https://packagephobia.now.sh/badge?p=phin" alt="phin package size"></a></td>
</tr>
Expand All @@ -160,7 +155,7 @@ <h2><a href="index.html">Home</a></h2><h3>Global</h3><ul><li><a href="global.htm
<br class="clear">

<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Mon Jun 03 2019 19:40:29 GMT-0700 (Pacific Daylight Time)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Mon Mar 01 2021 20:21:46 GMT-0500 (EST)
</footer>

<script> prettyPrint(); </script>
Expand Down
34 changes: 26 additions & 8 deletions docs/phin.js.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ <h1 class="page-title">Source: phin.js</h1>
* @property {Object} [form] - Object to send as form data (sets 'Content-Type' and 'Content-Length' headers, as well as request body) (overwrites 'data' option if present)
* @property {Object} [headers={}] - Request headers
* @property {Object} [core={}] - Custom core HTTP options
* @property {string} [parse=none] - Response parsing. Errors will be given if the response can't be parsed. ('none', 'json')
* @property {string} [parse=none] - Response parsing. Errors will be given if the response can't be parsed. 'none' returns body as a `Buffer`, 'json' attempts to parse the body as JSON, and 'string' attempts to parse the body as a string
* @property {boolean} [followRedirects=false] - Enable HTTP redirect following
* @property {boolean} [stream=false] - Enable streaming of response. (Removes body property)
* @property {boolean} [compression=false] - Enable compression for request
Expand Down Expand Up @@ -99,12 +99,20 @@ <h1 class="page-title">Source: phin.js</h1>
else {
res.coreRes.body = res.body

if (opts.parse &amp;&amp; opts.parse === 'json') {
res.coreRes.body = await res.json()

return res.coreRes
if (opts.parse) {
if (opts.parse === 'json') {
res.coreRes.body = await res.json()

return res.coreRes
}
else if (opts.parse === 'string') {
res.coreRes.body = res.coreRes.body.toString()

return res.coreRes
}
}
else return res.coreRes

return res.coreRes
}
}

Expand All @@ -122,7 +130,17 @@ <h1 class="page-title">Source: phin.js</h1>

// Defaults

phin.defaults = (defaultOpts) => async (opts) => await phin(Object.assign(defaultOpts, typeof opts === 'string' ? {'url': opts} : opts))
phin.defaults = (defaultOpts) => async (opts) => {
const nops = typeof opts === 'string' ? {'url': opts} : opts

Object.keys(defaultOpts).forEach((doK) => {
if (!nops.hasOwnProperty(doK) || nops[doK] === null) {
nops[doK] = defaultOpts[doK]
}
})

return await phin(nops)
}

module.exports = phin
</code></pre>
Expand All @@ -141,7 +159,7 @@ <h2><a href="index.html">Home</a></h2><h3>Global</h3><ul><li><a href="global.htm
<br class="clear">

<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Mon Jun 03 2019 19:40:29 GMT-0700 (Pacific Daylight Time)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Mon Mar 01 2021 20:21:46 GMT-0500 (EST)
</footer>

<script> prettyPrint(); </script>
Expand Down
20 changes: 14 additions & 6 deletions lib/phin.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const centra = require('centra')
* @property {Object} [form] - Object to send as form data (sets 'Content-Type' and 'Content-Length' headers, as well as request body) (overwrites 'data' option if present)
* @property {Object} [headers={}] - Request headers
* @property {Object} [core={}] - Custom core HTTP options
* @property {string} [parse=none] - Response parsing. Errors will be given if the response can't be parsed. ('none', 'json')
* @property {string} [parse=none] - Response parsing. Errors will be given if the response can't be parsed. 'none' returns body as a `Buffer`, 'json' attempts to parse the body as JSON, and 'string' attempts to parse the body as a string
* @property {boolean} [followRedirects=false] - Enable HTTP redirect following
* @property {boolean} [stream=false] - Enable streaming of response. (Removes body property)
* @property {boolean} [compression=false] - Enable compression for request
Expand Down Expand Up @@ -71,12 +71,20 @@ const phin = async (opts) => {
else {
res.coreRes.body = res.body

if (opts.parse && opts.parse === 'json') {
res.coreRes.body = await res.json()

return res.coreRes
if (opts.parse) {
if (opts.parse === 'json') {
res.coreRes.body = await res.json()

return res.coreRes
}
else if (opts.parse === 'string') {
res.coreRes.body = res.coreRes.body.toString()

return res.coreRes
}
}
else return res.coreRes

return res.coreRes
}
}

Expand Down
38 changes: 38 additions & 0 deletions tests/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,44 @@ w.add('Parse JSON', (result) => {
})
})

w.add('Parse string', (result) => {
p({
'url': 'http://localhost:5136/testget',
'method': 'GET',
'parse': 'string',
}, (err, res) => {
if (!err && typeof res.body === 'string' && res.body === 'Hi.') {
result(true, 'Parsed string properly.')
}
else result(false, 'Failed to parse string.')
})
})

w.add('Parse "none" returns Buffer', (result) => {
p({
'url': 'http://localhost:5136/testget',
'method': 'GET',
'parse': 'none',
}, (err, res) => {
if (!err && res.body instanceof Buffer && Buffer.from('Hi.').equals(res.body)) {
result(true, 'Buffer returned properly.')
}
else result(false, 'Failed to return Buffer.')
})
})

w.add('Default no parse returns Buffer', (result) => {
p({
'url': 'http://localhost:5136/testget',
'method': 'GET',
}, (err, res) => {
if (!err && res.body instanceof Buffer && Buffer.from('Hi.').equals(res.body)) {
result(true, 'Buffer returned properly.')
}
else result(false, 'Failed to return Buffer.')
})
})

w.add('Send object', (result) => {
p({
'url': 'http://localhost:5136/testjson',
Expand Down
22 changes: 21 additions & 1 deletion types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ declare function phin<T>(options:
IWithData<phin.IJSONResponseOptions> |
IWithForm<phin.IJSONResponseOptions>): Promise<phin.IJSONResponse<T>>

declare function phin(options:
phin.IStringResponseOptions |
IWithData<phin.IStringResponseOptions> |
IWithForm<phin.IStringResponseOptions>): Promise<phin.IStringResponse>

declare function phin(options:
phin.IStreamResponseOptions |
IWithData<phin.IStreamResponseOptions> |
Expand All @@ -51,6 +56,10 @@ declare namespace phin {
parse: 'json'
}

export interface IStringResponseOptions extends IOptionsBase {
parse: 'string';
}

export interface IStreamResponseOptions extends IOptionsBase {
stream: true
}
Expand All @@ -63,12 +72,16 @@ declare namespace phin {
body: T
}

export interface IStringResponse extends http.IncomingMessage {
body: string;
}

export interface IStreamResponse extends http.IncomingMessage {
stream: http.IncomingMessage
}

export interface IResponse extends http.IncomingMessage {
body: string
body: Buffer;
}

// NOTE: Typescript cannot infer type of union callback on the consumer side
Expand All @@ -85,6 +98,13 @@ declare namespace phin {
IWithForm<IJSONResponseOptions>,
callback: IErrorCallback | ICallback<IJSONResponse<T>>): void

export function unpromisified(
options:
IStringResponseOptions |
IWithData<IStringResponseOptions> |
IWithForm<IStringResponseOptions>,
callback: IErrorCallback | ICallback<IStringResponse>): void

export function unpromisified(
options:
IStreamResponseOptions |
Expand Down

0 comments on commit d4d0a74

Please sign in to comment.