-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 3322aea
Showing
27 changed files
with
11,026 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# Editor configuration, see https://editorconfig.org | ||
root = true | ||
|
||
[*] | ||
charset = utf-8 | ||
indent_style = space | ||
indent_size = 2 | ||
insert_final_newline = true | ||
trim_trailing_whitespace = true | ||
end_of_line = lf | ||
|
||
[*.md] | ||
max_line_length = off | ||
trim_trailing_whitespace = false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
/tmp | ||
/dist |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"extends": "@myunisoft/eslint-config", | ||
"rules": { | ||
"@typescript-eslint/no-non-null-assertion": "off" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
# Logs | ||
logs | ||
*.log | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
lerna-debug.log* | ||
|
||
# Diagnostic reports (https://nodejs.org/api/report.html) | ||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json | ||
|
||
# Runtime data | ||
pids | ||
*.pid | ||
*.seed | ||
*.pid.lock | ||
|
||
# Directory for instrumented libs generated by jscoverage/JSCover | ||
lib-cov | ||
|
||
# Coverage directory used by tools like istanbul | ||
coverage | ||
*.lcov | ||
|
||
# nyc test coverage | ||
.nyc_output | ||
|
||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) | ||
.grunt | ||
|
||
# Bower dependency directory (https://bower.io/) | ||
bower_components | ||
|
||
# node-waf configuration | ||
.lock-wscript | ||
|
||
# Compiled binary addons (https://nodejs.org/api/addons.html) | ||
build/Release | ||
|
||
# Dependency directories | ||
node_modules/ | ||
jspm_packages/ | ||
|
||
# Snowpack dependency directory (https://snowpack.dev/) | ||
web_modules/ | ||
|
||
# TypeScript cache | ||
*.tsbuildinfo | ||
|
||
# Optional npm cache directory | ||
.npm | ||
|
||
# Optional eslint cache | ||
.eslintcache | ||
|
||
# Microbundle cache | ||
.rpt2_cache/ | ||
.rts2_cache_cjs/ | ||
.rts2_cache_es/ | ||
.rts2_cache_umd/ | ||
|
||
# Optional REPL history | ||
.node_repl_history | ||
|
||
# Output of 'npm pack' | ||
*.tgz | ||
|
||
# Yarn Integrity file | ||
.yarn-integrity | ||
|
||
# dotenv environment variables file | ||
.env | ||
.env.test | ||
|
||
# parcel-bundler cache (https://parceljs.org/) | ||
.cache | ||
.parcel-cache | ||
|
||
# Next.js build output | ||
.next | ||
out | ||
|
||
# Nuxt.js build / generate output | ||
.nuxt | ||
dist | ||
|
||
# Gatsby files | ||
.cache/ | ||
# Comment in the public line in if your project uses Gatsby and not Next.js | ||
# https://nextjs.org/blog/next-9-1#public-directory-support | ||
# public | ||
|
||
# vuepress build output | ||
.vuepress/dist | ||
|
||
# Serverless directories | ||
.serverless/ | ||
|
||
# FuseBox cache | ||
.fusebox/ | ||
|
||
# DynamoDB Local files | ||
.dynamodb/ | ||
|
||
# TernJS port file | ||
.tern-port | ||
|
||
# IDE files | ||
.idea/ | ||
|
||
# Stores VSCode versions used for testing VSCode extensions | ||
.vscode-test | ||
|
||
# yarn v2 | ||
.yarn/cache | ||
.yarn/unplugged | ||
.yarn/build-state.yml | ||
.yarn/install-state.gz | ||
.pnp.* | ||
|
||
tmp/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# Httpie | ||
[httpie](https://github.com/lukeed/httpie) "like" request wrapper that use new Node.js http client [undici](https://github.com/nodejs/undici) under the hood. | ||
|
||
## Features | ||
|
||
- Implement httpie features. | ||
- Able to automatically detect domains and paths to assign the right Agent (use a LRU cache to avoid repetitive computation). | ||
- [**WIP**] Precise Rate-limit with the package `p-ratelimit`. | ||
- [**WIP**] Built-in retry mechanism with **custom policies**. | ||
|
||
Thanks to undici: | ||
|
||
- Support [HTTP redirections](https://developer.mozilla.org/en-US/docs/Web/HTTP/Redirections) with the `maxRedirections` argument | ||
- Bare metal rate-limit protection by using Undici Agent maximum connections. | ||
- Implement high-level API for undici **stream** and **pipeline** method. | ||
- Optimization and performance of the new client (**around 2.5x faster** than Node.js native http client). | ||
- Work well with **newest** Node.js API [AbortController](https://nodejs.org/dist/latest-v16.x/docs/api/globals.html#globals_class_abortcontroller) to cancel http request. | ||
|
||
## Requirements | ||
- [Node.js](https://nodejs.org/en/) version 14 or higher | ||
|
||
## Getting Started | ||
|
||
This package is available in the Node Package Repository and can be easily installed with [npm](https://docs.npmjs.com/getting-started/what-is-npm) or [yarn](https://yarnpkg.com). | ||
|
||
```bash | ||
$ npm i @myunisoft/httpie | ||
# or | ||
$ yarn add @myunisoft/httpie | ||
``` | ||
|
||
## Usage example | ||
|
||
The MyUnisoft httpie client is very similar to lukeed httpie http client. | ||
|
||
```js | ||
import * as httpie from "@myunisoft/httpie"; | ||
|
||
try { | ||
const response = await httpie.post("https://jsonplaceholder.typicode.com/posts", { | ||
body: { | ||
title: "foo", | ||
body: "bar", | ||
userId: 1 | ||
} | ||
}); | ||
|
||
console.log(response.statusCode); | ||
console.log(response.statusMessage); | ||
console.log(response.data); | ||
} | ||
catch (error) { | ||
console.log(error.message); | ||
console.log(error.statusCode); | ||
console.log(error.headers); | ||
console.log(error.data); | ||
} | ||
``` | ||
|
||
## API | ||
|
||
- [Request API](./docs/request.md) | ||
- [Work and manage Agents](./docs/agents.md) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# Agents | ||
|
||
Agents are custom constructs that are used to describe services internal to MyUnisoft. However this could also be used for external services. | ||
|
||
```js | ||
import { agents } from "@myunisoft/httpie"; | ||
|
||
console.log(agents); // <- push a new agent in this Array | ||
``` | ||
|
||
Those agents are described by the following TypeScript interface: | ||
```ts | ||
export interface CustomHttpAgent { | ||
customPath: string; | ||
domains: Set<string>; | ||
agent: Agent; | ||
prod: string; | ||
preprod: string; | ||
dev: string; | ||
} | ||
``` | ||
|
||
Example with a test custom agent: | ||
```ts | ||
export const test: CustomHttpAgent = { | ||
customPath: "test", | ||
domains: new Set([ | ||
"test.domain.fr", | ||
]), | ||
agent: new Agent({ | ||
connections: 30 | ||
}), | ||
prod: "", | ||
preprod: "", | ||
dev: "https://test.domain.fr" | ||
}; | ||
``` | ||
|
||
The **agent** property is an Undici Agent. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
# Request API | ||
The request method is the root method for making http requests. Short method like get or post use it under the hood. | ||
|
||
The method **options** and **response** are described by the following TypeScript interfaces: | ||
|
||
```ts | ||
export interface RequestOptions { | ||
/** Default: 0 */ | ||
maxRedirections?: number; | ||
/** Default: { "user-agent": "myun" } */ | ||
headers?: IncomingHttpHeaders; | ||
body?: any; | ||
authorization?: string; | ||
// Could be dynamically computed depending on the provided URI. | ||
agent?: undici.Agent; | ||
} | ||
|
||
export interface RequestResponse<T> { | ||
data: T; | ||
headers: IncomingHttpHeaders; | ||
statusMessage: string; | ||
statusCode: number; | ||
} | ||
``` | ||
|
||
## request< T >(method: string, uri: string | URL, options?: RequestOptions): Promise< RequestResponse< T > > | ||
The first **method** argument take an [HTTP Verb](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) like `GET`, `POST`, `PATCH` etc. The second one **uri** (Uniform Resource Identifier) take a string or a WHATWG URL. | ||
|
||
The options allow you to quickly authenticate and add additional headers: | ||
```js | ||
import { request } from "@myunisoft/httpie"; | ||
|
||
const { data } = await request("GET", "https://test.domain.fr/user/info", { | ||
authorization: "Token here", | ||
headers: { | ||
"society-id": 1 | ||
} | ||
}); | ||
console.log(data); | ||
``` | ||
|
||
By default the client will detect the `test.domain.fr` hostname and assign the right Undici Agent. But if necessary they can always be retrieved by hand to be passed to the options. | ||
|
||
```js | ||
import { windev } from "@myunisoft/httpie"; | ||
|
||
console.log(windev); | ||
``` | ||
|
||
## shorthand methods | ||
Those methods are equivalent to the request arguments (except for `method`) | ||
|
||
```ts | ||
export type RequestCallback = <T>(uri: string | URL, options?: RequestOptions) => Promise<RequestResponse<T>>; | ||
|
||
export const get = request.bind(null, "GET") as RequestCallback; | ||
export const post = request.bind(null, "POST") as RequestCallback; | ||
export const put = request.bind(null, "PUT") as RequestCallback; | ||
export const del = request.bind(null, "DELETE") as RequestCallback; | ||
export const patch = request.bind(null, "PATCH") as RequestCallback; | ||
``` | ||
|
||
## error | ||
|
||
Errors are triggered if the returned statusCode is equal or higher than 400. It can occur in case of error when reading the response body (for example an invalid JSON). | ||
|
||
The triggered error is constructed as follows: | ||
|
||
```ts | ||
export function toError<T>(response: RequestResponse<T>) { | ||
const err = new Error(response.statusMessage) as Error & RequestResponse<T>; | ||
err.statusMessage = response.statusMessage; | ||
err.statusCode = response.statusCode; | ||
err.headers = response.headers; | ||
err.data = response.data; | ||
|
||
return err; | ||
} | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
module.exports = { | ||
preset: "ts-jest", | ||
testEnvironment: "node", | ||
collectCoverage: true, | ||
collectCoverageFrom: [ | ||
"**/src/**/**/*.ts" | ||
], | ||
setupFilesAfterEnv: [ | ||
"./test/jest.setup.js" | ||
], | ||
testPathIgnorePatterns: [ | ||
"/node_modules/", | ||
"/test/fixtures/" | ||
], | ||
setupFiles: ["dotenv/config"] | ||
}; |
Oops, something went wrong.