Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

rest

Package Overview
Dependencies
Maintainers
2
Versions
22
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

rest - npm Package Compare versions

Comparing version 0.8.4 to 0.9.0

client/xdr.js

40

client/jsonp.js
/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -112,9 +97,14 @@

script.onload = script.onerror = script.onreadystatechange = function (e) {
script.onerror = function () {
if (global[callbackName]) {
response.error = 'loaderror';
clearProperty(global, callbackName);
cleanupScriptNode(response);
d.reject(response);
}
};
script.onload = script.onreadystatechange = function (e) {
// script tag load callbacks are completely non-standard
if ((e && (e.type === 'load' || e.type === 'error')) || script.readyState === 'loaded') {
if (global[callbackName]) {
response.error = 'loaderror';
d.reject(response);
}
script.onerror(e);
}

@@ -130,2 +120,6 @@ };

jsonp.chain = function (interceptor, config) {
return interceptor(jsonp, config);
};
return jsonp;

@@ -132,0 +126,0 @@

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Jeremy Grelle
* @author Scott Andrews
*/

@@ -39,2 +25,34 @@

// TODO remove once Node 0.6 is no longer supported
Buffer.concat = Buffer.concat || function (list, length) {
/*jshint plusplus:false, shadow:true */
// from https://github.com/joyent/node/blob/v0.8.21/lib/buffer.js
if (!Array.isArray(list)) {
throw new Error('Usage: Buffer.concat(list, [length])');
}
if (list.length === 0) {
return new Buffer(0);
} else if (list.length === 1) {
return list[0];
}
if (typeof length !== 'number') {
length = 0;
for (var i = 0; i < list.length; i++) {
var buf = list[i];
length += buf.length;
}
}
var buffer = new Buffer(length);
var pos = 0;
for (var i = 0; i < list.length; i++) {
var buf = list[i];
buf.copy(buffer, pos);
pos += buf.length;
}
return buffer;
};
function node(request) {

@@ -76,2 +94,5 @@

clientRequest = client.request(options, function (clientResponse) {
// Array of Buffers to collect response chunks
var buffers = [];
response.raw = {

@@ -91,13 +112,15 @@ request: clientRequest,

clientResponse.on('data', function (data) {
if (!('entity' in response)) {
response.entity = '';
}
// normalize Buffer to a string
response.entity += data.toString();
// Collect the next Buffer chunk
buffers.push(data);
});
clientResponse.on('end', function () {
// Create the final response entity
response.entity = buffers.length > 0 ? Buffer.concat(buffers).toString() : '';
buffers = null;
d.resolve(response);
});
});
clientRequest.on('error', function (e) {

@@ -116,2 +139,6 @@ response.error = e;

node.chain = function (interceptor, config) {
return interceptor(node, config);
};
return node;

@@ -118,0 +145,0 @@

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/
(function (define, XMLHttpRequest) {
(function (define, global) {
'use strict';

@@ -68,3 +53,3 @@

function xhr(request) {
var d, client, method, url, headers, entity, headerName, response;
var d, client, method, url, headers, entity, headerName, response, XMLHttpRequest;

@@ -81,3 +66,7 @@ response = {};

client = response.raw = new XMLHttpRequest();
XMLHttpRequest = request.engine || global.XMLHttpRequest;
if (!XMLHttpRequest) {
d.reject({ request: request, error: 'xhr-not-available' });
return d.promise;
}

@@ -90,2 +79,3 @@ entity = request.entity;

try {
client = response.raw = new XMLHttpRequest();
client.open(method, url, true);

@@ -143,2 +133,6 @@

xhr.chain = function (interceptor, config) {
return interceptor(xhr, config);
};
return xhr;

@@ -150,4 +144,4 @@

typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); },
this.XMLHttpRequest
this
// Boilerplate for AMD and Node
));
{
"name": "rest",
"version": "0.8.4",
"version": "0.9.0",
"main": "./rest.js",
"dependencies": {
"when": "~1"
"when": "~2"
}
}

@@ -1,5 +0,5 @@

_Have something you'd like to contribute to the framework? We welcome pull
requests, but ask that you carefully read this document first to understand how
best to submit them; what kind of changes are likely to be accepted; and what
to expect from the Spring team when evaluating your submission._
_Thanks for your interest in rest.js. Have something you'd like to contribute?
We welcome pull requests, but ask that you read this document first to
understand how best to submit them; what kind of changes are likely to be
accepted; and what to expect from the team when evaluating your submission._

@@ -27,27 +27,8 @@ _Please refer back to this document as a checklist before issuing any pull

If you're considering anything more than correcting a typo or fixing a minor
bug, please discuss it on the [s2js-contrib][] mailing list before submitting a
pull request. We're happy to provide guidance but please research the subject
on your own including searching the mailing list for prior discussions.
bug, please discuss it on the cujojs [mailing list][], or the #cujojs IRC
channel on freenode, before submitting a pull request. We're happy to provide
guidance but please research the subject on your own including searching the
mailing list for prior discussions.
## Sign the Contributor License Agreement
If you have not previously done so, please fill out and submit the
[s2js CLA form][]. You'll receive a token when this process is complete. Keep
track of this; you may be asked for it later!
Note that emailing/postal mailing a signed copy is _not_ necessary. Submission
of the web form is all that is required.
Once you've completed the web form, simply add the following in a comment on
your pull request:
I have signed and agree to the terms of the s2js Contributor License
Agreement.
You do not need to include your token/id. Please add the statement above to all
future pull requests as well, simply so that the team knows immediately that
this process is complete.
## Create your branch from `dev`

@@ -88,32 +69,20 @@

naming conventions, etc.
1. ascii encoding for JS sources, escape special characters
1. utf8 encoding for JS sources, escape special characters
## Add MIT license header to all new source files
## Add MIT license block to all new source files
```javascript
/*
* Copyright (c) 2013 VMware, Inc. All Rights Reserved.
* Copyright 2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author FirstName LastName <OptionalEmailAddress>
*/
```
If you are uncomfortable making the contribution under the MIT license, please
contact us before making a contribution.
## Update license header to modified files as necessary

@@ -125,3 +94,3 @@

```javascript
* Copyright (c) 2012 VMware, Inc.
* Copyright 2012 the original author or authors
```

@@ -132,3 +101,3 @@

```javascript
* Copyright (c) 2012-2013 VMware, Inc.
* Copyright 2012-2013 the original author or authors
```

@@ -166,29 +135,2 @@

## Use real name in git commits
Please configure git to use your real first and last name for any commits you
intend to submit as pull requests. For example, this is not acceptable:
Author: Nickname <user@mail.com>
Rather, please include your first and last name, properly capitalized, as
submitted against the SpringSource contributor license agreement:
Author: First Last <user@mail.com>
This helps ensure traceability against the CLA, and also goes a long way to
ensuring useful output from tools like `git shortlog` and others.
You can configure this globally via the account admin area GitHub (useful for
fork-and-edit cases); globally with
git config --global user.name "First Last"
git config --global user.email user@mail.com
or for the local repository only by omitting the '--global' flag:
git config user.name "First Last"
git config user.email user@mail.com
## Format commit messages

@@ -291,6 +233,5 @@

[help documentation]: http://help.github.com/send-pull-requests
[issue tracker]: https://github.com/s2js/rest/issues
[s2js-contrib]: https://groups.google.com/forum/#!forum/s2js-contrib
[s2js CLA form]: http://support.springsource.com/spring_s2js_signup
[issue tracker]: https://github.com/cujojs/rest/issues
[mailing list]: https://groups.google.com/forum/#!forum/cujojs
[fork-and-edit]: https://github.com/blog/844-forking-with-the-edit-button
[commit guidelines section of Pro Git]: http://progit.org/book/ch5-2.html#commit_guidelines
/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -28,6 +13,5 @@

var defaultClient, mixin, queryResults;
var SimpleRestStore, queryResults;
defaultClient = require('../../rest');
mixin = require('../util/mixin');
SimpleRestStore = require('./SimpleRestStore');
queryResults = require('dojo/store/util/QueryResults');

@@ -38,132 +22,28 @@

*
* The base path for requests is commonly provided by the `rest/interceptor/prefix` interceptor.
* The base path for requests is commonly provided by the
*`rest/interceptor/pathPrefix` interceptor.
*
* @param {RestStore} [options] configuration information that will be mixed into the store
* Extends SimpleRestStore, but wraps the query results with Dojo's
* QueryResults.
*
* @param {RestStore} [options] configuration information that will be mixed
* into the store
*/
function RestStore(options) {
mixin(this, options);
this.client = this.client || defaultClient;
function RestStore(/* options */) {
SimpleRestStore.apply(this, arguments);
}
RestStore.prototype = {
RestStore.prototype = Object.create(SimpleRestStore.prototype);
/**
* @field {Client} client rest client for this store
*/
client: null,
/**
* @field {string} [idProperty='id'] property to use as the identity property. The values of this property should be unique.
*/
idProperty: 'id',
/**
* @field {boolean} [ignoreId=false] if true, add() will always do a POST even if the data item already has an id
*/
ignoreId: false,
/**
* Retrieves an object by its identity. This will trigger a GET request to the server using the url `id`.
*
* @param {string|number} id identity to use to lookup the object
* @param {Object} [options] reserved for future use
*
* @returns {Object} record in the store that matches the given id
*/
get: function (id /*, options */) {
return this.client({
path: id
});
},
/**
* Resolves a records identity using the configured idProperty
*
* @param object to get the identity for
*
* @returns {string|number} the identity
*/
getIdentity: function (object) {
return object[this.idProperty];
},
/**
* Stores a record.
*
* Will trigger a PUT request to the server if the object has an id, otherwise it will trigger a POST request. Unless ignoreId is configured true, in which case POST will always be used.
*
* @param {Object} object record to store
* @param {string|number} [options.id] explicit ID for the record
* @param {boolean} [options.ignoreId] treat the record as if it does not have an ID property
* @param {boolean} [options.overwrite] adds If-Match or If-None-Match header to the request
* @param {boolean} [options.incremental=false] uses POST intead of PUT for a record with an ID
*
* @returns {Promise<Response>} promissed response
*/
put: function (object, options) {
var id, hasId, headers, ignoreId;
options = options || {};
ignoreId = ('ignoreId' in options) ? options.ignoreId : this.ignoreId;
id = ('id' in options) ? options.id : this.getIdentity(object);
hasId = !ignoreId && typeof id !== 'undefined';
headers = {};
if ('overwrite' in options) {
headers[options.overwrite ? 'If-Match' : 'If-None-Match'] = '*';
}
return this.client({
method: hasId && !options.incremental ? 'put' : 'post',
path: hasId ? id : '',
entity: object,
headers: headers
});
},
/**
* Stores a new record.
*
* Will trigger a PUT request to the server if the object has an id, otherwise it will trigger a POST request. Unless ignoreId is configured true, in which case POST will always be used.
*
* @param {Object} object record to add
* @param {string|number} [options.id] explicit ID for the record
* @param {boolean} [options.ignoreId] treat the record as if it does not have an ID property
* @param {boolean} [options.incremental=false] uses POST intead of PUT for a record with an ID
*
* @returns {Promise<Response>} promissed response
*/
add: function (object, options) {
options = options || {};
options.overwrite = false;
return this.put(object, options);
},
/**
* Deletes a record by its identity. This will trigger a DELETE request to the server.
*
* @param {string|number} id identity of the record to delete
*
* @returns {Promise<Response>} promissed response
*/
remove: function (id) {
return this.client({
method: 'delete',
path: id
});
},
/**
* Queries the store for objects. This will trigger a GET request to the server, with the query added as a query string.
*
* @param {Object} query params used for the query string
* @param {Object} [options] reserved for future use
*
* @returns {QueryResult} query results
*/
query: function (query /*, options */) {
return queryResults(this.client({ params: query }));
}
/**
* Queries the store for objects. This will trigger a GET request to the
* server, with the query added as a query string.
*
* @param {Object} query params used for the query string
* @param {Object} [options] reserved for future use
*
* @returns {QueryResult} query results
*/
RestStore.prototype.query = function query(/* query, options */) {
return queryResults(SimpleRestStore.prototype.query.apply(this, arguments));
};

@@ -170,0 +50,0 @@

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -35,27 +20,2 @@

/**
* If wait === true, waits for dataPromise to complete and resolves
* the reference to the resulting concrete data. If wait !== true,
* resolves the reference to dataPromise.
*
* @param dataPromise
* @param resolver
* @param wait
*/
function resolveData(dataPromise, resolver, wait) {
if (wait === true) {
dataPromise.then(
function (data) {
resolver.resolve(data);
},
function (err) {
resolver.reject(err);
}
);
}
else {
resolver.resolve(dataPromise);
}
}
return {

@@ -66,5 +26,8 @@ wire$plugin: function restPlugin(/* ready, destroyed, options */) {

plugin = {
resolvers: mixin({}, clientPlugin.wire$plugin.apply(clientPlugin, arguments).resolvers)
};
plugin = clientPlugin.wire$plugin.apply(clientPlugin, arguments);
Object.keys(plugin).forEach(function (key) {
if (typeof plugin[key] === 'object') {
plugin[key] = mixin({}, plugin[key]);
}
});

@@ -85,3 +48,3 @@ /**

when(client, function (client) {
when(client.promise, function (client) {
var args, store;

@@ -94,9 +57,7 @@

if (refObj.get) {
// If get was specified, get it, and resolve with the resulting item.
resolveData(store.get(refObj.get), resolver, refObj.wait);
store.get(refObj.get).then(resolver.resolve, resolver.reject);
}
else if (refObj.query) {
// Similarly, query and resolve with the result set.
resolveData(store.query(refObj.query), resolver, refObj.wait);
store.query(refObj.query).then(resolver.resolve, resolver.reject);

@@ -103,0 +64,0 @@ }

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -28,5 +13,7 @@

var defaultClient, when;
var defaultClient, beget, mixin, when;
defaultClient = require('../rest');
defaultClient = require('./rest');
beget = require('./util/beget');
mixin = require('./util/mixin');
when = require('when');

@@ -46,3 +33,3 @@

*
* @param {Client} [client] client to wrap
* @param {Client} [target] client to wrap
* @param {Object} [config] configuration for the interceptor, properties will be specific to the interceptor implementation

@@ -54,2 +41,6 @@ * @returns {Client} A client wrapped with the interceptor

function defaultInitHandler(config) {
return config;
}
function defaultRequestHandler(request /*, config */) {

@@ -59,11 +50,10 @@ return request;

function defaultResponseHandler(response /*, config, interceptor */) {
function defaultResponseHandler(response /*, config, client */) {
return response;
}
function whenFirst(promisesOrValues) {
// TODO this concept is likely to be added to when in the near future
function race(promisesOrValues) {
var d = when.defer();
promisesOrValues.forEach(function (promiseOrValue) {
when.chain(promiseOrValue, d.resolver);
when(promiseOrValue, d.resolve, d.reject);
});

@@ -74,4 +64,21 @@ return d.promise;

/**
* Alternate return type for the request handler that allows for more complex interactions.
*
* @param properties.request the traditional request return object
* @param {Promise} [properties.abort] promise that resolves if/when the request is aborted
* @param {Client} [properties.client] override the defined client chain with an alternate client
* @param [properties.response] response for the request, short circuit the request
*/
function ComplexRequest(properties) {
if (!(this instanceof ComplexRequest)) {
// in case users forget the 'new' don't mix into the interceptor
return new ComplexRequest(properties);
}
mixin(this, properties);
}
/**
* Create a new interceptor for the provided handlers.
*
* @param {Function} [handlers.init] one time intialization, must return the config object
* @param {Function} [handlers.request] request handler

@@ -85,8 +92,9 @@ * @param {Function} [handlers.response] response handler regardless of error state

*/
return function (handlers) {
function interceptor(handlers) {
var requestHandler, successResponseHandler, errorResponseHandler;
var initHandler, requestHandler, successResponseHandler, errorResponseHandler;
handlers = handlers || {};
initHandler = handlers.init || defaultInitHandler;
requestHandler = handlers.request || defaultRequestHandler;

@@ -99,44 +107,74 @@ successResponseHandler = handlers.success || handlers.response || defaultResponseHandler;

return function (client, config) {
var interceptor;
return function (target, config) {
var client;
if (typeof client === 'object') {
config = client;
if (typeof target === 'object') {
config = target;
}
if (typeof client !== 'function') {
client = handlers.client || defaultClient;
if (typeof target !== 'function') {
target = handlers.client || defaultClient;
}
config = config || {};
interceptor = function (request) {
config = initHandler(beget(config));
client = function (request) {
var context = {};
request = request || {};
return when(requestHandler(request, config)).then(function (request) {
var response, abort;
if (request instanceof Array) {
// unpack compound value
abort = request[1];
request = request[0];
request.originator = request.originator || client;
return when(
requestHandler.call(context, request, config),
function (request) {
var response, abort, next;
next = target;
if (request instanceof ComplexRequest) {
// unpack request
abort = request.abort;
next = request.client || next;
response = request.response;
// normalize request, must be last
request = request.request;
}
response = response || when(request, function (request) {
return when(
next(request),
function (response) {
return successResponseHandler.call(context, response, config, client);
},
function (response) {
return errorResponseHandler.call(context, response, config, client);
}
);
});
return abort ? race([response, abort]) : response;
},
function (error) {
return when.reject({ request: request, error: error });
}
response = when(request, function (request) {
return when(
client(request),
function (response) {
return successResponseHandler(response, config, interceptor);
},
function (response) {
return errorResponseHandler(response, config, interceptor);
}
);
});
return abort ? whenFirst([response, abort]) : response;
});
);
};
interceptor.skip = function () {
return client;
/**
* @returns {Client} the target client
*/
client.skip = function () {
return target;
};
return interceptor;
/**
* @param {Interceptor} interceptor the interceptor to wrap this client with
* @param [config] configuration for the interceptor
* @returns {Client} the newly wrapped client
*/
client.chain = function (interceptor, config) {
return interceptor(client, config);
};
return client;
};
};
}
interceptor.ComplexRequest = ComplexRequest;
return interceptor;
});

@@ -143,0 +181,0 @@

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -22,0 +7,0 @@

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -22,0 +7,0 @@

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -45,5 +30,8 @@

return interceptor({
init: function (config) {
config.code = config.code || 400;
return config;
},
response: function (response, config) {
var code = config.code || 400;
if (response.status && response.status.code >= code) {
if (response.status && response.status.code >= config.code) {
return when.reject(response);

@@ -50,0 +38,0 @@ }

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -60,3 +45,3 @@

* @param {string} [config.target='_links'] property to create on the entity and parse links into. If present and falsey, the response entity is used directly.
* @param {Client} [config.client] the parent client to use when creating clients for a linked resources. Defaults to the current interceptor's client
* @param {Client} [config.client=request.originator] the parent client to use when creating clients for a linked resources. Defaults to the request's originator if available, otherwise the current interceptor's client
*

@@ -66,7 +51,10 @@ * @returns {Client}

return interceptor({
init: function (config) {
config.target = 'target' in config ? config.target || '' : '_links';
return config;
},
response: function (response, config, hateoas) {
var targetName, client;
var client;
client = config.client || hateoas;
targetName = 'target' in config ? config.target || '' : '_links';
client = config.client || (response.request && response.request.originator) || hateoas;

@@ -108,3 +96,3 @@ function apply(target, links) {

if (Array.isArray(links)) {
if (targetName === '') {
if (config.target === '') {
target = obj;

@@ -114,3 +102,3 @@ }

target = {};
Object.defineProperty(obj, targetName, {
Object.defineProperty(obj, config.target, {
enumerable: false,

@@ -117,0 +105,0 @@ value: target

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -50,4 +35,7 @@

client: jsonpClient,
init: function (config) {
config.callback = config.callback || {};
return config;
},
request: function (request, config) {
config.callback = config.callback || {};
request.callback = request.callback || {};

@@ -54,0 +42,0 @@ request.callback.param = request.callback.param || config.callback.param;

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -39,8 +24,4 @@

*
* Note: this interceptor will only follow the Location header for the
* originating request. If nested redirects should be followed, install
* this interceptor twice. There is no infinite redirect detection
*
* @param {Client} [client] client to wrap
* @param {Client} [config.client] client to use for subsequent request
* @param {Client} [config.client=request.originator] client to use for subsequent request
*

@@ -52,3 +33,3 @@ * @returns {Client}

if (response.headers && response.headers.Location) {
return (config.client || client.skip())({
return (config.client || (response.request && response.request.originator) || client.skip())({
method: 'GET',

@@ -55,0 +36,0 @@ path: response.headers.Location

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -28,3 +13,3 @@

var interceptor, registry, when;
var interceptor, registry, plainText, when;

@@ -35,2 +20,4 @@ interceptor = require('../interceptor');

plainText = registry.lookup('text/plain');
/**

@@ -40,3 +27,4 @@ * MIME type support for request and response entities. Entities are

*
* Request entities are converted using the desired converter and the 'Accept' request header prefers this MIME.
* Request entities are converted using the desired converter and the
* 'Accept' request header prefers this MIME.
*

@@ -48,2 +36,3 @@ * Response entities are converted based on the Content-Type response header.

* @param {string} [config.accept] Accept header for the request
* @param {Registry} [config.registry] MIME registry, defaults to the root registry
*

@@ -53,7 +42,11 @@ * @returns {Client}

return interceptor({
init: function (config) {
config.registry = config.registry || registry;
return config;
},
request: function (request, config) {
var mime, headers, serializer, requestReady;
var mime, headers, requestReady;
headers = request.headers || (request.headers = {});
mime = headers['Content-Type'] || config.mime || 'text/plain';
mime = headers['Content-Type'] = headers['Content-Type'] || config.mime || 'text/plain';
headers.Accept = headers.Accept || config.accept || mime + ', application/json;q=0.8, text/plain;q=0.5, */*;q=0.2';

@@ -65,15 +58,17 @@

serializer = registry.lookup(mime);
requestReady = when.defer();
when(serializer, function (serializer) {
request.entity = serializer.write(request.entity);
headers['Content-Type'] = mime;
config.registry.lookup(mime).then(
function (serializer) {
request.entity = serializer.write(request.entity);
requestReady.resolve(request);
},
function () {
requestReady.reject('unknown-mime');
}
);
requestReady.resolve(request);
});
return requestReady.promise;
},
response: function (response) {
response: function (response, config) {
if (!(response.headers && response.headers['Content-Type'] && response.entity)) {

@@ -83,3 +78,3 @@ return response;

var mime, serializer, responseReady;
var mime, responseReady;

@@ -89,5 +84,4 @@ mime = response.headers['Content-Type'];

responseReady = when.defer();
serializer = registry.lookup(mime);
when(serializer, function (serializer) {
config.registry.lookup(mime).otherwise(function () { return plainText; }).then(function (serializer) {
response.entity = serializer.read(response.entity);

@@ -94,0 +88,0 @@ responseReady.resolve(response);

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -28,8 +13,8 @@

var defaultClient, when, UrlBuilder, pubsub;
var interceptor, UrlBuilder, pubsub, when;
defaultClient = require('../../rest');
when = require('when');
interceptor = require('../interceptor');
UrlBuilder = require('../UrlBuilder');
pubsub = require('../util/pubsub');
when = require('when');

@@ -60,2 +45,25 @@ function defaultOAuthCallback(hash) {

function authorize(config) {
var d, state, url, dismissWindow;
d = when.defer();
state = Math.random() * new Date().getTime();
url = new UrlBuilder(config.authorizationUrlBase).build({
'response_type': 'token',
'redirect_uri': config.redirectUrl,
'client_id': config.clientId,
'scope': config.scope,
'state': state
});
dismissWindow = config.windowStrategy(url);
pubsub.subscribe(state, function (authorization) {
dismissWindow();
d.resolve(authorization);
});
return d.promise;
}
/**

@@ -81,3 +89,3 @@ * OAuth implicit flow support

*
* @param {Client} [client] client to wrap
* @param {Client} [target] client to wrap
* @param {string} [config.token] pre-configured authentication token

@@ -94,98 +102,43 @@ * @param {string} config.clientId OAuth clientId

*/
return function (client, config) {
if (typeof client === 'object') {
config = client;
}
if (typeof client !== 'function') {
client = defaultClient;
}
return interceptor({
init: function (config) {
config.redirectUrl = new UrlBuilder(config.redirectUrl).fullyQualify().build();
config.windowStrategy = config.windowStrategy || defaultWindowStrategy;
config.oAuthCallback = config.oAuthCallback || defaultOAuthCallback;
config.oAuthCallbackName = config.oAuthCallbackName || 'oAuthCallback';
var interceptor, authorization, clientId, authorizationUrlBase, redirectUrl, scope, windowStrategy;
global[config.oAuthCallbackName] = config.oAuthCallback;
authorization = config.token;
clientId = config.clientId;
authorizationUrlBase = config.authorizationUrlBase;
redirectUrl = new UrlBuilder(config.redirectUrl).absolute().build();
scope = config.scope;
windowStrategy = config.windowStrategy || defaultWindowStrategy;
return config;
},
request: function (request, config) {
request.headers = request.headers || {};
global[config.oAuthCallbackName || 'oAuthCallback'] = config.oAuthCallback || defaultOAuthCallback;
function reauthorize() {
var d, state, url, dismissWindow;
d = when.defer();
state = Math.random() * new Date().getTime();
url = new UrlBuilder(authorizationUrlBase).build({
'response_type': 'token',
'redirect_uri': redirectUrl,
'client_id': clientId,
'scope': scope,
'state': state
});
dismissWindow = windowStrategy(url);
pubsub.subscribe(state, function (auth) {
authorization = auth;
dismissWindow();
d.resolve(authorization);
});
return d.promise;
}
interceptor = function (request) {
var response;
response = when.defer();
function doRequest() {
var headers;
headers = request.headers || (request.headers = {});
headers.Authorization = authorization;
when(
client(request),
function (success) {
if (success.status.code === 401) {
when(reauthorize(), function () {
doRequest(request);
});
}
else if (success.status.code === 403) {
response.reject(success);
}
else {
response.resolve(success);
}
},
function (error) {
response.reject(error);
},
function (progress) {
response.progress(progress);
}
);
if (config.token) {
request.headers.Authorization = config.token;
return request;
}
if (!authorization) {
when(reauthorize(), function () {
doRequest();
else {
return authorize(config).then(function (authorization) {
request.headers.Authorization = config.token = authorization;
return request;
});
}
else {
doRequest();
},
response: function (response, config, client) {
if (response.status.code === 401) {
// token probably expired, reauthorize
return authorize(config).then(function (authorization) {
config.token = authorization;
return client(response.request);
});
}
else if (response.status.code === 403) {
return when.reject(response);
}
return response.promise;
};
interceptor.skip = function () {
return client;
};
return response;
}
});
return interceptor;
};
});

@@ -192,0 +145,0 @@

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -28,5 +13,6 @@

var interceptor;
var interceptor, UrlBuilder;
interceptor = require('../interceptor');
UrlBuilder = require('../UrlBuilder');

@@ -53,3 +39,3 @@ function startsWith(str, prefix) {

if (config.prefix) {
if (config.prefix && !(new UrlBuilder(request.path).isFullyQualified())) {
path = config.prefix;

@@ -56,0 +42,0 @@ if (request.path) {

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Jeremy Grelle
* @author Scott Andrews
*/

@@ -47,15 +33,15 @@

return interceptor({
request: function (request, config) {
request.retry = request.retry || config.initial || 100;
return request;
init: function (config) {
config.initial = config.initial || 100;
config.multiplier = config.multiplier || 2;
config.max = config.max || Infinity;
return config;
},
error: function (response, config, client) {
var request, multiplier, max, sleep;
var request;
request = response.request;
multiplier = config.multiplier || 2;
max = config.max || Infinity;
sleep = Math.min(request.retry, request.retry *= multiplier, max);
request.retry = request.retry || config.initial;
return delay(request, sleep).then(function (request) {
return delay(request, request.retry).then(function (request) {
if (request.canceled) {

@@ -65,2 +51,3 @@ // cancel here in case client doesn't check canceled flag

}
request.retry = Math.min(request.retry * config.multiplier, config.max);
return client(request);

@@ -67,0 +54,0 @@ });

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Jeremy Grelle
* @author Scott Andrews
*/

@@ -28,7 +14,6 @@

var interceptor, when, delay;
var interceptor, when;
interceptor = require('../interceptor');
when = require('when');
delay = require('when/delay');

@@ -44,5 +29,9 @@ /**

return interceptor({
init: function (config) {
config.timeout = config.timeout || 0;
return config;
},
request: function (request, config) {
var timeout, abortTrigger;
timeout = 'timeout' in request ? request.timeout : 'timeout' in config ? config.timeout : 0;
timeout = 'timeout' in request ? request.timeout : config.timeout;
if (timeout <= 0) {

@@ -52,4 +41,4 @@ return request;

abortTrigger = when.defer();
delay(timeout).then(function () {
abortTrigger.resolver.reject({ request: request, error: 'timeout' });
this.timeout = setTimeout(function () {
abortTrigger.reject({ request: request, error: 'timeout' });
if (request.cancel) {

@@ -61,4 +50,11 @@ request.cancel();

}
});
return [request, abortTrigger.promise];
}, timeout);
return new interceptor.ComplexRequest({ request: request, abort: abortTrigger.promise });
},
response: function (response) {
if (this.timeout) {
clearTimeout(this.timeout);
delete this.timeout;
}
return response;
}

@@ -65,0 +61,0 @@ });

@@ -1,2 +0,2 @@

Copyright (c) 2012-2013 VMware, Inc. All Rights Reserved.
Copyright (c) 2012-2013 the original author or authors

@@ -20,1 +20,10 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of

SOFTWARE.
---
Code published by Scott Andrews or Jeremy Grelle is copyright VMware.
VMware, Inc.
3401 Hillview Avenue
Palo Alto, CA 94304
/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -28,38 +13,66 @@

var when, load, registry;
var when, registry;
when = require('when');
// include text/plain and application/json by default
registry = {
'text/plain': require('./type/text/plain'),
'application/json': require('./type/application/json')
};
function normalizeMime(mime) {
return mime.split(';')[0].trim();
}
/**
* Lookup the converter for a MIME type
*
* @param {string} mime the MIME type
* @return the converter for the MIME type
*/
function lookup(mime) {
// ignore charset if included
mime = mime.split(';')[0].trim();
if (!registry[mime]) {
return register(mime, load(mime));
function Registry(parent) {
var mimes = {};
if (typeof parent === 'function') {
// coerce a lookup function into the registry API
parent = (function (lookup) {
return {
lookup: function (mime) {
// cache to avoid duplicate lookups
mimes[mime] = lookup(mime);
return mimes[mime];
}
};
}(parent));
}
return registry[mime];
}
/**
* Register a custom converter for a MIME type
*
* @param {string} mime the MIME type
* @param converter the converter for the MIME type
* @return the converter
*/
function register(mime, converter) {
return registry[mime] = converter;
/**
* Lookup the converter for a MIME type
*
* @param {string} mime the MIME type
* @return a promise for the converter
*/
this.lookup = function lookup(mime) {
mime = normalizeMime(mime);
return mime in mimes ? mimes[mime] : parent.lookup(mime);
};
/**
* Register a custom converter for a MIME type
*
* @param {string} mime the MIME type
* @param converter the converter for the MIME type
* @return a promise for the converter
*/
this.register = function register(mime, converter) {
mime = normalizeMime(mime);
mimes[mime] = when.resolve(converter);
return mimes[mime];
};
}
Registry.prototype = {
/**
* Create a child registry whoes registered converters remain local, while
* able to lookup converters from its parent.
*
* @returns child MIME registry
*/
child: function child() {
return new Registry(this);
}
};
function loadAMD(mime) {

@@ -99,15 +112,10 @@ var d, timeout;

/**
* Attempts to resolve a new converter
*
* @param {string} mime the MIME type
* @return the converter for the MIME type
*/
load = typeof require === 'function' && require.amd ? loadAMD : loadNode;
registry = new Registry(typeof require === 'function' && require.amd ? loadAMD : loadNode);
return {
lookup: lookup,
register: register
};
// include text/plain and application/json by default
registry.register('text/plain', require('./type/text/plain'));
registry.register('application/json', require('./type/application/json'));
return registry;
});

@@ -114,0 +122,0 @@

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -22,0 +7,0 @@

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -22,0 +7,0 @@

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -22,0 +7,0 @@

{
"name": "rest",
"version": "0.8.4",
"description": "HTTP client library inspired by the Spring Framework's RestTemplate",
"keywords": ["rest", "http", "client", "rest-template", "spring", "s2js"],
"version": "0.9.0",
"description": "RESTful HTTP client library",
"keywords": ["rest", "http", "client", "rest-template", "spring", "cujojs"],
"licenses": [

@@ -15,6 +15,6 @@ {

"type": "git",
"url": "https://github.com/s2js/rest"
"url": "https://github.com/cujojs/rest"
}
],
"bugs": "https://github.com/s2js/rest/issues",
"bugs": "https://github.com/cujojs/rest/issues",
"maintainers": [

@@ -34,17 +34,18 @@ {

"dependencies": {
"when": "~1"
"when": "~2"
},
"devDependencies": {
"curl": "https://github.com/cujojs/curl/tarball/0.7.2",
"wire": "~0.9",
"dojo": "https://github.com/dojo/dojo/tarball/1.7.2",
"poly": "https://github.com/cujojs/poly/tarball/0.5.1",
"wire": "https://github.com/cujojs/wire/tarball/0.8.0",
"buster": "",
"jshint": ""
"test-support": "~0.2",
"curl": "https://github.com/cujojs/curl/tarball/0.7.3",
"poly": "https://github.com/cujojs/poly/tarball/0.5.1"
},
"main": "./rest",
"scripts": {
"test": "jshint . && buster test -e node --color none --reporter specification",
"start": "buster static -e browser"
"test": "jshint . && buster test --node",
"ci": "npm test && sauceme",
"start": "buster static -e browser",
"tunnel": "sauceme -m"
}
}

@@ -1,5 +0,5 @@

Rest.js
rest.js
=======
Just enough client, as you need it. Make HTTP requests from a browser or Node.js applying the only the client features you need. Configure a client once, and share it safely throughout your application. Easily extend with interceptors that wrap the request and/or response, or MIME type converters for rich data formats.
Just enough client, as you need it. Make HTTP requests from a browser or Node.js applying only the client features you need. Configure a client once, and share it safely throughout your application. Easily extend with interceptors that wrap the request and/or response, or MIME type converters for rich data formats.

@@ -11,46 +11,26 @@

<table>
<tr><td>Master</td><td><a href="http://travis-ci.org/s2js/rest" target="_blank"><img src="https://secure.travis-ci.org/s2js/rest.png?branch=master" /></a></tr>
<tr><td>Development</td><td><a href="http://travis-ci.org/s2js/rest" target="_blank"><img src="https://secure.travis-ci.org/s2js/rest.png?branch=dev" /></a></tr>
<tr><td>Master</td><td><a href="http://travis-ci.org/cujojs/rest" target="_blank"><img src="https://secure.travis-ci.org/cujojs/rest.png?branch=master" /></a></tr>
<tr><td>Development</td><td><a href="http://travis-ci.org/cujojs/rest" target="_blank"><img src="https://secure.travis-ci.org/cujojs/rest.png?branch=dev" /></a></tr>
</table>
Getting Started
---------------
Rest can be installed via [npm](https://npmjs.org/), [Bower](http://twitter.github.com/bower/), or from source.
To install without source:
$ npm install rest
or
$ bower install rest
From source:
$ npm install
Rest.js is designed to run in a browser environment, utilizing [AMD modules](https://github.com/amdjs/amdjs-api/wiki/AMD), or within [Node.js](http://nodejs.org/). [curl](https://github.com/cujojs/curl) is highly recommended as an AMD loader, although any loader should work.
An ECMAScript 5 compatible environment is assumed. Older browsers, ::cough:: IE, that do not support ES5 natively can be shimmed. Any shim should work, although we've tested against cujo's [poly](https://github.com/cujojs/poly)
Usage
-----
Using Rest.js is easy. The core clients provide limited functionality around the request and response lifecycle. The input and response objects are normalized to support portability between browser and server environments.
Using rest.js is easy. The core clients provide limited functionality around the request and response lifecycle. The request and response objects are normalized to support portability between different JavaScript environments.
The response from a client is a promise that is resolved when the remote request finishes.
The return value from a client is a promise that is resolved with the response when the remote request finishes.
The core client behavior can be augmented with interceptors. An interceptor wraps the client and transforms the request and response. For example: an interceptor may authenticate a request, or reject the promise if an error is encountered. Interceptors may be combined to create a client with the desired behavior. A configured interceptor acts just like a client.
The core client behavior can be augmented with [interceptors](docs/interceptors.md#interceptor-principals). An interceptor wraps the client and transforms the request and response. For example: an interceptor may authenticate a request, or reject the promise if an error is encountered. Interceptors may be combined to create a client with the desired behavior. A configured interceptor acts just like a client. The core clients are basic, they only know the low level mechanics of making a request and parsing the response. All other behavior is applied and configurated with interceptors.
Interceptors are applied to a client by chaining. To chain a client with an interceptor, call the `chain` function on the client providing the interceptor and optionally a configuration object. A new client is returned containing the interceptor's behavior applied to the parent client. It's important to note that the behavior of the original client is not modified, in order to use the new behavior, you must use the returned client.
### Making a basic request: ###
```javascript
define(['rest'], function(client) {
client({ path: '/' }).then(function(response) {
console.log('response: ', response);
});
var rest = require('rest');
rest({ path: '/' }).then(function(response) {
console.log('response: ', response);
});

@@ -66,10 +46,13 @@ ```

If you're paying attention, you may have noticed that the response.entity in the previous example is a String. Often we need to work with more complex data types. For this, Rest supports a rich set of MIME type conversions with the `mime` interceptor. The correct converter will automatically be chosen based on the Content-Type response header. Custom converts can be registered for a MIME type, more on that later...
If you paid attention when executing the previous example, you may have noticed that the response.entity is a string. Often we work with more complex data types. For this, rest.js supports a rich set of [MIME type conversions](docs/mime.md) with the [MIME Interceptor](docs/interceptors.md#module-rest/interceptor/mime). The correct converter will automatically be chosen based on the `Content-Type` response header. Custom converts can be registered for a MIME type, more on that later...
```javascript
define(['rest/interceptor/mime'], function(mime) {
var client = mime();
client({ path: '/data.json' }).then(function(response) {
console.log('response: ', response);
});
var rest, mime, client;
rest = require('rest'),
mime = require('rest/interceptor/mime');
client = rest.chain(mime);
client({ path: '/data.json' }).then(function(response) {
console.log('response: ', response);
});

@@ -84,19 +67,23 @@ ```

```javascript
define(['rest/interceptor/mime', 'rest/interceptor/errorCode'], function(mime, errorCode) {
var client = mime();
client = errorCode(client, { code: 500 });
client({ path: '/data.json' }).then(
function(response) {
console.log('response: ', response);
},
function(response) {
console.error('response error: ', response);
}
);
});
var rest, mime, errorCode, client;
rest = require('rest'),
mime = require('rest/interceptor/mime');
errorCode = require('rest/interceptor/errorCode');
client = rest.chain(mime)
.chain(errorCode, { code: 500 });
client({ path: '/data.json' }).then(
function(response) {
console.log('response: ', response);
},
function(response) {
console.error('response error: ', response);
}
);
```
In this example, we take the client create by the `mime` interceptor, and wrap it in the `errorCode` interceptor. The errorCode interceptor can accept a configuration object that indicates what status codes should be considered an error. In this case we override the default value of <=400, to only reject with 500 or greater status code.
In this example, we take the client create by the [MIME Interceptor](docs/interceptors.md#module-rest/interceptor/mime), and wrap it with the [Error Code Interceptor](https://github.com/s2js/rest/blob/cujojs/docs/interceptors.md#module-rest/interceptor/errorCode). The error code interceptor accepts a configuration object that indicates what status codes should be considered an error. In this case we override the default value of <=400, to only reject with 500 or greater status code.
Since the errorCode interceptor can reject the response promise, we also add a second handler function to receive the response for requests in error.
Since the error code interceptor can reject the response promise, we also add a second handler function to receive the response for requests in error.

@@ -106,22 +93,45 @@ Clients can continue to be composed with interceptors as needed. At any point the client as configured can be shared. It is safe to share clients and allow other parts of your application to continue to compose other clients around the shared core. Your client is protected from additional interceptors that other parts of the application may add.

### Declarative Interceptor Composition: ###
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.
Let's take the previous example and configure the client using a wire specification instead of imperative code.
```javascript
{
...,
client: {
rest: [
{ module: 'rest/interceptor/mime' },
{ module: 'rest/interceptor/errorCode', config: { code: 500 } }
]
},
plugins: [{ module: 'rest/wire' }]
}
```
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.
### Custom MIME Converters: ###
```javascript
define(['rest/mime/registry'], function(registry) {
registry.register('application/vnd.com.example', {
read: function(str) {
var obj;
// do string to object conversions
return obj;
},
write: function(obj) {
var str;
// do object to string conversions
return str;
}
});
var registry = require('rest/mime/registry');
registry.register('application/vnd.com.example', {
read: function(str) {
var obj;
// do string to object conversions
return obj;
},
write: function(obj) {
var str;
// do object to string conversions
return str;
}
});
```
Registering a custom converter is a simple as calling the register function on the mime registry with the type and converter. A converter has just two methods: `read` and `write`. Read converts a String to a more complex Object. Write converts an Object back into a String to be sent to the server. HTTP is fundamentally a text based protocol after all.
Registering a custom converter is a simple as calling the register function on the [mime registry](docs/mime.md#module-rest/mime/registry) with the type and converter. A converter has just two methods: `read` and `write`. Read converts a String to a more complex Object. Write converts an Object back into a String to be sent to the server. HTTP is fundamentally a text based protocol after all.

@@ -131,10 +141,48 @@ Built in converters are available under `rest/mime/type/{type}`, as an example, JSON support is located at `rest/mime/type/application/json`. You never need to know this as a consumer, but it's a good place to find examples.

Reporting Issues
----------------
Supported Environments
----------------------
Please report issues on [GitHub](https://github.com/s2js/rest/issues). Include a brief description of the error, information about the runtime (including shims) and any error messages.
Our goal is to work in every major JavaScript environment; Node.js and major browsers are actively tested and supported.
Feature requests are also welcome.
If your preferred environment is not supported, please let us know. Some features may not be available in all environments.
Tested environments:
- Node.js (0.8, 0.6, should work in 0.10)
- Chrome (stable)
- Firefox (stable, ESR, should work in earlier versions)
- IE (6-10)
- Safari (5, 6, iOS 4-6, should work in earlier versions)
- Opera (11, 12, should work in earlier versions)
Specific browser test are provided by [Travis CI](https://travis-ci.org/cujojs/rest) and [Sauce Labs' Open Sauce Plan](https://saucelabs.com/opensource). You can see [specific browser test results](https://saucelabs.com/u/cujojs-rest), although odds are they do not reference this specific release/branch/commit.
Getting Started
---------------
rest.js can be installed via [npm](https://npmjs.org/), [Bower](http://twitter.github.com/bower/), or from source.
To install without source:
$ npm install rest
or
$ bower install rest
From source:
$ npm install
rest.js is designed to run in a browser environment, utilizing [AMD modules](https://github.com/amdjs/amdjs-api/wiki/AMD), or within [Node.js](http://nodejs.org/). [curl.js](https://github.com/cujojs/curl) is highly recommended as an AMD loader, although any loader should work.
An ECMAScript 5 compatible environment is assumed. Older browsers, ::cough:: IE, that do not support ES5 natively can be shimmed. Any shim should work, although we've tested against cujo's [poly.js](https://github.com/cujojs/poly)
Documentation
-------------
Full project documentation is available in the [docs directory](docs).
Running the Tests

@@ -159,2 +207,12 @@ -----------------

Get in Touch
------------
You can find us on the [cujojs mailing list](https://groups.google.com/forum/#!forum/cujojs), or the #cujojs IRC channel on freenode.
Please report issues on [GitHub](https://github.com/cujojs/rest/issues). Include a brief description of the error, information about the runtime (including shims) and any error messages.
Feature requests are also welcome.
Contributors

@@ -172,14 +230,30 @@ ------------

Integration is made available under the MIT license. See LICENSE.txt for details.
Copyright 2012-2013 the original author or authors
Copyright (c) 2012-2013 VMware, Inc. All Rights Reserved.
rest.js is made available under the MIT license. See LICENSE.txt for details.
VMware, Inc.
3401 Hillview Avenue
Palo Alto, CA 94304
Change Log
----------
0.9.0
- moving from the 's2js' to the 'cujojs' organization
- new reference documentation in the docs directory
- Interceptor configuration chaining `rest.chain(interceptor, config).chain(interceptor, config)...`
- wire.js factory
- hateoas and location interceptors default to use request.originator
- defaultRequest interceptor, provide default values for any portion of a request
- XDomainRequest support for IE 8 and 9
- XHR fall back interceptor for older IE
- allow child MIME registries and configurable registry for the mime interceptor
- SimpleRestStore that provides the functionality of RestStore without Dojo's QueryResults
- rename UrlBuilder's 'absolute()' to 'fullyQualify()'
- added 'isAbsolute()', 'isFullyQualified()', 'isCrossOrigin()' and 'parts()' to UrlBuilder
- access to the originating client as request.originator
- shared 'this' between request/response phases of a single interceptor per request
- 'init' phase for interceptors, useful for defaulting config properties
- interceptor config object is now begotten, local modifications will not collide between two interceptors with the same config obj
- cleaned up interceptor's request handler for complex requests
- mutli-browser testing with Sauce Labs
0.8.4

@@ -186,0 +260,0 @@ - Bower installable, with dependencies

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -45,2 +30,3 @@

* @field {Function} [cancel] cancels the request if invoked, provided by the client
* @field {Client} [originator] the client that first handled this request, provided by the interceptor
*

@@ -66,2 +52,4 @@ * @class Request

*
* @field {function} chain wraps this client with a new interceptor returning the wrapped client
*
* @param {Request} the HTTP request

@@ -74,3 +62,3 @@ * @returns {Promise<Response>} a promise the resolves to the HTTP response

if (process && process.versions && process.versions.node) {
// avaid build tools
// evade build tools
moduleId = './client/node';

@@ -77,0 +65,0 @@ return require(moduleId);

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -31,3 +16,4 @@

'test/**/*-test-node.js'
]
],
testHelpers: ['test/failOnThrow.js']
};

@@ -51,3 +37,4 @@

'node_modules/when/**/*.js',
'node_modules/wire/**/*.js'
'node_modules/wire/**/*.js',
{ path: '/wait', backend: 'http://example.com' }
],

@@ -65,3 +52,4 @@ libs: [

'test/run.js'
]
],
testHelpers: ['test/failOnThrow.js']
};
/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -26,11 +11,9 @@

var assert, refute, fail;
var assert, refute, fail, failOnThrow;
assert = buster.assert;
refute = buster.refute;
assert = buster.assertions.assert;
refute = buster.assertions.refute;
fail = buster.assertions.fail;
failOnThrow = buster.assertions.failOnThrow;
fail = function () {
buster.assertions.fail('should never be called');
};
define('rest/client/jsonp-test', function (require) {

@@ -47,21 +30,17 @@

var request = { path: 'http://ajax.googleapis.com/ajax/services/search/web?v=1.0', params: { q: 'javascript' } };
client(request).then(
function (response) {
assert(response.entity.responseData);
assert.same(request, response.request);
refute(request.canceled);
refute(response.raw.parentNode);
}
).always(done);
client(request).then(function (response) {
assert(response.entity.responseData);
assert.same(request, response.request);
refute(request.canceled);
refute(response.raw.parentNode);
}).otherwise(fail).ensure(done);
},
'should use the jsonp client from the jsonp interceptor by default': function (done) {
var request = { path: 'http://ajax.googleapis.com/ajax/services/search/web?v=1.0', params: { q: 'html5' } };
jsonpInterceptor()(request).then(
function (response) {
assert(response.entity.responseData);
assert.same(request, response.request);
refute(request.canceled);
refute(response.raw.parentNode);
}
).always(done);
jsonpInterceptor()(request).then(function (response) {
assert(response.entity.responseData);
assert.same(request, response.request);
refute(request.canceled);
refute(response.raw.parentNode);
}).otherwise(fail).ensure(done);
},

@@ -72,8 +51,8 @@ 'should abort the request if canceled': function (done) {

fail,
function (response) {
failOnThrow(function (response) {
assert.same(request, response.request);
assert(request.canceled);
refute(response.raw.parentNode);
}
).always(done);
})
).ensure(done);
refute(request.canceled);

@@ -86,6 +65,6 @@ request.cancel();

fail,
function (response) {
failOnThrow(function (response) {
assert.same('loaderror', response.error);
}
).always(done);
})
).ensure(done);
},

@@ -96,11 +75,14 @@ 'should not make a request that has already been canceled': function (done) {

fail,
function (response) {
failOnThrow(function (response) {
assert.same(request, response.request);
assert(request.canceled);
assert.same('precanceled', response.error);
}
).always(done);
})
).ensure(done);
},
'should not be the default client': function () {
refute.same(client, rest);
},
'should support interceptor chaining': function () {
assert(typeof client.chain === 'function');
}

@@ -107,0 +89,0 @@ });

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Jeremy Grelle
* @author Scott Andrews
*/

@@ -26,13 +12,11 @@

var assert, refute, fail;
var assert, refute, fail, failOnThrow;
assert = buster.assert;
refute = buster.refute;
assert = buster.assertions.assert;
refute = buster.assertions.refute;
fail = buster.assertions.fail;
failOnThrow = buster.assertions.failOnThrow;
fail = function () {
buster.assertions.fail('should never be called');
};
define('rest/client/node-test', function (require) {
define('rest/client/jsonp-test', function (require) {
var rest, client, http, server;

@@ -70,56 +54,48 @@

},
'should make a GET by default': function (done) {
var request = { path: 'http://localhost:8080/' };
client(request).then(
function (response) {
assert(response.raw.request instanceof http.ClientRequest);
// assert(response.raw.response instanceof http.ClientResponse);
assert(response.raw.response);
assert.same(request, response.request);
assert.equals(response.request.method, 'GET');
assert.equals(response.entity, 'hello world');
assert.equals(response.status.code, 200);
assert.equals('text/plain', response.headers['Content-Type']);
assert.equals(response.entity.length, parseInt(response.headers['Content-Length'], 10));
refute(request.canceled);
}
).always(done);
client(request).then(function (response) {
assert(response.raw.request instanceof http.ClientRequest);
// assert(response.raw.response instanceof http.ClientResponse);
assert(response.raw.response);
assert.same(request, response.request);
assert.equals(response.request.method, 'GET');
assert.equals(response.entity, 'hello world');
assert.equals(response.status.code, 200);
assert.equals('text/plain', response.headers['Content-Type']);
assert.equals(response.entity.length, parseInt(response.headers['Content-Length'], 10));
refute(request.canceled);
}).otherwise(fail).ensure(done);
},
'should make an explicit GET': function (done) {
var request = { path: 'http://localhost:8080/', method: 'GET' };
client(request).then(
function (response) {
assert.same(request, response.request);
assert.equals(response.request.method, 'GET');
assert.equals(response.entity, 'hello world');
assert.equals(response.status.code, 200);
refute(request.canceled);
}
).always(done);
client(request).then(function (response) {
assert.same(request, response.request);
assert.equals(response.request.method, 'GET');
assert.equals(response.entity, 'hello world');
assert.equals(response.status.code, 200);
refute(request.canceled);
}).otherwise(fail).ensure(done);
},
'should make a POST with an entity': function (done) {
var request = { path: 'http://localhost:8080/', entity: 'echo' };
client(request).then(
function (response) {
assert.same(request, response.request);
assert.equals(response.request.method, 'POST');
assert.equals(response.entity, 'echo');
assert.equals(response.status.code, 200);
assert.equals('text/plain', response.headers['Content-Type']);
assert.equals(response.entity.length, parseInt(response.headers['Content-Length'], 10));
refute(request.canceled);
}
).always(done);
client(request).then(function (response) {
assert.same(request, response.request);
assert.equals(response.request.method, 'POST');
assert.equals(response.entity, 'echo');
assert.equals(response.status.code, 200);
assert.equals('text/plain', response.headers['Content-Type']);
assert.equals(response.entity.length, parseInt(response.headers['Content-Length'], 10));
refute(request.canceled);
}).otherwise(fail).ensure(done);
},
'should make an explicit POST with an entity': function (done) {
var request = { path: 'http://localhost:8080/', entity: 'echo', method: 'POST' };
client(request).then(
function (response) {
assert.same(request, response.request);
assert.equals(response.request.method, 'POST');
assert.equals(response.entity, 'echo');
refute(request.canceled);
}
).always(done);
client(request).then(function (response) {
assert.same(request, response.request);
assert.equals(response.request.method, 'POST');
assert.equals(response.entity, 'echo');
refute(request.canceled);
}).otherwise(fail).ensure(done);
},

@@ -130,6 +106,6 @@ 'should abort the request if canceled': function (done) {

fail,
function (/* response */) {
failOnThrow(function (/* response */) {
assert(request.canceled);
}
).always(done);
})
).ensure(done);
refute(request.canceled);

@@ -142,6 +118,6 @@ request.cancel();

fail,
function (response) {
failOnThrow(function (response) {
assert(response.error);
}
).always(done);
})
).ensure(done);
},

@@ -152,11 +128,14 @@ 'should not make a request that has already been canceled': function (done) {

fail,
function (response) {
failOnThrow(function (response) {
assert.same(request, response.request);
assert(request.canceled);
assert.same('precanceled', response.error);
}
).always(done);
})
).ensure(done);
},
'should be the default client': function () {
assert.same(client, rest);
},
'should support interceptor chaining': function () {
assert(typeof client.chain === 'function');
}

@@ -163,0 +142,0 @@ });

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -26,94 +11,89 @@

var assert, refute, fail;
var assert, refute, fail, failOnThrow;
assert = buster.assert;
refute = buster.refute;
assert = buster.assertions.assert;
refute = buster.assertions.refute;
fail = buster.assertions.fail;
failOnThrow = buster.assertions.failOnThrow;
fail = function () {
buster.assertions.fail('should never be called');
};
define('rest/client/xhr-test', function (require) {
var client, rest;
var xhr, rest, xhrFallback, when, client;
client = require('rest/client/xhr');
xhr = require('rest/client/xhr');
rest = require('rest');
xhrFallback = require('rest/interceptor/ie/xhr');
when = require('when');
// use xhrFallback when XHR is not native
client = !XMLHttpRequest ? xhr.chain(xhrFallback) : xhr;
buster.testCase('rest/client/xhr', {
'should make a GET by default': function (done) {
var request = { path: '/' };
client(request).then(
function (response) {
var xhr, name;
xhr = response.raw;
assert.same(request, response.request);
assert.equals(response.request.method, 'GET');
assert.equals(xhr.responseText, response.entity);
assert.equals(xhr.status, response.status.code);
assert.equals(xhr.statusText, response.status.text);
for (name in response.headers) {
/*jshint forin:false */
assert.equals(xhr.getResponseHeader(name), response.headers[name]);
}
refute(request.canceled);
client(request).then(function (response) {
var xhr, name;
xhr = response.raw;
assert.same(request, response.request);
assert.equals(response.request.method, 'GET');
assert.equals(xhr.responseText, response.entity);
assert.equals(xhr.status, response.status.code);
assert.equals(xhr.statusText, response.status.text);
for (name in response.headers) {
/*jshint forin:false */
assert.equals(xhr.getResponseHeader(name), response.headers[name]);
}
).always(done);
refute(request.canceled);
}).otherwise(fail).ensure(done);
},
'should make an explicit GET': function (done) {
var request = { path: '/', method: 'GET' };
client(request).then(
function (response) {
var xhr, name;
xhr = response.raw;
assert.same(request, response.request);
assert.equals(response.request.method, 'GET');
assert.equals(xhr.responseText, response.entity);
assert.equals(xhr.status, response.status.code);
assert.equals(xhr.statusText, response.status.text);
for (name in response.headers) {
/*jshint forin:false */
assert.equals(xhr.getResponseHeader(name), response.headers[name]);
}
refute(request.canceled);
client(request).then(function (response) {
var xhr, name;
xhr = response.raw;
assert.same(request, response.request);
assert.equals(response.request.method, 'GET');
assert.equals(xhr.responseText, response.entity);
assert.equals(xhr.status, response.status.code);
assert.equals(xhr.statusText, response.status.text);
for (name in response.headers) {
/*jshint forin:false */
assert.equals(xhr.getResponseHeader(name), response.headers[name]);
}
).always(done);
refute(request.canceled);
}).otherwise(fail).ensure(done);
},
'should make a POST with an entity': function (done) {
var request = { path: '/', entity: 'hello world' };
client(request).then(
function (response) {
var xhr, name;
xhr = response.raw;
assert.same(request, response.request);
assert.equals(response.request.method, 'POST');
assert.equals(xhr.responseText, response.entity);
assert.equals(xhr.status, response.status.code);
assert.equals(xhr.statusText, response.status.text);
for (name in response.headers) {
/*jshint forin:false */
assert.equals(xhr.getResponseHeader(name), response.headers[name]);
}
refute(request.canceled);
client(request).then(function (response) {
var xhr, name;
xhr = response.raw;
assert.same(request, response.request);
assert.equals(response.request.method, 'POST');
assert.equals(xhr.responseText, response.entity);
assert.equals(xhr.status, response.status.code);
assert.equals(xhr.statusText, response.status.text);
for (name in response.headers) {
/*jshint forin:false */
assert.equals(xhr.getResponseHeader(name), response.headers[name]);
}
).always(done);
refute(request.canceled);
}).otherwise(fail).ensure(done);
},
'should make an explicit POST with an entity': function (done) {
var request = { path: '/', entity: 'hello world', method: 'POST' };
client(request).then(
function (response) {
var xhr, name;
xhr = response.raw;
assert.same(request, response.request);
assert.equals(response.request.method, 'POST');
assert.equals(xhr.responseText, response.entity);
assert.equals(xhr.status, response.status.code);
assert.equals(xhr.statusText, response.status.text);
for (name in response.headers) {
/*jshint forin:false */
assert.equals(xhr.getResponseHeader(name), response.headers[name]);
}
refute(request.canceled);
client(request).then(function (response) {
var xhr, name;
xhr = response.raw;
assert.same(request, response.request);
assert.equals(response.request.method, 'POST');
assert.equals(xhr.responseText, response.entity);
assert.equals(xhr.status, response.status.code);
assert.equals(xhr.statusText, response.status.text);
for (name in response.headers) {
/*jshint forin:false */
assert.equals(xhr.getResponseHeader(name), response.headers[name]);
}
).always(done);
refute(request.canceled);
}).otherwise(fail).ensure(done);
},

@@ -123,24 +103,37 @@ 'should abort the request if canceled': function (done) {

var request = { path: '/wait/' + new Date().getTime() };
client(request).then(
fail,
function (response) {
assert(request.canceled);
assert.same(0, response.raw.status);
when.all([
client(request).then(
fail,
failOnThrow(function (response) {
assert(request.canceled);
try {
// accessing 'status' will throw in older Firefox
assert.same(0, response.raw.status);
}
catch (e) {
// ignore
}
// this assertion is true in every browser except for IE 6
// assert.same(XMLHttpRequest.UNSENT || 0, response.raw.readyState);
assert(response.raw.readyState <= 3);
}
).always(done);
refute(request.canceled);
request.cancel();
// this assertion is true in every browser except for IE 6
// assert.same(XMLHttpRequest.UNSENT || 0, response.raw.readyState);
assert(response.raw.readyState <= 3);
})
),
when({}, function () {
// push into when's nextTick resolution
refute(request.canceled);
request.cancel();
})
]).ensure(done);
},
'should propogate request errors': function (done) {
'//should propogate request errors': function (done) {
// TODO follow up with Sauce Labs
// this test is valid, but fails with sauce as their proxy returns a 400
var request = { path: 'http://localhost:1234' };
client(request).then(
fail,
function (response) {
failOnThrow(function (response) {
assert.same('loaderror', response.error);
}
).always(done);
})
).ensure(done);
},

@@ -151,11 +144,27 @@ 'should not make a request that has already been canceled': function (done) {

fail,
function (response) {
failOnThrow(function (response) {
assert.same(request, response.request);
assert(request.canceled);
assert.same('precanceled', response.error);
}
).always(done);
})
).ensure(done);
},
'should reject if an XHR impl is not available': {
requiresSupportFor: { 'no-xhr': !window.XMLHttpRequest },
'': function (done) {
var request = { path: '/' };
xhr(request).then(
fail,
failOnThrow(function (response) {
assert.same(request, response.request);
assert.same('xhr-not-available', response.error);
})
).ensure(done);
}
},
'should be the default client': function () {
assert.same(client, rest);
assert.same(xhr, rest);
},
'should support interceptor chaining': function () {
assert(typeof xhr.chain === 'function');
}

@@ -162,0 +171,0 @@ });

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -35,5 +20,6 @@

],
preloads: ['poly']
// avoid poly/xhr as we need to test the case without it
preloads: ['poly/object', 'poly/string', 'poly/date', 'poly/array', 'poly/function', 'poly/json']
};
}(this));
/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -26,12 +11,14 @@

var assert, refute;
var assert, refute, fail;
assert = buster.assert;
refute = buster.refute;
assert = buster.assertions.assert;
refute = buster.assertions.refute;
fail = buster.assertions.fail;
define('rest/dojo/RestStore-test', function (require) {
var RestStore, when;
var RestStore, SimpleRestStore, when;
RestStore = require('rest/dojo/RestStore');
SimpleRestStore = require('rest/dojo/SimpleRestStore');
when = require('when');

@@ -58,103 +45,87 @@

var store = new RestStore({ client: client });
store.query({ q: 'what is the meaning of life?' }).then(
function (response) {
assert.equals('what is the meaning of life?', response.request.params.q);
}
).always(done);
store.query({ q: 'what is the meaning of life?' }).then(function (response) {
assert.equals('what is the meaning of life?', response.request.params.q);
}).otherwise(fail).ensure(done);
},
'should get based on the id': function (done) {
var store = new RestStore({ client: client });
store.get(42).then(
function (response) {
assert.equals('42', response.request.path);
refute(response.request.method);
}
).always(done);
store.get(42).then(function (response) {
assert.equals('42', response.request.path);
refute(response.request.method);
}).otherwise(fail).ensure(done);
},
'should remove based on the id': function (done) {
var store = new RestStore({ client: client });
store.remove(42).then(
function (response) {
assert.equals('42', response.request.path);
assert.equals('delete', response.request.method);
}
).always(done);
store.remove(42).then(function (response) {
assert.equals('42', response.request.path);
assert.equals('delete', response.request.method);
}).otherwise(fail).ensure(done);
},
'should add a record without an ID': function (done) {
var store = new RestStore({ client: client });
store.add({ foo: 'bar' }).then(
function (response) {
assert.equals('', response.request.path);
assert.equals('post', response.request.method);
assert.equals('*', response.request.headers['If-None-Match']);
assert.equals('bar', response.request.entity.foo);
}
).always(done);
store.add({ foo: 'bar' }).then(function (response) {
assert.equals('', response.request.path);
assert.equals('post', response.request.method);
assert.equals('*', response.request.headers['If-None-Match']);
assert.equals('bar', response.request.entity.foo);
}).otherwise(fail).ensure(done);
},
'should add a record with an explicit ID': function (done) {
var store = new RestStore({ client: client });
store.add({ foo: 'bar' }, { id: 42 }).then(
function (response) {
assert.equals('42', response.request.path);
assert.equals('put', response.request.method);
assert.equals('*', response.request.headers['If-None-Match']);
assert.equals('bar', response.request.entity.foo);
refute.equals('42', response.request.entity.id);
}
).always(done);
store.add({ foo: 'bar' }, { id: 42 }).then(function (response) {
assert.equals('42', response.request.path);
assert.equals('put', response.request.method);
assert.equals('*', response.request.headers['If-None-Match']);
assert.equals('bar', response.request.entity.foo);
refute.equals('42', response.request.entity.id);
}).otherwise(fail).ensure(done);
},
'should add a record with an implicit ID': function (done) {
var store = new RestStore({ client: client });
store.add({ foo: 'bar', id: 42 }).then(
function (response) {
assert.equals('42', response.request.path);
assert.equals('put', response.request.method);
assert.equals('*', response.request.headers['If-None-Match']);
assert.equals('bar', response.request.entity.foo);
assert.equals('42', response.request.entity.id);
}
).always(done);
store.add({ foo: 'bar', id: 42 }).then(function (response) {
assert.equals('42', response.request.path);
assert.equals('put', response.request.method);
assert.equals('*', response.request.headers['If-None-Match']);
assert.equals('bar', response.request.entity.foo);
assert.equals('42', response.request.entity.id);
}).otherwise(fail).ensure(done);
},
'should add a record ignoring the ID': function (done) {
var store = new RestStore({ client: client, ignoreId: true });
store.add({ foo: 'bar', id: 42 }).then(
function (response) {
assert.equals('', response.request.path);
assert.equals('post', response.request.method);
assert.equals('*', response.request.headers['If-None-Match']);
assert.equals('bar', response.request.entity.foo);
assert.equals('42', response.request.entity.id);
}
).always(done);
store.add({ foo: 'bar', id: 42 }).then(function (response) {
assert.equals('', response.request.path);
assert.equals('post', response.request.method);
assert.equals('*', response.request.headers['If-None-Match']);
assert.equals('bar', response.request.entity.foo);
assert.equals('42', response.request.entity.id);
}).otherwise(fail).ensure(done);
},
'should put overwriting target': function (done) {
var store = new RestStore({ client: client });
store.put({ foo: 'bar', id: 42 }, { overwrite: true }).then(
function (response) {
assert.equals('42', response.request.path);
assert.equals('put', response.request.method);
assert.equals('*', response.request.headers['If-Match']);
}
).always(done);
store.put({ foo: 'bar', id: 42 }, { overwrite: true }).then(function (response) {
assert.equals('42', response.request.path);
assert.equals('put', response.request.method);
assert.equals('*', response.request.headers['If-Match']);
}).otherwise(fail).ensure(done);
},
'should put without overwriting target': function (done) {
var store = new RestStore({ client: client });
store.put({ foo: 'bar', id: 42 }, { overwrite: false }).then(
function (response) {
assert.equals('42', response.request.path);
assert.equals('put', response.request.method);
assert.equals('*', response.request.headers['If-None-Match']);
}
).always(done);
store.put({ foo: 'bar', id: 42 }, { overwrite: false }).then(function (response) {
assert.equals('42', response.request.path);
assert.equals('put', response.request.method);
assert.equals('*', response.request.headers['If-None-Match']);
}).otherwise(fail).ensure(done);
},
'should put with default config': function (done) {
var store = new RestStore({ client: client });
store.put({ foo: 'bar', id: 42 }).then(
function (response) {
assert.equals('42', response.request.path);
assert.equals('put', response.request.method);
refute(response.request.headers['If-None-Match']);
refute(response.request.headers['If-Match']);
}
).always(done);
store.put({ foo: 'bar', id: 42 }).then(function (response) {
assert.equals('42', response.request.path);
assert.equals('put', response.request.method);
refute(response.request.headers['If-None-Match']);
refute(response.request.headers['If-Match']);
}).otherwise(fail).ensure(done);
},
'should have a proper prototype chain': function () {
assert(new RestStore() instanceof RestStore);
assert(new RestStore() instanceof SimpleRestStore);
}

@@ -161,0 +132,0 @@ });

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -26,6 +11,7 @@

var assert, refute;
var assert, refute, fail;
assert = buster.assert;
refute = buster.refute;
assert = buster.assertions.assert;
refute = buster.assertions.refute;
fail = buster.assertions.fail;

@@ -42,3 +28,3 @@ define('rest/dojo/wire-test', function (require) {

function client(request) {
return when({
return {
request: request,

@@ -50,3 +36,3 @@ status: { code: 200 },

entity: '{"foo":"bar"}'
});
};
}

@@ -63,5 +49,5 @@

assert(spec.store instanceof RestStore);
}).always(done);
}).otherwise(fail).ensure(done);
},
'should get with resource! returning a promise': function (done) {
'should get with resource! waiting for data': function (done) {
var spec;

@@ -73,18 +59,5 @@ spec = {

wire(spec).then(function (spec) {
spec.resource.then(function (resource) {
assert.equals('bar', resource.entity.foo);
assert.equals('test/dojo/hello.json', resource.request.path);
});
}).always(done);
},
'should get with resource! returning data': function (done) {
var spec;
spec = {
resource: { $ref: 'resource!test/dojo', get: 'hello.json', entity: false, wait: true, client: client },
plugins: [{ module: 'rest/dojo/wire' }]
};
wire(spec).then(function (spec) {
assert.equals('bar', spec.resource.entity.foo);
assert.equals('test/dojo/hello.json', spec.resource.request.path);
}).always(done);
}).otherwise(fail).ensure(done);
},

@@ -98,8 +71,6 @@ 'should support client!': function (done) {

wire(spec).then(function (spec) {
spec.client({}).then(
function (response) {
assert.equals('bar', response.foo);
}
);
}).always(done);
return spec.client({}).then(function (response) {
assert.equals('bar', response.foo);
});
}).otherwise(fail).ensure(done);
}

@@ -106,0 +77,0 @@ });

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -26,6 +11,7 @@

var assert, refute;
var assert, refute, fail;
assert = buster.assertions.assert;
refute = buster.assertions.refute;
fail = buster.assertions.fail;

@@ -47,3 +33,3 @@ define('rest/interceptor/basicAuth-test', function (require) {

assert.equals('Basic dXNlcjpwYXNz', response.request.headers.Authorization);
}).always(done);
}).otherwise(fail).ensure(done);
},

@@ -56,3 +42,3 @@ 'should authenticate the requst from the request': function (done) {

assert.equals('Basic dXNlcjpwYXNz', response.request.headers.Authorization);
}).always(done);
}).otherwise(fail).ensure(done);
},

@@ -65,6 +51,9 @@ 'should not authenticate without a username': function (done) {

refute.defined(response.request.headers.Authorization);
}).always(done);
}).otherwise(fail).ensure(done);
},
'should have the default client as the parent by default': function () {
assert.same(rest, basicAuth().skip());
},
'should support interceptor chaining': function () {
assert(typeof basicAuth().chain === 'function');
}

@@ -71,0 +60,0 @@ });

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -26,6 +11,7 @@

var assert, refute;
var assert, refute, fail;
assert = buster.assertions.assert;
refute = buster.assertions.refute;
fail = buster.assertions.fail;

@@ -48,3 +34,3 @@ define('rest/interceptor/entity-test', function (require) {

assert.same(body, response);
}).always(done);
}).otherwise(fail).ensure(done);
},

@@ -59,6 +45,9 @@ 'should return the whole response if there is no entity': function (done) {

assert.same(response, r);
}).always(done);
}).otherwise(fail).ensure(done);
},
'should have the default client as the parent by default': function () {
assert.same(rest, entity().skip());
},
'should support interceptor chaining': function () {
assert(typeof entity().chain === 'function');
}

@@ -65,0 +54,0 @@ });

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -26,6 +11,8 @@

var assert, refute;
var assert, refute, fail, failOnThrow;
assert = buster.assertions.assert;
refute = buster.assertions.refute;
fail = buster.assertions.fail;
failOnThrow = buster.assertions.failOnThrow;

@@ -44,7 +31,5 @@ define('rest/interceptor/errorCode-test', function (require) {

);
client({}).then(
function (response) {
assert.equals(399, response.status.code);
}
).always(done);
client({}).then(function (response) {
assert.equals(399, response.status.code);
}).otherwise(fail).ensure(done);
},

@@ -56,7 +41,7 @@ 'should reject for 400 or greater by default': function (done) {

client({}).then(
undefined,
function (response) {
fail,
failOnThrow(function (response) {
assert.equals(400, response.status.code);
}
).always(done);
})
).ensure(done);
},

@@ -69,10 +54,13 @@ 'should reject lower then 400 with a custom code': function (done) {

client({}).then(
undefined,
function (response) {
fail,
failOnThrow(function (response) {
assert.equals(300, response.status.code);
}
).always(done);
})
).ensure(done);
},
'should have the default client as the parent by default': function () {
assert.same(rest, errorCode().skip());
},
'should support interceptor chaining': function () {
assert(typeof errorCode().chain === 'function');
}

@@ -79,0 +67,0 @@ });

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -26,10 +11,11 @@

var assert, refute;
var assert, refute, fail;
assert = buster.assertions.assert;
refute = buster.assertions.refute;
fail = buster.assertions.fail;
define('rest/interceptor/hateoas-test', function (require) {
var hateoas, rest, when;
var hateoas, rest, when, supports;

@@ -40,16 +26,28 @@ hateoas = require('rest/interceptor/hateoas');

buster.testCase('rest/interceptor/hateoas', {
requiresSupportFor: {
'Object.defineProperty': function () {
try {
var obj = {};
Object.defineProperty(obj, 'test', { enumerable: false, configurable: true, value: true });
return obj.test;
}
catch (e) {
return false;
}
supports = {
'Object.defineProperty': (function () {
try {
var obj = {};
Object.defineProperty(obj, 'test', { enumerable: false, configurable: true, value: true });
return obj.test;
}
},
catch (e) {
return false;
}
}()),
'ES5 getters': (function () {
try {
var obj = {};
Object.defineProperty(obj, 'test', { get: function () { return true; } });
return obj.test;
}
catch (e) {
return false;
}
}())
};
buster.testCase('rest/interceptor/hateoas', {
requiresSupportFor: { 'Object.defineProperty': supports['Object.defineProperty'] },
'should parse links in the entity': function (done) {

@@ -67,3 +65,3 @@ var client, body, parent, self;

assert.same(self, response.entity._links.selfLink);
}).always(done);
}).otherwise(fail).ensure(done);
},

@@ -82,3 +80,3 @@ 'should parse links in the entity into the entity': function (done) {

assert.same(self, response.entity.selfLink);
}).always(done);
}).otherwise(fail).ensure(done);
},

@@ -96,27 +94,34 @@ 'should create a client for the related resource': function (done) {

var parentClient = response.entity._links.clientFor('parent', function (request) { return { request: request }; });
parentClient().then(function (response) {
return parentClient().then(function (response) {
assert.same(parent.href, response.request.path);
}).always(done);
});
});
}).otherwise(fail).ensure(done);
},
'should fetch a related resource': function (done) {
// NOTE this functionality requires a native implementation of Object.defineProperty
var client, parentClient, body, parent, self;
'should fetch a related resource': {
requiresSupportFor: { 'ES5 getters': supports['ES5 getters'] },
'': function (done) {
var client, parentClient;
parent = { rel: 'parent', href: '/' };
self = { rel: 'self', href: '/resource' };
parentClient = function (request) {
return request.path === '/' ?
{ request: request, entity: { links: [ { rel: 'self', href: '/' }, { rel: 'child', href: '/resource' } ] } } :
{ request: request, entity: { links: [ { rel: 'self', href: '/resource' }, { rel: 'parent', href: '/' } ] } };
};
client = hateoas(parentClient);
body = { links: [ parent, self ]};
parentClient = function (request) { return { request: request, entity: { links: [ parent, self ] } }; };
client = hateoas(function () { return { entity: body }; }, { client: parentClient });
client().then(function (response) {
when(response.entity._links.parent, function (response) {
assert.same(parent.href, response.request.path);
assert.same(self, response.entity._links.selfLink);
}).always(done);
});
client({ path: '/' }).then(function (response) {
assert.same('/', response.request.path);
assert.same('/', response.entity._links.selfLink.href);
return response.entity._links.child.then(function (response) {
assert.same('/resource', response.request.path);
assert.same('/resource', response.entity._links.selfLink.href);
});
}).otherwise(fail).ensure(done);
}
},
'should have the default client as the parent by default': function () {
assert.same(rest, hateoas().skip());
},
'should support interceptor chaining': function () {
assert(typeof hateoas().chain === 'function');
}

@@ -123,0 +128,0 @@ });

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -26,6 +11,7 @@

var assert, refute;
var assert, refute, fail;
assert = buster.assertions.assert;
refute = buster.assertions.refute;
fail = buster.assertions.fail;

@@ -47,8 +33,6 @@ define('rest/interceptor/jsonp-test', function (require) {

);
client({}).then(
function (response) {
assert.equals('callback', response.request.callback.param);
assert.equals('jsonp', response.request.callback.prefix);
}
).always(done);
client({}).then(function (response) {
assert.equals('callback', response.request.callback.param);
assert.equals('jsonp', response.request.callback.prefix);
}).otherwise(fail).ensure(done);
},

@@ -60,8 +44,6 @@ 'should include callback info from request overridding config values': function (done) {

);
client({ callback: { param: 'customCallback', prefix: 'customPrefix' } }).then(
function (response) {
assert.equals('customCallback', response.request.callback.param);
assert.equals('customPrefix', response.request.callback.prefix);
}
).always(done);
client({ callback: { param: 'customCallback', prefix: 'customPrefix' } }).then(function (response) {
assert.equals('customCallback', response.request.callback.param);
assert.equals('customPrefix', response.request.callback.prefix);
}).otherwise(fail).ensure(done);
},

@@ -71,2 +53,5 @@ 'should have the jsonp client as the parent by default': function () {

assert.same(jsonpClient, jsonp().skip());
},
'should support interceptor chaining': function () {
assert(typeof jsonp().chain === 'function');
}

@@ -73,0 +58,0 @@ });

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -26,6 +11,7 @@

var assert, refute;
var assert, refute, fail;
assert = buster.assertions.assert;
refute = buster.assertions.refute;
fail = buster.assertions.fail;

@@ -40,12 +26,23 @@ define('rest/interceptor/location-test', function (require) {

buster.testCase('rest/interceptor/location', {
'should follow the location header, once': function (done) {
'should follow the location header': function (done) {
var client, spy;
spy = this.spy(function (/* request */) { return { headers: { Location: '/foo/' + spy.callCount } }; });
spy = this.spy(function (request) {
var response = { request: request, headers: { } };
if (spy.callCount < 3) {
response.headers.Location = '/foo/' + spy.callCount;
}
return response;
});
client = location(spy);
client({}).then(
function (response) {
assert.equals('/foo/2', response.headers.Location);
assert.same(2, spy.callCount);
}
).always(done);
client({}).then(function (response) {
refute(response.headers.Location);
assert.same(3, spy.callCount);
assert.same(spy.returnValues[0].headers.Location, '/foo/1');
assert.same(spy.args[1][0].path, '/foo/1');
assert.same(spy.args[1][0].method, 'GET');
assert.same(spy.returnValues[1].headers.Location, '/foo/2');
assert.same(spy.args[2][0].path, '/foo/2');
assert.same(spy.args[2][0].method, 'GET');
refute(spy.returnValues[2].headers.Location);
}).otherwise(fail).ensure(done);
},

@@ -56,8 +53,12 @@ 'should return the response if there is no location header': function (done) {

client = location(spy);
client({}).then(
function (response) {
assert.equals(200, response.status.code);
assert.same(1, spy.callCount);
}
).always(done);
client({}).then(function (response) {
assert.equals(200, response.status.code);
assert.same(1, spy.callCount);
}).otherwise(fail).ensure(done);
},
'should have the default client as the parent by default': function () {
assert.same(rest, location().skip());
},
'should support interceptor chaining': function () {
assert(typeof location().chain === 'function');
}

@@ -64,0 +65,0 @@ });

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -26,12 +11,15 @@

var assert, refute;
var assert, refute, fail, failOnThrow;
assert = buster.assertions.assert;
refute = buster.assertions.refute;
fail = buster.assertions.fail;
failOnThrow = buster.assertions.failOnThrow;
define('rest/interceptor/mime-test', function (require) {
var mime, rest;
var mime, registry, rest;
mime = require('rest/interceptor/mime');
registry = require('rest/mime/registry');
rest = require('rest');

@@ -49,3 +37,3 @@

assert.equals({}, response.entity);
}).always(done);
}).otherwise(fail).ensure(done);
},

@@ -64,3 +52,3 @@ 'should encode the request entity': function (done) {

assert.equals('{}', response.request.entity);
}).always(done);
}).otherwise(fail).ensure(done);
},

@@ -81,3 +69,3 @@ 'should encode the request entity from the Content-Type of the request, ignoring the filter config': function (done) {

assert.equals(0, response.request.headers.Accept.indexOf('application/json'));
}).always(done);
}).otherwise(fail).ensure(done);
},

@@ -98,6 +86,61 @@ 'should not overwrite the requests Accept header': function (done) {

assert.equals('foo', response.request.headers.Accept);
}).always(done);
}).otherwise(fail).ensure(done);
},
'should error the request if unable to find a converter for the desired mime': function (done) {
var client, request;
client = mime();
request = { headers: { 'Content-Type': 'application/vnd.com.example' }, entity: {} };
client(request).then(
fail,
failOnThrow(function (response) {
assert.same('unknown-mime', response.error);
assert.same(request, response.request);
})
).ensure(done);
},
'should use text/plain converter for a response if unable to find a converter for the desired mime': function (done) {
var client;
client = mime(function () {
return { entity: '{}', headers: { 'Content-Type': 'application/vnd.com.example' } };
});
client({}).then(function (response) {
assert.same('{}', response.entity);
}).otherwise(fail).ensure(done);
},
'should use the configured mime registry': function (done) {
var client, customRegistry;
customRegistry = registry.child();
customRegistry.register('application/vnd.com.example', {
read: function (str) {
return 'read: ' + str;
},
write: function (obj) {
return 'write: ' + obj.toString();
}
});
client = mime(
function (request) {
return { request: request, headers: { 'Content-Type': 'application/vnd.com.example' }, entity: 'response entity' };
},
{ mime: 'application/vnd.com.example', registry: customRegistry }
);
client({ entity: 'request entity' }).then(function (response) {
assert.equals('application/vnd.com.example', response.request.headers['Content-Type']);
assert.equals('write: request entity', response.request.entity);
assert.equals('application/vnd.com.example', response.headers['Content-Type']);
assert.equals('read: response entity', response.entity);
}).otherwise(fail).ensure(done);
},
'should have the default client as the parent by default': function () {
assert.same(rest, mime().skip());
},
'should support interceptor chaining': function () {
assert(typeof mime().chain === 'function');
}

@@ -104,0 +147,0 @@ });

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -26,6 +11,7 @@

var assert, refute;
var assert, refute, fail;
assert = buster.assertions.assert;
refute = buster.assertions.refute;
fail = buster.assertions.fail;

@@ -51,3 +37,3 @@ define('rest/interceptor/oAuth-test', function (require) {

assert.equals('bearer abcxyz', response.request.headers.Authorization);
}).always(done);
}).otherwise(fail).ensure(done);
},

