Comparing version 0.9.1 to 0.9.2
@@ -70,5 +70,4 @@ /* | ||
response = { | ||
request: request | ||
}; | ||
request = typeof request === 'string' ? { path: request } : request || {}; | ||
response = { request: request }; | ||
@@ -75,0 +74,0 @@ if (request.canceled) { |
@@ -61,4 +61,4 @@ /* | ||
response = {}; | ||
response.request = request; | ||
request = typeof request === 'string' ? { path: request } : request || {}; | ||
response = { request: request }; | ||
@@ -65,0 +65,0 @@ if (request.canceled) { |
@@ -21,4 +21,4 @@ /* | ||
response = {}; | ||
response.request = request; | ||
request = typeof request === 'string' ? { path: request } : request || {}; | ||
response = { request: request }; | ||
@@ -25,0 +25,0 @@ if (request.canceled) { |
@@ -55,4 +55,4 @@ /* | ||
response = {}; | ||
response.request = request; | ||
request = typeof request === 'string' ? { path: request } : request || {}; | ||
response = { request: request }; | ||
@@ -59,0 +59,0 @@ if (request.canceled) { |
{ | ||
"name": "rest", | ||
"version": "0.9.1", | ||
"version": "0.9.2", | ||
"main": "./rest.js", | ||
@@ -5,0 +5,0 @@ "dependencies": { |
@@ -214,2 +214,4 @@ # Interceptors | ||
The 'Link' response header is also parsed for related resources following rfc5988. The values parsed from the headers are indexed into the response.links object. | ||
Also defines a `clientFor` factory function that creates a new client configured to communicate with a related resource. | ||
@@ -216,0 +218,0 @@ |
@@ -9,2 +9,4 @@ # Common Interfaces | ||
A request may be represented by either a string or an object. Strings are coerced to an object as soon as they are encountered, where the string's value becomes the value of the path property on the object. | ||
<table> | ||
@@ -11,0 +13,0 @@ <tr> |
# wire.js | ||
[wire.js](https://github.com/cujojs/wire/) is an Inversion of Control container that allows applications to be composed together at runtime based on a declarative configuration. A rest.js plugin is provided for wire that enables declarative configuration of rest clients, including chaning interceptors with their configuration. | ||
[wire.js](https://github.com/cujojs/wire/) is an Inversion of Control container that allows applications to be composed together at runtime based on a declarative configuration. A rest.js plugin is provided for wire.js that enables declarative configuration of rest.js clients, including chaning interceptors with their configuration. | ||
@@ -13,3 +13,3 @@ | ||
**TIP:** In each of these examples, `{ module: 'rest/wire' }` is loaded as it provides the 'rest' factory to the wire spec. Without this module being loaded into the spec, the facilities below will silently fail. | ||
**TIP:** In each of these examples, `{ module: 'rest/wire' }` is loaded as it provides the 'rest' factory to the wire.js spec. Without this module being loaded into the spec, the facilities below will silently fail. | ||
@@ -20,3 +20,3 @@ | ||
The `rest` factory provides a declarative way to define a client with an interceptor chain that is nearly identical in capability to imperative JavaScript. The factory access two main config properties, a parent client, and an array of interceptors. Each entry in the interceptor array contains a reference to the interceptor module, and the configuration for that interceptor. The array of interceptors is chained off the client in order returning the resulting client as the wire component. | ||
The `rest` factory provides a declarative way to define a client with an interceptor chain that is nearly identical in capability to imperative JavaScript. The factory access two main config properties, a parent client, and an array of interceptors. Each entry in the interceptor array contains a reference to the interceptor module, and the configuration for that interceptor. The array of interceptors is chained off the client in order returning the resulting client as the wire.js component. | ||
@@ -69,3 +69,3 @@ In it's basic form, the array of interceptors is processed in order, chaining off the parent client. | ||
An individual interceptors array entry can use any facility available within wire, including $ref. | ||
An individual interceptors array entry can use any facility available within wire.js, including $ref. | ||
@@ -72,0 +72,0 @@ ```javascript |
@@ -115,3 +115,3 @@ /* | ||
var context = {}; | ||
request = request || {}; | ||
request = typeof request === 'string' ? { path: request } : request || {}; | ||
request.originator = request.originator || client; | ||
@@ -118,0 +118,0 @@ return when( |
@@ -13,6 +13,7 @@ /* | ||
var interceptor, pathPrefix, cycleFlag; | ||
var interceptor, pathPrefix, rfc5988LinkParser, cycleFlag; | ||
interceptor = require('../interceptor'); | ||
pathPrefix = require('./pathPrefix'); | ||
rfc5988LinkParser = require('../parsers/rfc5988'); | ||
@@ -35,2 +36,6 @@ cycleFlag = '__rest_hateoas_seen__'; | ||
* | ||
* The 'Link' response header is also parsed for related resources | ||
* following rfc5988. The values parsed from the headers are indexed | ||
* into the response.links object. | ||
* | ||
* Also defines a 'clientFor' factory function that creates a new | ||
@@ -118,2 +123,20 @@ * client configured to communicate with a related resource. | ||
function parseLinkHeaders(headers) { | ||
var links = []; | ||
[].concat(headers).forEach(function (header) { | ||
try { | ||
links = links.concat(rfc5988LinkParser.parse(header)); | ||
} | ||
catch (e) { | ||
// ignore | ||
// TODO consider a debug mode that logs | ||
} | ||
}); | ||
return links; | ||
} | ||
if (response.headers && response.headers.Link) { | ||
response.links = response.links || {}; | ||
apply(response.links, parseLinkHeaders(response.headers.Link)); | ||
} | ||
walk(response); | ||
@@ -120,0 +143,0 @@ |
@@ -24,3 +24,4 @@ Copyright (c) 2012-2013 the original author or authors | ||
Code published by Scott Andrews or Jeremy Grelle is copyright VMware. | ||
Code published by Scott Andrews or Jeremy Grelle is copyright VMware and | ||
licensed under the above terms. | ||
@@ -27,0 +28,0 @@ VMware, Inc. |
@@ -80,17 +80,18 @@ /* | ||
d = when.defer(); | ||
timeout = setTimeout(function () { | ||
// HOPE reject on a local require would be nice | ||
function reject(ex) { | ||
clearTimeout(timeout); | ||
timeout = null; | ||
d.reject(); | ||
}, 1000); | ||
d.reject(ex || new Error('Timeout while loading mime module: ' + mime)); | ||
} | ||
// 'define' is a bit of a hack, but other options are non-standard | ||
define('rest/mime/type/' + mime + '-' + Math.random(), ['./type/' + mime], function (m) { | ||
function resolve(m) { | ||
clearTimeout(timeout); | ||
timeout = null; | ||
d.resolve(m); | ||
}); | ||
} | ||
d = when.defer(); | ||
// HOPE reject on a local require would be nice | ||
timeout = setTimeout(reject, 1000); | ||
require(['./type/' + mime], resolve, reject); | ||
return d.promise; | ||
@@ -112,3 +113,3 @@ } | ||
registry = new Registry(typeof require === 'function' && require.amd ? loadAMD : loadNode); | ||
registry = new Registry(typeof define === 'function' && define.amd ? loadAMD : loadNode); | ||
@@ -115,0 +116,0 @@ // include text/plain and application/json by default |
{ | ||
"name": "rest", | ||
"version": "0.9.1", | ||
"version": "0.9.2", | ||
"description": "RESTful HTTP client library", | ||
@@ -5,0 +5,0 @@ "keywords": ["rest", "http", "client", "rest-template", "spring", "cujojs"], |
@@ -33,3 +33,3 @@ rest.js | ||
rest({ path: '/' }).then(function(response) { | ||
rest('/').then(function(response) { | ||
console.log('response: ', response); | ||
@@ -39,3 +39,3 @@ }); | ||
In this example, you can see that the request object is very simple, it just includes the path. All of the attributes of a request are optional. | ||
In this example, you can see that the request object is very simple, it just a string representing the path. The request may also be a proper [object containing other HTTP properties](docs/interfaces.md#interface-request). | ||
@@ -94,5 +94,5 @@ The response should look familiar as well, it contains all the fields you would expect, including the response headers (many clients ignore the headers). | ||
First class support is provided for [declaratively composing interceptors using wire.js](docs/wire.md). wire.js is an dependency injection container; you specify how the parts of your application interrelate and wire takes care of the dirty work to make it so. | ||
First class support is provided for [declaratively composing interceptors using wire.js](docs/wire.md). wire.js is an dependency injection container; you specify how the parts of your application interrelate and wire.js takes care of the dirty work to make it so. | ||
Let's take the previous example and configure the client using a wire specification instead of imperative code. | ||
Let's take the previous example and configure the client using a wire.js specification instead of imperative code. | ||
@@ -112,3 +112,3 @@ ```javascript | ||
There are a couple things to notice. First is the 'plugins' section, by declaring the `rest/wire` module, the `rest` factory becomes available within the specification. The second thing to notice is that we no longer need to individually `require()` interceptor modules; wire is smart enough to automatically fetch the modules. The interceptors are then chained together in the order they are defined and provided with the corresponding config object, if it's defined. The resulting client can then be injected into any other object using standard wire facilities. | ||
There are a couple things to notice. First is the 'plugins' section, by declaring the `rest/wire` module, the `rest` factory becomes available within the specification. The second thing to notice is that we no longer need to individually `require()` interceptor modules; wire.js is smart enough to automatically fetch the modules. The interceptors are then chained together in the order they are defined and provided with the corresponding config object, if it's defined. The resulting client can then be injected into any other object using standard wire.js facilities. | ||
@@ -235,5 +235,9 @@ | ||
0.9.2 | ||
- allow strings to represent request objects, the string value is treated as the path property | ||
- parsing 'Link' response headers in hateoas interceptor (rfc5988) | ||
0.9.1 | ||
- add Node 0.10 as a tested environment | ||
- restore when 1.8 compat, when 2.0 is still preferred | ||
- restore when.js 1.8 compat, when.js 2.0 is still preferred | ||
@@ -240,0 +244,0 @@ 0.9.0 |
@@ -31,2 +31,3 @@ /* | ||
'mime/**/*.js', | ||
'parsers/**/*.js', | ||
'util/**/*.js', | ||
@@ -33,0 +34,0 @@ 'node_modules/curl/**/*.js', |
@@ -80,2 +80,8 @@ /* | ||
}, | ||
'should normalize a string to a request object': function () { | ||
var request = 'http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=javascript'; | ||
return client(request).then(function (response) { | ||
assert.same(request, response.request.path); | ||
}).otherwise(fail); | ||
}, | ||
'should not be the default client': function () { | ||
@@ -82,0 +88,0 @@ refute.same(client, rest); |
@@ -133,2 +133,7 @@ /* | ||
}, | ||
'should normalize a string to a request object': function () { | ||
return client('http://localhost:8080/').then(function (response) { | ||
assert.same('http://localhost:8080/', response.request.path); | ||
}).otherwise(fail); | ||
}, | ||
'should be the default client': function () { | ||
@@ -135,0 +140,0 @@ assert.same(client, rest); |
@@ -33,4 +33,2 @@ /* | ||
return client(request).then(function (response) { | ||
var xdr; | ||
xdr = response.raw; | ||
assert.same(request, response.request); | ||
@@ -107,2 +105,7 @@ assert.equals(response.request.method, 'GET'); | ||
); | ||
}, | ||
'should normalize a string to a request object': function () { | ||
return client(flickrUrl).then(function (response) { | ||
assert.same(flickrUrl, response.request.path); | ||
}).otherwise(fail); | ||
} | ||
@@ -109,0 +112,0 @@ }, |
@@ -162,2 +162,7 @@ /* | ||
}, | ||
'should normalize a string to a request object': function () { | ||
return client('/').then(function (response) { | ||
assert.same('/', response.request.path); | ||
}).otherwise(fail); | ||
}, | ||
'should be the default client': function () { | ||
@@ -164,0 +169,0 @@ assert.same(xhr, rest); |
@@ -455,2 +455,10 @@ /* | ||
}, | ||
'should normalize a string to a request object': function () { | ||
var theInterceptor, client; | ||
theInterceptor = interceptor(); | ||
client = theInterceptor(defaultClient); | ||
return client('/').then(function (response) { | ||
assert.same('/', response.request.path); | ||
}).otherwise(fail); | ||
}, | ||
'should have the default client as the parent by default': function () { | ||
@@ -457,0 +465,0 @@ var theInterceptor = interceptor(); |
@@ -49,47 +49,97 @@ /* | ||
buster.testCase('rest/interceptor/hateoas', { | ||
requiresSupportFor: { 'Object.defineProperty': supports['Object.defineProperty'] }, | ||
'should parse header links': function () { | ||
var client, entity, headers; | ||
'should parse links in the entity': function () { | ||
var client, body, parent, self; | ||
headers = { | ||
Link: [ | ||
'<http://example.com/TheBook/chapter2>; rel="previous"; title="previous chapter"', | ||
'<http://example.com/TheBook/chapter4>; rel="next"; title="next chapter"' | ||
] | ||
}; | ||
entity = {}; | ||
client = hateoas(function () { return { entity: entity, headers: headers }; }); | ||
parent = { rel: 'parent', href: '/' }; | ||
self = { rel: 'self', href: '/resource' }; | ||
return client().then(function (response) { | ||
assert('previous' in response.links); | ||
assert.same(response.links.previousLink.href, 'http://example.com/TheBook/chapter2'); | ||
assert.same(response.links.previousLink.title, 'previous chapter'); | ||
assert('next' in response.links); | ||
assert.same(response.links.nextLink.href, 'http://example.com/TheBook/chapter4'); | ||
assert.same(response.links.nextLink.title, 'next chapter'); | ||
}).otherwise(fail); | ||
}, | ||
'should parse compound header links': function () { | ||
var client, entity, headers; | ||
body = { links: [ parent, self ]}; | ||
client = hateoas(function () { return { entity: body }; }); | ||
headers = { Link: '<http://example.com/TheBook/chapter2>; rel="previous"; title="previous chapter", <http://example.com/TheBook/chapter4>; rel="next"; title="next chapter"' }; | ||
entity = {}; | ||
client = hateoas(function () { return { entity: entity, headers: headers }; }); | ||
return client().then(function (response) { | ||
assert.same(parent, response.entity._links.parentLink); | ||
assert.same(self, response.entity._links.selfLink); | ||
assert('previous' in response.links); | ||
assert.same(response.links.previousLink.href, 'http://example.com/TheBook/chapter2'); | ||
assert.same(response.links.previousLink.title, 'previous chapter'); | ||
assert('next' in response.links); | ||
assert.same(response.links.nextLink.href, 'http://example.com/TheBook/chapter4'); | ||
assert.same(response.links.nextLink.title, 'next chapter'); | ||
}).otherwise(fail); | ||
}, | ||
'should parse links in the entity into the entity': function () { | ||
var client, body, parent, self; | ||
'should gracefully recover from maleformed header links': function () { | ||
var client, entity, headers; | ||
parent = { rel: 'parent', href: '/' }; | ||
self = { rel: 'self', href: '/resource' }; | ||
headers = { Link: 'foo bar' }; | ||
entity = {}; | ||
client = hateoas(function () { return { entity: entity, headers: headers }; }); | ||
body = { links: [ parent, self ]}; | ||
client = hateoas(function () { return { entity: body }; }, { target: '' }); | ||
return client().then(function (response) { | ||
assert.same(parent, response.entity.parentLink); | ||
assert.same(self, response.entity.selfLink); | ||
assert.same(entity, response.entity); | ||
}).otherwise(fail); | ||
}, | ||
'should create a client for the related resource': function () { | ||
var client, body, parent, self; | ||
'': { | ||
requiresSupportFor: { 'Object.defineProperty': supports['Object.defineProperty'] }, | ||
parent = { rel: 'parent', href: '/' }; | ||
self = { rel: 'self', href: '/resource' }; | ||
'should parse links in the entity': function () { | ||
var client, body, parent, self; | ||
body = { links: [ parent, self ]}; | ||
client = hateoas(function () { return { entity: body }; }); | ||
parent = { rel: 'parent', href: '/' }; | ||
self = { rel: 'self', href: '/resource' }; | ||
return client().then(function (response) { | ||
var parentClient = response.entity._links.clientFor('parent', function (request) { return { request: request }; }); | ||
return parentClient().then(function (response) { | ||
assert.same(parent.href, response.request.path); | ||
}); | ||
}).otherwise(fail); | ||
body = { links: [ parent, self ]}; | ||
client = hateoas(function () { return { entity: body }; }); | ||
return client().then(function (response) { | ||
assert.same(parent, response.entity._links.parentLink); | ||
assert.same(self, response.entity._links.selfLink); | ||
}).otherwise(fail); | ||
}, | ||
'should parse links in the entity into the entity': function () { | ||
var client, body, parent, self; | ||
parent = { rel: 'parent', href: '/' }; | ||
self = { rel: 'self', href: '/resource' }; | ||
body = { links: [ parent, self ]}; | ||
client = hateoas(function () { return { entity: body }; }, { target: '' }); | ||
return client().then(function (response) { | ||
assert.same(parent, response.entity.parentLink); | ||
assert.same(self, response.entity.selfLink); | ||
}).otherwise(fail); | ||
}, | ||
'should create a client for the related resource': function () { | ||
var client, body, parent, self; | ||
parent = { rel: 'parent', href: '/' }; | ||
self = { rel: 'self', href: '/resource' }; | ||
body = { links: [ parent, self ]}; | ||
client = hateoas(function () { return { entity: body }; }); | ||
return client().then(function (response) { | ||
var parentClient = response.entity._links.clientFor('parent', function (request) { return { request: request }; }); | ||
return parentClient().then(function (response) { | ||
assert.same(parent.href, response.request.path); | ||
}); | ||
}).otherwise(fail); | ||
} | ||
}, | ||
@@ -96,0 +146,0 @@ 'should fetch a related resource': { |
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
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
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
341275
90
7214
292
50