-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #426 from swrlab/dev/undici-merge
chore: merge `frytg/undici-wrapper` into this package
- Loading branch information
Showing
9 changed files
with
301 additions
and
39 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
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
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 |
---|---|---|
@@ -1,16 +1,57 @@ | ||
# SWR Audio Lab / Undici | ||
|
||
Please see [github/undici-wrapper](https://github.com/frytg/undici-wrapper) for the full configuration options. | ||
See [undici.nodejs.org](https://undici.nodejs.org) for the full Undici configuration and usage. | ||
|
||
- [SWR Audio Lab / Undici](#swr-audio-lab--undici) | ||
- [Import](#import) | ||
- [Request](#request) | ||
|
||
## Import | ||
|
||
Basic import: | ||
|
||
```js | ||
// load request handler | ||
const undici = require('@swrlab/utils/packages/undici') | ||
|
||
// export handler | ||
module.exports = undici() | ||
``` | ||
|
||
Import with Datadog tracer enabled: | ||
|
||
```js | ||
// add tracing | ||
const tracer = process.env.DD_TRACE_ENABLED === 'true' ? require('../tracer') : null | ||
|
||
// load request handler | ||
const undici = require('@swrlab/utils/packages/undici') | ||
|
||
// export handler | ||
module.exports = undici(tracer) | ||
``` | ||
|
||
## Request | ||
|
||
Simple request: | ||
|
||
```js | ||
const data = await undici(someApiUrl) | ||
``` | ||
|
||
Advanced usage: | ||
|
||
```js | ||
const data = await undici(someApiUrl, { | ||
method: 'GET', | ||
timeout: 6e3, | ||
reject: false, | ||
maxRedirections: 5 | ||
}) | ||
``` | ||
|
||
You can also use object desctructuring for easy access to the output: | ||
|
||
```js | ||
const { headers, statusCode, json } = await undici(someApiUrl) | ||
``` |
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,13 @@ | ||
// load config | ||
const { name, version } = require('../../package.json') | ||
|
||
const userAgent = `${name.replace('@', '')}/${version}` | ||
|
||
module.exports = { | ||
keepAliveTimeout: 30e3, | ||
headersTimeout: 0, | ||
bodyTimeout: 0, | ||
headers: { | ||
'user-agent': process.env.USER_AGENT || userAgent, | ||
}, | ||
} |
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,18 @@ | ||
// provide util to confert readable stream to buffer | ||
module.exports = async (readable) => { | ||
// create output details | ||
let string = '' | ||
const chunks = [] | ||
|
||
// handle each chunk | ||
for await (const chunk of readable) { | ||
string += chunk | ||
chunks.push(chunk) | ||
} | ||
|
||
// reformat buffer | ||
const buffer = Buffer.concat(chunks) | ||
|
||
// return data | ||
return { string, buffer } | ||
} |
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 |
---|---|---|
@@ -1,5 +1,5 @@ | ||
// load request handler | ||
const undici = require('undici-wrapper') | ||
// load utils | ||
const request = require('./request') | ||
|
||
// export handler | ||
module.exports = undici | ||
// export handler with tracing, if enabled | ||
module.exports = (tracer) => tracer?.wrap('undici.request', request) || request |
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,77 @@ | ||
/* eslint-disable prefer-promise-reject-errors */ | ||
|
||
// load node utils | ||
const undici = require('undici') | ||
const AbortController = require('abort-controller') | ||
|
||
// fetch options and utils | ||
const _options = require('./_options') | ||
const convertReadableStream = require('./convertReadableStream') | ||
|
||
const DEFAULT_TIMEOUT = 7e3 | ||
|
||
module.exports = async (url, options) => { | ||
// use controller for timeouts | ||
const abortController = new AbortController() | ||
const abortTimeout = setTimeout(() => { | ||
abortController.abort() | ||
}, options?.timeout || DEFAULT_TIMEOUT) | ||
|
||
// calculcate redirect | ||
const maxRedirections = | ||
options?.maxRedirections !== null && options?.maxRedirections !== undefined | ||
? options.maxRedirections | ||
: 5 | ||
|
||
// prepare options | ||
const requestOptions = { | ||
..._options, | ||
method: options?.method || 'GET', | ||
body: options?.body || undefined, | ||
signal: abortController.signal, | ||
maxRedirections, | ||
} | ||
if (options?.headers) requestOptions.headers = { ...requestOptions.headers, ...options.headers } | ||
|
||
// make actual request | ||
const { statusCode, headers, trailers, body } = await undici.request(url, requestOptions) | ||
|
||
// remove timeout since request finished beforehand | ||
clearTimeout(abortTimeout) | ||
|
||
// set ok | ||
const ok = statusCode >= 200 && statusCode < 300 | ||
if (!ok && (!options || options?.reject !== false)) return Promise.reject({ statusCode, ok, headers, url }) | ||
|
||
// turn stream into string | ||
const { string, buffer } = await convertReadableStream(body) | ||
|
||
// detect/ set redirect | ||
const redirect = | ||
statusCode >= 300 && statusCode < 400 && headers.location ? new URL(headers.location, url) : null | ||
|
||
// fetch header vars | ||
const contentType = headers['content-type'] | ||
|
||
// parse json if set | ||
let json | ||
try { | ||
json = contentType?.indexOf('application/json') !== -1 ? JSON.parse(string) : null | ||
} catch (error) { | ||
json = null | ||
} | ||
|
||
// return data | ||
return Promise.resolve({ | ||
statusCode, | ||
ok, | ||
redirect, | ||
headers, | ||
contentType, | ||
trailers, | ||
body, | ||
string, | ||
buffer, | ||
json, | ||
}) | ||
} |
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
Oops, something went wrong.