@@ -86,6 +72,9 @@ 'should use implicit flow to authenticate the request': function (done) {

assert.called(windowStrategyClose);
}).always(done);
}).otherwise(fail).ensure(done);
},
'should have the default client as the parent by default': function () {
assert.same(rest, oAuth({ token: 'bearer abcxyz' }).skip());
},
'should support interceptor chaining': function () {
assert(typeof oAuth().chain === 'function');
}

@@ -92,0 +81,0 @@ });

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -26,6 +11,7 @@

var assert, refute;
var assert, refute, fail;
assert = buster.assertions.assert;
refute = buster.assertions.refute;
fail = buster.assertions.fail;

@@ -47,3 +33,3 @@ define('rest/interceptor/pathPrefix-test', function (require) {

assert.equals('/foo/bar', response.request.path);
}).always(done);
}).otherwise(fail).ensure(done);
},

@@ -57,3 +43,3 @@ 'should prepend prefix before path, adding slash between path segments': function (done) {

assert.equals('/foo/bar', response.request.path);
}).always(done);
}).otherwise(fail).ensure(done);
},

@@ -67,6 +53,18 @@ 'should prepend prefix before path, not adding extra slash between path segments': function (done) {

assert.equals('/foo/bar', response.request.path);
}).always(done);
}).otherwise(fail).ensure(done);
},
'should not prepend prefix before a fully qualified path': function (done) {
var client = pathPrefix(
function (request) { return { request: request }; },
{ prefix: '/foo' }
);
client({ path: 'http://www.example.com/' }).then(function (response) {
assert.equals('http://www.example.com/', response.request.path);
}).otherwise(fail).ensure(done);
},
'should have the default client as the parent by default': function () {
assert.same(rest, pathPrefix().skip());
},
'should support interceptor chaining': function () {
assert(typeof pathPrefix().chain === 'function');
}

