Skip to content

Commit

Permalink
fix: implement fetch per spec (#928)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
ronag authored Aug 12, 2021
1 parent 75a4f1b commit 95c82ab
Show file tree
Hide file tree
Showing 37 changed files with 6,445 additions and 790 deletions.
22 changes: 15 additions & 7 deletions .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,33 @@ jobs:
- uses: actions/checkout@v2

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}

- name: Install
run: |
npm install
- name: Unit test (no coverage)
- name: Test Tap
run: |
npm test
npm run test:tap
- name: Unit test (coverage)
- name: Test Jest
run: |
npm run coverage:ci
npm run test:jest
- name: Test node-fetch
run: |
npm run test:node-fetch
- name: Test types
- name: Test Types
run: |
npm run test:typescript
- name: Coverage report
- name: Coverage
run: |
npm run coverage:ci
- name: Coverage Report
uses: codecov/codecov-action@v1
44 changes: 4 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,55 +155,19 @@ Calls `options.dispatch.connect(options)`.

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

https://fetch.spec.whatwg.org/

### `undici.fetch([url, options]): Promise`
### `undici.fetch(input[, init]): Promise`

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

https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch
https://fetch.spec.whatwg.org/#fetch-method

Only supported on Node 16+.

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.

Arguments:

* **url** `string | URL | object`
* **options** `RequestInit`

Returns: `Promise<Response>`

#### Parameter: `RequestInit`

https://fetch.spec.whatwg.org/#request-class

* **method** `string`
* **headers** `HeadersInit`
* **body** `BodyInit?`
* **referrer** *not supported*
* **referrerPolicy** *not supported*
* **mode** *not supported*
* **credentials** *not supported*
* **cache** *not supported*
* **redirect** `RequestRedirect`
* **integrity** *not supported*
* **keepalive** *not supported*
* **signal** `AbortSignal?`
* **window** `null`

#### Parameter: `Response`

https://fetch.spec.whatwg.org/#response-class

* **type** `ResponseType`
* **url** `string`
* **redirected** `boolean`
* **status** `number`
* **ok** `boolean`
* **statusText** `string`
* **headers** `Headers`

See [Dispatcher.fetch](docs/api/Dispatcher.md#dispatcherfetchoptions-callback) for more details.

### `undici.upgrade([url, options]): Promise`

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.
Expand Down
8 changes: 0 additions & 8 deletions docs/api/Dispatcher.md
Original file line number Diff line number Diff line change
Expand Up @@ -305,14 +305,6 @@ client.dispatch({
})
```

### `Dispatcher.fetch(options)`

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

Only supported on Node 16+.

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.

### `Dispatcher.pipeline(options, handler)`

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.
Expand Down
14 changes: 13 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ const MockAgent = require('./lib/mock/mock-agent')
const MockPool = require('./lib/mock/mock-pool')
const mockErrors = require('./lib/mock/mock-errors')

const nodeMajor = Number(process.versions.node.split('.')[0])

Object.assign(Dispatcher.prototype, api)

module.exports.Dispatcher = Dispatcher
Expand Down Expand Up @@ -84,7 +86,17 @@ function makeDispatcher (fn) {
module.exports.setGlobalDispatcher = setGlobalDispatcher
module.exports.getGlobalDispatcher = getGlobalDispatcher

module.exports.fetch = makeDispatcher(api.fetch)
if (nodeMajor >= 16) {
const fetchImpl = require('./lib/fetch')
module.exports.fetch = async function fetch (resource, init) {
const dispatcher = getGlobalDispatcher()
return fetchImpl.call(dispatcher, resource, init)
}
module.exports.Headers = require('./lib/fetch/headers').Headers
module.exports.Response = require('./lib/fetch/response').Response
module.exports.Request = require('./lib/fetch/request').Request
}

module.exports.request = makeDispatcher(api.request)
module.exports.stream = makeDispatcher(api.stream)
module.exports.pipeline = makeDispatcher(api.pipeline)
Expand Down
66 changes: 0 additions & 66 deletions lib/api/api-fetch/body.js

This file was deleted.

Loading

0 comments on commit 95c82ab

Please sign in to comment.