@nocobase/plugin-idp-oauth 2.1.0-alpha.17 → 2.1.0-alpha.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build.config.ts +1 -1
- package/dist/externalVersion.js +6 -4
- package/dist/node_modules/light-my-request/package.json +1 -1
- package/dist/node_modules/undici/LICENSE +21 -0
- package/dist/node_modules/undici/README.md +741 -0
- package/dist/node_modules/undici/docs/docs/api/Agent.md +84 -0
- package/dist/node_modules/undici/docs/docs/api/BalancedPool.md +99 -0
- package/dist/node_modules/undici/docs/docs/api/CacheStorage.md +30 -0
- package/dist/node_modules/undici/docs/docs/api/CacheStore.md +164 -0
- package/dist/node_modules/undici/docs/docs/api/Client.md +285 -0
- package/dist/node_modules/undici/docs/docs/api/ClientStats.md +27 -0
- package/dist/node_modules/undici/docs/docs/api/Connector.md +115 -0
- package/dist/node_modules/undici/docs/docs/api/ContentType.md +57 -0
- package/dist/node_modules/undici/docs/docs/api/Cookies.md +101 -0
- package/dist/node_modules/undici/docs/docs/api/Debug.md +62 -0
- package/dist/node_modules/undici/docs/docs/api/DiagnosticsChannel.md +315 -0
- package/dist/node_modules/undici/docs/docs/api/Dispatcher.md +1392 -0
- package/dist/node_modules/undici/docs/docs/api/EnvHttpProxyAgent.md +159 -0
- package/dist/node_modules/undici/docs/docs/api/Errors.md +49 -0
- package/dist/node_modules/undici/docs/docs/api/EventSource.md +45 -0
- package/dist/node_modules/undici/docs/docs/api/Fetch.md +60 -0
- package/dist/node_modules/undici/docs/docs/api/GlobalInstallation.md +139 -0
- package/dist/node_modules/undici/docs/docs/api/H2CClient.md +263 -0
- package/dist/node_modules/undici/docs/docs/api/MockAgent.md +603 -0
- package/dist/node_modules/undici/docs/docs/api/MockCallHistory.md +197 -0
- package/dist/node_modules/undici/docs/docs/api/MockCallHistoryLog.md +43 -0
- package/dist/node_modules/undici/docs/docs/api/MockClient.md +81 -0
- package/dist/node_modules/undici/docs/docs/api/MockErrors.md +12 -0
- package/dist/node_modules/undici/docs/docs/api/MockPool.md +555 -0
- package/dist/node_modules/undici/docs/docs/api/Pool.md +84 -0
- package/dist/node_modules/undici/docs/docs/api/PoolStats.md +35 -0
- package/dist/node_modules/undici/docs/docs/api/ProxyAgent.md +229 -0
- package/dist/node_modules/undici/docs/docs/api/RedirectHandler.md +93 -0
- package/dist/node_modules/undici/docs/docs/api/RetryAgent.md +50 -0
- package/dist/node_modules/undici/docs/docs/api/RetryHandler.md +118 -0
- package/dist/node_modules/undici/docs/docs/api/RoundRobinPool.md +145 -0
- package/dist/node_modules/undici/docs/docs/api/SnapshotAgent.md +616 -0
- package/dist/node_modules/undici/docs/docs/api/Socks5ProxyAgent.md +274 -0
- package/dist/node_modules/undici/docs/docs/api/Util.md +25 -0
- package/dist/node_modules/undici/docs/docs/api/WebSocket.md +141 -0
- package/dist/node_modules/undici/docs/docs/api/api-lifecycle.md +91 -0
- package/dist/node_modules/undici/docs/docs/best-practices/client-certificate.md +64 -0
- package/dist/node_modules/undici/docs/docs/best-practices/crawling.md +58 -0
- package/dist/node_modules/undici/docs/docs/best-practices/mocking-request.md +190 -0
- package/dist/node_modules/undici/docs/docs/best-practices/proxy.md +127 -0
- package/dist/node_modules/undici/docs/docs/best-practices/undici-vs-builtin-fetch.md +224 -0
- package/dist/node_modules/undici/docs/docs/best-practices/writing-tests.md +63 -0
- package/dist/node_modules/undici/index-fetch.js +65 -0
- package/dist/node_modules/undici/index.d.ts +3 -0
- package/dist/node_modules/undici/index.js +234 -0
- package/dist/node_modules/undici/lib/api/abort-signal.js +59 -0
- package/dist/node_modules/undici/lib/api/api-connect.js +110 -0
- package/dist/node_modules/undici/lib/api/api-pipeline.js +252 -0
- package/dist/node_modules/undici/lib/api/api-request.js +214 -0
- package/dist/node_modules/undici/lib/api/api-stream.js +209 -0
- package/dist/node_modules/undici/lib/api/api-upgrade.js +111 -0
- package/dist/node_modules/undici/lib/api/index.js +7 -0
- package/dist/node_modules/undici/lib/api/readable.js +580 -0
- package/dist/node_modules/undici/lib/cache/memory-cache-store.js +234 -0
- package/dist/node_modules/undici/lib/cache/sqlite-cache-store.js +461 -0
- package/dist/node_modules/undici/lib/core/connect.js +137 -0
- package/dist/node_modules/undici/lib/core/constants.js +143 -0
- package/dist/node_modules/undici/lib/core/diagnostics.js +227 -0
- package/dist/node_modules/undici/lib/core/errors.js +477 -0
- package/dist/node_modules/undici/lib/core/request.js +438 -0
- package/dist/node_modules/undici/lib/core/socks5-client.js +407 -0
- package/dist/node_modules/undici/lib/core/socks5-utils.js +203 -0
- package/dist/node_modules/undici/lib/core/symbols.js +75 -0
- package/dist/node_modules/undici/lib/core/tree.js +160 -0
- package/dist/node_modules/undici/lib/core/util.js +992 -0
- package/dist/node_modules/undici/lib/dispatcher/agent.js +158 -0
- package/dist/node_modules/undici/lib/dispatcher/balanced-pool.js +219 -0
- package/dist/node_modules/undici/lib/dispatcher/client-h1.js +1610 -0
- package/dist/node_modules/undici/lib/dispatcher/client-h2.js +995 -0
- package/dist/node_modules/undici/lib/dispatcher/client.js +659 -0
- package/dist/node_modules/undici/lib/dispatcher/dispatcher-base.js +165 -0
- package/dist/node_modules/undici/lib/dispatcher/dispatcher.js +48 -0
- package/dist/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +146 -0
- package/dist/node_modules/undici/lib/dispatcher/fixed-queue.js +135 -0
- package/dist/node_modules/undici/lib/dispatcher/h2c-client.js +51 -0
- package/dist/node_modules/undici/lib/dispatcher/pool-base.js +214 -0
- package/dist/node_modules/undici/lib/dispatcher/pool.js +118 -0
- package/dist/node_modules/undici/lib/dispatcher/proxy-agent.js +318 -0
- package/dist/node_modules/undici/lib/dispatcher/retry-agent.js +35 -0
- package/dist/node_modules/undici/lib/dispatcher/round-robin-pool.js +137 -0
- package/dist/node_modules/undici/lib/dispatcher/socks5-proxy-agent.js +249 -0
- package/dist/node_modules/undici/lib/encoding/index.js +33 -0
- package/dist/node_modules/undici/lib/global.js +50 -0
- package/dist/node_modules/undici/lib/handler/cache-handler.js +578 -0
- package/dist/node_modules/undici/lib/handler/cache-revalidation-handler.js +124 -0
- package/dist/node_modules/undici/lib/handler/decorator-handler.js +67 -0
- package/dist/node_modules/undici/lib/handler/deduplication-handler.js +460 -0
- package/dist/node_modules/undici/lib/handler/redirect-handler.js +238 -0
- package/dist/node_modules/undici/lib/handler/retry-handler.js +394 -0
- package/dist/node_modules/undici/lib/handler/unwrap-handler.js +100 -0
- package/dist/node_modules/undici/lib/handler/wrap-handler.js +105 -0
- package/dist/node_modules/undici/lib/interceptor/cache.js +495 -0
- package/dist/node_modules/undici/lib/interceptor/decompress.js +259 -0
- package/dist/node_modules/undici/lib/interceptor/deduplicate.js +117 -0
- package/dist/node_modules/undici/lib/interceptor/dns.js +571 -0
- package/dist/node_modules/undici/lib/interceptor/dump.js +112 -0
- package/dist/node_modules/undici/lib/interceptor/redirect.js +21 -0
- package/dist/node_modules/undici/lib/interceptor/response-error.js +95 -0
- package/dist/node_modules/undici/lib/interceptor/retry.js +19 -0
- package/dist/node_modules/undici/lib/llhttp/.gitkeep +0 -0
- package/dist/node_modules/undici/lib/llhttp/constants.d.ts +195 -0
- package/dist/node_modules/undici/lib/llhttp/constants.js +531 -0
- package/dist/node_modules/undici/lib/llhttp/llhttp-wasm.js +15 -0
- package/dist/node_modules/undici/lib/llhttp/llhttp_simd-wasm.js +15 -0
- package/dist/node_modules/undici/lib/llhttp/utils.d.ts +2 -0
- package/dist/node_modules/undici/lib/llhttp/utils.js +12 -0
- package/dist/node_modules/undici/lib/mock/mock-agent.js +232 -0
- package/dist/node_modules/undici/lib/mock/mock-call-history.js +248 -0
- package/dist/node_modules/undici/lib/mock/mock-client.js +68 -0
- package/dist/node_modules/undici/lib/mock/mock-errors.js +29 -0
- package/dist/node_modules/undici/lib/mock/mock-interceptor.js +209 -0
- package/dist/node_modules/undici/lib/mock/mock-pool.js +68 -0
- package/dist/node_modules/undici/lib/mock/mock-symbols.js +32 -0
- package/dist/node_modules/undici/lib/mock/mock-utils.js +486 -0
- package/dist/node_modules/undici/lib/mock/pending-interceptors-formatter.js +43 -0
- package/dist/node_modules/undici/lib/mock/snapshot-agent.js +353 -0
- package/dist/node_modules/undici/lib/mock/snapshot-recorder.js +588 -0
- package/dist/node_modules/undici/lib/mock/snapshot-utils.js +158 -0
- package/dist/node_modules/undici/lib/util/cache.js +407 -0
- package/dist/node_modules/undici/lib/util/date.js +653 -0
- package/dist/node_modules/undici/lib/util/promise.js +28 -0
- package/dist/node_modules/undici/lib/util/runtime-features.js +124 -0
- package/dist/node_modules/undici/lib/util/stats.js +32 -0
- package/dist/node_modules/undici/lib/util/timers.js +425 -0
- package/dist/node_modules/undici/lib/web/cache/cache.js +864 -0
- package/dist/node_modules/undici/lib/web/cache/cachestorage.js +152 -0
- package/dist/node_modules/undici/lib/web/cache/util.js +45 -0
- package/dist/node_modules/undici/lib/web/cookies/constants.js +12 -0
- package/dist/node_modules/undici/lib/web/cookies/index.js +199 -0
- package/dist/node_modules/undici/lib/web/cookies/parse.js +322 -0
- package/dist/node_modules/undici/lib/web/cookies/util.js +282 -0
- package/dist/node_modules/undici/lib/web/eventsource/eventsource-stream.js +399 -0
- package/dist/node_modules/undici/lib/web/eventsource/eventsource.js +501 -0
- package/dist/node_modules/undici/lib/web/eventsource/util.js +29 -0
- package/dist/node_modules/undici/lib/web/fetch/LICENSE +21 -0
- package/dist/node_modules/undici/lib/web/fetch/body.js +509 -0
- package/dist/node_modules/undici/lib/web/fetch/constants.js +131 -0
- package/dist/node_modules/undici/lib/web/fetch/data-url.js +596 -0
- package/dist/node_modules/undici/lib/web/fetch/formdata-parser.js +575 -0
- package/dist/node_modules/undici/lib/web/fetch/formdata.js +259 -0
- package/dist/node_modules/undici/lib/web/fetch/global.js +40 -0
- package/dist/node_modules/undici/lib/web/fetch/headers.js +719 -0
- package/dist/node_modules/undici/lib/web/fetch/index.js +2397 -0
- package/dist/node_modules/undici/lib/web/fetch/request.js +1115 -0
- package/dist/node_modules/undici/lib/web/fetch/response.js +641 -0
- package/dist/node_modules/undici/lib/web/fetch/util.js +1520 -0
- package/dist/node_modules/undici/lib/web/infra/index.js +229 -0
- package/dist/node_modules/undici/lib/web/subresource-integrity/Readme.md +9 -0
- package/dist/node_modules/undici/lib/web/subresource-integrity/subresource-integrity.js +307 -0
- package/dist/node_modules/undici/lib/web/webidl/index.js +1006 -0
- package/dist/node_modules/undici/lib/web/websocket/connection.js +329 -0
- package/dist/node_modules/undici/lib/web/websocket/constants.js +126 -0
- package/dist/node_modules/undici/lib/web/websocket/events.js +331 -0
- package/dist/node_modules/undici/lib/web/websocket/frame.js +133 -0
- package/dist/node_modules/undici/lib/web/websocket/permessage-deflate.js +118 -0
- package/dist/node_modules/undici/lib/web/websocket/receiver.js +450 -0
- package/dist/node_modules/undici/lib/web/websocket/sender.js +109 -0
- package/dist/node_modules/undici/lib/web/websocket/stream/websocketerror.js +104 -0
- package/dist/node_modules/undici/lib/web/websocket/stream/websocketstream.js +497 -0
- package/dist/node_modules/undici/lib/web/websocket/util.js +347 -0
- package/dist/node_modules/undici/lib/web/websocket/websocket.js +751 -0
- package/dist/node_modules/undici/package.json +152 -0
- package/dist/node_modules/undici/scripts/strip-comments.js +10 -0
- package/dist/node_modules/undici/types/README.md +6 -0
- package/dist/node_modules/undici/types/agent.d.ts +32 -0
- package/dist/node_modules/undici/types/api.d.ts +43 -0
- package/dist/node_modules/undici/types/balanced-pool.d.ts +30 -0
- package/dist/node_modules/undici/types/cache-interceptor.d.ts +179 -0
- package/dist/node_modules/undici/types/cache.d.ts +36 -0
- package/dist/node_modules/undici/types/client-stats.d.ts +15 -0
- package/dist/node_modules/undici/types/client.d.ts +123 -0
- package/dist/node_modules/undici/types/connector.d.ts +36 -0
- package/dist/node_modules/undici/types/content-type.d.ts +21 -0
- package/dist/node_modules/undici/types/cookies.d.ts +30 -0
- package/dist/node_modules/undici/types/diagnostics-channel.d.ts +74 -0
- package/dist/node_modules/undici/types/dispatcher.d.ts +273 -0
- package/dist/node_modules/undici/types/env-http-proxy-agent.d.ts +22 -0
- package/dist/node_modules/undici/types/errors.d.ts +177 -0
- package/dist/node_modules/undici/types/eventsource.d.ts +66 -0
- package/dist/node_modules/undici/types/fetch.d.ts +231 -0
- package/dist/node_modules/undici/types/formdata.d.ts +114 -0
- package/dist/node_modules/undici/types/global-dispatcher.d.ts +9 -0
- package/dist/node_modules/undici/types/global-origin.d.ts +7 -0
- package/dist/node_modules/undici/types/h2c-client.d.ts +73 -0
- package/dist/node_modules/undici/types/handlers.d.ts +14 -0
- package/dist/node_modules/undici/types/header.d.ts +160 -0
- package/dist/node_modules/undici/types/index.d.ts +91 -0
- package/dist/node_modules/undici/types/interceptors.d.ts +80 -0
- package/dist/node_modules/undici/types/mock-agent.d.ts +68 -0
- package/dist/node_modules/undici/types/mock-call-history.d.ts +111 -0
- package/dist/node_modules/undici/types/mock-client.d.ts +27 -0
- package/dist/node_modules/undici/types/mock-errors.d.ts +12 -0
- package/dist/node_modules/undici/types/mock-interceptor.d.ts +94 -0
- package/dist/node_modules/undici/types/mock-pool.d.ts +27 -0
- package/dist/node_modules/undici/types/patch.d.ts +29 -0
- package/dist/node_modules/undici/types/pool-stats.d.ts +19 -0
- package/dist/node_modules/undici/types/pool.d.ts +41 -0
- package/dist/node_modules/undici/types/proxy-agent.d.ts +29 -0
- package/dist/node_modules/undici/types/readable.d.ts +68 -0
- package/dist/node_modules/undici/types/retry-agent.d.ts +8 -0
- package/dist/node_modules/undici/types/retry-handler.d.ts +125 -0
- package/dist/node_modules/undici/types/round-robin-pool.d.ts +41 -0
- package/dist/node_modules/undici/types/snapshot-agent.d.ts +109 -0
- package/dist/node_modules/undici/types/socks5-proxy-agent.d.ts +25 -0
- package/dist/node_modules/undici/types/util.d.ts +18 -0
- package/dist/node_modules/undici/types/utility.d.ts +7 -0
- package/dist/node_modules/undici/types/webidl.d.ts +347 -0
- package/dist/node_modules/undici/types/websocket.d.ts +188 -0
- package/dist/server/collections/oidcStates.d.ts +10 -0
- package/dist/server/collections/oidcStates.js +96 -0
- package/dist/server/db-adapter.d.ts +25 -0
- package/dist/server/db-adapter.js +156 -0
- package/dist/server/service.js +11 -10
- package/package.json +2 -2
- package/dist/server/cache-adapter.d.ts +0 -33
- package/dist/server/cache-adapter.js +0 -159
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# Mocking Request
|
|
2
|
+
|
|
3
|
+
Undici has its own mocking [utility](/docs/docs/api/MockAgent.md). It allow us to intercept undici HTTP requests and return mocked values instead. It can be useful for testing purposes.
|
|
4
|
+
|
|
5
|
+
Example:
|
|
6
|
+
|
|
7
|
+
```js
|
|
8
|
+
// bank.mjs
|
|
9
|
+
import { request } from 'undici'
|
|
10
|
+
|
|
11
|
+
export async function bankTransfer(recipient, amount) {
|
|
12
|
+
const { body } = await request('http://localhost:3000/bank-transfer',
|
|
13
|
+
{
|
|
14
|
+
method: 'POST',
|
|
15
|
+
headers: {
|
|
16
|
+
'X-TOKEN-SECRET': 'SuperSecretToken',
|
|
17
|
+
},
|
|
18
|
+
body: JSON.stringify({
|
|
19
|
+
recipient,
|
|
20
|
+
amount
|
|
21
|
+
})
|
|
22
|
+
}
|
|
23
|
+
)
|
|
24
|
+
return await body.json()
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
And this is what the test file looks like:
|
|
29
|
+
|
|
30
|
+
```js
|
|
31
|
+
// index.test.mjs
|
|
32
|
+
import { strict as assert } from 'node:assert'
|
|
33
|
+
import { MockAgent, setGlobalDispatcher, } from 'undici'
|
|
34
|
+
import { bankTransfer } from './bank.mjs'
|
|
35
|
+
|
|
36
|
+
const mockAgent = new MockAgent();
|
|
37
|
+
|
|
38
|
+
setGlobalDispatcher(mockAgent);
|
|
39
|
+
|
|
40
|
+
// Provide the base url to the request
|
|
41
|
+
const mockPool = mockAgent.get('http://localhost:3000');
|
|
42
|
+
|
|
43
|
+
// intercept the request
|
|
44
|
+
mockPool.intercept({
|
|
45
|
+
path: '/bank-transfer',
|
|
46
|
+
method: 'POST',
|
|
47
|
+
headers: {
|
|
48
|
+
'X-TOKEN-SECRET': 'SuperSecretToken',
|
|
49
|
+
},
|
|
50
|
+
body: JSON.stringify({
|
|
51
|
+
recipient: '1234567890',
|
|
52
|
+
amount: '100'
|
|
53
|
+
})
|
|
54
|
+
}).reply(200, {
|
|
55
|
+
message: 'transaction processed'
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
const success = await bankTransfer('1234567890', '100')
|
|
59
|
+
|
|
60
|
+
assert.deepEqual(success, { message: 'transaction processed' })
|
|
61
|
+
|
|
62
|
+
// if you dont want to check whether the body or the headers contain the same value
|
|
63
|
+
// just remove it from interceptor
|
|
64
|
+
mockPool.intercept({
|
|
65
|
+
path: '/bank-transfer',
|
|
66
|
+
method: 'POST',
|
|
67
|
+
}).reply(400, {
|
|
68
|
+
message: 'bank account not found'
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
const badRequest = await bankTransfer('1234567890', '100')
|
|
72
|
+
|
|
73
|
+
assert.deepEqual(badRequest, { message: 'bank account not found' })
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Explore other MockAgent functionality [here](/docs/docs/api/MockAgent.md)
|
|
77
|
+
|
|
78
|
+
## Access agent call history
|
|
79
|
+
|
|
80
|
+
Using a MockAgent also allows you to make assertions on the configuration used to make your request in your application.
|
|
81
|
+
|
|
82
|
+
Here is an example :
|
|
83
|
+
|
|
84
|
+
```js
|
|
85
|
+
// index.test.mjs
|
|
86
|
+
import { strict as assert } from 'node:assert'
|
|
87
|
+
import { MockAgent, setGlobalDispatcher, fetch } from 'undici'
|
|
88
|
+
import { app } from './app.mjs'
|
|
89
|
+
|
|
90
|
+
// given an application server running on http://localhost:3000
|
|
91
|
+
await app.start()
|
|
92
|
+
|
|
93
|
+
// enable call history at instantiation
|
|
94
|
+
const mockAgent = new MockAgent({ enableCallHistory: true })
|
|
95
|
+
// or after instantiation
|
|
96
|
+
mockAgent.enableCallHistory()
|
|
97
|
+
|
|
98
|
+
setGlobalDispatcher(mockAgent)
|
|
99
|
+
|
|
100
|
+
// this call is made (not intercepted)
|
|
101
|
+
await fetch(`http://localhost:3000/endpoint?query='hello'`, {
|
|
102
|
+
method: 'POST',
|
|
103
|
+
headers: { 'content-type': 'application/json' }
|
|
104
|
+
body: JSON.stringify({ data: '' })
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
// access to the call history of the MockAgent (which register every call made intercepted or not)
|
|
108
|
+
assert.ok(mockAgent.getCallHistory()?.calls().length === 1)
|
|
109
|
+
assert.strictEqual(mockAgent.getCallHistory()?.firstCall()?.fullUrl, `http://localhost:3000/endpoint?query='hello'`)
|
|
110
|
+
assert.strictEqual(mockAgent.getCallHistory()?.firstCall()?.body, JSON.stringify({ data: '' }))
|
|
111
|
+
assert.deepStrictEqual(mockAgent.getCallHistory()?.firstCall()?.searchParams, { query: 'hello' })
|
|
112
|
+
assert.strictEqual(mockAgent.getCallHistory()?.firstCall()?.port, '3000')
|
|
113
|
+
assert.strictEqual(mockAgent.getCallHistory()?.firstCall()?.host, 'localhost:3000')
|
|
114
|
+
assert.strictEqual(mockAgent.getCallHistory()?.firstCall()?.method, 'POST')
|
|
115
|
+
assert.strictEqual(mockAgent.getCallHistory()?.firstCall()?.path, '/endpoint')
|
|
116
|
+
assert.deepStrictEqual(mockAgent.getCallHistory()?.firstCall()?.headers, { 'content-type': 'application/json' })
|
|
117
|
+
|
|
118
|
+
// clear all call history logs
|
|
119
|
+
mockAgent.clearCallHistory()
|
|
120
|
+
|
|
121
|
+
assert.ok(mockAgent.getCallHistory()?.calls().length === 0)
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Calling `mockAgent.close()` will automatically clear and delete every call history for you.
|
|
125
|
+
|
|
126
|
+
Explore other MockAgent functionality [here](/docs/docs/api/MockAgent.md)
|
|
127
|
+
|
|
128
|
+
Explore other MockCallHistory functionality [here](/docs/docs/api/MockCallHistory.md)
|
|
129
|
+
|
|
130
|
+
Explore other MockCallHistoryLog functionality [here](/docs/docs/api/MockCallHistoryLog.md)
|
|
131
|
+
|
|
132
|
+
## Debug Mock Value
|
|
133
|
+
|
|
134
|
+
When the interceptor and the request options are not the same, undici will automatically make a real HTTP request. To prevent real requests from being made, use `mockAgent.disableNetConnect()`:
|
|
135
|
+
|
|
136
|
+
```js
|
|
137
|
+
const mockAgent = new MockAgent();
|
|
138
|
+
|
|
139
|
+
setGlobalDispatcher(mockAgent);
|
|
140
|
+
mockAgent.disableNetConnect()
|
|
141
|
+
|
|
142
|
+
// Provide the base url to the request
|
|
143
|
+
const mockPool = mockAgent.get('http://localhost:3000');
|
|
144
|
+
|
|
145
|
+
mockPool.intercept({
|
|
146
|
+
path: '/bank-transfer',
|
|
147
|
+
method: 'POST',
|
|
148
|
+
}).reply(200, {
|
|
149
|
+
message: 'transaction processed'
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
const badRequest = await bankTransfer('1234567890', '100')
|
|
153
|
+
// Will throw an error
|
|
154
|
+
// MockNotMatchedError: Mock dispatch not matched for path '/bank-transfer':
|
|
155
|
+
// subsequent request to origin http://localhost:3000 was not allowed (net.connect disabled)
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Reply with data based on request
|
|
159
|
+
|
|
160
|
+
If the mocked response needs to be dynamically derived from the request parameters, you can provide a function instead of an object to `reply`:
|
|
161
|
+
|
|
162
|
+
```js
|
|
163
|
+
mockPool.intercept({
|
|
164
|
+
path: '/bank-transfer',
|
|
165
|
+
method: 'POST',
|
|
166
|
+
headers: {
|
|
167
|
+
'X-TOKEN-SECRET': 'SuperSecretToken',
|
|
168
|
+
},
|
|
169
|
+
body: JSON.stringify({
|
|
170
|
+
recipient: '1234567890',
|
|
171
|
+
amount: '100'
|
|
172
|
+
})
|
|
173
|
+
}).reply(200, (opts) => {
|
|
174
|
+
// do something with opts
|
|
175
|
+
|
|
176
|
+
return { message: 'transaction processed' }
|
|
177
|
+
})
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
in this case opts will be
|
|
181
|
+
|
|
182
|
+
```
|
|
183
|
+
{
|
|
184
|
+
method: 'POST',
|
|
185
|
+
headers: { 'X-TOKEN-SECRET': 'SuperSecretToken' },
|
|
186
|
+
body: '{"recipient":"1234567890","amount":"100"}',
|
|
187
|
+
origin: 'http://localhost:3000',
|
|
188
|
+
path: '/bank-transfer'
|
|
189
|
+
}
|
|
190
|
+
```
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Connecting through a proxy
|
|
2
|
+
|
|
3
|
+
Connecting through a proxy is possible by:
|
|
4
|
+
|
|
5
|
+
- Using [ProxyAgent](/docs/docs/api/ProxyAgent.md).
|
|
6
|
+
- Configuring `Client` or `Pool` constructor.
|
|
7
|
+
|
|
8
|
+
The proxy url should be passed to the `Client` or `Pool` constructor, while the upstream server url
|
|
9
|
+
should be added to every request call in the `path`.
|
|
10
|
+
For instance, if you need to send a request to the `/hello` route of your upstream server,
|
|
11
|
+
the `path` should be `path: 'http://upstream.server:port/hello?foo=bar'`.
|
|
12
|
+
|
|
13
|
+
If you proxy requires basic authentication, you can send it via the `proxy-authorization` header.
|
|
14
|
+
|
|
15
|
+
### Connect without authentication
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
import { Client } from 'undici'
|
|
19
|
+
import { createServer } from 'http'
|
|
20
|
+
import { createProxy } from 'proxy'
|
|
21
|
+
|
|
22
|
+
const server = await buildServer()
|
|
23
|
+
const proxyServer = await buildProxy()
|
|
24
|
+
|
|
25
|
+
const serverUrl = `http://localhost:${server.address().port}`
|
|
26
|
+
const proxyUrl = `http://localhost:${proxyServer.address().port}`
|
|
27
|
+
|
|
28
|
+
server.on('request', (req, res) => {
|
|
29
|
+
console.log(req.url) // '/hello?foo=bar'
|
|
30
|
+
res.setHeader('content-type', 'application/json')
|
|
31
|
+
res.end(JSON.stringify({ hello: 'world' }))
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
const client = new Client(proxyUrl)
|
|
35
|
+
|
|
36
|
+
const response = await client.request({
|
|
37
|
+
method: 'GET',
|
|
38
|
+
path: serverUrl + '/hello?foo=bar'
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
response.body.setEncoding('utf8')
|
|
42
|
+
let data = ''
|
|
43
|
+
for await (const chunk of response.body) {
|
|
44
|
+
data += chunk
|
|
45
|
+
}
|
|
46
|
+
console.log(response.statusCode) // 200
|
|
47
|
+
console.log(JSON.parse(data)) // { hello: 'world' }
|
|
48
|
+
|
|
49
|
+
server.close()
|
|
50
|
+
proxyServer.close()
|
|
51
|
+
client.close()
|
|
52
|
+
|
|
53
|
+
function buildServer () {
|
|
54
|
+
return new Promise((resolve, reject) => {
|
|
55
|
+
const server = createServer()
|
|
56
|
+
server.listen(0, () => resolve(server))
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function buildProxy () {
|
|
61
|
+
return new Promise((resolve, reject) => {
|
|
62
|
+
const server = createProxy(createServer())
|
|
63
|
+
server.listen(0, () => resolve(server))
|
|
64
|
+
})
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Connect with authentication
|
|
69
|
+
|
|
70
|
+
```js
|
|
71
|
+
import { Client } from 'undici'
|
|
72
|
+
import { createServer } from 'http'
|
|
73
|
+
import { createProxy } from 'proxy'
|
|
74
|
+
|
|
75
|
+
const server = await buildServer()
|
|
76
|
+
const proxyServer = await buildProxy()
|
|
77
|
+
|
|
78
|
+
const serverUrl = `http://localhost:${server.address().port}`
|
|
79
|
+
const proxyUrl = `http://localhost:${proxyServer.address().port}`
|
|
80
|
+
|
|
81
|
+
proxyServer.authenticate = function (req) {
|
|
82
|
+
return req.headers['proxy-authorization'] === `Basic ${Buffer.from('user:pass').toString('base64')}`
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
server.on('request', (req, res) => {
|
|
86
|
+
console.log(req.url) // '/hello?foo=bar'
|
|
87
|
+
res.setHeader('content-type', 'application/json')
|
|
88
|
+
res.end(JSON.stringify({ hello: 'world' }))
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
const client = new Client(proxyUrl)
|
|
92
|
+
|
|
93
|
+
const response = await client.request({
|
|
94
|
+
method: 'GET',
|
|
95
|
+
path: serverUrl + '/hello?foo=bar',
|
|
96
|
+
headers: {
|
|
97
|
+
'proxy-authorization': `Basic ${Buffer.from('user:pass').toString('base64')}`
|
|
98
|
+
}
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
response.body.setEncoding('utf8')
|
|
102
|
+
let data = ''
|
|
103
|
+
for await (const chunk of response.body) {
|
|
104
|
+
data += chunk
|
|
105
|
+
}
|
|
106
|
+
console.log(response.statusCode) // 200
|
|
107
|
+
console.log(JSON.parse(data)) // { hello: 'world' }
|
|
108
|
+
|
|
109
|
+
server.close()
|
|
110
|
+
proxyServer.close()
|
|
111
|
+
client.close()
|
|
112
|
+
|
|
113
|
+
function buildServer () {
|
|
114
|
+
return new Promise((resolve, reject) => {
|
|
115
|
+
const server = createServer()
|
|
116
|
+
server.listen(0, () => resolve(server))
|
|
117
|
+
})
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function buildProxy () {
|
|
121
|
+
return new Promise((resolve, reject) => {
|
|
122
|
+
const server = createProxy(createServer())
|
|
123
|
+
server.listen(0, () => resolve(server))
|
|
124
|
+
})
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
# Undici Module vs. Node.js Built-in Fetch
|
|
2
|
+
|
|
3
|
+
Node.js has shipped a built-in `fetch()` implementation powered by undici since
|
|
4
|
+
Node.js v18. This guide explains the relationship between the `undici` npm
|
|
5
|
+
package and the built-in `fetch`, and when you should install one versus relying
|
|
6
|
+
on the other.
|
|
7
|
+
|
|
8
|
+
## Background
|
|
9
|
+
|
|
10
|
+
The `fetch()`, `Request`, `Response`, `Headers`, and `FormData` globals in
|
|
11
|
+
Node.js v18+ are provided by a version of undici that is bundled into Node.js
|
|
12
|
+
itself. You can check which version is bundled with:
|
|
13
|
+
|
|
14
|
+
```js
|
|
15
|
+
console.log(process.versions.undici); // e.g., "7.5.0"
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
When you install undici from npm, you get the full library with all of its
|
|
19
|
+
additional APIs, and potentially a newer release than what your Node.js version
|
|
20
|
+
bundles.
|
|
21
|
+
|
|
22
|
+
## Keep `fetch` and `FormData` from the same implementation
|
|
23
|
+
|
|
24
|
+
When you send a `FormData` body, keep `fetch` and `FormData` together from the
|
|
25
|
+
same implementation.
|
|
26
|
+
|
|
27
|
+
Use one of these patterns:
|
|
28
|
+
|
|
29
|
+
### Built-in globals
|
|
30
|
+
|
|
31
|
+
```js
|
|
32
|
+
const body = new FormData()
|
|
33
|
+
body.set('name', 'some')
|
|
34
|
+
body.set('someOtherProperty', '8000')
|
|
35
|
+
|
|
36
|
+
await fetch('https://example.com', {
|
|
37
|
+
method: 'POST',
|
|
38
|
+
body
|
|
39
|
+
})
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### `undici` module imports
|
|
43
|
+
|
|
44
|
+
```js
|
|
45
|
+
import { fetch, FormData } from 'undici'
|
|
46
|
+
|
|
47
|
+
const body = new FormData()
|
|
48
|
+
body.set('name', 'some')
|
|
49
|
+
body.set('someOtherProperty', '8000')
|
|
50
|
+
|
|
51
|
+
await fetch('https://example.com', {
|
|
52
|
+
method: 'POST',
|
|
53
|
+
body
|
|
54
|
+
})
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### `undici.install()` globals
|
|
58
|
+
|
|
59
|
+
If you want the installed `undici` package to provide the globals, call
|
|
60
|
+
[`install()`](/docs/api/GlobalInstallation.md):
|
|
61
|
+
|
|
62
|
+
```js
|
|
63
|
+
import { install } from 'undici'
|
|
64
|
+
|
|
65
|
+
install()
|
|
66
|
+
|
|
67
|
+
const body = new FormData()
|
|
68
|
+
body.set('name', 'some')
|
|
69
|
+
body.set('someOtherProperty', '8000')
|
|
70
|
+
|
|
71
|
+
await fetch('https://example.com', {
|
|
72
|
+
method: 'POST',
|
|
73
|
+
body
|
|
74
|
+
})
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
`install()` replaces the global `fetch`, `Headers`, `Response`, `Request`, and
|
|
78
|
+
`FormData` implementations with undici's versions, and also installs undici's
|
|
79
|
+
`WebSocket`, `CloseEvent`, `ErrorEvent`, `MessageEvent`, and `EventSource`
|
|
80
|
+
globals.
|
|
81
|
+
|
|
82
|
+
Avoid mixing implementations in the same request, for example:
|
|
83
|
+
|
|
84
|
+
```js
|
|
85
|
+
import { fetch } from 'undici'
|
|
86
|
+
|
|
87
|
+
const body = new FormData()
|
|
88
|
+
|
|
89
|
+
await fetch('https://example.com', {
|
|
90
|
+
method: 'POST',
|
|
91
|
+
body
|
|
92
|
+
})
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
```js
|
|
96
|
+
import { FormData } from 'undici'
|
|
97
|
+
|
|
98
|
+
const body = new FormData()
|
|
99
|
+
|
|
100
|
+
await fetch('https://example.com', {
|
|
101
|
+
method: 'POST',
|
|
102
|
+
body
|
|
103
|
+
})
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Those combinations may behave differently across Node.js and undici versions.
|
|
107
|
+
Using matching pairs keeps multipart handling predictable.
|
|
108
|
+
|
|
109
|
+
## When you do NOT need to install undici
|
|
110
|
+
|
|
111
|
+
If all of the following are true, you can rely on the built-in globals and skip
|
|
112
|
+
adding undici to your dependencies:
|
|
113
|
+
|
|
114
|
+
- You only need the standard Fetch API (`fetch`, `Request`, `Response`,
|
|
115
|
+
`Headers`, `FormData`).
|
|
116
|
+
- You are running Node.js v18 or later.
|
|
117
|
+
- You do not depend on features or bug fixes introduced in a version of undici
|
|
118
|
+
newer than the one bundled with your Node.js release.
|
|
119
|
+
- You want zero additional runtime dependencies.
|
|
120
|
+
- You want cross-platform interoperability with browsers and other runtimes
|
|
121
|
+
(Deno, Bun, Cloudflare Workers, etc.) using the same Fetch API surface.
|
|
122
|
+
|
|
123
|
+
This is common in applications that make straightforward HTTP requests or in
|
|
124
|
+
libraries that target multiple JavaScript runtimes.
|
|
125
|
+
|
|
126
|
+
## When you SHOULD install undici
|
|
127
|
+
|
|
128
|
+
Install undici from npm when you need capabilities beyond the standard Fetch API:
|
|
129
|
+
|
|
130
|
+
### Advanced HTTP APIs
|
|
131
|
+
|
|
132
|
+
undici exposes `request`, `stream`, `pipeline`, and `connect` methods that
|
|
133
|
+
provide lower-level control and significantly better performance than `fetch`:
|
|
134
|
+
|
|
135
|
+
```js
|
|
136
|
+
import { request } from 'undici';
|
|
137
|
+
|
|
138
|
+
const { statusCode, headers, body } = await request('https://example.com');
|
|
139
|
+
const data = await body.json();
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Connection pooling and dispatchers
|
|
143
|
+
|
|
144
|
+
`Client`, `Pool`, `BalancedPool`, `Agent`, and their configuration options
|
|
145
|
+
let you manage connection lifecycle, keep-alive behavior, pipelining depth,
|
|
146
|
+
and concurrency limits:
|
|
147
|
+
|
|
148
|
+
```js
|
|
149
|
+
import { Pool } from 'undici';
|
|
150
|
+
|
|
151
|
+
const pool = new Pool('https://example.com', { connections: 10 });
|
|
152
|
+
const { body } = await pool.request({ path: '/', method: 'GET' });
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Proxy support
|
|
156
|
+
|
|
157
|
+
`ProxyAgent` and `EnvHttpProxyAgent` handle HTTP(S) proxying. Note that
|
|
158
|
+
Node.js v22.21.0+ and v24.0.0+ support environment-variable-based proxy
|
|
159
|
+
configuration for the built-in `fetch` via the `--use-env-proxy` flag (or
|
|
160
|
+
`NODE_USE_ENV_PROXY=1`). However, undici's `ProxyAgent` still provides
|
|
161
|
+
programmatic control through the dispatcher API:
|
|
162
|
+
|
|
163
|
+
```js
|
|
164
|
+
import { ProxyAgent, fetch } from 'undici';
|
|
165
|
+
|
|
166
|
+
const proxyAgent = new ProxyAgent('https://my-proxy.example.com:8080');
|
|
167
|
+
const response = await fetch('https://example.com', { dispatcher: proxyAgent });
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Testing and mocking
|
|
171
|
+
|
|
172
|
+
`MockAgent`, `MockClient`, and `MockPool` let you intercept and mock HTTP
|
|
173
|
+
requests without patching globals or depending on external libraries:
|
|
174
|
+
|
|
175
|
+
```js
|
|
176
|
+
import { MockAgent, setGlobalDispatcher, fetch } from 'undici';
|
|
177
|
+
|
|
178
|
+
const mockAgent = new MockAgent();
|
|
179
|
+
setGlobalDispatcher(mockAgent);
|
|
180
|
+
|
|
181
|
+
const pool = mockAgent.get('https://example.com');
|
|
182
|
+
pool.intercept({ path: '/api' }).reply(200, { message: 'mocked' });
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Interceptors and middleware
|
|
186
|
+
|
|
187
|
+
Custom dispatchers and interceptors (retry, redirect, cache, DNS) give you
|
|
188
|
+
fine-grained control over how requests are processed.
|
|
189
|
+
|
|
190
|
+
### Newer version than what Node.js bundles
|
|
191
|
+
|
|
192
|
+
The npm package often includes features, performance improvements, and bug fixes
|
|
193
|
+
that have not yet landed in a Node.js release. If you need a specific fix or
|
|
194
|
+
feature, you can install a newer version directly.
|
|
195
|
+
|
|
196
|
+
## Version compatibility
|
|
197
|
+
|
|
198
|
+
| Node.js version | Bundled undici version | Notes |
|
|
199
|
+
|---|---|---|
|
|
200
|
+
| v18.x | ~5.x | `fetch` is experimental (behind `--experimental-fetch` in early v18) |
|
|
201
|
+
| v20.x | ~6.x | `fetch` is stable |
|
|
202
|
+
| v22.x | ~6.x / ~7.x | `fetch` is stable |
|
|
203
|
+
| v24.x | ~7.x | `fetch` is stable; env-proxy support via `--use-env-proxy` |
|
|
204
|
+
|
|
205
|
+
You can always check the exact bundled version at runtime with
|
|
206
|
+
`process.versions.undici`.
|
|
207
|
+
|
|
208
|
+
Installing undici from npm does not replace the built-in globals. If you want
|
|
209
|
+
your installed version to replace the global `fetch` and related classes, use
|
|
210
|
+
[`install()`](/docs/api/GlobalInstallation.md). Otherwise, import `fetch`
|
|
211
|
+
directly from `'undici'`:
|
|
212
|
+
|
|
213
|
+
```js
|
|
214
|
+
import { fetch } from 'undici' // uses your installed version, not the built-in
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## Further reading
|
|
218
|
+
|
|
219
|
+
- [API Reference: Fetch](/docs/api/Fetch.md)
|
|
220
|
+
- [API Reference: Client](/docs/api/Client.md)
|
|
221
|
+
- [API Reference: Pool](/docs/api/Pool.md)
|
|
222
|
+
- [API Reference: ProxyAgent](/docs/api/ProxyAgent.md)
|
|
223
|
+
- [API Reference: MockAgent](/docs/api/MockAgent.md)
|
|
224
|
+
- [API Reference: Global Installation](/docs/api/GlobalInstallation.md)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Writing tests
|
|
2
|
+
|
|
3
|
+
Undici is tuned for a production use case and its default will keep
|
|
4
|
+
a socket open for a few seconds after an HTTP request is completed to
|
|
5
|
+
remove the overhead of opening up a new socket. These settings that makes
|
|
6
|
+
Undici shine in production are not a good fit for using Undici in automated
|
|
7
|
+
tests, as it will result in longer execution times.
|
|
8
|
+
|
|
9
|
+
The following are good defaults that will keep the socket open for only 10ms:
|
|
10
|
+
|
|
11
|
+
```js
|
|
12
|
+
import { request, setGlobalDispatcher, Agent } from 'undici'
|
|
13
|
+
|
|
14
|
+
const agent = new Agent({
|
|
15
|
+
keepAliveTimeout: 10, // milliseconds
|
|
16
|
+
keepAliveMaxTimeout: 10 // milliseconds
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
setGlobalDispatcher(agent)
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Guarding against unexpected disconnects
|
|
23
|
+
|
|
24
|
+
Undici's `Client` automatically reconnects after a socket error. This means
|
|
25
|
+
a test can silently disconnect, reconnect, and still pass. Unfortunately,
|
|
26
|
+
this could mask bugs like unexpected parser errors or protocol violations.
|
|
27
|
+
To catch these silent reconnections, add a disconnect guard after creating
|
|
28
|
+
a `Client`:
|
|
29
|
+
|
|
30
|
+
```js
|
|
31
|
+
const { Client } = require('undici')
|
|
32
|
+
const { test, after } = require('node:test')
|
|
33
|
+
const { tspl } = require('@matteo.collina/tspl')
|
|
34
|
+
|
|
35
|
+
test('example with disconnect guard', async (t) => {
|
|
36
|
+
t = tspl(t, { plan: 1 })
|
|
37
|
+
|
|
38
|
+
const client = new Client('http://localhost:3000')
|
|
39
|
+
after(() => client.close())
|
|
40
|
+
|
|
41
|
+
client.on('disconnect', () => {
|
|
42
|
+
if (!client.closed && !client.destroyed) {
|
|
43
|
+
t.fail('unexpected disconnect')
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
// ... test logic ...
|
|
48
|
+
})
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
`client.close()` and `client.destroy()` both emit `'disconnect'` events, but
|
|
52
|
+
those are expected. The guard only fails when a disconnect happens during the
|
|
53
|
+
active test (i.e., `!client.closed && !client.destroyed` is true).
|
|
54
|
+
|
|
55
|
+
Skip the guard for tests where a disconnect is expected behavior, such as:
|
|
56
|
+
|
|
57
|
+
- Signal aborts (`signal.emit('abort')`, `ac.abort()`)
|
|
58
|
+
- Server-side destruction (`res.destroy()`, `req.socket.destroy()`)
|
|
59
|
+
- Client-side body destruction mid-stream (`data.body.destroy()`)
|
|
60
|
+
- Timeout errors (`HeadersTimeoutError`, `BodyTimeoutError`)
|
|
61
|
+
- Successful upgrades (the socket is detached from the `Client`)
|
|
62
|
+
- Retry/reconnect tests where the disconnect triggers the retry
|
|
63
|
+
- HTTP parser errors from malformed responses (`HTTPParserError`)
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { getGlobalDispatcher, setGlobalDispatcher } = require('./lib/global')
|
|
4
|
+
const EnvHttpProxyAgent = require('./lib/dispatcher/env-http-proxy-agent')
|
|
5
|
+
const fetchImpl = require('./lib/web/fetch').fetch
|
|
6
|
+
|
|
7
|
+
// Capture __filename at module load time for stack trace augmentation.
|
|
8
|
+
// This may be undefined when bundled in environments like Node.js internals.
|
|
9
|
+
const currentFilename = typeof __filename !== 'undefined' ? __filename : undefined
|
|
10
|
+
|
|
11
|
+
function appendFetchStackTrace (err, filename) {
|
|
12
|
+
if (!err || typeof err !== 'object') {
|
|
13
|
+
return
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const stack = typeof err.stack === 'string' ? err.stack : ''
|
|
17
|
+
const normalizedFilename = filename.replace(/\\/g, '/')
|
|
18
|
+
|
|
19
|
+
if (stack && (stack.includes(filename) || stack.includes(normalizedFilename))) {
|
|
20
|
+
return
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const capture = {}
|
|
24
|
+
Error.captureStackTrace(capture, appendFetchStackTrace)
|
|
25
|
+
|
|
26
|
+
if (!capture.stack) {
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const captureLines = capture.stack.split('\n').slice(1).join('\n')
|
|
31
|
+
|
|
32
|
+
err.stack = stack ? `${stack}\n${captureLines}` : capture.stack
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
module.exports.fetch = function fetch (init, options = undefined) {
|
|
36
|
+
return fetchImpl(init, options).catch(err => {
|
|
37
|
+
if (currentFilename) {
|
|
38
|
+
appendFetchStackTrace(err, currentFilename)
|
|
39
|
+
} else if (err && typeof err === 'object') {
|
|
40
|
+
Error.captureStackTrace(err, module.exports.fetch)
|
|
41
|
+
}
|
|
42
|
+
throw err
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
module.exports.FormData = require('./lib/web/fetch/formdata').FormData
|
|
46
|
+
module.exports.Headers = require('./lib/web/fetch/headers').Headers
|
|
47
|
+
module.exports.Response = require('./lib/web/fetch/response').Response
|
|
48
|
+
module.exports.Request = require('./lib/web/fetch/request').Request
|
|
49
|
+
|
|
50
|
+
const { CloseEvent, ErrorEvent, MessageEvent, createFastMessageEvent } = require('./lib/web/websocket/events')
|
|
51
|
+
module.exports.WebSocket = require('./lib/web/websocket/websocket').WebSocket
|
|
52
|
+
module.exports.CloseEvent = CloseEvent
|
|
53
|
+
module.exports.ErrorEvent = ErrorEvent
|
|
54
|
+
module.exports.MessageEvent = MessageEvent
|
|
55
|
+
module.exports.createFastMessageEvent = createFastMessageEvent
|
|
56
|
+
|
|
57
|
+
module.exports.EventSource = require('./lib/web/eventsource/eventsource').EventSource
|
|
58
|
+
|
|
59
|
+
const api = require('./lib/api')
|
|
60
|
+
const Dispatcher = require('./lib/dispatcher/dispatcher')
|
|
61
|
+
Object.assign(Dispatcher.prototype, api)
|
|
62
|
+
// Expose the fetch implementation to be enabled in Node.js core via a flag
|
|
63
|
+
module.exports.EnvHttpProxyAgent = EnvHttpProxyAgent
|
|
64
|
+
module.exports.getGlobalDispatcher = getGlobalDispatcher
|
|
65
|
+
module.exports.setGlobalDispatcher = setGlobalDispatcher
|