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
JSON improvements: throw if JSON parsing failed; number, boolean can be passed directly as payload for encoding to JSON #2613, #61, #907 #3688
Merged
jasonsaayman
merged 14 commits into
axios:master
from
DigitalBrainJS:feat/json-improvements
Apr 19, 2021
Merged
Changes from 11 commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
c26b1b5
Draft
DigitalBrainJS 4d06575
Merge branch 'master' of https://github.com/axios/axios into feat/jso…
DigitalBrainJS bc402a7
Added support for primitive types to be converted to JSON if the requ…
DigitalBrainJS 5112ba3
Fixed isOlderVersion helper;
DigitalBrainJS aa63605
Added forcedJSONParsing transitional option #2791
DigitalBrainJS b30a737
Merge branch 'master' into feat/json-improvements
DigitalBrainJS 7cdfb90
Merge branch 'master' of https://github.com/axios/axios into feat/jso…
DigitalBrainJS ba6d2bc
`transformData` is now called in the default configuration context if…
DigitalBrainJS 07441a6
Merge remote-tracking branch 'origin/feat/json-improvements' into fea…
DigitalBrainJS bb5b761
Merge branch 'master' into feat/json-improvements
DigitalBrainJS b8bd73c
Merge branch 'master' into feat/json-improvements
DigitalBrainJS e1340e0
Added `transitional.clarifyTimeoutError` to throw ETIMEDOUT error ins…
DigitalBrainJS f2dd788
Merge branch 'master' of https://github.com/axios/axios into feat/jso…
DigitalBrainJS d7f938b
Merge remote-tracking branch 'origin/feat/json-improvements' into fea…
DigitalBrainJS File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
'use strict'; | ||
|
||
var pkg = require('./../../package.json'); | ||
|
||
var validators = {}; | ||
|
||
// eslint-disable-next-line func-names | ||
['object', 'boolean', 'number', 'function', 'string', 'symbol'].forEach(function(type, i) { | ||
validators[type] = function validator(thing) { | ||
return typeof thing === type || 'a' + (i < 1 ? 'n ' : ' ') + type; | ||
}; | ||
}); | ||
|
||
var deprecatedWarnings = {}; | ||
var currentVerArr = pkg.version.split('.'); | ||
|
||
/** | ||
* Compare package versions | ||
* @param {string} version | ||
* @param {string?} thanVersion | ||
* @returns {boolean} | ||
*/ | ||
function isOlderVersion(version, thanVersion) { | ||
var pkgVersionArr = thanVersion ? thanVersion.split('.') : currentVerArr; | ||
var destVer = version.split('.'); | ||
for (var i = 0; i < 3; i++) { | ||
if (pkgVersionArr[i] > destVer[i]) { | ||
return true; | ||
} else if (pkgVersionArr[i] < destVer[i]) { | ||
return false; | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
/** | ||
* Transitional option validator | ||
* @param {function|boolean?} validator | ||
* @param {string?} version | ||
* @param {string} message | ||
* @returns {function} | ||
*/ | ||
validators.transitional = function transitional(validator, version, message) { | ||
var isDeprecated = version && isOlderVersion(version); | ||
|
||
function formatMessage(opt, desc) { | ||
return '[Axios v' + pkg.version + '] Transitional option \'' + opt + '\'' + desc + (message ? '. ' + message : ''); | ||
} | ||
|
||
// eslint-disable-next-line func-names | ||
return function(value, opt, opts) { | ||
if (validator === false) { | ||
throw new Error(formatMessage(opt, ' has been removed in ' + version)); | ||
} | ||
|
||
if (isDeprecated && !deprecatedWarnings[opt]) { | ||
deprecatedWarnings[opt] = true; | ||
// eslint-disable-next-line no-console | ||
console.warn( | ||
formatMessage( | ||
opt, | ||
' has been deprecated since v' + version + ' and will be removed in the near future' | ||
) | ||
); | ||
} | ||
|
||
return validator ? validator(value, opt, opts) : true; | ||
}; | ||
}; | ||
|
||
/** | ||
* Assert object's properties type | ||
* @param {object} options | ||
* @param {object} schema | ||
* @param {boolean} allowUnknown | ||
*/ | ||
|
||
function assertOptions(options, schema, allowUnknown) { | ||
if (typeof options !== 'object') { | ||
throw new TypeError('options must be an object'); | ||
} | ||
var keys = Object.keys(options); | ||
var i = keys.length; | ||
while (i-- > 0) { | ||
var opt = keys[i]; | ||
var validator = schema[opt]; | ||
if (validator) { | ||
var value = options[opt]; | ||
var result = value === undefined || validator(value, opt, options); | ||
if (result !== true) { | ||
throw new TypeError('option ' + opt + ' must be ' + result); | ||
} | ||
continue; | ||
} | ||
if (allowUnknown !== true) { | ||
throw Error('Unknown option ' + opt); | ||
} | ||
} | ||
} | ||
|
||
module.exports = { | ||
isOlderVersion: isOlderVersion, | ||
assertOptions: assertOptions, | ||
validators: validators | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
'use strict'; | ||
|
||
var validator = require('../../../lib/helpers/validator'); | ||
|
||
describe('validator::isOlderVersion', function () { | ||
it('should return true if dest version is older than the package version', function () { | ||
expect(validator.isOlderVersion('0.0.1', '1.0.0')).toEqual(true); | ||
expect(validator.isOlderVersion('0.0.1', '0.1.0')).toEqual(true); | ||
expect(validator.isOlderVersion('0.0.1', '0.0.1')).toEqual(false); | ||
|
||
|
||
expect(validator.isOlderVersion('100.0.0', '1.0.0')).toEqual(false); | ||
expect(validator.isOlderVersion('100.0.0', '0.1.0')).toEqual(false); | ||
expect(validator.isOlderVersion('100.0.0', '0.0.1')).toEqual(false); | ||
|
||
expect(validator.isOlderVersion('0.10000.0', '1000.0.1')).toEqual(true); | ||
}); | ||
}); | ||
|
||
describe('validator::assertOptions', function () { | ||
it('should throw only if unknown an option was passed', function () { | ||
expect(function() { | ||
validator.assertOptions({ | ||
x: true | ||
}, { | ||
y: validator.validators.boolean | ||
}); | ||
}).toThrow(new Error('Unknown option x')); | ||
|
||
expect(function() { | ||
validator.assertOptions({ | ||
x: true | ||
}, { | ||
x: validator.validators.boolean, | ||
y: validator.validators.boolean | ||
}); | ||
}).not.toThrow(new Error('Unknown option x')); | ||
}); | ||
|
||
it('should throw TypeError only if option type doesn\'t match', function () { | ||
expect(function() { | ||
validator.assertOptions({ | ||
x: 123 | ||
}, { | ||
x: validator.validators.boolean | ||
}); | ||
}).toThrow(new TypeError('option x must be a boolean')); | ||
|
||
expect(function() { | ||
validator.assertOptions({ | ||
x: true | ||
}, { | ||
x: validator.validators.boolean, | ||
y: validator.validators.boolean | ||
}); | ||
}).not.toThrow(); | ||
}); | ||
}); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
var pkg = require('./../../package.json');
tries to load my project's package.json which has no version key set, causing the application to fail on boot in the browser.what's the purpose of this validator and why does it need my project's package.json and a potentially non-existing version? (it was brought to my attention that that's the culprit after all - for the version is a required package.json field https://docs.npmjs.com/creating-a-package-json-file#required-name-and-version-fields)
it's a vue3/webpack project.
edit: seems to be related? #3499
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will have a look as to why this is happening
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's an edge case, really - people do the weirdest things in their project's package.json (as my own example showed). the fix is simple enough, the package.json just has to be valid and meet the minimum requirements (the version should be there at all times, technically - til).
yet, this issue might highlight a completely different problem. relying on the validity of / bundling the package.json might not be the best solution to use a version for negotiation (as seen in this PR) nor to be used for the user agent (as seen in the linked issue above where it is imported in the http adapter).
is this actually a path/loader issue and the version to be read is the one from axios' own package.json, not the project's? looking at the http adapter code it looks like it wants axios' version (
headers['User-Agent'] = 'axios/' + pkg.version;
)if that's the case then i'd assume that axios is potentially sending the wrong version (the project's it's used in) in the user agent header, too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meet the same question here, so do you know how to solve it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For me the solution was to add a version to
package.json
."version": "0.0.0"
works just fine.