Repository: sindresorhus/got
Pull request #530 (2018-07-19 11:27:09)

Expose `assignOptions`
IOW: the correct way to inherit from options.

sindresorhus: Makes sense to me, but then `assignOptions` needs to be documented properly in the API docs: https://github.com/sindresorhus/got#api
szmarczak: Yeah, completely forgot about this.

Patch:
diff --git a/advanced-creation.md b/advanced-creation.md
index 0cae26a..b7a8993 100644
--- a/advanced-creation.md
+++ b/advanced-creation.md
@@ -11,7 +11,8 @@ Configure a new `got` instance with the provided settings.<br>
 
 ##### [options](readme.md#options)
 
-To inherit from parent, set it as `got.defaults.options` or use [object spread](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals).
+To inherit from parent, set it as `got.defaults.options` or use [`got.assignOptions(defaults.options, options)`](readme.md#gotassignoptionsparentoptions-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.
 
 ##### methods
 
@@ -53,10 +54,9 @@ const settings = {
 		return next(options);
 	},
 	methods: got.defaults.methods,
-	options: {
-		...got.defaults.options,
+	options: got.assignOptions(got.defaults.options, {
 		json: true
-	}
+	})
 };
 
 const jsonGot = got.create(settings);
@@ -99,12 +99,11 @@ const unchangedGot = got.create(defaults);
 const settings = {
 	handler: got.defaults.handler,
 	methods: got.defaults.methods,
-	options: {
-		...got.defaults.options,
+	options: got.assignOptions(got.defaults.options, {
 		headers: {
 			unicorn: 'rainbow'
 		}
-	}
+	})
 };
 
 const unicorn = got.create(settings);
diff --git a/readme.md b/readme.md
index 5e20aaf..643c435 100644
--- a/readme.md
+++ b/readme.md
@@ -398,6 +398,18 @@ client.get('/demo');
 
 *Need more control over the behavior of Got? Check out the [`got.create()`](advanced-creation.md).*
 
+#### got.assignOptions(parentOptions, newOptions)
+
+Extends parent options. 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:
+
+```js
+const a = {headers: {cat: 'meow'}};
+const b = {headers: {dog: 'woof'}};
+ 
+{...a, ...b}            // => {headers: {dog: 'woof'}}
+got.assignOptions(a, b) // => {headers: {cat: 'meow', dog: 'woof'}}
+```
+
 ## Errors
 
 Each error contains (if available) `statusCode`, `statusMessage`, `host`, `hostname`, `method`, `path`, `protocol` and `url` properties to make debugging easier.
diff --git a/source/create.js b/source/create.js
index 41bb8de..a649373 100644
--- a/source/create.js
+++ b/source/create.js
@@ -46,7 +46,7 @@ const create = defaults => {
 		got.stream[method] = (url, options) => got.stream(url, {...options, method});
 	}
 
-	Object.assign(got, errors);
+	Object.assign(got, {...errors, assignOptions});
 	Object.defineProperty(got, 'defaults', {
 		value: deepFreeze(defaults),
 		writable: false,


Test patch:
diff --git a/test/create.js b/test/create.js
index c225dff..b08b62a 100644
--- a/test/create.js
+++ b/test/create.js
@@ -105,10 +105,9 @@ test('no tampering with defaults', t => {
 	const instance = got.create({
 		handler: got.defaults.handler,
 		methods: got.defaults.methods,
-		options: {
-			...got.defaults.options,
+		options: got.assignOptions(got.defaults.options, {
 			baseUrl: 'example'
-		}
+		})
 	});
 
 	const instance2 = instance.create({