nordnet-next-api
Advanced tools
Comparing version 2.4.0 to 3.0.0
@@ -61,6 +61,6 @@ 'use strict'; | ||
function testThrows(conditions) { | ||
function testRejected(conditions) { | ||
return function () { | ||
conditions.forEach(function (condition) { | ||
return Object.keys(_index2.default).forEach(testMethodThrows(condition)); | ||
return conditions.forEach(function (condition) { | ||
return Object.keys(_index2.default).forEach(testMethodRejected(condition)); | ||
}); | ||
@@ -70,8 +70,6 @@ }; | ||
function testMethodThrows(condition) { | ||
function testMethodRejected(condition) { | ||
return function (method) { | ||
return it('should throw an error with ' + method + ' and url \'' + condition + '\'', function () { | ||
return (0, _chai.expect)(function () { | ||
return _index2.default[method](condition); | ||
}).to.throw(Error); | ||
return it('should reject promise with an error for ' + method + ' and url \'' + condition + '\'', function () { | ||
return (0, _chai.expect)(_index2.default[method](condition)).to.be.rejectedWith(Error); | ||
}); | ||
@@ -82,3 +80,4 @@ }; | ||
describe('api', function () { | ||
describe('when url is invalid', testThrows([undefined, '', '/api/2/accounts/{accno}'])); | ||
describe('when url is invalid', testRejected([undefined, ''])); | ||
describe('when required path params are missing', testRejected(['/api/2/accounts/{accno}'])); | ||
describe('when request succeeded', test(_expectations2.default.getInstrument)); | ||
@@ -85,0 +84,0 @@ describe('when request failed', test(_expectations2.default.getAccounts)); |
@@ -27,2 +27,3 @@ 'use strict'; | ||
var HTTP_BAD_REQUEST = 400; | ||
var regUrlParam = /{([\s\S]+?)}/g; | ||
@@ -119,4 +120,13 @@ var defaultHeaders = { | ||
function httpFetch(options) { | ||
validateUrl(options.url); | ||
if (!options.url) { | ||
// @TODO should check type | ||
return Promise.reject(new Error('Invalid url, got `' + options.url + '`')); | ||
} | ||
if (isNotValidPath(options.url, options.params)) { | ||
// @TODO should check types | ||
// @TODO should have testcase in place | ||
return Promise.reject(new Error('Params object doesn\'t have all required keys for url.\n Got url `' + options.url + '` and params `' + JSON.stringify(options.params) + '`')); | ||
} | ||
var path = buildPath(options.url, options.params); | ||
@@ -181,10 +191,4 @@ var params = omit(options.params, getPathParams(options.url)); | ||
function validateUrl(url) { | ||
if (!url) { | ||
throw new Error('Invalid URL'); | ||
} | ||
} | ||
function getPathParams(url) { | ||
var keys = url.match(/{([\s\S]+?)}/g) || []; | ||
var keys = url.match(regUrlParam) || []; | ||
return keys.map(function (key) { | ||
@@ -211,4 +215,14 @@ return key.replace(/({|})/g, ''); | ||
function isNotValidPath(url) { | ||
var params = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
return !!(url.match(regUrlParam) || []).map(function (key) { | ||
return key.replace(/({|})/g, ''); | ||
}).find(function (key) { | ||
return !params[key]; | ||
}); | ||
} | ||
function buildPath(url, params) { | ||
return url.replace(/{([\s\S]+?)}/g, matchParams(params)); | ||
return url.replace(regUrlParam, matchParams(params)); | ||
} | ||
@@ -218,6 +232,2 @@ | ||
return function matchParamKeyValue(match, key) { | ||
if (params[key] === undefined) { | ||
throw new Error('unknown parameter ' + key); | ||
} | ||
return uriEncode(params[key]); | ||
@@ -224,0 +234,0 @@ }; |
{ | ||
"name": "nordnet-next-api", | ||
"version": "2.4.0", | ||
"version": "3.0.0", | ||
"description": "Nordnet nExt API Javascript client", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
@@ -46,2 +46,51 @@ # Nordnet nExt API Javascript client | ||
## API | ||
* `api.get(url, params = {}, headers = {})` | ||
* `api.post(url, params = {}, headers = {})` | ||
* `api.put(url, params = {}, headers = {})` | ||
* `api.del(url, params = {}, headers = {})` | ||
Each method returns a Promise, which resolves or rejects with `Object { response, data, status }` where | ||
* `response`, Type `Object`, [Fetch API Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) | ||
* `data`, Type `Object || String || (undefined if HTTP status === 204)` | ||
* `status`, Type `Number`, [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/API/Response/status) | ||
Promise is rejected when HTTP status code is greater or equal 400. | ||
#### url | ||
*Required* | ||
Type: `String` | ||
Example: | ||
* `/api/2/login` | ||
* `/api/2/accounts/{accno}` | ||
* `/api/2/instruments/{instrument_id}?positions={positions}` | ||
**`Note:` interpolated url params are taken from `params` argument. If `url` contains a key, | ||
which doesn't exist in `params`, promise will be rejected with `Error`.** | ||
#### params | ||
*Required* | ||
Type: `Object` | ||
Default: `{}` | ||
Object `params` is used to | ||
* interpolate `url` params. | ||
* if `headers` contains `"Content-type": "application/json"` for constructing request `payload`. | ||
* otherwise for constructing request body. | ||
#### headers | ||
*Required* | ||
Type: `Object` | ||
Default: `{}` | ||
See [Fetch API Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers) | ||
### Basic usage | ||
@@ -48,0 +97,0 @@ |
@@ -36,15 +36,14 @@ import { initSandBox, respondWith, execute, expectations } from 'test-helper'; | ||
function testThrows(conditions) { | ||
return function () { | ||
conditions.forEach(condition => Object.keys(api).forEach(testMethodThrows(condition))); | ||
}; | ||
function testRejected(conditions) { | ||
return () => conditions.forEach(condition => Object.keys(api).forEach(testMethodRejected(condition))); | ||
} | ||
function testMethodThrows(condition) { | ||
return method => it(`should throw an error with ${method} and url '${condition}'`, | ||
() => expect(() => api[method](condition)).to.throw(Error)); | ||
function testMethodRejected(condition) { | ||
return method => it(`should reject promise with an error for ${method} and url '${condition}'`, | ||
() => expect(api[method](condition)).to.be.rejectedWith(Error)); | ||
} | ||
describe('api', function () { | ||
describe('when url is invalid', testThrows([undefined, '', '/api/2/accounts/{accno}'])); | ||
describe('when url is invalid', testRejected([undefined, ''])); | ||
describe('when required path params are missing', testRejected(['/api/2/accounts/{accno}'])); | ||
describe('when request succeeded', test(tests.getInstrument)); | ||
@@ -51,0 +50,0 @@ describe('when request failed', test(tests.getAccounts)); |
@@ -9,2 +9,3 @@ import es6Promise from 'es6-promise'; | ||
const HTTP_BAD_REQUEST = 400; | ||
const regUrlParam = /{([\s\S]+?)}/g; | ||
@@ -83,4 +84,12 @@ const defaultHeaders = { | ||
function httpFetch(options) { | ||
validateUrl(options.url); | ||
if (!options.url) { // @TODO should check type | ||
return Promise.reject(new Error(`Invalid url, got \`${options.url}\``)); | ||
} | ||
if (isNotValidPath(options.url, options.params)) { // @TODO should check types | ||
// @TODO should have testcase in place | ||
return Promise.reject(new Error(`Params object doesn't have all required keys for url. | ||
Got url \`${options.url}\` and params \`${JSON.stringify(options.params)}\``)); | ||
} | ||
const path = buildPath(options.url, options.params); | ||
@@ -144,10 +153,4 @@ const params = omit(options.params, getPathParams(options.url)); | ||
function validateUrl(url) { | ||
if (!url) { | ||
throw new Error('Invalid URL'); | ||
} | ||
} | ||
function getPathParams(url) { | ||
const keys = url.match(/{([\s\S]+?)}/g) || []; | ||
const keys = url.match(regUrlParam) || []; | ||
return keys.map(key => key.replace(/({|})/g, '')); | ||
@@ -170,4 +173,10 @@ } | ||
function isNotValidPath(url, params = {}) { | ||
return !!(url.match(regUrlParam) || []) | ||
.map(key => key.replace(/({|})/g, '')) | ||
.find(key => !params[key]); | ||
} | ||
function buildPath(url, params) { | ||
return url.replace(/{([\s\S]+?)}/g, matchParams(params)); | ||
return url.replace(regUrlParam, matchParams(params)); | ||
} | ||
@@ -177,6 +186,2 @@ | ||
return function matchParamKeyValue(match, key) { | ||
if (params[key] === undefined) { | ||
throw new Error(`unknown parameter ${key}`); | ||
} | ||
return uriEncode(params[key]); | ||
@@ -183,0 +188,0 @@ }; |
@@ -6,3 +6,5 @@ // make phantomjs happy, polyfill .bind etc... | ||
var sinonChai = require('sinon-chai'); | ||
var chaiAsPromised = require('chai-as-promised'); | ||
chai.use(sinonChai); | ||
chai.use(chaiAsPromised); | ||
@@ -9,0 +11,0 @@ // --- Load all common js tests via webpack |
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
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
47627
1203
195