Comparing version 1.1.0 to 1.2.0
@@ -307,7 +307,11 @@ /** | ||
if (!options.bodyKeyCase || !this.isValidBodyKeyCase(options.bodyKeyCase)) { | ||
if (!this.isValidBodyKeyCase(options.bodyKeyCase)) { | ||
throw new Error('This body key formatting option is not allowed.'); | ||
} | ||
this.bodyKeyCase = options.bodyKeyCase; | ||
this.bodyKeyCase = options.bodyKeyCase; | ||
if (!this.isValidLogger(options.logger)) { | ||
throw new Error('The provided logger is not a function.'); | ||
} | ||
this.logger = options.logger; | ||
} | ||
@@ -318,5 +322,10 @@ | ||
value: function isValidBodyKeyCase(bodyKeyCase) { | ||
return Object.keys(BODY_KEY_CASE_OPTIONS).includes(bodyKeyCase); | ||
return bodyKeyCase && Object.keys(BODY_KEY_CASE_OPTIONS).includes(bodyKeyCase); | ||
} | ||
}, { | ||
key: 'isValidLogger', | ||
value: function isValidLogger(logger) { | ||
return typeof logger === 'function'; | ||
} | ||
}, { | ||
key: 'getBodyKeyConverter', | ||
@@ -520,3 +529,3 @@ value: function getBodyKeyConverter() { | ||
var defaultMetaOptions = { bodyKeyCase: 'SNAKE_CASE' }; | ||
var defaultMetaOptions = { bodyKeyCase: 'SNAKE_CASE', logger: function logger() {} }; | ||
@@ -526,3 +535,3 @@ var Snuffles = function () { | ||
var defaultRequestOptions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
var metaOptions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : defaultMetaOptions; | ||
var metaOptions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; | ||
classCallCheck(this, Snuffles); | ||
@@ -536,3 +545,4 @@ | ||
this.defaultRequestOptions = defaultRequestOptions; | ||
this.metaOptions = new MetaOptions(metaOptions); | ||
this.metaOptions = new MetaOptions(_extends({}, defaultMetaOptions, metaOptions)); | ||
this.log = this.metaOptions.logger; | ||
} | ||
@@ -595,2 +605,4 @@ | ||
value: function request(path) { | ||
var _this = this; | ||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
@@ -616,5 +628,8 @@ | ||
return fetch('' + url + queryString$$1, _extends({}, requestOptions)).then(function (res) { | ||
var urlWithQueryString = '' + url + queryString$$1; | ||
this.log('request', urlWithQueryString, requestOptions); | ||
return fetch(urlWithQueryString, _extends({}, requestOptions)).then(function (res) { | ||
if (!res.ok) { | ||
var error = new Error('API response was not ok.'); | ||
_this.log(_extends({}, res, { error: error })); | ||
error.response = res; | ||
@@ -626,5 +641,39 @@ throw error; | ||
}).then(function (res) { | ||
return res.json(); | ||
}).then(function (json) { | ||
return changeCaseObject_1.camelCase(json); | ||
return res.json().then(function (json) { | ||
var headers = {}; | ||
var _iteratorNormalCompletion = true; | ||
var _didIteratorError = false; | ||
var _iteratorError = undefined; | ||
try { | ||
for (var _iterator = res.headers.entries()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | ||
var pair = _step.value; | ||
headers[pair[0]] = pair[1]; | ||
} | ||
} catch (err) { | ||
_didIteratorError = true; | ||
_iteratorError = err; | ||
} finally { | ||
try { | ||
if (!_iteratorNormalCompletion && _iterator.return) { | ||
_iterator.return(); | ||
} | ||
} finally { | ||
if (_didIteratorError) { | ||
throw _iteratorError; | ||
} | ||
} | ||
} | ||
return { | ||
status: res.status, | ||
headers: headers, | ||
body: json | ||
}; | ||
}); | ||
}).then(function (parsedResponse) { | ||
parsedResponse.body = changeCaseObject_1.camelCase(parsedResponse.body); | ||
_this.log('response', parsedResponse); | ||
return parsedResponse.body; | ||
}); | ||
@@ -631,0 +680,0 @@ } |
@@ -309,7 +309,11 @@ 'use strict'; | ||
if (!options.bodyKeyCase || !this.isValidBodyKeyCase(options.bodyKeyCase)) { | ||
if (!this.isValidBodyKeyCase(options.bodyKeyCase)) { | ||
throw new Error('This body key formatting option is not allowed.'); | ||
} | ||
this.bodyKeyCase = options.bodyKeyCase; | ||
this.bodyKeyCase = options.bodyKeyCase; | ||
if (!this.isValidLogger(options.logger)) { | ||
throw new Error('The provided logger is not a function.'); | ||
} | ||
this.logger = options.logger; | ||
} | ||
@@ -320,5 +324,10 @@ | ||
value: function isValidBodyKeyCase(bodyKeyCase) { | ||
return Object.keys(BODY_KEY_CASE_OPTIONS).includes(bodyKeyCase); | ||
return bodyKeyCase && Object.keys(BODY_KEY_CASE_OPTIONS).includes(bodyKeyCase); | ||
} | ||
}, { | ||
key: 'isValidLogger', | ||
value: function isValidLogger(logger) { | ||
return typeof logger === 'function'; | ||
} | ||
}, { | ||
key: 'getBodyKeyConverter', | ||
@@ -522,3 +531,3 @@ value: function getBodyKeyConverter() { | ||
var defaultMetaOptions = { bodyKeyCase: 'SNAKE_CASE' }; | ||
var defaultMetaOptions = { bodyKeyCase: 'SNAKE_CASE', logger: function logger() {} }; | ||
@@ -528,3 +537,3 @@ var Snuffles = function () { | ||
var defaultRequestOptions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
var metaOptions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : defaultMetaOptions; | ||
var metaOptions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; | ||
classCallCheck(this, Snuffles); | ||
@@ -538,3 +547,4 @@ | ||
this.defaultRequestOptions = defaultRequestOptions; | ||
this.metaOptions = new MetaOptions(metaOptions); | ||
this.metaOptions = new MetaOptions(_extends({}, defaultMetaOptions, metaOptions)); | ||
this.log = this.metaOptions.logger; | ||
} | ||
@@ -597,2 +607,4 @@ | ||
value: function request(path) { | ||
var _this = this; | ||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
@@ -618,5 +630,8 @@ | ||
return fetch('' + url + queryString$$1, _extends({}, requestOptions)).then(function (res) { | ||
var urlWithQueryString = '' + url + queryString$$1; | ||
this.log('request', urlWithQueryString, requestOptions); | ||
return fetch(urlWithQueryString, _extends({}, requestOptions)).then(function (res) { | ||
if (!res.ok) { | ||
var error = new Error('API response was not ok.'); | ||
_this.log(_extends({}, res, { error: error })); | ||
error.response = res; | ||
@@ -628,5 +643,39 @@ throw error; | ||
}).then(function (res) { | ||
return res.json(); | ||
}).then(function (json) { | ||
return changeCaseObject_1.camelCase(json); | ||
return res.json().then(function (json) { | ||
var headers = {}; | ||
var _iteratorNormalCompletion = true; | ||
var _didIteratorError = false; | ||
var _iteratorError = undefined; | ||
try { | ||
for (var _iterator = res.headers.entries()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | ||
var pair = _step.value; | ||
headers[pair[0]] = pair[1]; | ||
} | ||
} catch (err) { | ||
_didIteratorError = true; | ||
_iteratorError = err; | ||
} finally { | ||
try { | ||
if (!_iteratorNormalCompletion && _iterator.return) { | ||
_iterator.return(); | ||
} | ||
} finally { | ||
if (_didIteratorError) { | ||
throw _iteratorError; | ||
} | ||
} | ||
} | ||
return { | ||
status: res.status, | ||
headers: headers, | ||
body: json | ||
}; | ||
}); | ||
}).then(function (parsedResponse) { | ||
parsedResponse.body = changeCaseObject_1.camelCase(parsedResponse.body); | ||
_this.log('response', parsedResponse); | ||
return parsedResponse.body; | ||
}); | ||
@@ -633,0 +682,0 @@ } |
{ | ||
"name": "snuffles", | ||
"version": "1.1.0", | ||
"version": "1.2.0", | ||
"description": "A wrapper around the native fetch function, returning the response body as a camelCased object", | ||
@@ -55,6 +55,6 @@ "author": "railslove", | ||
"dependencies": { | ||
"change-case-object": "2.0.0", | ||
"deepmerge": "2.2.1", | ||
"change-case-object": "2.0.0", | ||
"query-string": "4.1.0" | ||
} | ||
} |
@@ -65,2 +65,3 @@ <p align="center"> | ||
- **`bodyKeyCase`**: A string defining which casing the keys of a request body for **outgoing requests** should have. Can be either of `SNAKE_CASE`, `CAMEL_CASE` or `PARAM_CASE`. | ||
- **`logger`**: A custom logger function (see [Logging](#logging) section) | ||
@@ -71,3 +72,4 @@ If no object is passed for `metaOptions`, the following defaul configuration will be used: | ||
{ | ||
bodyKeyCase: 'SNAKE_CASE' | ||
bodyKeyCase: 'SNAKE_CASE', | ||
logger: () => {} // no-op logger | ||
} | ||
@@ -165,2 +167,29 @@ ``` | ||
## Logging | ||
For normal browser-based development the network tab in your browser's developer tools is probably all you need. | ||
If you should have custom logging requirements (e.g. if you work with React Native, where you cannot use the network tab in the remote React Native Debugger) you can pass in your custom logger function as an option to the 3rd argument of the `Snuffles()` constructor. | ||
Here is an example using [debug](https://github.com/visionmedia/debug) as a custom logger: | ||
```js | ||
import createDebug from 'debug' | ||
const debug = createDebug('api') | ||
const apiClient = new Snuffles( | ||
apiUrl, | ||
{ ... } | ||
{ logger: debug } | ||
) | ||
``` | ||
The first argument of each log call is always the `type` of the log entry (either `'request'` or `'response'`), so you can take advantage of this to log them differently. E.g. into separate logging namespaces: | ||
```js | ||
{ logger: (type, ...data) => createDebug(`api:${type}`)(...data) } | ||
``` | ||
Beware: if the logs should get persisted/streamed to anywhere, be careful that you could be exposing sensitive information like passwords, API tokens, which are part of the logged HTTP requests. | ||
## License | ||
@@ -167,0 +196,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
168304
1255
204
3