Repository: sindresorhus/got (ts)

Issue:
Cannot use custom agent with got.extend()
Hi,

Because of unfortunate [deepFreeze of defaults](https://github.com/sindresorhus/got/blob/b8a086f8da53d57fdf11ba49eefa01d778a4f69f/source/create.js#L62) I cannot longer use any agent defined in the way like:

```javascript
const agents = require("./keepalive");
const got = require("got");

const request = exports.request = got.extend({
  timeout: 4000,
  agent: {
    http: agents.httpAgent,
    https: agents.httpsAgent
  }
});
```

This code will always break with error like `Cannot add property localhost:8080:, object is not extensible` as internal structures of agent object are also freezed. I do not want to set it per request as it is the main reason of `got.extend` existence...


Pull request description:
Don't freeze any other values than plain objects and arrays
Fixes #576

Patch:
diff --git a/source/deep-freeze.js b/source/deep-freeze.js
index b4ded11..5052b71 100644
--- a/source/deep-freeze.js
+++ b/source/deep-freeze.js
@@ -3,7 +3,7 @@ const is = require('@sindresorhus/is');
 
 module.exports = function deepFreeze(object) {
 	for (const [key, value] of Object.entries(object)) {
-		if (is.object(value)) {
+		if (is.plainObject(value) || is.array(value)) {
 			deepFreeze(object[key]);
 		}
 	}


Test patch:
diff --git a/test/create.js b/test/create.js
index ddafa80..4e688b8 100644
--- a/test/create.js
+++ b/test/create.js
@@ -1,3 +1,4 @@
+import http from 'http';
 import {URL} from 'url';
 import test from 'ava';
 import got from '../source';
@@ -145,6 +146,14 @@ test('no tampering with defaults', t => {
 	t.is(instance2.defaults.options.baseUrl, 'example');
 });
 
+test('only plain objects are freezed', async t => {
+	const instance = got.extend({
+		agent: new http.Agent({keepAlive: true})
+	});
+
+	await t.notThrowsAsync(() => instance(s.url));
+});
+
 test('defaults are cloned on instance creation', t => {
 	const options = {foo: 'bar', hooks: {beforeRequest: [() => {}]}};
 	const instance = got.create({options});