@@ -73,0 +71,0 @@ });

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Jeremy Grelle
* @author Scott Andrews
*/

@@ -26,10 +12,11 @@

var assert, fail;
var assert, fail, failOnThrow;
assert = buster.assertions.assert;
fail = buster.assertions.fail;
failOnThrow = buster.assertions.failOnThrow;
define('rest/interceptor/retry-test', function (require) {
var interceptor, retry, rest, when;
var interceptor, retry, rest, when, delay, clock, timeout;

@@ -40,3 +27,7 @@ interceptor = require('rest/interceptor');

when = require('when');
delay = require('when/delay');
// retain access to the native setTimeout function
timeout = setTimeout;
buster.testCase('rest/interceptor/retry', {

@@ -54,50 +45,40 @@ 'should retry until successful': function (done) {

);
client({}).then(
function (response) {
assert.equals(200, response.status.code);
},
function (/* response */) {
fail('Error should not propagate to client.');
}
).always(done);
client({}).then(function (response) {
assert.equals(200, response.status.code);
}).otherwise(fail).ensure(done);
},
'should accept custom config': function (done) {
var count = 0, client, start;
client = retry(
function (request) {
count += 1;
if (count === 4) {
return { request: request, status: { code: 200 } };
} else {
return when.reject({ request: request, error: 'Thrown by fake client' });
}
}, { initial: 10, multiplier: 3, max: 20 }
);
client = interceptor({
request: function (request /*, config */) {
start = new Date().getTime();
return request;
},
response: function (response /*, config */) {
var elapsed = new Date().getTime() - start;
assert.equals(count, 4);
assert.equals(response.request.retry, Math.pow(3, count - 1) * 10);
assert(elapsed < 100); // Total paused time should be 50 - this allows padding
// for execution time that would be much larger without max
// TODO - A more accurate test might be to use a spy on when.delay
return response;
}
})(client);
client({}).then(
function (response) {
assert.equals(200, response.status.code);
},
function (response) {
console.log(response);
fail('Error should not propagate to client.');
}
).always(done);
'should accept custom config': {
setUp: function () {
clock = this.useFakeTimers();
},
tearDown: function () {
clock.restore();
},
'': function (done) {
var count = 0, client, start, config;
start = new Date().getTime();
config = { initial: 10, multiplier: 3, max: 20 };
client = retry(
function (request) {
var tick = Math.min(Math.pow(config.multiplier, count) * config.initial, config.max);
count += 1;
if (count === 4) {
return { request: request, status: { code: 200 } };
} else {
timeout(function () {
clock.tick(tick);
}, 0);
return when.reject({ request: request, error: 'Thrown by fake client' });
}
},
config
);
client({}).then(function (response) {
assert.equals(200, response.status.code);
assert.equals(count, 4);
assert.equals(50, new Date().getTime() - start);
}).otherwise(fail).ensure(done);
}
},

@@ -114,11 +95,9 @@ 'should not make propagate request if marked as canceled': function (done) {

client(request).then(
function () {
fail('should not be called');
},
function (response) {
fail,
failOnThrow(function (response) {
assert(request.canceled);
assert.equals('precanceled', response.error);
assert.same(1, parent.callCount);
}
).always(done);
})
).ensure(done);

@@ -129,2 +108,5 @@ request.canceled = true;

assert.same(rest, retry().skip());
},
'should support interceptor chaining': function () {
assert(typeof retry().chain === 'function');
}

@@ -131,0 +113,0 @@ });

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Jeremy Grelle
* @author Scott Andrews
*/

@@ -26,11 +12,9 @@

var assert, refute, fail;
var assert, refute, fail, failOnThrow;
assert = buster.assertions.assert;
refute = buster.assertions.refute;
fail = buster.assertions.fail;
failOnThrow = buster.assertions.failOnThrow;
fail = function () {
buster.assertions.fail('should never be called');
};
define('rest/interceptor/timeout-test', function (require) {

@@ -73,24 +57,15 @@

// TODO setTimeout hack will not be nessesary once when resolves promises in nextTick.
// Expected in the when 2.0 time frame
buster.testCase('rest/interceptor/timeout', {
'should resolve if client responds immediately': function (done) {
var client, request;
client = timeout(immediateClient, { timeout: 10 });
client = timeout(immediateClient, { timeout: 20 });
request = {};
client(request).then(
function (response) {
assert.same(request, response.request);
refute(response.error);
setTimeout(function () {
refute(request.canceled);
done();
}, 0);
},
function () {
fail();
done();
}
);
client(request).then(function (response) {
assert.same(request, response.request);
refute(response.error);
return delay(40).then(function () {
// delay to make sure timeout has fired, but not rejected the response
refute(request.canceled);
});
}).otherwise(fail).ensure(done);
},

@@ -101,16 +76,7 @@ 'should resolve if client responds before timeout': function (done) {

request = {};
client(request).then(
function (response) {
assert.same(request, response.request);
refute(response.error);
setTimeout(function () {
refute(request.canceled);
done();
}, 0);
},
function () {
fail();
done();
}
);
client(request).then(function (response) {
assert.same(request, response.request);
refute(response.error);
refute(request.canceled);
}).otherwise(fail).ensure(done);
},

@@ -122,15 +88,9 @@ 'should reject even if client responds after timeout': function (done) {

client(request).then(
function () {
fail();
done();
},
function (response) {
fail,
failOnThrow(function (response) {
assert.same(request, response.request);
assert.equals('timeout', response.error);
setTimeout(function () {
assert(request.canceled);
done();
}, 0);
}
);
assert(request.canceled);
})
).ensure(done);
},

@@ -142,15 +102,9 @@ 'should reject if client hanges': function (done) {

client(request).then(
function () {
fail();
done();
},
function (response) {
fail,
failOnThrow(function (response) {
assert.same(request, response.request);
assert.equals('timeout', response.error);
setTimeout(function () {
assert(request.canceled);
done();
}, 0);
}
);
assert(request.canceled);
})
).ensure(done);
},

@@ -161,16 +115,7 @@ 'should use request timeout value in perference to interceptor value': function (done) {

request = { timeout: 0 };
client(request).then(
function (response) {
assert.same(request, response.request);
refute(response.error);
setTimeout(function () {
refute(request.canceled);
done();
}, 0);
},
function () {
fail();
done();
}
);
client(request).then(function (response) {
assert.same(request, response.request);
refute(response.error);
refute(request.canceled);
}).otherwise(fail).ensure(done);
},

@@ -181,35 +126,20 @@ 'should not reject without a configured timeout value': function (done) {

request = {};
client(request).then(
function (response) {
assert.same(request, response.request);
refute(response.error);
setTimeout(function () {
refute(request.canceled);
done();
}, 0);
},
function () {
fail();
done();
}
);
client(request).then(function (response) {
assert.same(request, response.request);
refute(response.error);
refute(request.canceled);
}).otherwise(fail).ensure(done);
},
'should cancel request if client support cancelation': function (done) {
var client, request;
client = timeout(cancelableClient, { timeout: 10 });
client = timeout(cancelableClient, { timeout: 11 });
request = {};
client(request).then(
function () {
fail();
done();
},
function (response) {
fail,
failOnThrow(function (response) {
assert.same(request, response.request);
assert.equals('timeout', response.error);
setTimeout(function () {
assert(request.canceled);
done();
}, 0);
}
);
assert(request.canceled);
})
).ensure(done);
refute(request.canceled);

@@ -219,2 +149,5 @@ },

assert.same(rest, timeout().skip());
},
'should support interceptor chaining': function () {
assert(typeof timeout().chain === 'function');
}

@@ -221,0 +154,0 @@ });

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -26,42 +11,70 @@

