@hqoss/http-client
Advanced tools
Comparing version 0.1.26-0 to 0.1.27-0
@@ -12,7 +12,27 @@ /// <reference types="node" /> | ||
get: (pathOrUrl: string | URL, reqOpts?: RequestOptions | undefined, telemetry?: EventEmitter | undefined) => Promise<IncomingMessage>; | ||
post: (pathOrUrl: string | URL, data?: string | Readable | Buffer | undefined, reqOpts?: RequestOptions | undefined, telemetry?: EventEmitter | undefined) => Promise<IncomingMessage>; | ||
patch: (pathOrUrl: string | URL, data?: string | Readable | Buffer | undefined, reqOpts?: RequestOptions | undefined, telemetry?: EventEmitter | undefined) => Promise<IncomingMessage>; | ||
put: (pathOrUrl: string | URL, data?: string | Readable | Buffer | undefined, reqOpts?: RequestOptions | undefined, telemetry?: EventEmitter | undefined) => Promise<IncomingMessage>; | ||
delete: (pathOrUrl: string | URL, data?: string | Readable | Buffer | undefined, reqOpts?: RequestOptions | undefined, telemetry?: EventEmitter | undefined) => Promise<IncomingMessage>; | ||
request: (pathOrUrl: string | URL, method: Method, reqOpts?: RequestOptions | undefined, data?: string | Readable | Buffer | undefined, telemetry?: EventEmitter | undefined) => Promise<IncomingMessage>; | ||
post: (pathOrUrl: string | URL, data?: string | Readable | Buffer | (EventEmitter & { | ||
pipe<T extends NodeJS.WritableStream>(destination: T, options?: { | ||
end?: boolean | undefined; | ||
} | undefined): T; | ||
}) | undefined, reqOpts?: RequestOptions | undefined, telemetry?: EventEmitter | undefined) => Promise<IncomingMessage>; | ||
patch: (pathOrUrl: string | URL, data?: string | Readable | Buffer | (EventEmitter & { | ||
pipe<T extends NodeJS.WritableStream>(destination: T, options?: { | ||
end?: boolean | undefined; | ||
} | undefined): T; | ||
}) | undefined, reqOpts?: RequestOptions | undefined, telemetry?: EventEmitter | undefined) => Promise<IncomingMessage>; | ||
put: (pathOrUrl: string | URL, data?: string | Readable | Buffer | (EventEmitter & { | ||
pipe<T extends NodeJS.WritableStream>(destination: T, options?: { | ||
end?: boolean | undefined; | ||
} | undefined): T; | ||
}) | undefined, reqOpts?: RequestOptions | undefined, telemetry?: EventEmitter | undefined) => Promise<IncomingMessage>; | ||
delete: (pathOrUrl: string | URL, data?: string | Readable | Buffer | (EventEmitter & { | ||
pipe<T extends NodeJS.WritableStream>(destination: T, options?: { | ||
end?: boolean | undefined; | ||
} | undefined): T; | ||
}) | undefined, reqOpts?: RequestOptions | undefined, telemetry?: EventEmitter | undefined) => Promise<IncomingMessage>; | ||
request: (pathOrUrl: string | URL, method: Method, reqOpts?: RequestOptions | undefined, data?: string | Readable | Buffer | (EventEmitter & { | ||
pipe<T extends NodeJS.WritableStream>(destination: T, options?: { | ||
end?: boolean | undefined; | ||
} | undefined): T; | ||
}) | undefined, telemetry?: EventEmitter | undefined) => Promise<IncomingMessage>; | ||
private buildUrl; | ||
@@ -19,0 +39,0 @@ private combineOpts; |
@@ -58,3 +58,4 @@ "use strict"; | ||
}); | ||
if (data instanceof stream_1.Readable) { | ||
if ((data instanceof events_1.EventEmitter && typeof data.pipe === "function") || | ||
data instanceof stream_1.Readable) { | ||
// If there is an error reading data, destroy the request and pass the error. | ||
@@ -112,2 +113,4 @@ data.once("error", (error) => { | ||
maybeConsumable instanceof stream_1.Readable || | ||
(maybeConsumable instanceof events_1.EventEmitter && | ||
typeof maybeConsumable.pipe === "function") || | ||
typeof maybeConsumable === "string"); | ||
@@ -114,0 +117,0 @@ }; |
/// <reference types="node" /> | ||
import type { IncomingHttpHeaders, RequestOptions } from "http"; | ||
import type { RequestOptions as SecureRequestOptions } from "https"; | ||
import { EventEmitter } from "events"; | ||
import type { Readable } from "stream"; | ||
import type { RequestOptions as SecureRequestOptions } from "https"; | ||
export declare type Consumable = Readable | Buffer | string; | ||
export declare type Consumable = Readable | Buffer | string | (EventEmitter & { | ||
pipe<T extends NodeJS.WritableStream>(destination: T, options?: { | ||
end?: boolean; | ||
}): T; | ||
}); | ||
export declare enum Method { | ||
@@ -7,0 +12,0 @@ Get = "GET", |
@@ -13,7 +13,27 @@ /// <reference types="node" /> | ||
get: (pathOrUrl: string | URL, reqOpts?: RequestOptions | undefined, telemetry?: EventEmitter | undefined) => Promise<IncomingMessage>; | ||
post: (pathOrUrl: string | URL, data?: string | Readable | Buffer | undefined, reqOpts?: RequestOptions | undefined, telemetry?: EventEmitter | undefined) => Promise<IncomingMessage>; | ||
patch: (pathOrUrl: string | URL, data?: string | Readable | Buffer | undefined, reqOpts?: RequestOptions | undefined, telemetry?: EventEmitter | undefined) => Promise<IncomingMessage>; | ||
put: (pathOrUrl: string | URL, data?: string | Readable | Buffer | undefined, reqOpts?: RequestOptions | undefined, telemetry?: EventEmitter | undefined) => Promise<IncomingMessage>; | ||
delete: (pathOrUrl: string | URL, data?: string | Readable | Buffer | undefined, reqOpts?: RequestOptions | undefined, telemetry?: EventEmitter | undefined) => Promise<IncomingMessage>; | ||
request: (pathOrUrl: string | URL, method: Method, reqOpts?: RequestOptions | undefined, data?: string | Readable | Buffer | undefined, telemetry?: EventEmitter | undefined) => Promise<IncomingMessage>; | ||
post: (pathOrUrl: string | URL, data?: string | Readable | Buffer | (EventEmitter & { | ||
pipe<T extends NodeJS.WritableStream>(destination: T, options?: { | ||
end?: boolean | undefined; | ||
} | undefined): T; | ||
}) | undefined, reqOpts?: RequestOptions | undefined, telemetry?: EventEmitter | undefined) => Promise<IncomingMessage>; | ||
patch: (pathOrUrl: string | URL, data?: string | Readable | Buffer | (EventEmitter & { | ||
pipe<T extends NodeJS.WritableStream>(destination: T, options?: { | ||
end?: boolean | undefined; | ||
} | undefined): T; | ||
}) | undefined, reqOpts?: RequestOptions | undefined, telemetry?: EventEmitter | undefined) => Promise<IncomingMessage>; | ||
put: (pathOrUrl: string | URL, data?: string | Readable | Buffer | (EventEmitter & { | ||
pipe<T extends NodeJS.WritableStream>(destination: T, options?: { | ||
end?: boolean | undefined; | ||
} | undefined): T; | ||
}) | undefined, reqOpts?: RequestOptions | undefined, telemetry?: EventEmitter | undefined) => Promise<IncomingMessage>; | ||
delete: (pathOrUrl: string | URL, data?: string | Readable | Buffer | (EventEmitter & { | ||
pipe<T extends NodeJS.WritableStream>(destination: T, options?: { | ||
end?: boolean | undefined; | ||
} | undefined): T; | ||
}) | undefined, reqOpts?: RequestOptions | undefined, telemetry?: EventEmitter | undefined) => Promise<IncomingMessage>; | ||
request: (pathOrUrl: string | URL, method: Method, reqOpts?: RequestOptions | undefined, data?: string | Readable | Buffer | (EventEmitter & { | ||
pipe<T extends NodeJS.WritableStream>(destination: T, options?: { | ||
end?: boolean | undefined; | ||
} | undefined): T; | ||
}) | undefined, telemetry?: EventEmitter | undefined) => Promise<IncomingMessage>; | ||
private buildUrl; | ||
@@ -20,0 +40,0 @@ private combineOpts; |
@@ -58,3 +58,4 @@ "use strict"; | ||
}); | ||
if (data instanceof stream_1.Readable) { | ||
if ((data instanceof events_1.EventEmitter && typeof data.pipe === "function") || | ||
data instanceof stream_1.Readable) { | ||
// If there is an error reading data, destroy the request and pass the error. | ||
@@ -112,2 +113,4 @@ data.once("error", (error) => { | ||
maybeConsumable instanceof stream_1.Readable || | ||
(maybeConsumable instanceof events_1.EventEmitter && | ||
typeof maybeConsumable.pipe === "function") || | ||
typeof maybeConsumable === "string"); | ||
@@ -114,0 +117,0 @@ }; |
@@ -275,2 +275,3 @@ "use strict"; | ||
"content-length": `${Buffer.byteLength(data)}`, | ||
"keep-alive": "timeout=5", | ||
connection: "keep-alive", | ||
@@ -277,0 +278,0 @@ date, |
@@ -149,3 +149,6 @@ import { EventEmitter } from "events"; | ||
if (data instanceof Readable) { | ||
if ( | ||
(data instanceof EventEmitter && typeof data.pipe === "function") || | ||
data instanceof Readable | ||
) { | ||
// If there is an error reading data, destroy the request and pass the error. | ||
@@ -202,2 +205,4 @@ data.once("error", (error) => { | ||
maybeConsumable instanceof Readable || | ||
(maybeConsumable instanceof EventEmitter && | ||
typeof maybeConsumable.pipe === "function") || | ||
typeof maybeConsumable === "string" | ||
@@ -204,0 +209,0 @@ ); |
import type { IncomingHttpHeaders, RequestOptions } from "http"; | ||
import type { RequestOptions as SecureRequestOptions } from "https"; | ||
import { EventEmitter } from "events"; | ||
import type { Readable } from "stream"; | ||
import type { RequestOptions as SecureRequestOptions } from "https"; | ||
export type Consumable = Readable | Buffer | string; | ||
export type Consumable = | ||
| Readable | ||
| Buffer | ||
| string | ||
| (EventEmitter & { | ||
pipe<T extends NodeJS.WritableStream>( | ||
destination: T, | ||
options?: { end?: boolean }, | ||
): T; | ||
}); | ||
@@ -7,0 +17,0 @@ export enum Method { |
@@ -154,3 +154,6 @@ import { EventEmitter } from "events"; | ||
if (data instanceof Readable) { | ||
if ( | ||
(data instanceof EventEmitter && typeof data.pipe === "function") || | ||
data instanceof Readable | ||
) { | ||
// If there is an error reading data, destroy the request and pass the error. | ||
@@ -207,2 +210,4 @@ data.once("error", (error) => { | ||
maybeConsumable instanceof Readable || | ||
(maybeConsumable instanceof EventEmitter && | ||
typeof maybeConsumable.pipe === "function") || | ||
typeof maybeConsumable === "string" | ||
@@ -209,0 +214,0 @@ ); |
{ | ||
"name": "@hqoss/http-client", | ||
"version": "0.1.26-0", | ||
"version": "0.1.27-0", | ||
"description": "A light-weight, performant, composable blueprint for writing consistent and re-usable Node.js HTTP clients", | ||
@@ -5,0 +5,0 @@ "main": "./dist/lib/index.js", |
![Node.js CI](https://github.com/hqoss/node-http-client/workflows/Node.js%20CI/badge.svg) | ||
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/65406302416243f788cee055ce10821a)](https://www.codacy.com/gh/hqoss/node-http-client?utm_source=github.com&utm_medium=referral&utm_content=hqoss/node-http-client&utm_campaign=Badge_Grade) | ||
[![Codacy Badge](https://app.codacy.com/project/badge/Coverage/65406302416243f788cee055ce10821a)](https://www.codacy.com/gh/hqoss/node-http-client?utm_source=github.com&utm_medium=referral&utm_content=hqoss/node-http-client&utm_campaign=Badge_Coverage) | ||
[![GuardRails badge](https://badges.guardrails.io/hqoss/node-http-client.svg?token=030dd9506fbf19af907d144a89e2973e05876de87f886a9df07e88581d6119fe&provider=github)](https://dashboard.guardrails.io/gh/hqoss/36608) | ||
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/65406302416243f788cee055ce10821a)](https://www.codacy.com/gh/hqoss/node-http-client?utm_source=github.com\&utm_medium=referral\&utm_content=hqoss/node-http-client\&utm_campaign=Badge_Grade) | ||
[![Codacy Badge](https://app.codacy.com/project/badge/Coverage/65406302416243f788cee055ce10821a)](https://www.codacy.com/gh/hqoss/node-http-client?utm_source=github.com\&utm_medium=referral\&utm_content=hqoss/node-http-client\&utm_campaign=Badge_Coverage) | ||
[![GuardRails badge](https://badges.guardrails.io/hqoss/node-http-client.svg?token=030dd9506fbf19af907d144a89e2973e05876de87f886a9df07e88581d6119fe\&provider=github)](https://dashboard.guardrails.io/gh/hqoss/36608) | ||
![npm](https://img.shields.io/npm/v/@hqoss/http-client) | ||
@@ -9,30 +9,28 @@ | ||
A light-weight, performant, composable blueprint for writing **consistent _and_ re-usable** Node.js HTTP clients. | ||
A light-weight, performant, composable blueprint for writing **consistent *and* re-usable** Node.js HTTP(S) clients. | ||
Extends `node-fetch`, therefore 100% compatible with the underlying APIs. | ||
## Table of contents | ||
- [🤔 Why use `http-client`](#-why-use-http-client) | ||
* [🤔 Why use `http-client`](#-why-use-http-client) | ||
- [⏳ Install](#-install) | ||
* [⏳ Install](#-install) | ||
- [📝 Usage](#-usage) | ||
* [📝 Usage](#-usage) | ||
- [SDK-like HTTP client](#sdk-like-http-client) | ||
- [Advanced example](#advanced-example) | ||
- [Gotchas and useful know-how](#gotchas-and-useful-know-how) | ||
- [API Docs](#api-docs) | ||
* [SDK-like HTTP client](#sdk-like-http-client) | ||
* [Advanced example](#advanced-example) | ||
* [Gotchas and useful know-how](#gotchas-and-useful-know-how) | ||
* [API Docs](#api-docs) | ||
- [⚡️ Performance](#️-performance) | ||
* [⚡️ Performance](#️-performance) | ||
- [Core design principles](#core-design-principles) | ||
* [Core design principles](#core-design-principles) | ||
- [Node version support](#node-version-support) | ||
* [Node version support](#node-version-support) | ||
- [Why ES2018](#why-es2018) | ||
* [Why ES2018](#why-es2018) | ||
- [Testing](#testing) | ||
* [Testing](#testing) | ||
- [TODO](#todo) | ||
* [TODO](#todo) | ||
@@ -43,18 +41,18 @@ ## 🤔 Why use `http-client` | ||
- `request` is/was great, but it [has entered maintenance mode](https://github.com/request/request/issues/3142). | ||
- Both `node-fetch` and `request` are relatively low-level (in JavaScript terms) implementations and as such lack certain convenience methods/APIs that help design maintainable and consistent HTTP clients. This is especially true in the microservices architecture context, where consistency is paramount. | ||
* `request` is/was great, but it [has entered maintenance mode](https://github.com/request/request/issues/3142). | ||
* Both `node-fetch` and `request` are relatively low-level (in JavaScript terms) implementations and as such lack certain convenience methods/APIs that help design maintainable and consistent HTTP clients. This is especially true in the microservices architecture context, where consistency is paramount. | ||
**`http-client` builds on `node-fetch` to enable composable and re-usable HTTP client implementations.** | ||
**`http-client` builds on the Node.js `http` module to enable highly performant, composable, and re-usable HTTP client implementations.** | ||
- Enforces a consistent approach to writing HTTP clients. | ||
* Enforces a consistent approach to writing HTTP clients. | ||
- Greatly reduces common boilerplate, expressly | ||
- authentication, | ||
- default headers, | ||
- default options, | ||
- composing urls, | ||
- connection pooling, | ||
- parsing responses, and more. | ||
* Greatly reduces common boilerplate, expressly | ||
* authentication, | ||
* default headers, | ||
* default options, | ||
* composing urls, | ||
* connection pooling, | ||
* parsing responses, and more. | ||
- It is written in TypeScript. | ||
* It is written in TypeScript. | ||
@@ -65,4 +63,2 @@ ## ⏳ Install | ||
npm install @hqoss/http-client | ||
# Additionally, for TypeScript users | ||
npm install @types/node-fetch --save-dev | ||
``` | ||
@@ -297,3 +293,3 @@ | ||
1. `json` mode is _not_ the default. It needs to be enabled explicitly in the `constructor`. | ||
1. `json` mode is *not* the default. It needs to be enabled explicitly in the `constructor`. | ||
@@ -310,3 +306,3 @@ ```typescript | ||
2. Non-ok responses are _not_ rejected by default. You can mimic this behaviour in the `transformResponse` lifecycle method. | ||
2. Non-ok responses are *not* rejected by default. You can mimic this behaviour in the `transformResponse` lifecycle method. | ||
@@ -343,3 +339,3 @@ ```typescript | ||
**⚠️ WARNING:** Unlike `request`, `http-client` (using `node-fetch` under the hood) does _NOT_ reject non-ok responses by default as per [the whatwg spec](https://fetch.spec.whatwg.org/#fetch-method). You can, however, mimic this behaviour with a custom `responseTransformer` (see example above). | ||
**⚠️ WARNING:** Unlike `request`, `http-client` (using `node-fetch` under the hood) does *NOT* reject non-ok responses by default as per [the whatwg spec](https://fetch.spec.whatwg.org/#fetch-method). You can, however, mimic this behaviour with a custom `responseTransformer` (see example above). | ||
@@ -354,5 +350,5 @@ ## ⚡️ Performance | ||
- Default `request` setup (used by _most_ projects): 10,893 requests in 30.08s; **362.19 requests/sec** | ||
- Default `node-fetch` setup (used by _many_ projects): 8,632 requests in 30.08s; **286.98 requests/sec** | ||
- Default `http-client` setup: 71,359 requests in 30.10s; **2,370.72 requests/sec** | ||
* Default `request` setup (used by *most* projects): 10,893 requests in 30.08s; **362.19 requests/sec** | ||
* Default `node-fetch` setup (used by *many* projects): 8,632 requests in 30.08s; **286.98 requests/sec** | ||
* Default `http-client` setup: 71,359 requests in 30.10s; **2,370.72 requests/sec** | ||
@@ -373,7 +369,7 @@ Please note that these benchmarks were run through `wrk`, each lasting 30 seconds, using 5 threads and keeping 500 connections open. | ||
- **Code quality**; This package may end up being used in mission-critical software, so it's important that the code is performant, secure, and battle-tested. | ||
* **Code quality**; This package may end up being used in mission-critical software, so it's important that the code is performant, secure, and battle-tested. | ||
- **Developer experience**; Developers must be able to use this package with no significant barriers to entry. It has to be easy-to-find, well-documented, and pleasant to use. | ||
* **Developer experience**; Developers must be able to use this package with no significant barriers to entry. It has to be easy-to-find, well-documented, and pleasant to use. | ||
- **Modularity & Configurability**; It's important that users can compose and easily change the ways in which they consume and work with this package. | ||
* **Modularity & Configurability**; It's important that users can compose and easily change the ways in which they consume and work with this package. | ||
@@ -408,10 +404,10 @@ ## Node version support | ||
- [ ] Write a **Contributing** guide | ||
- [ ] Complete testing section, add best practices | ||
- [ ] Describe scripts and usage, add best practices | ||
- [ ] Add typespec and generate docs | ||
- [ ] Describe security best practices, e.g. `npm doctor`, `npm audit`, `npm outdated`, `ignore-scripts` in `.npmrc`, etc. | ||
- [ ] Add "Why should I use this" section | ||
- [ ] Implement and document support for basic auth | ||
- [ ] Document `willSendRequest` and `reponseTransformer` | ||
- [ ] Library architectural design (+ diagram?) | ||
* \[ ] Write a **Contributing** guide | ||
* \[ ] Complete testing section, add best practices | ||
* \[ ] Describe scripts and usage, add best practices | ||
* \[ ] Add typespec and generate docs | ||
* \[ ] Describe security best practices, e.g. `npm doctor`, `npm audit`, `npm outdated`, `ignore-scripts` in `.npmrc`, etc. | ||
* \[ ] Add "Why should I use this" section | ||
* \[ ] Implement and document support for basic auth | ||
* \[ ] Document `willSendRequest` and `reponseTransformer` | ||
* \[ ] Library architectural design (+ diagram?) |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
218292
1391
405