Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Major refactoring #921

Merged
merged 35 commits into from
Nov 16, 2019
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
c29d4d3
init
szmarczak Nov 5, 2019
fcc18f8
Big big changes
szmarczak Nov 6, 2019
b803076
fixes
szmarczak Nov 7, 2019
3ceba12
Merge with master
szmarczak Nov 7, 2019
29fee34
remove unnecessary semicolon
szmarczak Nov 7, 2019
d5a2ff2
enhancements
szmarczak Nov 7, 2019
5236d84
rename stream to isStream
szmarczak Nov 7, 2019
c7dbe1e
throw on legacy url input
szmarczak Nov 7, 2019
f1f203a
enhancements
szmarczak Nov 10, 2019
461e8d9
bug fixes
szmarczak Nov 10, 2019
b044037
fixes
szmarczak Nov 10, 2019
22c36bf
fix option merge
szmarczak Nov 11, 2019
aedac8c
more bug fixes
szmarczak Nov 11, 2019
d7c7d53
fixes
szmarczak Nov 11, 2019
507a3cc
make tests pass
szmarczak Nov 11, 2019
9255df7
remove todo
szmarczak Nov 11, 2019
778cf67
Remove got.create() & update docs
szmarczak Nov 12, 2019
e8ff08b
update docs
szmarczak Nov 12, 2019
0841642
another fix
szmarczak Nov 12, 2019
fe76e8c
nitpick
szmarczak Nov 12, 2019
3def303
types
szmarczak Nov 12, 2019
695ebaf
generic cookiejar object
szmarczak Nov 12, 2019
52496df
make tests pass
szmarczak Nov 12, 2019
c6b22e1
Refactor the got() function, aka: fix bugs
szmarczak Nov 14, 2019
ef32a0e
Throw on null value headers
szmarczak Nov 14, 2019
dde0b76
bug fixes
szmarczak Nov 14, 2019
a0850bd
Improve is usage
szmarczak Nov 14, 2019
0d9baf1
remove useless line
szmarczak Nov 14, 2019
42b2605
comments
szmarczak Nov 14, 2019
3b313a7
call beforeRetry hook when retrying in afterResponse hook
szmarczak Nov 14, 2019
518c00d
nitpicks
szmarczak Nov 15, 2019
7f2f477
nitpicks
szmarczak Nov 15, 2019
5bc7319
nitpicks
szmarczak Nov 15, 2019
3ff5ebb
no unnecessary escape
szmarczak Nov 15, 2019
a7e73f2
Update readme.md
sindresorhus Nov 16, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
113 changes: 0 additions & 113 deletions documentation/advanced-creation.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,119 +2,6 @@

> Make calling REST APIs easier by creating niche-specific `got` instances.

#### got.create(settings)