var assert, refute;
var assert, refute, fail;
assert = buster.assertions.assert;
refute = buster.assertions.refute;
fail = buster.assertions.fail;
define('rest/mime/registry-test', function (require) {
var registry, when;
var mimeRegistry, when, registry;
registry = require('rest/mime/registry');
mimeRegistry = require('rest/mime/registry');
when = require('when');
buster.testCase('rest/mime/registry', {
'should discover unregisted serializers': function (done) {
when(
registry.lookup('text/plain'),
function (serializer) {
assert.isFunction(serializer.read);
assert.isFunction(serializer.write);
}
).always(done);
setUp: function () {
registry = mimeRegistry.child();
},
'should return registed serializer': function (done) {
var serializer = {};
registry.register('application/vnd.com.foo', serializer);
when(
registry.lookup('application/vnd.com.foo'),
function (s) {
assert.same(serializer, s);
}
).always(done);
'should discover unregisted converter': function (done) {
registry.lookup('text/plain').then(function (converter) {
assert.isFunction(converter.read);
assert.isFunction(converter.write);
}).otherwise(fail).ensure(done);
},
'should reject for non-existant serializer': function (done) {
when(
registry.lookup('application/bogus'),
undefined,
'should return registed converter': function (done) {
var converter = {};
registry.register('application/vnd.com.example', converter);
registry.lookup('application/vnd.com.example').then(function (c) {
assert.same(converter, c);
}).otherwise(fail).ensure(done);
},
'should reject for non-existant converter': function (done) {
registry.lookup('application/bogus').then(
fail,
function () {
assert(true);
}
).always(done);
).ensure(done);
},
'should resolve converters from parent registries': function (done) {
var child, converter;
child = registry.child();
converter = {};
registry.register('application/vnd.com.example', converter);
child.lookup('application/vnd.com.example').then(function (c) {
assert.same(converter, c);
}).otherwise(fail).ensure(done);
},
'should override parent registries when registering in a child': function (done) {
var child, converterParent, converterChild;
child = registry.child();
converterParent = {};
converterChild = {};
registry.register('application/vnd.com.example', converterParent);
child.register('application/vnd.com.example', converterChild);
child.lookup('application/vnd.com.example').then(function (c) {
assert.same(converterChild, c);
}).otherwise(fail).ensure(done);
},
'should not have any side effects in a parent registry from a child': function (done) {
var child, converterParent, converterChild;
child = registry.child();
converterParent = {};
converterChild = {};
registry.register('application/vnd.com.example', converterParent);
child.register('application/vnd.com.example', converterChild);
registry.lookup('application/vnd.com.example').then(function (c) {
assert.same(converterParent, c);
}).otherwise(fail).ensure(done);
}

@@ -68,0 +81,0 @@ });

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -28,4 +13,4 @@

assert = buster.assert;
refute = buster.refute;
assert = buster.assertions.assert;
refute = buster.assertions.refute;

@@ -32,0 +17,0 @@ define('rest/mime/type/application/json-test', function (require) {

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -28,4 +13,4 @@

assert = buster.assert;
refute = buster.refute;
assert = buster.assertions.assert;
refute = buster.assertions.refute;

@@ -32,0 +17,0 @@ define('rest/mime/type/application/x-www-form-urlencoded-test', function (require) {

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -28,4 +13,4 @@

assert = buster.assert;
refute = buster.refute;
assert = buster.assertions.assert;
refute = buster.assertions.refute;

@@ -32,0 +17,0 @@ define('rest/mime/type/text/plain-test', function (require) {

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -22,0 +7,0 @@

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/
(function (buster, define) {
(function (buster, define, location) {
'use strict';

@@ -28,4 +13,4 @@

assert = buster.assert;
refute = buster.refute;
assert = buster.assertions.assert;
refute = buster.assertions.refute;

@@ -76,2 +61,106 @@ define('rest/UrlBuilder-test', function (require) {

assert.equals('/foo/bar?bleep=bloop', bar.build());
},
'should make the URL fully qualified': {
requiresSupportFor: { location: location },
'': function () {
assert.same(location.toString(), new UrlBuilder('').fullyQualify().build());
assert.same(location.protocol + '//' + location.host + '/', new UrlBuilder('/').fullyQualify().build());
assert.same(location.protocol + '//' + location.host + '/foo', new UrlBuilder('/foo').fullyQualify().build());
assert.same(location.protocol + '//example.com/', new UrlBuilder('//example.com').fullyQualify().build());
assert.same('http://example.com/', new UrlBuilder('http://example.com').fullyQualify().build());
assert.same('https://example.com/', new UrlBuilder('https://example.com').fullyQualify().build());
}
},
'should indicate if the URL is absolute': function () {
refute(new UrlBuilder('').isAbsolute());
assert(new UrlBuilder('/foo').isAbsolute());
assert(new UrlBuilder('//foo').isAbsolute());
assert(new UrlBuilder('http://example.com').isAbsolute());
assert(new UrlBuilder('https://example.com').isAbsolute());
},
'should indicate if the URL is fully qualified': function () {
refute(new UrlBuilder('').isFullyQualified());
refute(new UrlBuilder('/foo').isFullyQualified());
refute(new UrlBuilder('//foo').isFullyQualified());
refute(new UrlBuilder('http://example.com').isFullyQualified());
refute(new UrlBuilder('https://example.com').isFullyQualified());
assert(new UrlBuilder('http://example.com/').isFullyQualified());
assert(new UrlBuilder('https://example.com/').isFullyQualified());
},
'should indicate if the URL is cross origin': {
requiresSupportFor: { location: location },
'': function () {
refute(new UrlBuilder('').isCrossOrigin());
refute(new UrlBuilder('/foo').isCrossOrigin());
refute(new UrlBuilder(location.protocol + '//' + location.host + '/foo').isCrossOrigin());
assert(new UrlBuilder('//example.com').isCrossOrigin());
assert(new UrlBuilder('http://example.com').isCrossOrigin());
assert(new UrlBuilder('https://example.com').isCrossOrigin());
}
},
'should split a URL into its parts': {
'for a simple http URL': function () {
var parts = new UrlBuilder('http://www.example.com/').parts();
assert.same('http://www.example.com/', parts.href);
assert.same('http:', parts.protocol);
assert.same('www.example.com', parts.host);
assert.same('www.example.com', parts.hostname);
assert.same('80', parts.port);
assert.same('http://www.example.com', parts.origin);
assert.same('/', parts.pathname);
assert.same('', parts.search);
assert.same('', parts.hash);
},
'for a simple https URL': function () {
var parts = new UrlBuilder('https://www.example.com/').parts();
assert.same('https://www.example.com/', parts.href);
assert.same('https:', parts.protocol);
assert.same('www.example.com', parts.host);
assert.same('www.example.com', parts.hostname);
assert.same('443', parts.port);
assert.same('https://www.example.com', parts.origin);
assert.same('/', parts.pathname);
assert.same('', parts.search);
assert.same('', parts.hash);
},
'for a complex URL': function () {
var parts = new UrlBuilder('http://user:pass@www.example.com:8080/some/path?hello=world#main').parts();
assert.same('http://user:pass@www.example.com:8080/some/path?hello=world#main', parts.href);
assert.same('http:', parts.protocol);
assert.same('www.example.com:8080', parts.host);
assert.same('www.example.com', parts.hostname);
assert.same('8080', parts.port);
assert.same('http://www.example.com:8080', parts.origin);
assert.same('/some/path', parts.pathname);
assert.same('?hello=world', parts.search);
assert.same('#main', parts.hash);
},
'for a path-less URL': function () {
var parts = new UrlBuilder('http://www.example.com/?hello=world#main').parts();
assert.same('http://www.example.com/?hello=world#main', parts.href);
assert.same('http:', parts.protocol);
assert.same('www.example.com', parts.host);
assert.same('www.example.com', parts.hostname);
assert.same('80', parts.port);
assert.same('http://www.example.com', parts.origin);
assert.same('/', parts.pathname);
assert.same('?hello=world', parts.search);
assert.same('#main', parts.hash);
},
'for a path and query-less URL': function () {
var parts = new UrlBuilder('http://www.example.com/#main').parts();
assert.same('http://www.example.com/#main', parts.href);
assert.same('http:', parts.protocol);
assert.same('www.example.com', parts.host);
assert.same('www.example.com', parts.hostname);
assert.same('80', parts.port);
assert.same('http://www.example.com', parts.origin);
assert.same('/', parts.pathname);
assert.same('', parts.search);
assert.same('#main', parts.hash);
}
},
'should be forgiving of non constructor calls': function () {
/*jshint newcap:false */
assert(UrlBuilder() instanceof UrlBuilder);
}

@@ -91,4 +180,5 @@ // TODO test .absolute()

});
}
},
this.location
// Boilerplate for AMD and Node
));
/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -28,4 +13,4 @@

assert = buster.assert;
refute = buster.refute;
assert = buster.assertions.assert;
refute = buster.assertions.refute;

@@ -32,0 +17,0 @@ define('rest/util/base64-test', function (require) {

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -28,4 +13,4 @@

assert = buster.assert;
refute = buster.refute;
assert = buster.assertions.assert;
refute = buster.assertions.refute;

@@ -40,3 +25,3 @@ define('rest/util/beget-test', function (require) {

result = beget();
assert(result);
assert.equals(result, {});
for (prop in result) {

@@ -43,0 +28,0 @@ /*jshint forin:false */

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -28,4 +13,4 @@

assert = buster.assert;
refute = buster.refute;
assert = buster.assertions.assert;
refute = buster.assertions.refute;

@@ -32,0 +17,0 @@ define('rest/util/mixin-test', function (require) {

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -28,4 +13,4 @@

assert = buster.assert;
refute = buster.refute;
assert = buster.assertions.assert;
refute = buster.assertions.refute;

@@ -32,0 +17,0 @@ define('rest/util/normalizeHeaderName-test', function (require) {

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -28,4 +13,4 @@

assert = buster.assert;
refute = buster.refute;
assert = buster.assertions.assert;
refute = buster.assertions.refute;

@@ -32,0 +17,0 @@ define('rest/util/pubsub-test', function (require) {

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -28,4 +13,4 @@

assert = buster.assert;
refute = buster.refute;
assert = buster.assertions.assert;
refute = buster.assertions.refute;

@@ -32,0 +17,0 @@ define('rest/version-test', function (require) {

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/
(function (define, document) {
(function (define, location) {
'use strict';
var undef;
define(function (require) {
var beget, absoluteUrlRE, urlEncodedBraceOpenRE, urlEncodedBraceCloseRE;
var beget, origin, urlRE, absoluteUrlRE, fullyQualifiedUrlRE;
beget = require('./util/beget');
absoluteUrlRE = /^https?:\/\//i;
urlEncodedBraceOpenRE = /%7b/i;
urlEncodedBraceCloseRE = /%7d/i;
urlRE = /([a-z][a-z0-9\+\-\.]*:)\/\/([^@]+@)?(([^:\/]+)(:([0-9]+))?)(\/[^?#]*)?(\?[^#]*)?(#\S*)?/i;
absoluteUrlRE = /^([a-z][a-z0-9\-\+\.]*:\/\/|\/)/i;
fullyQualifiedUrlRE = /([a-z][a-z0-9\+\-\.]*:)\/\/([^@]+@)?(([^:\/]+)(:([0-9]+))?)\//i;

@@ -76,2 +63,6 @@ /**

function startsWith(str, test) {
return str.indexOf(test) === 0;
}
/**

@@ -85,2 +76,7 @@ * Create a new URL Builder

function UrlBuilder(template, params) {
if (!(this instanceof UrlBuilder)) {
// invoke as a constructor
return new UrlBuilder(template, params);
}
if (template instanceof UrlBuilder) {

@@ -121,11 +117,23 @@ this._template = template.template;

*/
absolute: function () {
if (!document || absoluteUrlRE.test(this._template)) { return this; }
fullyQualify: function () {
if (!location) { return this; }
if (this.isFullyQualified()) { return this; }
var a, template;
var template = this._template;
a = document.createElement('a');
a.href = this._template;
template = a.href.replace(urlEncodedBraceOpenRE, '{').replace(urlEncodedBraceCloseRE, '}');
if (startsWith(template, '//')) {
template = origin.protocol + template;
}
else if (startsWith(template, '/')) {
template = origin.origin + template;
}
else if (!this.isAbsolute()) {
template = origin.origin + origin.pathname.substring(0, origin.pathname.lastIndexOf('/') + 1);
}
if (template.indexOf('/', 8) === -1) {
// default the pathname to '/'
template = template + '/';
}
return new UrlBuilder(template, this._params);

@@ -135,2 +143,63 @@ },

/**
* True if the URL is absolute
*
* @return {boolean}
*/
isAbsolute: function () {
return absoluteUrlRE.test(this.build());
},
/**
* True if the URL is fully qualified
*
* @return {boolean}
*/
isFullyQualified: function () {
return fullyQualifiedUrlRE.test(this.build());
},
/**
* True if the URL is cross origin. The protocol, host and port must not be
* the same in order to be cross origin,
*
* @return {boolean}
*/
isCrossOrigin: function () {
if (!origin) {
return true;
}
var url = this.parts();
return url.protocol !== origin.protocol ||
url.hostname !== origin.hostname ||
url.port !== origin.port;
},
/**
* Split a URL into its consituent parts following the naming convention of
* 'window.location'. One difference is that the port will contain the
* protocol default if not specified.
*
* @see https://developer.mozilla.org/en-US/docs/DOM/window.location
*
* @returns {Object} a 'window.location'-like object
*/
parts: function () {
var url, parts;
url = this.fullyQualify().build().match(urlRE);
parts = {
href: url[0],
protocol: url[1],
host: url[3],
hostname: url[4],
port: url[6],
pathname: url[7] || '',
search: url[8] || '',
hash: url[9] || ''
};
parts.origin = parts.protocol + '//' + parts.host;
parts.port = parts.port || (parts.protocol === 'https:' ? '443' : parts.protocol === 'http:' ? '80' : '');
return parts;
},
/**
* Expand the template replacing path variables with parameters

@@ -154,2 +223,4 @@ *

origin = location ? new UrlBuilder(location.href).parts() : undef;
return UrlBuilder;

@@ -160,4 +231,4 @@ });

typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); },
this.document
this.location
// Boilerplate for AMD and Node
));
/*
* Base 64 implementation in JavaScript
* Copyright (c) 2009 Nicholas C. Zakas. All rights reserved.

@@ -25,2 +24,3 @@ *

/*
* Base 64 implementation in JavaScript
* Original source available at https://raw.github.com/nzakas/computer-science-in-javascript/02a2745b4aa8214f2cae1bf0b15b447ca1a91b23/encodings/base64/base64.js

@@ -27,0 +27,0 @@ *

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -22,0 +7,0 @@

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -31,20 +16,6 @@

function _mixin(dest, source, copyFunc) {
var name;
for (name in source) {
// the (!(name in empty) || empty[name] !== source[name]) condition avoids
// copying properties in "source" inherited from Object.prototype. For
// example, if dest has a custom toString() method, don't overwrite it with
// the toString() method that source inherited from Object.prototype
if (!(name in dest) || (dest[name] !== source[name] && (!(name in empty) || empty[name] !== source[name]))) {
dest[name] = copyFunc ? copyFunc(source[name]) : source[name];
}
}
return dest; // Object
}
/**
* Mix the properties from the source object into the destination object
* Mix the properties from the source object into the destination object.
* When the same property occurs in more then one object, the right most
* value wins.
*

@@ -56,7 +27,12 @@ * @param {Object} dest the object to copy properties to

function mixin(dest /*, sources... */) {
var i, l;
var i, l, source, name;
if (!dest) { dest = {}; }
for (i = 1, l = arguments.length; i < l; i += 1) {
_mixin(dest, arguments[i]);
source = arguments[i];
for (name in source) {
if (!(name in dest) || (dest[name] !== source[name] && (!(name in empty) || empty[name] !== source[name]))) {
dest[name] = source[name];
}
}
}

@@ -63,0 +39,0 @@

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -22,0 +7,0 @@

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -22,0 +7,0 @@

/*
* Copyright (c) 2012 VMware, Inc. All Rights Reserved.
* Copyright 2012-2013 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @author Scott Andrews
*/

@@ -28,3 +13,3 @@

var client, errorCode, mime, entity, pathPrefix, when, plugin;
var client, errorCode, mime, entity, pathPrefix, when, pipeline, plugin;

@@ -37,2 +22,3 @@ client = require('../rest');

when = require('when');
pipeline = require('when/pipeline');

@@ -89,3 +75,37 @@

function normalizeRestFactoryConfig(spec, wire) {
var config = {};
config.parent = wire(spec.parent || client);
config.interceptors = when.all((Array.isArray(spec) ? spec : spec.interceptors || []).map(function (interceptorDef) {
var interceptorConfig = interceptorDef.config;
delete interceptorDef.config;
return wire(typeof interceptorDef === 'string' ? { module: interceptorDef } : interceptorDef).then(function (interceptor) {
return { interceptor: interceptor, config: interceptorConfig };
});
}));
return config;
}
/**
* Creates a rest client for the "rest" factory.
* @param resolver
* @param spec
* @param wire
*/
function restFactory(resolver, spec, wire) {
var config = normalizeRestFactoryConfig(spec.rest || spec.options, wire);
return config.parent.then(function (parent) {
return config.interceptors.then(function (interceptorDefs) {
pipeline(interceptorDefs.map(function (interceptorDef) {
return function (parent) {
return interceptorDef.interceptor(parent, interceptorDef.config);
};
}), parent).then(resolver.resolve, resolver.reject);
});
});
}
/**
* The plugin instance. Can be the same for all wiring runs

@@ -96,2 +116,5 @@ */

client: resolveClient
},
factories: {
rest: restFactory
}

@@ -98,0 +121,0 @@ };

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc