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

Pass normalized options to the handler #532

Merged
merged 4 commits into from
Jul 25, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 6 additions & 8 deletions advanced-creation.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,26 +31,26 @@ Function making additional changes to the request.
To inherit from parent, set it as `got.defaults.handler`.<br>
To use the default handler, just omit specifying this.

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

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

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

###### next()

Normalizes arguments and returns a `Promise` or a `Stream` depending on [`options.stream`](readme.md#stream).

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

// It's a Promise
return next(url, options);
return next(options);
},
methods: got.defaults.methods,
options: {
Expand All @@ -64,9 +64,7 @@ const jsonGot = got.create(settings);

```js
const defaults = {
handler: (url, options, next) => {
return next(url, options);
},
handler: (options, next) => next(options),
methods: [
'get',
'post',
Expand Down
18 changes: 4 additions & 14 deletions source/create.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,12 @@
'use strict';
const URLGlobal = typeof URL === 'undefined' ? require('url').URL : URL; // TODO: Use the `URL` global when targeting Node.js 10
const errors = require('./errors');
const assignOptions = require('./assign-options');
const asStream = require('./as-stream');
const asPromise = require('./as-promise');
const normalizeArguments = require('./normalize-arguments');
const deepFreeze = require('./deep-freeze');

const makeNext = defaults => (path, options) => {
let url = path;

if (options.baseUrl) {
url = new URLGlobal(path, options.baseUrl);
}

options = normalizeArguments(url, options, defaults);

const next = options => {
if (options.stream) {
return asStream(options);
}
Expand All @@ -24,15 +15,14 @@ const makeNext = defaults => (path, options) => {
};

const create = defaults => {
const next = makeNext(defaults);
if (!defaults.handler) {
defaults.handler = next;
defaults.handler = (options, next) => next(options);
}

function got(url, options) {
try {
options = assignOptions(defaults.options, options);
return defaults.handler(url, options, next);
return defaults.handler(normalizeArguments(url, options, defaults), next);
} catch (error) {
return Promise.reject(error);
}
Expand All @@ -48,7 +38,7 @@ const create = defaults => {
got.stream = (url, options) => {
options = assignOptions(defaults.options, options);
options.stream = true;
return defaults.handler(url, options, next);
return defaults.handler(normalizeArguments(url, options, defaults), next);
};

for (const method of defaults.methods) {
Expand Down
30 changes: 19 additions & 11 deletions source/normalize-arguments.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict';
const URLSearchParamsGlobal = typeof URLSearchParams === 'undefined' ? require('url').URLSearchParams : URLSearchParams; // TODO: Use the `URL` global when targeting Node.js 10
const URLGlobal = typeof URL === 'undefined' ? require('url').URL : URL; // TODO: Use the `URL` global when targeting Node.js 10
const URLSearchParamsGlobal = typeof URLSearchParams === 'undefined' ? require('url').URLSearchParams : URLSearchParams;
const is = require('@sindresorhus/is');
const toReadableStream = require('to-readable-stream');
const urlParseLax = require('url-parse-lax');
Expand All @@ -17,25 +18,32 @@ module.exports = (url, options, defaults) => {

if (!is.string(url) && !is.object(url)) {
throw new TypeError(`Parameter \`url\` must be a string or object, not ${is(url)}`);
} else if (is.string(url)) {
url = url.replace(/^unix:/, 'http://$&');
}

try {
decodeURI(url);
} catch (_) {
throw new Error('Parameter `url` must contain valid UTF-8 character sequences');
}
if (is.string(url)) {
if (options.baseUrl) {
url = urlToOptions(new URLGlobal(url, options.baseUrl));
} else {
url = url.replace(/^unix:/, 'http://$&');

url = urlParseLax(url);
if (url.auth) {
throw new Error('Basic authentication must be done with the `auth` option');
try {
decodeURI(url);
} catch (_) {
throw new Error('Parameter `url` must contain valid UTF-8 character sequences');
}

url = urlParseLax(url);
if (url.auth) {
throw new Error('Basic authentication must be done with the `auth` option');
}
}
} else if (is(url) === 'URL') {
url = urlToOptions(url);
}

options = {
path: '',
headers: {},
...url,
protocol: url.protocol || 'http:', // Override both null/undefined with default protocol
...options
Expand Down
23 changes: 11 additions & 12 deletions test/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,17 +76,16 @@ test('custom headers (extend)', async t => {
t.is(headers.unicorn, 'rainbow');
});

test('custom endpoint with custom headers (create)', async t => {
const options = {headers: {unicorn: 'rainbow'}};
const handler = (url, options, next) => {
url = `${s.url}` + url;

return next(url, options);
};
const methods = ['get'];

const instance = got.create({options, methods, handler});
const headers = (await instance('/', {
test('create', async t => {
const instance = got.create({
options: {},
methods: ['get'],
handler: (options, next) => {
options.headers.unicorn = 'rainbow';
return next(options);
}
});
const headers = (await instance(s.url, {
json: true
})).body;
t.is(headers.unicorn, 'rainbow');
Expand All @@ -99,7 +98,7 @@ test('custom endpoint with custom headers (extend)', async t => {
json: true
})).body;
t.is(headers.unicorn, 'rainbow');
t.is(headers['user-agent'] === undefined, false);
t.not(headers['user-agent'], undefined);
});

test('no tampering with defaults', t => {
Expand Down