Example: [gh-got](https://github.com/sindresorhus/gh-got/blob/master/index.js)

Configures a new `got` instance with the provided settings. You can access the resolved options with the `.defaults` property on the instance.

**Note:** In contrast to [`got.extend()`](../readme.md#gotextendinstances), this method has no defaults.

##### [options](readme.md#options)

To inherit from the parent, set it to `got.defaults.options` or use [`got.mergeOptions(defaults.options, options)`](../readme.md#gotmergeoptionsparentoptions-newoptions).<br>
**Note:** Avoid using [object spread](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals) as it doesn't work recursively.

##### mutableDefaults

Type: `boolean`<br>
Default: `false`

States if the defaults are mutable. It can be useful when you need to [update headers over time](readme.md#hooksafterresponse), for example, update an access token when it expires.

##### handlers

Type: `Function[]`<br>
Default: `[]`

An array of functions. You execute them directly by calling `got()`. They are some sort of "global hooks" - these functions are called first. The last handler (*it's hidden*) is either [`asPromise`](../source/as-promise.ts) or [`asStream`](../source/as-stream.ts), depending on the `options.stream` property.

To inherit from the parent, set it as `got.defaults.handlers`.<br>
To use the default handler, just omit specifying this.

Each handler takes two arguments:

###### [options](readme.md#options)

**Note:** These options are [normalized](source/normalize-arguments.js).

###### next()

Returns a `Promise` or a `Stream` depending on [`options.stream`](readme.md#stream).

```js
const settings = {
handlers: [
(options, next) => {
if (options.stream) {
// It's a Stream, so we can perform stream-specific actions on it
return next(options)
.on('request', request => {
setTimeout(() => {
request.abort();
}, 50);
});
}

// It's a Promise
return next(options);
}
],
options: got.mergeOptions(got.defaults.options, {
responseType: 'json'
})
};

const jsonGot = got.create(settings);
```

Sometimes you don't need to use `got.create(defaults)`. You should go for `got.extend(options)` if you don't want to overwrite the defaults:

```js
const settings = {
handler: got.defaults.handler,
options: got.mergeOptions(got.defaults.options, {
headers: {
unicorn: 'rainbow'
}
})
};

const unicorn = got.create(settings);

// Same as:
const unicorn = got.extend({headers: {unicorn: 'rainbow'}});
```

**Note:** Handlers can be asynchronous. The recommended approach is:

```js
const handler = (options, next) => {
if (options.stream) {
// It's a Stream
return next(options);
}

// It's a Promise
return (async () => {
try {
const response = await next(options);

response.yourOwnProperty = true;

return response;
} catch (error) {
// Every error will be replaced by this one.
// Before you receive any error here,
// it will be passed to the `beforeError` hooks first.

// Note: this one won't be passed to `beforeError` hook. It's final.
throw new Error('Your very own error.');
}
})();
};
```

### Merging instances

Got supports composing multiple instances together. This is very powerful. You can create a client that limits download speed and then compose it with an instance that signs a request. It's like plugins without any of the plugin mess. You just create instances and then compose them together.
Expand Down
2 changes: 1 addition & 1 deletion documentation/examples/gh-got.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const instance = got.extend({
}

// Don't touch streams
if (options.stream) {
if (options.isStream) {
return next(options);
}

Expand Down
4 changes: 2 additions & 2 deletions documentation/lets-make-a-plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ We should name our errors, just to know if the error is from the API response. S
}

// Don't touch streams
if (options.stream) {
if (options.isStream) {
return next(options);
}

Expand Down Expand Up @@ -197,7 +197,7 @@ const getRateLimit = ({headers}) => ({
}

// Don't touch streams
if (options.stream) {
if (options.isStream) {
return next(options);
}

Expand Down
114 changes: 101 additions & 13 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ It's a `GET` request by default, but can be changed by using different methods o

#### got([url], [options])

Returns a Promise for a [`response` object](#response) or a [stream](#streams-1) if `options.stream` is set to true.
Returns a Promise for a [`response` object](#response) or a [stream](#streams-1) if `options.isStream` is set to true.

##### url

Expand Down Expand Up @@ -154,9 +154,9 @@ Default: `{}`

Request headers.

Existing headers will be overwritten. Headers set to `null` will be omitted.
Existing headers will be overwritten. Headers set to `undefined` will be omitted.

###### stream
###### isStream

Type: `boolean`<br>
Default: `false`
Expand Down Expand Up @@ -246,11 +246,23 @@ When set to `true` the promise will return the [Response body](#body-1) instead

###### cookieJar

Type: [`tough.CookieJar` instance](https://github.com/salesforce/tough-cookie#cookiejar)
Type: `object` | [`tough.CookieJar` instance](https://github.com/salesforce/tough-cookie#cookiejar)

**Note:** If you provide this option, `options.headers.cookie` will be overridden.

Cookie support. You don't have to care about parsing or how to store them. [Example.](#cookies)
Cookie support. You don't have to care about parsing or how to store them. [Example](#cookies).

###### cookieJar.setCookie

Type: `Function<Promise>`

The function takes two arguments: `rawCookie` (`string`) and `url` (`string`).

###### cookieJar.getCookieString

Type: `Function<Promise>`

The function takes one argument: `url` (`string`).

###### ignoreInvalidCookies

Expand Down Expand Up @@ -280,8 +292,6 @@ If set to `true` and the `Content-Type` header is not set, it will be set to `ap

Type: `string | object<string, string | number> | URLSearchParams`

**Note:** The `query` option was renamed to `searchParams` in Got v10. The `query` option name is still functional, but is being deprecated and will be completely removed in Got v11.

Query string that will be added to the request URL. This will override the query string in `url`.

If you need to pass in an array, you can do it using a `URLSearchParams` instance:
Expand Down Expand Up @@ -518,6 +528,8 @@ got.post('https://example.com', {
});
```

**Note:** When retrying in a `afterResponse` hook, all remaining `beforeRetry` hooks will be called without the `error` and `retryCount` arguments.
sindresorhus marked this conversation as resolved.
Show resolved Hide resolved

###### hooks.afterResponse

Type: `Function[]`<br>
Expand Down Expand Up @@ -677,7 +689,7 @@ The number of times the request was retried.

#### got.stream(url, [options])

Sets `options.stream` to `true`.
Sets `options.isStream` to `true`.

Returns a [duplex stream](https://nodejs.org/api/stream.html#stream_class_stream_duplex) with additional events:

Expand Down Expand Up @@ -789,8 +801,6 @@ client.get('/demo');
})();
```

**Tip:** Need more control over the behavior of Got? Check out the [`got.create()`](documentation/advanced-creation.md).

Additionally, `got.extend()` accepts two properties from the `defaults` object: `mutableDefaults` and `handlers`. Example:

```js
Expand All @@ -808,6 +818,34 @@ const mergedHandlers = got.extend({
});
```

**Note:** Handlers can be asynchronous. The recommended approach is:

```js
const handler = (options, next) => {
if (options.stream) {
// It's a Stream
return next(options);
}

// It's a Promise
return (async () => {
try {
const response = await next(options);
response.yourOwnProperty = true;
return response;
} catch (error) {
// Every error will be replaced by this one.
// Before you receive any error here,
// it will be passed to the `beforeError` hooks first.
// Note: this one won't be passed to `beforeError` hook. It's final.
throw new Error('Your very own error.');
}
})();
};

const instance = got.extend({handlers: [handler]});
```

#### got.extend(...instances)

Merges many instances into a single one:
Expand Down Expand Up @@ -862,7 +900,57 @@ Options are deeply merged to a new object. The value of each key is determined a

Type: `object`

The default Got options used in that instance.
The Got defaults used in that instance.

##### [options](readme.md#options)
szmarczak marked this conversation as resolved.
Show resolved Hide resolved

##### handlers

Type: `Function[]`<br>
Default: `[]`

An array of functions. You execute them directly by calling `got()`. They are some sort of "global hooks" - these functions are called first. The last handler (*it's hidden*) is either [`asPromise`](../source/as-promise.ts) or [`asStream`](../source/as-stream.ts), depending on the `options.isStream` property.
szmarczak marked this conversation as resolved.
Show resolved Hide resolved

Each handler takes two arguments:

###### [options](readme.md#options)
szmarczak marked this conversation as resolved.
Show resolved Hide resolved

###### next()

Returns a `Promise` or a `Stream` depending on [`options.isStream`](../readme.md#isstream).
szmarczak marked this conversation as resolved.
Show resolved Hide resolved

```js
const settings = {
handlers: [
(options, next) => {
if (options.isStream) {
// It's a Stream, so we can perform stream-specific actions on it
return next(options)
.on('request', request => {
setTimeout(() => {
request.abort();
}, 50);
});
}

// It's a Promise
return next(options);
}
],
options: got.mergeOptions(got.defaults.options, {
responseType: 'json'
})
};

const jsonGot = got.create(settings);
```

##### mutableDefaults

Type: `boolean`<br>
Default: `false`

A read-only boolean describing whether the defaults are mutable or not. If set to `true`, you can [update headers over time](../readme.md#hooksafterresponse), for example, update an access token when it expires.
szmarczak marked this conversation as resolved.
Show resolved Hide resolved

## Errors

Expand Down Expand Up @@ -1229,7 +1317,7 @@ const got = require('got');

### User Agent

It's a good idea to set the `'user-agent'` header so the provider can more easily see how their resource is used. By default, it's the URL to this repo. You can omit this header by setting it to `null`.
It's a good idea to set the `'user-agent'` header so the provider can more easily see how their resource is used. By default, it's the URL to this repo. You can omit this header by setting it to `undefined`.

```js
const got = require('got');
Expand All @@ -1243,7 +1331,7 @@ got('https://sindresorhus.com', {

got('https://sindresorhus.com', {
headers: {
'user-agent': null
'user-agent': undefined
}
});
```
Expand Down