@trayio/threadneedle
Advanced tools
Comparing version 1.0.16 to 1.0.17
module.exports = { | ||
url: require('./url'), | ||
baseUrl: require('./baseUrl'), | ||
object: require('./object'), | ||
@@ -10,2 +10,2 @@ before: require('./before'), | ||
afterFailure: require('./afterFailure') | ||
}; | ||
}; |
@@ -66,3 +66,3 @@ var when = require('when'); | ||
// The URL endpoint. Query parameters allowed from here. | ||
var url = globalize.url.call(threadneedle, config, params); | ||
var url = globalize.baseUrl.call(threadneedle, config, params); | ||
// var url = globalize.call(threadneedle, config.globals, 'url', config, params); | ||
@@ -69,0 +69,0 @@ |
/* | ||
* Validate a response vs expected status codes and body. | ||
* | ||
* When something is not right, an __object__ is returned, containing | ||
* | ||
* When something is not right, an __object__ is returned, containing | ||
* full details on the response and how it compared to the expected values. | ||
@@ -16,3 +16,3 @@ * Sample object: | ||
statusCode: 201, | ||
body: { | ||
body: { | ||
created: true | ||
@@ -42,5 +42,5 @@ } | ||
var statusCode = res.statusCode; | ||
var bodyString = stringify(res.body); | ||
var bodyString = stringify(res.body); | ||
var errResponse = { | ||
statusCode: res.statusCode, | ||
statusCode: res.statusCode, | ||
body: res.body | ||
@@ -69,9 +69,37 @@ }; | ||
if (expects.statusCode.indexOf(res.statusCode) === -1) { | ||
return { | ||
code: 'invalid_response_status_code', | ||
message: 'Invalid response status code', | ||
var niceErrors = { | ||
400: { | ||
code: 'bad_request', | ||
message: 'Bad API request. Try checking your input properties.' | ||
}, | ||
401: { | ||
code: 'unauthorized', | ||
message: 'Unauthorized request. Have you added your API details correctly?' | ||
}, | ||
403: { | ||
code: 'forbidden', | ||
message: 'Forbidden. Check you have the appropriate permissions to access this resource.' | ||
}, | ||
404: { | ||
code: 'not_found', | ||
message: 'Not found. Looks like this has been removed.' | ||
} | ||
}; | ||
var error = { | ||
response: errResponse, | ||
expects: expects, | ||
}; | ||
} | ||
if (niceErrors[res.statusCode]) { | ||
error.code = niceErrors[res.statusCode].code; | ||
error.message = niceErrors[res.statusCode].message; | ||
} else { | ||
error.code = 'invalid_response_status_code'; | ||
error.message = 'Invalid response status code'; | ||
} | ||
return error; | ||
} | ||
} | ||
@@ -96,3 +124,1 @@ | ||
}; | ||
{ | ||
"name": "@trayio/threadneedle", | ||
"version": "1.0.16", | ||
"version": "1.0.17", | ||
"description": "A framework for simplifying working with HTTP-based APIs.", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
@@ -32,3 +32,3 @@ # threadneedle | ||
And to actually run the method and get the MailChimp lists: | ||
And to actually run the method and get the MailChimp lists: | ||
@@ -56,5 +56,5 @@ ```js | ||
The vast majority of threadneedle focuses around this singular method. Whenever you run `addMethod`, you're adding another method to the core `threadneedle` object. | ||
The vast majority of threadneedle focuses around this singular method. Whenever you run `addMethod`, you're adding another method to the core `threadneedle` object. | ||
You can declare template-style parameters to be passed into specific fields, using Mustache-style templating. | ||
You can declare template-style parameters to be passed into specific fields, using Mustache-style templating. | ||
@@ -115,3 +115,3 @@ Parameters are: | ||
### data | ||
### data | ||
@@ -249,8 +249,8 @@ The payload you'd like to send to the third party. Relevant for `put`, `delete,` and `post` methods only. | ||
body: 'error' | ||
} | ||
} | ||
} | ||
} | ||
``` | ||
Like `expects`, `notExpects` can be specified shorthand, or as a function. | ||
Like `expects`, `notExpects` can be specified shorthand, or as a function. | ||
@@ -261,3 +261,3 @@ | ||
If you'd like to map or alter the `params` before running the main request, you can use | ||
the `before` function argument. | ||
the `before` function argument. | ||
@@ -323,3 +323,3 @@ Runs **before** any templating or requests. | ||
Sometimes you'll want to modify the failure message in some way. You can do | ||
Sometimes you'll want to modify the failure message in some way. You can do | ||
@@ -334,3 +334,3 @@ ```js | ||
err.code = 'oauth_refresh'; | ||
} | ||
} | ||
@@ -347,3 +347,3 @@ // You can also return a promise to do async logic. It should resolve | ||
Sometimes you'll have a method which isn't REST-based, or you'd like to use a third-party wrapper. | ||
Sometimes you'll have a method which isn't REST-based, or you'd like to use a third-party wrapper. | ||
@@ -367,4 +367,4 @@ While this behaviour should be kept to a minimum, you can simply pass a function (that should return a promise) | ||
Another good use-case here is to create a method that wraps around a chain of other methods. | ||
Because these methods are run in the context where `this` is `threadneedle`, you can easily | ||
Another good use-case here is to create a method that wraps around a chain of other methods. | ||
Because these methods are run in the context where `this` is `threadneedle`, you can easily | ||
access the other methods you've declared: | ||
@@ -395,8 +395,8 @@ | ||
Typically you'll be creating one threadneedle instance for each third party API service | ||
(MailChimp, Facebook etc) you're integrating with. Sometimes these services will have | ||
generic response status codes and authentication criteria - and you'll want to write | ||
Typically you'll be creating one threadneedle instance for each third party API service | ||
(MailChimp, Facebook etc) you're integrating with. Sometimes these services will have | ||
generic response status codes and authentication criteria - and you'll want to write | ||
the logic once, rather than add the same logic across every method config. | ||
The philosophy of the `global` system is that the less you have to write in each method config, | ||
The philosophy of the `global` system is that the less you have to write in each method config, | ||
the better. | ||
@@ -406,3 +406,3 @@ | ||
* [url](#url-1) | ||
* [baseUrl](#baseurl-1) | ||
* [data](#data-1) | ||
@@ -430,6 +430,6 @@ * [query](#query-1) | ||
### url | ||
### baseUrl | ||
A base level URL. Automatically gets **prepended** to the individual method URL **unless** the | ||
method URL starts with http(s)://. (In which case the global `url` field has no affect on the call) | ||
A base level URL. (Previously `url`) Automatically gets **prepended** to the individual method URL **unless** the | ||
method URL starts with http(s)://. (In which case the global `baseUrl` field has no affect on the call) | ||
@@ -439,3 +439,3 @@ ```js | ||
{ | ||
url: 'https://{{dc}}.api.mailchimp.com/2.0' | ||
baseUrl: 'https://{{dc}}.api.mailchimp.com/2.0' | ||
} | ||
@@ -450,3 +450,3 @@ | ||
If `url` is a function, it will get evaluated and prepended. | ||
If `baseUrl` is a function, it will get evaluated and prepended. | ||
@@ -456,3 +456,3 @@ | ||
Data for POST, PUT etc that you want to send in every request. Gets deep extended by the `data` | ||
Data for POST, PUT etc that you want to send in every request. Gets deep extended by the `data` | ||
config in the individual methods. | ||
@@ -471,3 +471,3 @@ | ||
### query | ||
### query | ||
@@ -492,3 +492,3 @@ Query string data that you'd like to send in every request. Gets extended by the `query` object | ||
The options for the request. Gets deep extended into the `options` object. Great for things | ||
The options for the request. Gets deep extended into the `options` object. Great for things | ||
like header based authentication. | ||
@@ -510,3 +510,3 @@ | ||
Global [expects](#expects) config. Good for things like always expecting all calls to return with a | ||
Global [expects](#expects) config. Good for things like always expecting all calls to return with a | ||
specific set of status codes. | ||
@@ -529,3 +529,3 @@ | ||
Global [notExpects](#notexpects) config. Good for things like specifically flagging certain status | ||
Global [notExpects](#notexpects) config. Good for things like specifically flagging certain status | ||
codes as errors, or for automatically erroring when an `errors` field appears in the response. | ||
@@ -548,4 +548,4 @@ | ||
A function to run before every query happens. Runs **before** the `before` function declared | ||
in the model, if specified. | ||
A function to run before every query happens. Runs **before** the `before` function declared | ||
in the model, if specified. | ||
@@ -566,3 +566,3 @@ ```js | ||
Runs after a method runs successfully, immediately **before** the `afterSuccess` function | ||
Runs after a method runs successfully, immediately **before** the `afterSuccess` function | ||
of the individual method. | ||
@@ -581,8 +581,8 @@ | ||
### afterFailure | ||
### afterFailure | ||
Runs after a method runs successfully, immediately **before** the `afterFailure` function | ||
Runs after a method runs successfully, immediately **before** the `afterFailure` function | ||
of the individual method. | ||
A good example use-case here is a generic error handler for invalid status codes. For example: | ||
A good example use-case here is a generic error handler for invalid status codes. For example: | ||
@@ -605,3 +605,1 @@ * Campaign Monitor - a `121` status code means that an access token needs refreshing | ||
``` | ||
@@ -19,3 +19,3 @@ var assert = require('assert'); | ||
assert.strictEqual( | ||
globalize.url.call(sample, { url: '/mypath' }, {}), | ||
globalize.baseUrl.call(sample, { url: '/mypath' }, {}), | ||
'http://mydomain.com/mypath' | ||
@@ -25,3 +25,3 @@ ); | ||
assert.strictEqual( | ||
globalize.url.call(sample, { url: 'http://yourdomain.com/mypath' }, {}), | ||
globalize.baseUrl.call(sample, { url: 'http://yourdomain.com/mypath' }, {}), | ||
'http://yourdomain.com/mypath' | ||
@@ -31,3 +31,3 @@ ); | ||
assert.strictEqual( | ||
globalize.url.call(sample, { url: 'https://yourdomain.com/mypath' }, {}), | ||
globalize.baseUrl.call(sample, { url: 'https://yourdomain.com/mypath' }, {}), | ||
'https://yourdomain.com/mypath' | ||
@@ -45,3 +45,3 @@ ); | ||
assert.strictEqual( | ||
globalize.url.call(sample, { url: '/mypath/{{id}}' }, { | ||
globalize.baseUrl.call(sample, { url: '/mypath/{{id}}' }, { | ||
dc: 'us5', | ||
@@ -62,3 +62,3 @@ id: '123' | ||
assert.strictEqual( | ||
globalize.url.call(sample, { url: '/mypath/{{id}}?opt_fields={{fields}}' }, { | ||
globalize.baseUrl.call(sample, { url: '/mypath/{{id}}?opt_fields={{fields}}' }, { | ||
dc: 'us5', | ||
@@ -82,3 +82,3 @@ id: '123', | ||
assert.strictEqual( | ||
globalize.url.call(sample, { | ||
globalize.baseUrl.call(sample, { | ||
url: function(params) { | ||
@@ -103,3 +103,3 @@ return '/mypath/' + params.id; | ||
assert.strictEqual( | ||
globalize.url.call(sample, { url: '/mypath', globals: false }, {}), | ||
globalize.baseUrl.call(sample, { url: '/mypath', globals: false }, {}), | ||
'/mypath' | ||
@@ -266,3 +266,3 @@ ); | ||
}); | ||
}); | ||
}); | ||
@@ -314,2 +314,22 @@ it('should call the global promise before the local one', function (done) { | ||
it('should use baseUrl rather than url, but still fall back to url', function () { | ||
assert.strictEqual( | ||
globalize.baseUrl.call({ | ||
_globalOptions: { | ||
baseUrl: 'http://mydomain.com' | ||
} | ||
}, { url: '/mypath' }, {}), | ||
'http://mydomain.com/mypath' | ||
); | ||
assert.strictEqual( | ||
globalize.baseUrl.call({ | ||
_globalOptions: { | ||
url: 'http://mydomain.com' | ||
} | ||
}, { url: '/mypath' }, {}), | ||
'http://mydomain.com/mypath' | ||
); | ||
}); | ||
}); | ||
@@ -341,3 +361,3 @@ | ||
}; | ||
assert.deepEqual(globalize.expects.call(sample, {}), { | ||
assert.deepEqual(globalize.expects.call(sample, {}), { | ||
statusCode: [200, 201], | ||
@@ -356,6 +376,6 @@ body: ['chris'] | ||
expects: { | ||
statusCode: 201 | ||
statusCode: 201 | ||
} | ||
}), { | ||
statusCode: [201] | ||
}), { | ||
statusCode: [201] | ||
}); | ||
@@ -365,4 +385,4 @@ | ||
expects: 202 | ||
}), { | ||
statusCode: [202] | ||
}), { | ||
statusCode: [202] | ||
}); | ||
@@ -412,3 +432,3 @@ }); | ||
}; | ||
assert.deepEqual(globalize.notExpects.call(sample, {}), { | ||
assert.deepEqual(globalize.notExpects.call(sample, {}), { | ||
statusCode: [200, 201], | ||
@@ -427,6 +447,6 @@ body: ['chris'] | ||
notExpects: { | ||
statusCode: 201 | ||
statusCode: 201 | ||
} | ||
}), { | ||
statusCode: [201] | ||
}), { | ||
statusCode: [201] | ||
}); | ||
@@ -436,4 +456,4 @@ | ||
notExpects: 202 | ||
}), { | ||
statusCode: [202] | ||
}), { | ||
statusCode: [202] | ||
}); | ||
@@ -454,6 +474,6 @@ }); | ||
notExpects: { | ||
body: 'steve' | ||
body: 'steve' | ||
}, | ||
globals: false | ||
}), { | ||
}), { | ||
body: ['steve'] | ||
@@ -499,3 +519,3 @@ }); | ||
}); | ||
}); | ||
}); | ||
@@ -579,3 +599,3 @@ it('should call the global promise before the local one', function (done) { | ||
}); | ||
}); | ||
}); | ||
@@ -582,0 +602,0 @@ it('should call the global promise before the local one', function (done) { |
@@ -38,2 +38,20 @@ var assert = require('assert'); | ||
it('should make the errors nicely for certain invalid status codes', function () { | ||
_.each([400, 401, 403, 404], function (statusCode) { | ||
var err = validateExpects({ | ||
statusCode: statusCode | ||
}, { | ||
statusCode: [202] | ||
}); | ||
assert(_.isObject(err)); | ||
assert(err.code.length); | ||
assert(err.message.length); | ||
assert.notEqual(err.code, 'invalid_response_status_code'); | ||
assert.notEqual(err.message, 'Invalid response status code'); | ||
}); | ||
}); | ||
it('it should be ok with valid bodies', function () { | ||
@@ -82,4 +100,4 @@ var err = validateExpects({ | ||
}); | ||
}); |
83283
2207
583