Skip to content

Commit 95c82ab

Browse files
authored
fix: implement fetch per spec (#928)
* fix: implement fetch per spec Also ports node-fetch tests. * fixup: strict null check * fixup: extractBody * fixup: body used * fixup: use instanceof Blob * fixup * fixup * fixup: isBodyReadable * fixup: localURLSOnly * fixup: timingAllow * fixup: timingInfo * fixup: disregard any enqueuing * fixup: strict cmp * fixup: clone * fixup: don't need to copy URL * fix: Response init * fixup: opaqueredirect * fixup: avoid new Response * fixup: abort default err * fixup: url * fixup: don't use body.source when writing request body * fixup * fixup * fixup: fixes from review * fixup: check valid reason phrase * fixup: error messages * fixup: isBuffer * fixup: more error msg * fixup: forbidden methods * fixup: node stream body does not violate spec * fixup: error msgs * fixup * fixup * fixup * fixup * fixup: chrome compat * fixup * fixup: error msgs * fixup * fixup: timingInfo * fixup: comments * fixup: prettier + standard --fix * fixup: bad port + missing cond * fixup: docs * fixup: move fetch to new folder * fixup: Dispatcher.fetch doesn't exist * fixup: link MDN docs * fixup * fixup: node fetch in CI * fixup: terminate on onError * fixup * fixup: transmit request body algorithm * fixup * fixup * fixup * fixup
1 parent 75a4f1b commit 95c82ab

37 files changed

+6445
-790
lines changed

.github/workflows/nodejs.yml

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,25 +20,33 @@ jobs:
2020
- uses: actions/checkout@v2
2121

2222
- name: Use Node.js ${{ matrix.node-version }}
23-
uses: actions/setup-node@v1
23+
uses: actions/setup-node@v2
2424
with:
2525
node-version: ${{ matrix.node-version }}
2626

2727
- name: Install
2828
run: |
2929
npm install
3030
31-
- name: Unit test (no coverage)
31+
- name: Test Tap
3232
run: |
33-
npm test
33+
npm run test:tap
3434
35-
- name: Unit test (coverage)
35+
- name: Test Jest
3636
run: |
37-
npm run coverage:ci
37+
npm run test:jest
38+
39+
- name: Test node-fetch
40+
run: |
41+
npm run test:node-fetch
3842
39-
- name: Test types
43+
- name: Test Types
4044
run: |
4145
npm run test:typescript
4246
43-
- name: Coverage report
47+
- name: Coverage
48+
run: |
49+
npm run coverage:ci
50+
51+
- name: Coverage Report
4452
uses: codecov/codecov-action@v1

README.md

Lines changed: 4 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -155,55 +155,19 @@ Calls `options.dispatch.connect(options)`.
155155

156156
See [Dispatcher.connect](docs/api/Dispatcher.md#dispatcherconnect) for more details.
157157

158-
https://fetch.spec.whatwg.org/
159-
160-
### `undici.fetch([url, options]): Promise`
158+
### `undici.fetch(input[, init]): Promise`
161159

162160
Implements [fetch](https://fetch.spec.whatwg.org/).
163161

162+
https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch
163+
https://fetch.spec.whatwg.org/#fetch-method
164+
164165
Only supported on Node 16+.
165166

166167
This is [experimental](https://nodejs.org/api/documentation.html#documentation_stability_index) and is not yet fully compliant the Fetch Standard. We plan to ship breaking changes to this feature until it is out of experimental.
167168

168-
Arguments:
169-
170-
* **url** `string | URL | object`
171-
* **options** `RequestInit`
172-
173169
Returns: `Promise<Response>`
174170

175-
#### Parameter: `RequestInit`
176-
177-
https://fetch.spec.whatwg.org/#request-class
178-
179-
* **method** `string`
180-
* **headers** `HeadersInit`
181-
* **body** `BodyInit?`
182-
* **referrer** *not supported*
183-
* **referrerPolicy** *not supported*
184-
* **mode** *not supported*
185-
* **credentials** *not supported*
186-
* **cache** *not supported*
187-
* **redirect** `RequestRedirect`
188-
* **integrity** *not supported*
189-
* **keepalive** *not supported*
190-
* **signal** `AbortSignal?`
191-
* **window** `null`
192-
193-
#### Parameter: `Response`
194-
195-
https://fetch.spec.whatwg.org/#response-class
196-
197-
* **type** `ResponseType`
198-
* **url** `string`
199-
* **redirected** `boolean`
200-
* **status** `number`
201-
* **ok** `boolean`
202-
* **statusText** `string`
203-
* **headers** `Headers`
204-
205-
See [Dispatcher.fetch](docs/api/Dispatcher.md#dispatcherfetchoptions-callback) for more details.
206-
207171
### `undici.upgrade([url, options]): Promise`
208172

209173
Upgrade to a different protocol. See [MDN - HTTP - Protocol upgrade mechanism](https://developer.mozilla.org/en-US/docs/Web/HTTP/Protocol_upgrade_mechanism) for more details.

docs/api/Dispatcher.md

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -305,14 +305,6 @@ client.dispatch({
305305
})
306306
```
307307

308-
### `Dispatcher.fetch(options)`
309-
310-
Implements [fetch](https://fetch.spec.whatwg.org/).
311-
312-
Only supported on Node 16+.
313-
314-
This is [experimental](https://nodejs.org/api/documentation.html#documentation_stability_index) and is not yet fully compliant the Fetch Standard. We plan to ship breaking changes to this feature until it is out of experimental.
315-
316308
### `Dispatcher.pipeline(options, handler)`
317309

318310
For easy use with [stream.pipeline](https://nodejs.org/api/stream.html#stream_stream_pipeline_source_transforms_destination_callback). The `handler` argument should return a `Readable` from which the result will be read. Usually it should just return the `body` argument unless some kind of transformation needs to be performed based on e.g. `headers` or `statusCode`. The `handler` should validate the response and save any required state. If there is an error, it should be thrown. The function returns a `Duplex` which writes to the request and reads from the response.

index.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ const MockAgent = require('./lib/mock/mock-agent')
1414
const MockPool = require('./lib/mock/mock-pool')
1515
const mockErrors = require('./lib/mock/mock-errors')
1616

17+
const nodeMajor = Number(process.versions.node.split('.')[0])
18+
1719
Object.assign(Dispatcher.prototype, api)
1820

1921
module.exports.Dispatcher = Dispatcher
@@ -84,7 +86,17 @@ function makeDispatcher (fn) {
8486
module.exports.setGlobalDispatcher = setGlobalDispatcher
8587
module.exports.getGlobalDispatcher = getGlobalDispatcher
8688

87-
module.exports.fetch = makeDispatcher(api.fetch)
89+
if (nodeMajor >= 16) {
90+
const fetchImpl = require('./lib/fetch')
91+
module.exports.fetch = async function fetch (resource, init) {
92+
const dispatcher = getGlobalDispatcher()
93+
return fetchImpl.call(dispatcher, resource, init)
94+
}
95+
module.exports.Headers = require('./lib/fetch/headers').Headers
96+
module.exports.Response = require('./lib/fetch/response').Response
97+
module.exports.Request = require('./lib/fetch/request').Request
98+
}
99+
88100
module.exports.request = makeDispatcher(api.request)
89101
module.exports.stream = makeDispatcher(api.stream)
90102
module.exports.pipeline = makeDispatcher(api.pipeline)

lib/api/api-fetch/body.js

Lines changed: 0 additions & 66 deletions
This file was deleted.

0 commit comments

Comments
 (0)