Socket
Socket
Sign inDemoInstall

rest

Package Overview
Dependencies
Maintainers
1
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 1.3.2 to 2.0.0

interceptor/params.js

8

bower.json
{
"name": "rest",
"version": "1.3.2",
"version": "2.0.0",
"main": "./browser.js",
"moduleType": ["amd", "node"],
"dependencies": {
"when": "~3"
},
"moduleType": ["node"],
"dependencies": {},
"ignore": [

@@ -10,0 +8,0 @@ "docs",

/*
* Copyright 2014 the original author or authors
* Copyright 2014-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,19 +8,9 @@ *

(function (define) {
'use strict';
'use strict';
define(function (require) {
var rest = require('./client/default'),
browser = require('./client/xhr');
var rest = require('./client/default'),
browser = require('./client/xhr');
rest.setPlatformDefaultClient(browser);
rest.setPlatformDefaultClient(browser);
return rest;
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
module.exports = rest;
/*
* Copyright 2014 the original author or authors
* Copyright 2014-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,58 +8,48 @@ *

(function (define) {
'use strict';
'use strict';
define(function (/* require */) {
/**
* Add common helper methods to a client impl
*
* @param {function} impl the client implementation
* @param {Client} [target] target of this client, used when wrapping other clients
* @returns {Client} the client impl with additional methods
*/
module.exports = function client(impl, target) {
if (target) {
/**
* Add common helper methods to a client impl
*
* @param {function} impl the client implementation
* @param {Client} [target] target of this client, used when wrapping other clients
* @returns {Client} the client impl with additional methods
* @returns {Client} the target client
*/
return function client(impl, target) {
impl.skip = function skip() {
return target;
};
if (target) {
}
/**
* @returns {Client} the target client
*/
impl.skip = function skip() {
return target;
};
/**
* Allow a client to easily be wrapped by an interceptor
*
* @param {Interceptor} interceptor the interceptor to wrap this client with
* @param [config] configuration for the interceptor
* @returns {Client} the newly wrapped client
*/
impl.wrap = function wrap(interceptor, config) {
return interceptor(impl, config);
};
}
/**
* @deprecated
*/
impl.chain = function chain() {
if (typeof console !== 'undefined') {
console.log('rest.js: client.chain() is deprecated, use client.wrap() instead');
}
/**
* Allow a client to easily be wrapped by an interceptor
*
* @param {Interceptor} interceptor the interceptor to wrap this client with
* @param [config] configuration for the interceptor
* @returns {Client} the newly wrapped client
*/
impl.wrap = function wrap(interceptor, config) {
return interceptor(impl, config);
};
return impl.wrap.apply(this, arguments);
};
/**
* @deprecated
*/
impl.chain = function chain() {
if (typeof console !== 'undefined') {
console.log('rest.js: client.chain() is deprecated, use client.wrap() instead');
}
return impl;
return impl.wrap.apply(this, arguments);
};
return impl;
};
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
};
/*
* Copyright 2014 the original author or authors
* Copyright 2014-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,118 +8,110 @@ *

(function (define) {
'use strict';
'use strict';
var undef;
/**
* Plain JS Object containing properties that represent an HTTP request.
*
* Depending on the capabilities of the underlying client, a request
* may be cancelable. If a request may be canceled, the client will add
* a canceled flag and cancel function to the request object. Canceling
* the request will put the response into an error state.
*
* @field {string} [method='GET'] HTTP method, commonly GET, POST, PUT, DELETE or HEAD
* @field {string|UrlBuilder} [path=''] path template with optional path variables
* @field {Object} [params] parameters for the path template and query string
* @field {Object} [headers] custom HTTP headers to send, in addition to the clients default headers
* @field [entity] the HTTP entity, common for POST or PUT requests
* @field {boolean} [canceled] true if the request has been canceled, set by the client
* @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
*
* @class Request
*/
define(function (require) {
/**
* Plain JS Object containing properties that represent an HTTP response
*
* @field {Object} [request] the request object as received by the root client
* @field {Object} [raw] the underlying request object, like XmlHttpRequest in a browser
* @field {number} [status.code] status code of the response (i.e. 200, 404)
* @field {string} [status.text] status phrase of the response
* @field {Object] [headers] response headers hash of normalized name, value pairs
* @field [entity] the response body
*
* @class Response
*/
/**
* Plain JS Object containing properties that represent an HTTP request.
*
* Depending on the capabilities of the underlying client, a request
* may be cancelable. If a request may be canceled, the client will add
* a canceled flag and cancel function to the request object. Canceling
* the request will put the response into an error state.
*
* @field {string} [method='GET'] HTTP method, commonly GET, POST, PUT, DELETE or HEAD
* @field {string|UrlBuilder} [path=''] path template with optional path variables
* @field {Object} [params] parameters for the path template and query string
* @field {Object} [headers] custom HTTP headers to send, in addition to the clients default headers
* @field [entity] the HTTP entity, common for POST or PUT requests
* @field {boolean} [canceled] true if the request has been canceled, set by the client
* @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
*
* @class Request
*/
/**
* HTTP client particularly suited for RESTful operations.
*
* @field {function} wrap wraps this client with a new interceptor returning the wrapped client
*
* @param {Request} the HTTP request
* @returns {ResponsePromise<Response>} a promise the resolves to the HTTP response
*
* @class Client
*/
/**
* Plain JS Object containing properties that represent an HTTP response
*
* @field {Object} [request] the request object as received by the root client
* @field {Object} [raw] the underlying request object, like XmlHttpRequest in a browser
* @field {number} [status.code] status code of the response (i.e. 200, 404)
* @field {string} [status.text] status phrase of the response
* @field {Object] [headers] response headers hash of normalized name, value pairs
* @field [entity] the response body
*
* @class Response
*/
/**
* Extended when.js Promises/A+ promise with HTTP specific helpers
*q
* @method entity promise for the HTTP entity
* @method status promise for the HTTP status code
* @method headers promise for the HTTP response headers
* @method header promise for a specific HTTP response header
*
* @class ResponsePromise
* @extends Promise
*/
/**
* HTTP client particularly suited for RESTful operations.
*
* @field {function} wrap wraps this client with a new interceptor returning the wrapped client
*
* @param {Request} the HTTP request
* @returns {ResponsePromise<Response>} a promise the resolves to the HTTP response
*
* @class Client
*/
var client, target, platformDefault;
/**
* Extended when.js Promises/A+ promise with HTTP specific helpers
*q
* @method entity promise for the HTTP entity
* @method status promise for the HTTP status code
* @method headers promise for the HTTP response headers
* @method header promise for a specific HTTP response header
*
* @class ResponsePromise
* @extends Promise
*/
client = require('../client');
var client, target, platformDefault;
if (typeof Promise !== 'function' && console && console.log) {
console.log('An ES6 Promise implementation is required to use rest.js. See https://github.com/cujojs/when/blob/master/docs/es6-promise-shim.md for using when.js as a Promise polyfill.');
}
client = require('../client');
/**
* Make a request with the default client
* @param {Request} the HTTP request
* @returns {Promise<Response>} a promise the resolves to the HTTP response
*/
function defaultClient() {
return target.apply(void 0, arguments);
}
/**
* Make a request with the default client
* @param {Request} the HTTP request
* @returns {Promise<Response>} a promise the resolves to the HTTP response
*/
function defaultClient() {
return target.apply(undef, arguments);
}
/**
* Change the default client
* @param {Client} client the new default client
*/
defaultClient.setDefaultClient = function setDefaultClient(client) {
target = client;
};
/**
* Change the default client
* @param {Client} client the new default client
*/
defaultClient.setDefaultClient = function setDefaultClient(client) {
target = client;
};
/**
* Obtain a direct reference to the current default client
* @returns {Client} the default client
*/
defaultClient.getDefaultClient = function getDefaultClient() {
return target;
};
/**
* Obtain a direct reference to the current default client
* @returns {Client} the default client
*/
defaultClient.getDefaultClient = function getDefaultClient() {
return target;
};
/**
* Reset the default client to the platform default
*/
defaultClient.resetDefaultClient = function resetDefaultClient() {
target = platformDefault;
};
/**
* Reset the default client to the platform default
*/
defaultClient.resetDefaultClient = function resetDefaultClient() {
target = platformDefault;
};
/**
* @private
*/
defaultClient.setPlatformDefaultClient = function setPlatformDefaultClient(client) {
if (platformDefault) {
throw new Error('Unable to redefine platformDefaultClient');
}
target = platformDefault = client;
};
/**
* @private
*/
defaultClient.setPlatformDefaultClient = function setPlatformDefaultClient(client) {
if (platformDefault) {
throw new Error('Unable to redefine platformDefaultClient');
}
target = platformDefault = client;
};
return client(defaultClient);
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
module.exports = client(defaultClient);
/*
* Copyright 2012-2014 the original author or authors
* Copyright 2012-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,139 +8,124 @@ *

(function (define, global, document) {
'use strict';
'use strict';
var undef;
var UrlBuilder, responsePromise, client;
define(function (require) {
UrlBuilder = require('../UrlBuilder');
responsePromise = require('../util/responsePromise');
client = require('../client');
var when, UrlBuilder, responsePromise, client;
// consider abstracting this into a util module
function clearProperty(scope, propertyName) {
try {
delete scope[propertyName];
}
catch (e) {
// IE doesn't like to delete properties on the window object
if (propertyName in scope) {
scope[propertyName] = void 0;
}
}
}
when = require('when');
UrlBuilder = require('../UrlBuilder');
responsePromise = require('../util/responsePromise');
client = require('../client');
// consider abstracting this into a util module
function clearProperty(scope, propertyName) {
try {
delete scope[propertyName];
}
catch (e) {
// IE doesn't like to delete properties on the window object
if (propertyName in scope) {
scope[propertyName] = undef;
}
}
function cleanupScriptNode(response) {
try {
if (response.raw && response.raw.parentNode) {
response.raw.parentNode.removeChild(response.raw);
}
} catch (e) {
// ignore
}
}
function cleanupScriptNode(response) {
try {
if (response.raw && response.raw.parentNode) {
response.raw.parentNode.removeChild(response.raw);
}
} catch (e) {
// ignore
}
function registerCallback(prefix, resolve, response, name) {
if (!name) {
do {
name = prefix + Math.floor(new Date().getTime() * Math.random());
}
while (name in window);
}
function registerCallback(prefix, resolve, response, name) {
if (!name) {
do {
name = prefix + Math.floor(new Date().getTime() * Math.random());
}
while (name in global);
}
global[name] = function jsonpCallback(data) {
response.entity = data;
clearProperty(global, name);
cleanupScriptNode(response);
if (!response.request.canceled) {
resolve(response);
}
};
return name;
window[name] = function jsonpCallback(data) {
response.entity = data;
clearProperty(window, name);
cleanupScriptNode(response);
if (!response.request.canceled) {
resolve(response);
}
};
/**
* Executes the request as JSONP.
*
* @param {string} request.path the URL to load
* @param {Object} [request.params] parameters to bind to the path
* @param {string} [request.callback.param='callback'] the parameter name for
* which the callback function name is the value
* @param {string} [request.callback.prefix='jsonp'] prefix for the callback
* function, as the callback is attached to the window object, a unique,
* unobtrusive prefix is desired
* @param {string} [request.callback.name=<generated>] pins the name of the
* callback function, useful for cases where the server doesn't allow
* custom callback names. Generally not recommended.
*
* @returns {Promise<Response>}
*/
return client(function jsonp(request) {
return responsePromise.promise(function (resolve, reject) {
return name;
}
var callbackName, callbackParams, script, firstScript, response;
/**
* Executes the request as JSONP.
*
* @param {string} request.path the URL to load
* @param {Object} [request.params] parameters to bind to the path
* @param {string} [request.callback.param='callback'] the parameter name for
* which the callback function name is the value
* @param {string} [request.callback.prefix='jsonp'] prefix for the callback
* function, as the callback is attached to the window object, a unique,
* unobtrusive prefix is desired
* @param {string} [request.callback.name=<generated>] pins the name of the
* callback function, useful for cases where the server doesn't allow
* custom callback names. Generally not recommended.
*
* @returns {Promise<Response>}
*/
module.exports = client(function jsonp(request) {
return responsePromise.promise(function (resolve, reject) {
request = typeof request === 'string' ? { path: request } : request || {};
response = { request: request };
var callbackName, callbackParams, script, firstScript, response;
if (request.canceled) {
response.error = 'precanceled';
reject(response);
return;
}
request = typeof request === 'string' ? { path: request } : request || {};
response = { request: request };
request.callback = request.callback || {};
callbackName = registerCallback(request.callback.prefix || 'jsonp', resolve, response, request.callback.name);
callbackParams = {};
callbackParams[request.callback.param || 'callback'] = callbackName;
if (request.canceled) {
response.error = 'precanceled';
reject(response);
return;
}
request.canceled = false;
request.cancel = function cancel() {
request.canceled = true;
cleanupScriptNode(response);
reject(response);
};
request.callback = request.callback || {};
callbackName = registerCallback(request.callback.prefix || 'jsonp', resolve, response, request.callback.name);
callbackParams = {};
callbackParams[request.callback.param || 'callback'] = callbackName;
script = document.createElement('script');
script.type = 'text/javascript';
script.async = true;
script.src = response.url = new UrlBuilder(request.path, request.params).build(callbackParams);
request.canceled = false;
request.cancel = function cancel() {
request.canceled = true;
cleanupScriptNode(response);
reject(response);
};
function handlePossibleError() {
if (typeof global[callbackName] === 'function') {
response.error = 'loaderror';
clearProperty(global, callbackName);
cleanupScriptNode(response);
reject(response);
}
}
script.onerror = function () {
handlePossibleError();
};
script.onload = script.onreadystatechange = function (e) {
// script tag load callbacks are completely non-standard
// handle case where onreadystatechange is fired for an error instead of onerror
if ((e && (e.type === 'load' || e.type === 'error')) || script.readyState === 'loaded') {
handlePossibleError();
}
};
script = document.createElement('script');
script.type = 'text/javascript';
script.async = true;
script.src = response.url = new UrlBuilder(request.path, callbackParams).build();
response.raw = script;
firstScript = document.getElementsByTagName('script')[0];
firstScript.parentNode.insertBefore(script, firstScript);
function handlePossibleError() {
if (typeof window[callbackName] === 'function') {
response.error = 'loaderror';
clearProperty(window, callbackName);
cleanupScriptNode(response);
reject(response);
}
}
script.onerror = function () {
handlePossibleError();
};
script.onload = script.onreadystatechange = function (e) {
// script tag load callbacks are completely non-standard
// handle case where onreadystatechange is fired for an error instead of onerror
if ((e && (e.type === 'load' || e.type === 'error')) || script.readyState === 'loaded') {
handlePossibleError();
}
};
});
});
response.raw = script;
firstScript = document.getElementsByTagName('script')[0];
firstScript.parentNode.insertBefore(script, firstScript);
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); },
typeof window !== 'undefined' ? window : void 0,
typeof document !== 'undefined' ? document : void 0
// Boilerplate for AMD and Node
));
});
/*
* Copyright 2012-2014 the original author or authors
* Copyright 2012-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -9,140 +9,127 @@ *

(function (define, envRequire) {
'use strict';
'use strict';
define(function (require) {
var parser, http, https, mixin, normalizeHeaderName, responsePromise, client, httpsExp;
var parser, http, https, when, UrlBuilder, mixin, normalizeHeaderName, responsePromise, client, httpsExp;
parser = require('url');
http = require('http');
https = require('https');
mixin = require('../util/mixin');
normalizeHeaderName = require('../util/normalizeHeaderName');
responsePromise = require('../util/responsePromise');
client = require('../client');
parser = envRequire('url');
http = envRequire('http');
https = envRequire('https');
when = require('when');
UrlBuilder = require('../UrlBuilder');
mixin = require('../util/mixin');
normalizeHeaderName = require('../util/normalizeHeaderName');
responsePromise = require('../util/responsePromise');
client = require('../client');
httpsExp = /^https/i;
httpsExp = /^https/i;
// 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])');
}
// 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 (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;
}
}
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;
};
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;
};
module.exports = client(function node(request) {
/*jshint maxcomplexity:20 */
return responsePromise.promise(function (resolve, reject) {
return client(function node(request) {
/*jshint maxcomplexity:20 */
return responsePromise.promise(function (resolve, reject) {
var options, clientRequest, client, url, headers, entity, response;
var options, clientRequest, client, url, headers, entity, response;
request = typeof request === 'string' ? { path: request } : request || {};
response = { request: request };
request = typeof request === 'string' ? { path: request } : request || {};
response = { request: request };
if (request.canceled) {
response.error = 'precanceled';
reject(response);
return;
}
if (request.canceled) {
response.error = 'precanceled';
reject(response);
return;
}
url = response.url = request.path || '';
client = url.match(httpsExp) ? https : http;
url = response.url = new UrlBuilder(request.path || '', request.params).build();
client = url.match(httpsExp) ? https : http;
options = mixin({}, request.mixin, parser.parse(url));
options = mixin({}, request.mixin, parser.parse(url));
entity = request.entity;
request.method = request.method || (entity ? 'POST' : 'GET');
options.method = request.method;
headers = options.headers = {};
Object.keys(request.headers || {}).forEach(function (name) {
headers[normalizeHeaderName(name)] = request.headers[name];
});
if (!headers['Content-Length']) {
headers['Content-Length'] = entity ? Buffer.byteLength(entity, 'utf8') : 0;
}
entity = request.entity;
request.method = request.method || (entity ? 'POST' : 'GET');
options.method = request.method;
headers = options.headers = {};
Object.keys(request.headers || {}).forEach(function (name) {
headers[normalizeHeaderName(name)] = request.headers[name];
});
if (!headers['Content-Length']) {
headers['Content-Length'] = entity ? Buffer.byteLength(entity, 'utf8') : 0;
}
request.canceled = false;
request.cancel = function cancel() {
request.canceled = true;
clientRequest.abort();
};
request.canceled = false;
request.cancel = function cancel() {
request.canceled = true;
clientRequest.abort();
};
clientRequest = client.request(options, function (clientResponse) {
// Array of Buffers to collect response chunks
var buffers = [];
clientRequest = client.request(options, function (clientResponse) {
// Array of Buffers to collect response chunks
var buffers = [];
response.raw = {
request: clientRequest,
response: clientResponse
};
response.status = {
code: clientResponse.statusCode
// node doesn't provide access to the status text
};
response.headers = {};
Object.keys(clientResponse.headers).forEach(function (name) {
response.headers[normalizeHeaderName(name)] = clientResponse.headers[name];
});
response.raw = {
request: clientRequest,
response: clientResponse
};
response.status = {
code: clientResponse.statusCode
// node doesn't provide access to the status text
};
response.headers = {};
Object.keys(clientResponse.headers).forEach(function (name) {
response.headers[normalizeHeaderName(name)] = clientResponse.headers[name];
});
clientResponse.on('data', function (data) {
// Collect the next Buffer chunk
buffers.push(data);
});
clientResponse.on('data', function (data) {
// 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;
clientResponse.on('end', function () {
// Create the final response entity
response.entity = buffers.length > 0 ? Buffer.concat(buffers).toString() : '';
buffers = null;
resolve(response);
});
});
resolve(response);
});
});
clientRequest.on('error', function (e) {
response.error = e;
reject(response);
});
clientRequest.on('error', function (e) {
response.error = e;
reject(response);
});
if (entity) {
clientRequest.write(entity);
}
clientRequest.end();
if (entity) {
clientRequest.write(entity);
}
clientRequest.end();
});
});
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); },
typeof require === 'function' && require
// Boilerplate for AMD and Node
));
});
/*
* Copyright 2012-2014 the original author or authors
* Copyright 2012-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,168 +8,161 @@ *

(function (define, global) {
'use strict';
'use strict';
define(function (require) {
var normalizeHeaderName, responsePromise, client, headerSplitRE;
var when, UrlBuilder, normalizeHeaderName, responsePromise, client, headerSplitRE;
normalizeHeaderName = require('../util/normalizeHeaderName');
responsePromise = require('../util/responsePromise');
client = require('../client');
when = require('when');
UrlBuilder = require('../UrlBuilder');
normalizeHeaderName = require('../util/normalizeHeaderName');
responsePromise = require('../util/responsePromise');
client = require('../client');
// according to the spec, the line break is '\r\n', but doesn't hold true in practice
headerSplitRE = /[\r|\n]+/;
// according to the spec, the line break is '\r\n', but doesn't hold true in practice
headerSplitRE = /[\r|\n]+/;
function parseHeaders(raw) {
// Note: Set-Cookie will be removed by the browser
var headers = {};
function parseHeaders(raw) {
// Note: Set-Cookie will be removed by the browser
var headers = {};
if (!raw) { return headers; }
if (!raw) { return headers; }
raw.trim().split(headerSplitRE).forEach(function (header) {
var boundary, name, value;
boundary = header.indexOf(':');
name = normalizeHeaderName(header.substring(0, boundary).trim());
value = header.substring(boundary + 1).trim();
if (headers[name]) {
if (Array.isArray(headers[name])) {
// add to an existing array
headers[name].push(value);
}
else {
// convert single value to array
headers[name] = [headers[name], value];
}
}
else {
// new, single value
headers[name] = value;
}
});
return headers;
raw.trim().split(headerSplitRE).forEach(function (header) {
var boundary, name, value;
boundary = header.indexOf(':');
name = normalizeHeaderName(header.substring(0, boundary).trim());
value = header.substring(boundary + 1).trim();
if (headers[name]) {
if (Array.isArray(headers[name])) {
// add to an existing array
headers[name].push(value);
}
else {
// convert single value to array
headers[name] = [headers[name], value];
}
}
else {
// new, single value
headers[name] = value;
}
});
function safeMixin(target, source) {
Object.keys(source || {}).forEach(function (prop) {
// make sure the property already exists as
// IE 6 will blow up if we add a new prop
if (source.hasOwnProperty(prop) && prop in target) {
try {
target[prop] = source[prop];
}
catch (e) {
// ignore, expected for some properties at some points in the request lifecycle
}
}
});
return headers;
}
return target;
function safeMixin(target, source) {
Object.keys(source || {}).forEach(function (prop) {
// make sure the property already exists as
// IE 6 will blow up if we add a new prop
if (source.hasOwnProperty(prop) && prop in target) {
try {
target[prop] = source[prop];
}
catch (e) {
// ignore, expected for some properties at some points in the request lifecycle
}
}
});
return client(function xhr(request) {
return responsePromise.promise(function (resolve, reject) {
/*jshint maxcomplexity:20 */
return target;
}
var client, method, url, headers, entity, headerName, response, XMLHttpRequest;
module.exports = client(function xhr(request) {
return responsePromise.promise(function (resolve, reject) {
/*jshint maxcomplexity:20 */
request = typeof request === 'string' ? { path: request } : request || {};
response = { request: request };
var client, method, url, headers, entity, headerName, response, XHR;
if (request.canceled) {
response.error = 'precanceled';
reject(response);
return;
}
request = typeof request === 'string' ? { path: request } : request || {};
response = { request: request };
entity = request.entity;
request.method = request.method || (entity ? 'POST' : 'GET');
method = request.method;
url = response.url = new UrlBuilder(request.path || '', request.params).build();
if (request.canceled) {
response.error = 'precanceled';
reject(response);
return;
}
XMLHttpRequest = request.engine || global.XMLHttpRequest;
if (!XMLHttpRequest) {
reject({ request: request, url: url, error: 'xhr-not-available' });
return;
}
XHR = request.engine || XMLHttpRequest;
if (!XHR) {
reject({ request: request, error: 'xhr-not-available' });
return;
}
try {
client = response.raw = new XMLHttpRequest();
entity = request.entity;
request.method = request.method || (entity ? 'POST' : 'GET');
method = request.method;
url = response.url = request.path || '';
// mixin extra request properties before and after opening the request as some properties require being set at different phases of the request
safeMixin(client, request.mixin);
client.open(method, url, true);
safeMixin(client, request.mixin);
try {
client = response.raw = new XHR();
headers = request.headers;
for (headerName in headers) {
/*jshint forin:false */
if (headerName === 'Content-Type' && headers[headerName] === 'multipart/form-data') {
// XMLHttpRequest generates its own Content-Type header with the
// appropriate multipart boundary when sending multipart/form-data.
continue;
}
// mixin extra request properties before and after opening the request as some properties require being set at different phases of the request
safeMixin(client, request.mixin);
client.open(method, url, true);
safeMixin(client, request.mixin);
client.setRequestHeader(headerName, headers[headerName]);
}
headers = request.headers;
for (headerName in headers) {
/*jshint forin:false */
if (headerName === 'Content-Type' && headers[headerName] === 'multipart/form-data') {
// XMLHttpRequest generates its own Content-Type header with the
// appropriate multipart boundary when sending multipart/form-data.
continue;
}
request.canceled = false;
request.cancel = function cancel() {
request.canceled = true;
client.abort();
reject(response);
};
client.setRequestHeader(headerName, headers[headerName]);
}
client.onreadystatechange = function (/* e */) {
if (request.canceled) { return; }
if (client.readyState === (XMLHttpRequest.DONE || 4)) {
response.status = {
code: client.status,
text: client.statusText
};
response.headers = parseHeaders(client.getAllResponseHeaders());
response.entity = client.responseText;
request.canceled = false;
request.cancel = function cancel() {
request.canceled = true;
client.abort();
reject(response);
};
if (response.status.code > 0) {
// check status code as readystatechange fires before error event
resolve(response);
}
else {
// give the error callback a chance to fire before resolving
// requests for file:// URLs do not have a status code
setTimeout(function () {
resolve(response);
}, 0);
}
}
client.onreadystatechange = function (/* e */) {
if (request.canceled) { return; }
if (client.readyState === (XHR.DONE || 4)) {
response.status = {
code: client.status,
text: client.statusText
};
response.headers = parseHeaders(client.getAllResponseHeaders());
response.entity = client.responseText;
try {
client.onerror = function (/* e */) {
response.error = 'loaderror';
reject(response);
};
// #125 -- Sometimes IE8-9 uses 1223 instead of 204
// http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request
if (response.status.code === 1223) {
response.status.code = 204;
}
catch (e) {
// IE 6 will not support error handling
if (response.status.code > 0) {
// check status code as readystatechange fires before error event
resolve(response);
}
else {
// give the error callback a chance to fire before resolving
// requests for file:// URLs do not have a status code
setTimeout(function () {
resolve(response);
}, 0);
}
}
};
client.send(entity);
}
catch (e) {
try {
client.onerror = function (/* e */) {
response.error = 'loaderror';
reject(response);
}
};
}
catch (e) {
// IE 6 will not support error handling
}
});
});
client.send(entity);
}
catch (e) {
response.error = 'loaderror';
reject(response);
}
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); },
typeof window !== 'undefined' ? window : void 0
// Boilerplate for AMD and Node
));
});

@@ -8,3 +8,2 @@ # Clients

- [JSONP Client](#module-rest/client/jsonp)
- [IE XDomainRequest Client](#module-rest/client/xdr)

@@ -48,3 +47,3 @@

The default client for browsers. The XHR client utilizes the XMLHttpRequest object provided by many browsers. Most every browser has direct support for XHR today. The `rest/interceptor/ie/xhr` interceptor can provided fall back support for older IE without native XHR.
The default client for browsers. The XHR client utilizes the XMLHttpRequest object provided by many browsers.

@@ -141,18 +140,1 @@ **Special Properties**

</table>
<a name="module-rest/client/xdr"></a>
### IE XDomainRequest Client
`rest/client/xdr` ([src](../client/xdr.js))
Cross-origin support available within IE, in particular IE 8 and 9. This client is typically employed via the `rest/interceptor/ie/xdomain` interceptor. Never used as the default client.
**Know limitations**
- only GET and POST methods are available
- must use same scheme as origin http-to-http, https-to-https
- no headers, request or response (the response Content-Type is available)
- no response status code
[Limitation details](http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx)

@@ -12,2 +12,3 @@ # Interceptors

- [Template Interceptor](#module-rest/interceptor/template)
- [Params Interceptor](#module-rest/interceptor/params)
- [Authentication Interceptors](#interceptor-provided-auth)

@@ -23,4 +24,2 @@ - [Basic Auth Interceptor](#module-rest/interceptor/basicAuth)

- [JSONP Interceptor](#module-rest/interceptor/jsonp)
- [Cross Domain Request for IE Interceptor](#module-rest/interceptor/ie/xdomain)
- [ActiveX XHR for IE Interceptor](#module-rest/interceptor/ie/xhr)
- [Custom Interceptors](#interceptor-custom)

@@ -38,3 +37,2 @@ - [Interceptor Best Practices](#interceptor-custom-practices)

- [Async Request/Response](#interceptor-custom-concepts-async)
- [Override Parent Client (ComplexRequest)](#interceptor-custom-concepts-parent)
- [Abort Request (ComplexRequest)](#interceptor-custom-concepts-abort)

@@ -437,4 +435,2 @@

Note: primitive templating is provided by `rest/UrlBuilder`, however, its behavior is non-standard and less powerful.
**Phases**

@@ -478,2 +474,45 @@

<a name="module-rest/interceptor/params"></a>
#### Params Interceptor
`rest/interceptor/template` ([src](../interceptor/params.js))
**Deprecated**
The params interceptor expands token in the path defined by the param named wrapped in curly braces. Unbound params are appended to the end of the path as a query string. The params object is consumed by this interceptor.
The [Template Interceptor](#module-rest/interceptor/template) is recommended instead of this interceptor. It is more powerful and flexible.
**Phases**
- request
**Configuration**
<table>
<tr>
<th>Property</th>
<th>Required?</th>
<th>Default</th>
<th>Description</th>
</tr>
<tr>
<td>params</td>
<td>optional</td>
<td><em>empty object</em></td>
<td>default params to be combined with request.params</td>
</tr>
</table>
**Example**
```javascript
client = rest.wrap(params, { params: { lang: 'en-us' } });
client({ path: '/dictionary/{term}', params: { term: 'hypermedia' } }).then(function (response) {
assert.same('/dictionary/hypermedia?lang=en-us', response.request.path);
assert.same(undefined, response.request.params);
});
```
<a name="interceptor-provided-auth"></a>

@@ -897,54 +936,2 @@ ### Authentication Interceptors

<a name="module-rest/interceptor/ie/xdomain"></a>
#### Cross Domain Request for IE Interceptor
`rest/interceptor/ie/xdomain` ([src](../interceptor/ie/xdomain.js))
Utilizes IE's XDomainRequest support via the [XDomainRequest client](clients.md#module-rest/client/xdr) for making cross origin requests if needed, available and a CORS enabled XMLHttpRequest is not available. XDR request have a number of limitations, see the [XDR client](clients.md#module-rest/client/xdr) for limitation details. Will not interfere if installed in other environments.
This interceptor should be installed as close to the root of the interceptor chain as possible. When a XDomainRequest client is needed, the normal parent client will not be invoked.
**Phases**
- request
**Configuration**
*none*
**Example**
```javascript
client = rest.wrap(xdomain)
.wrap(defaultRequest, { params: { api_key: '95f41bfa4faa0f43bf7c24795eabbed4', format: 'rest' } });
client({ params: { method: 'flickr.test.echo' } }).then(function (response) {
// response from flickr
});
```
<a name="module-rest/interceptor/ie/xhr"></a>
#### ActiveX XHR for IE Interceptor
`rest/interceptor/ie/xhr` ([src](../interceptor/ie/xhr.js))
Attempts to use an ActiveX XHR replacement if a native XMLHttpRequest object is not available. Useful for IE < 9, which does not natively support XMLHttpRequest. Will not interfere if installed in other environments.
**Phases**
- request
**Configuration**
*none*
**Example**
```javascript
client = rest.wrap(xhr);
client({}).then(function (response) {
// normal XHR response, even in IE without XHR
});
```
<a name="interceptor-custom"></a>

@@ -1165,7 +1152,2 @@ ## Custom Interceptors

<a name="interceptor-custom-concepts-parent"></a>
**Override Parent Client (ComplexRequest)**
- [rest/interceptor/ie/xdomain](#module-rest/interceptor/ie/xdomain)
<a name="interceptor-custom-concepts-abort"></a>

@@ -1172,0 +1154,0 @@ **Abort Request (ComplexRequest)**

/*
* Copyright 2012-2015 the original author or authors
* Copyright 2012-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,159 +8,139 @@ *

(function (define) {
'use strict';
'use strict';
define(function (require) {
var defaultClient, mixin, responsePromise, client;
var defaultClient, mixin, responsePromise, client, when;
defaultClient = require('./client/default');
mixin = require('./util/mixin');
responsePromise = require('./util/responsePromise');
client = require('./client');
defaultClient = require('./client/default');
mixin = require('./util/mixin');
responsePromise = require('./util/responsePromise');
client = require('./client');
when = require('when');
/**
* Interceptors have the ability to intercept the request and/org response
* objects. They may augment, prune, transform or replace the
* request/response as needed. Clients may be composed by wrapping
* together multiple interceptors.
*
* Configured interceptors are functional in nature. Wrapping a client in
* an interceptor will not affect the client, merely the data that flows in
* and out of that client. A common configuration can be created once and
* shared; specialization can be created by further wrapping that client
* with custom interceptors.
*
* @param {Client} [target] client to wrap
* @param {Object} [config] configuration for the interceptor, properties will be specific to the interceptor implementation
* @returns {Client} A client wrapped with the interceptor
*
* @class Interceptor
*/
/**
* Interceptors have the ability to intercept the request and/org response
* objects. They may augment, prune, transform or replace the
* request/response as needed. Clients may be composed by wrapping
* together multiple interceptors.
*
* Configured interceptors are functional in nature. Wrapping a client in
* an interceptor will not affect the client, merely the data that flows in
* and out of that client. A common configuration can be created once and
* shared; specialization can be created by further wrapping that client
* with custom interceptors.
*
* @param {Client} [target] client to wrap
* @param {Object} [config] configuration for the interceptor, properties will be specific to the interceptor implementation
* @returns {Client} A client wrapped with the interceptor
*
* @class Interceptor
*/
function defaultInitHandler(config) {
return config;
}
function defaultInitHandler(config) {
return config;
}
function defaultRequestHandler(request /*, config, meta */) {
return request;
}
function defaultRequestHandler(request /*, config, meta */) {
return request;
}
function defaultResponseHandler(response /*, config, meta */) {
return response;
}
function defaultResponseHandler(response /*, config, meta */) {
return response;
}
/**
* 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 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);
}
function race(promisesOrValues) {
// this function is different than when.any as the first to reject also wins
return when.promise(function (resolve, reject) {
promisesOrValues.forEach(function (promiseOrValue) {
when(promiseOrValue, resolve, reject);
});
});
}
/**
* 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
* @param {Function} [handlers.response] response handler regardless of error state
* @param {Function} [handlers.success] response handler when the request is not in error
* @param {Function} [handlers.error] response handler when the request is in error, may be used to 'unreject' an error state
* @param {Function} [handlers.client] the client to use if otherwise not specified, defaults to platform default client
*
* @returns {Interceptor}
*/
function interceptor(handlers) {
/**
* 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 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);
}
var initHandler, requestHandler, successResponseHandler, errorResponseHandler;
/**
* 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
* @param {Function} [handlers.response] response handler regardless of error state
* @param {Function} [handlers.success] response handler when the request is not in error
* @param {Function} [handlers.error] response handler when the request is in error, may be used to 'unreject' an error state
* @param {Function} [handlers.client] the client to use if otherwise not specified, defaults to platform default client
*
* @returns {Interceptor}
*/
function interceptor(handlers) {
handlers = handlers || {};
var initHandler, requestHandler, successResponseHandler, errorResponseHandler;
initHandler = handlers.init || defaultInitHandler;
requestHandler = handlers.request || defaultRequestHandler;
successResponseHandler = handlers.success || handlers.response || defaultResponseHandler;
errorResponseHandler = handlers.error || function () {
// Propagate the rejection, with the result of the handler
return Promise.resolve((handlers.response || defaultResponseHandler).apply(this, arguments))
.then(Promise.reject.bind(Promise));
};
handlers = handlers || {};
return function (target, config) {
initHandler = handlers.init || defaultInitHandler;
requestHandler = handlers.request || defaultRequestHandler;
successResponseHandler = handlers.success || handlers.response || defaultResponseHandler;
errorResponseHandler = handlers.error || function () {
// Propagate the rejection, with the result of the handler
return when((handlers.response || defaultResponseHandler).apply(this, arguments), when.reject, when.reject);
};
if (typeof target === 'object') {
config = target;
}
if (typeof target !== 'function') {
target = handlers.client || defaultClient;
}
return function (target, config) {
config = initHandler(config || {});
if (typeof target === 'object') {
config = target;
}
if (typeof target !== 'function') {
target = handlers.client || defaultClient;
}
config = initHandler(config || {});
function interceptedClient(request) {
var context, meta;
context = {};
meta = { 'arguments': Array.prototype.slice.call(arguments), client: interceptedClient };
request = typeof request === 'string' ? { path: request } : request || {};
request.originator = request.originator || interceptedClient;
return responsePromise(
requestHandler.call(context, request, config, meta),
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;
function interceptedClient(request) {
var context, meta;
context = {};
meta = { 'arguments': Array.prototype.slice.call(arguments), client: interceptedClient };
request = typeof request === 'string' ? { path: request } : request || {};
request.originator = request.originator || interceptedClient;
return responsePromise(
requestHandler.call(context, request, config, meta),
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 || Promise.resolve(request).then(function (request) {
return Promise.resolve(next(request)).then(
function (response) {
return successResponseHandler.call(context, response, config, meta);
},
function (response) {
return errorResponseHandler.call(context, response, config, meta);
}
response = response || when(request, function (request) {
return when(
next(request),
function (response) {
return successResponseHandler.call(context, response, config, meta);
},
function (response) {
return errorResponseHandler.call(context, response, config, meta);
}
);
});
return abort ? race([response, abort]) : response;
},
function (error) {
return when.reject({ request: request, error: error });
}
);
);
});
return abort ? Promise.race([response, abort]) : response;
},
function (error) {
return Promise.reject({ request: request, error: error });
}
return client(interceptedClient, target);
};
);
}
interceptor.ComplexRequest = ComplexRequest;
return client(interceptedClient, target);
};
}
return interceptor;
interceptor.ComplexRequest = ComplexRequest;
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
module.exports = interceptor;
/*
* Copyright 2012-2013 the original author or authors
* Copyright 2012-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,42 +8,32 @@ *

(function (define) {
'use strict';
'use strict';
define(function (require) {
var interceptor, base64;
var interceptor, base64;
interceptor = require('../interceptor');
base64 = require('../util/base64');
interceptor = require('../interceptor');
base64 = require('../util/base64');
/**
* Authenticates the request using HTTP Basic Authentication (rfc2617)
*
* @param {Client} [client] client to wrap
* @param {string} config.username username
* @param {string} [config.password=''] password for the user
*
* @returns {Client}
*/
module.exports = interceptor({
request: function handleRequest(request, config) {
var headers, username, password;
/**
* Authenticates the request using HTTP Basic Authentication (rfc2617)
*
* @param {Client} [client] client to wrap
* @param {string} config.username username
* @param {string} [config.password=''] password for the user
*
* @returns {Client}
*/
return interceptor({
request: function handleRequest(request, config) {
var headers, username, password;
headers = request.headers || (request.headers = {});
username = request.username || config.username;
password = request.password || config.password || '';
headers = request.headers || (request.headers = {});
username = request.username || config.username;
password = request.password || config.password || '';
if (username) {
headers.Authorization = 'Basic ' + base64.encode(username + ':' + password);
}
if (username) {
headers.Authorization = 'Basic ' + base64.encode(username + ':' + password);
}
return request;
}
});
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
return request;
}
});
/*
* Copyright 2013 the original author or authors
* Copyright 2013-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,55 +8,45 @@ *

(function (define) {
'use strict';
'use strict';
define(function (require) {
var interceptor;
var interceptor;
interceptor = require('../interceptor');
interceptor = require('../interceptor');
/**
* Applies a Cross-Site Request Forgery protection header to a request
*
* CSRF protection helps a server verify that a request came from a
* trusted client and not another client that was able to masquerade
* as an authorized client. Sites that use cookie based authentication
* are particularly vulnerable to request forgeries without extra
* protection.
*
* @see http://en.wikipedia.org/wiki/Cross-site_request_forgery
*
* @param {Client} [client] client to wrap
* @param {string} [config.name='X-Csrf-Token'] name of the request
* header, may be overridden by `request.csrfTokenName`
* @param {string} [config.token] CSRF token, may be overridden by
* `request.csrfToken`
*
* @returns {Client}
*/
module.exports = interceptor({
init: function (config) {
config.name = config.name || 'X-Csrf-Token';
return config;
},
request: function handleRequest(request, config) {
var headers, name, token;
/**
* Applies a Cross-Site Request Forgery protection header to a request
*
* CSRF protection helps a server verify that a request came from a
* trusted client and not another client that was able to masquerade
* as an authorized client. Sites that use cookie based authentication
* are particularly vulnerable to request forgeries without extra
* protection.
*
* @see http://en.wikipedia.org/wiki/Cross-site_request_forgery
*
* @param {Client} [client] client to wrap
* @param {string} [config.name='X-Csrf-Token'] name of the request
* header, may be overridden by `request.csrfTokenName`
* @param {string} [config.token] CSRF token, may be overridden by
* `request.csrfToken`
*
* @returns {Client}
*/
return interceptor({
init: function (config) {
config.name = config.name || 'X-Csrf-Token';
return config;
},
request: function handleRequest(request, config) {
var headers, name, token;
headers = request.headers || (request.headers = {});
name = request.csrfTokenName || config.name;
token = request.csrfToken || config.token;
headers = request.headers || (request.headers = {});
name = request.csrfTokenName || config.name;
token = request.csrfToken || config.token;
if (token) {
headers[name] = token;
}
if (token) {
headers[name] = token;
}
return request;
}
});
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
return request;
}
});
/*
* Copyright 2013 the original author or authors
* Copyright 2013-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,73 +8,63 @@ *

(function (define) {
'use strict';
'use strict';
define(function (require) {
var interceptor, mixinUtil, defaulter;
var interceptor, mixinUtil, defaulter;
interceptor = require('../interceptor');
mixinUtil = require('../util/mixin');
interceptor = require('../interceptor');
mixinUtil = require('../util/mixin');
defaulter = (function () {
defaulter = (function () {
function mixin(prop, target, defaults) {
if (prop in target || prop in defaults) {
target[prop] = mixinUtil({}, defaults[prop], target[prop]);
}
}
function mixin(prop, target, defaults) {
if (prop in target || prop in defaults) {
target[prop] = mixinUtil({}, defaults[prop], target[prop]);
}
}
function copy(prop, target, defaults) {
if (prop in defaults && !(prop in target)) {
target[prop] = defaults[prop];
}
}
function copy(prop, target, defaults) {
if (prop in defaults && !(prop in target)) {
target[prop] = defaults[prop];
}
}
var mappings = {
method: copy,
path: copy,
params: mixin,
headers: mixin,
entity: copy,
mixin: mixin
};
var mappings = {
method: copy,
path: copy,
params: mixin,
headers: mixin,
entity: copy,
mixin: mixin
};
return function (target, defaults) {
for (var prop in mappings) {
/*jshint forin: false */
mappings[prop](prop, target, defaults);
}
return target;
};
return function (target, defaults) {
for (var prop in mappings) {
/*jshint forin: false */
mappings[prop](prop, target, defaults);
}
return target;
};
}());
}());
/**
* Provide default values for a request. These values will be applied to the
* request if the request object does not already contain an explicit value.
*
* For 'params', 'headers', and 'mixin', individual values are mixed in with the
* request's values. The result is a new object representiing the combined
* request and config values. Neither input object is mutated.
*
* @param {Client} [client] client to wrap
* @param {string} [config.method] the default method
* @param {string} [config.path] the default path
* @param {Object} [config.params] the default params, mixed with the request's existing params
* @param {Object} [config.headers] the default headers, mixed with the request's existing headers
* @param {Object} [config.mixin] the default "mixins" (http/https options), mixed with the request's existing "mixins"
*
* @returns {Client}
*/
return interceptor({
request: function handleRequest(request, config) {
return defaulter(request, config);
}
});
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
/**
* Provide default values for a request. These values will be applied to the
* request if the request object does not already contain an explicit value.
*
* For 'params', 'headers', and 'mixin', individual values are mixed in with the
* request's values. The result is a new object representiing the combined
* request and config values. Neither input object is mutated.
*
* @param {Client} [client] client to wrap
* @param {string} [config.method] the default method
* @param {string} [config.path] the default path
* @param {Object} [config.params] the default params, mixed with the request's existing params
* @param {Object} [config.headers] the default headers, mixed with the request's existing headers
* @param {Object} [config.mixin] the default "mixins" (http/https options), mixed with the request's existing "mixins"
*
* @returns {Client}
*/
module.exports = interceptor({
request: function handleRequest(request, config) {
return defaulter(request, config);
}
});
/*
* Copyright 2012-2014 the original author or authors
* Copyright 2012-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,39 +8,29 @@ *

(function (define) {
'use strict';
'use strict';
define(function (require) {
var interceptor;
var interceptor;
interceptor = require('../interceptor');
interceptor = require('../interceptor');
if (typeof console !== 'undefined') {
console.log('rest.js: rest/interceptor/entity is deprecated, please use response.entity() instead');
}
if (typeof console !== 'undefined') {
console.log('rest.js: rest/interceptor/entity is deprecated, please use response.entity() instead');
/**
* @deprecated use response.entity() instead
*
* Returns the response entity as the response, discarding other response
* properties.
*
* @param {Client} [client] client to wrap
*
* @returns {Client}
*/
module.exports = interceptor({
response: function (response) {
if ('entity' in response) {
return response.entity;
}
/**
* @deprecated use response.entity() instead
*
* Returns the response entity as the response, discarding other response
* properties.
*
* @param {Client} [client] client to wrap
*
* @returns {Client}
*/
return interceptor({
response: function (response) {
if ('entity' in response) {
return response.entity;
}
return response;
}
});
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
return response;
}
});
/*
* Copyright 2012-2013 the original author or authors
* Copyright 2012-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,41 +8,30 @@ *

(function (define) {
'use strict';
'use strict';
define(function (require) {
var interceptor;
var interceptor, when;
interceptor = require('../interceptor');
interceptor = require('../interceptor');
when = require('when');
/**
* Rejects the response promise based on the status code.
*
* Codes greater than or equal to the provided value are rejected. Default
* value 400.
*
* @param {Client} [client] client to wrap
* @param {number} [config.code=400] code to indicate a rejection
*
* @returns {Client}
*/
return interceptor({
init: function (config) {
config.code = config.code || 400;
return config;
},
response: function (response, config) {
if (response.status && response.status.code >= config.code) {
return when.reject(response);
}
return response;
}
});
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
/**
* Rejects the response promise based on the status code.
*
* Codes greater than or equal to the provided value are rejected. Default
* value 400.
*
* @param {Client} [client] client to wrap
* @param {number} [config.code=400] code to indicate a rejection
*
* @returns {Client}
*/
module.exports = interceptor({
init: function (config) {
config.code = config.code || 400;
return config;
},
response: function (response, config) {
if (response.status && response.status.code >= config.code) {
return Promise.reject(response);
}
return response;
}
});
/*
* Copyright 2012-2013 the original author or authors
* Copyright 2012-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,142 +8,132 @@ *

(function (define) {
'use strict';
'use strict';
define(function (require) {
var interceptor, pathPrefix, rfc5988LinkParser, find;
var interceptor, pathPrefix, rfc5988LinkParser, find;
interceptor = require('../interceptor');
pathPrefix = require('./pathPrefix');
rfc5988LinkParser = require('../parsers/rfc5988');
find = require('../util/find');
interceptor = require('../interceptor');
pathPrefix = require('./pathPrefix');
rfc5988LinkParser = require('../parsers/rfc5988');
find = require('../util/find');
/**
* [Experimental]
*
* Supports 'Hypertext As The Engine Of Application State' style
* services by indexing the 'links' property from the entity to make
* accessing links via the 'rel' attribute easier.
*
* Links are index in two ways:
* 1. as link's 'rel' which when accessed issues a request for the
* linked resource. A promise for the related resourse is expected
* to be returned.
* 2. as link's 'rel' with 'Link' appended, as a reference to the link
* object
*
* The 'Link' response header is also parsed for related resources
* following rfc5988. The values parsed from the headers are indexed
* into the response.links object.
*
* Also defines a 'clientFor' factory function that creates a new
* client configured to communicate with a related resource.
*
* The client for the resoruce reference and the 'clientFor' function
* can be provided by the 'client' config property.
*
* Index links are exposed by default on the entity. A child object may be
* configed by the 'target' config property.
*
* @param {Client} [client] client to wrap
* @param {string} [config.target=''] property to create on the entity and
* parse links into. If empty, the response entity is used directly.
* @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
*
* @returns {Client}
*/
module.exports = interceptor({
init: function (config) {
config.target = config.target || '';
return config;
},
response: function (response, config, meta) {
var client;
/**
* [Experimental]
*
* Supports 'Hypertext As The Engine Of Application State' style
* services by indexing the 'links' property from the entity to make
* accessing links via the 'rel' attribute easier.
*
* Links are index in two ways:
* 1. as link's 'rel' which when accessed issues a request for the
* linked resource. A promise for the related resourse is expected
* to be returned.
* 2. as link's 'rel' with 'Link' appended, as a reference to the link
* object
*
* The 'Link' response header is also parsed for related resources
* following rfc5988. The values parsed from the headers are indexed
* into the response.links object.
*
* Also defines a 'clientFor' factory function that creates a new
* client configured to communicate with a related resource.
*
* The client for the resoruce reference and the 'clientFor' function
* can be provided by the 'client' config property.
*
* Index links are exposed by default on the entity. A child object may be
* configed by the 'target' config property.
*
* @param {Client} [client] client to wrap
* @param {string} [config.target=''] property to create on the entity and
* parse links into. If empty, the response entity is used directly.
* @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
*
* @returns {Client}
*/
return interceptor({
init: function (config) {
config.target = config.target || '';
return config;
},
response: function (response, config, meta) {
var client;
client = config.client || (response.request && response.request.originator) || meta.client;
client = config.client || (response.request && response.request.originator) || meta.client;
function apply(target, links) {
links.forEach(function (link) {
Object.defineProperty(target, link.rel + 'Link', {
enumerable: false,
configurable: true,
value: link
});
function apply(target, links) {
links.forEach(function (link) {
Object.defineProperty(target, link.rel + 'Link', {
enumerable: false,
configurable: true,
value: link
});
Object.defineProperty(target, link.rel, {
enumerable: false,
configurable: true,
get: function () {
var response = client({ path: link.href });
Object.defineProperty(target, link.rel, {
enumerable: false,
configurable: true,
get: function () {
var response = client({ path: link.href });
Object.defineProperty(target, link.rel, {
enumerable: false,
configurable: true,
value: response
});
return response;
}
value: response
});
});
return response;
}
});
});
// if only Proxy was well supported...
Object.defineProperty(target, 'clientFor', {
enumerable: false,
value: function clientFor(rel, parentClient) {
return pathPrefix(
parentClient || client,
{ prefix: target[rel + 'Link'].href }
);
}
});
// if only Proxy was well supported...
Object.defineProperty(target, 'clientFor', {
enumerable: false,
value: function clientFor(rel, parentClient) {
return pathPrefix(
parentClient || client,
{ prefix: target[rel + 'Link'].href }
);
}
});
}
function parseLinkHeaders(headers) {
var links = [];
[].concat(headers).forEach(function (header) {
try {
links = links.concat(rfc5988LinkParser.parse(header));
}
catch (e) {
// ignore
// TODO consider a debug mode that logs
}
});
return links;
function parseLinkHeaders(headers) {
var links = [];
[].concat(headers).forEach(function (header) {
try {
links = links.concat(rfc5988LinkParser.parse(header));
}
if (response.headers && response.headers.Link) {
response.links = response.links || {};
apply(response.links, parseLinkHeaders(response.headers.Link));
catch (e) {
// ignore
// TODO consider a debug mode that logs
}
});
return links;
}
find.findProperties(response.entity, 'links', function (obj, host) {
var target;
if (response.headers && response.headers.Link) {
response.links = response.links || {};
apply(response.links, parseLinkHeaders(response.headers.Link));
}
if (Array.isArray(host.links)) {
if (config.target === '') {
target = host;
}
else {
target = {};
Object.defineProperty(host, config.target, {
enumerable: false,
value: target
});
}
find.findProperties(response.entity, 'links', function (obj, host) {
var target;
apply(target, host.links);
}
});
if (Array.isArray(host.links)) {
if (config.target === '') {
target = host;
}
else {
target = {};
Object.defineProperty(host, config.target, {
enumerable: false,
value: target
});
}
return response;
apply(target, host.links);
}
});
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
return response;
}
});
/*
* Copyright 2012-2013 the original author or authors
* Copyright 2012-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,53 +8,43 @@ *

(function (define) {
'use strict';
'use strict';
define(function (require) {
var interceptor, jsonpClient;
var interceptor, jsonpClient;
interceptor = require('../interceptor');
jsonpClient = require('../client/jsonp');
interceptor = require('../interceptor');
jsonpClient = require('../client/jsonp');
/**
* Allows common configuration of JSONP clients.
*
* Values provided to this interceptor are added to the request, if the
* request dose not already contain the property.
*
* The rest/client/jsonp client is used by default instead of the
* common default client for the platform.
*
* @param {Client} [client=rest/client/jsonp] custom client to wrap
* @param {string} [config.callback.param] the parameter name for which the
* callback function name is the value
* @param {string} [config.callback.prefix] prefix for the callback function,
* as the callback is attached to the window object, a unique, unobtrusive
* prefix is desired
* @param {string} [request.callback.name=<generated>] pins the name of the
* callback function, useful for cases where the server doesn't allow
* custom callback names. Generally not recommended.
*
* @returns {Client}
*/
return interceptor({
client: jsonpClient,
init: function (config) {
config.callback = config.callback || {};
return config;
},
request: function (request, config) {
request.callback = request.callback || {};
request.callback.param = request.callback.param || config.callback.param;
request.callback.prefix = request.callback.prefix || config.callback.prefix;
request.callback.name = request.callback.name || config.callback.name;
return request;
}
});
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
/**
* Allows common configuration of JSONP clients.
*
* Values provided to this interceptor are added to the request, if the
* request dose not already contain the property.
*
* The rest/client/jsonp client is used by default instead of the
* common default client for the platform.
*
* @param {Client} [client=rest/client/jsonp] custom client to wrap
* @param {string} [config.callback.param] the parameter name for which the
* callback function name is the value
* @param {string} [config.callback.prefix] prefix for the callback function,
* as the callback is attached to the window object, a unique, unobtrusive
* prefix is desired
* @param {string} [request.callback.name=<generated>] pins the name of the
* callback function, useful for cases where the server doesn't allow
* custom callback names. Generally not recommended.
*
* @returns {Client}
*/
module.exports = interceptor({
client: jsonpClient,
init: function (config) {
config.callback = config.callback || {};
return config;
},
request: function (request, config) {
request.callback = request.callback || {};
request.callback.param = request.callback.param || config.callback.param;
request.callback.prefix = request.callback.prefix || config.callback.prefix;
request.callback.name = request.callback.name || config.callback.name;
return request;
}
});
/*
* Copyright 2012-2013 the original author or authors
* Copyright 2012-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,55 +8,45 @@ *

(function (define) {
'use strict';
'use strict';
define(function (require) {
var interceptor;
var interceptor;
interceptor = require('../interceptor');
interceptor = require('../interceptor');
function isRedirect(response, config) {
var matchesRedirectCode = config.code === 0 || (response.status && response.status.code >= config.code);
return response.headers && response.headers.Location && matchesRedirectCode;
}
function isRedirect(response, config) {
var matchesRedirectCode = config.code === 0 || (response.status && response.status.code >= config.code);
return response.headers && response.headers.Location && matchesRedirectCode;
}
/**
* Follows the Location header in a response, if present. The response
* returned is for the subsequent request.
*
* Most browsers will automatically follow HTTP 3xx redirects, however,
* they will not automatically follow 2xx locations.
*
* @param {Client} [client] client to wrap
* @param {Client} [config.client=request.originator] client to use for subsequent request
*
* @returns {Client}
*/
module.exports = interceptor({
init: function (config) {
config.code = config.code || 0;
return config;
},
success: function (response, config, client) {
var request;
/**
* Follows the Location header in a response, if present. The response
* returned is for the subsequent request.
*
* Most browsers will automatically follow HTTP 3xx redirects, however,
* they will not automatically follow 2xx locations.
*
* @param {Client} [client] client to wrap
* @param {Client} [config.client=request.originator] client to use for subsequent request
*
* @returns {Client}
*/
return interceptor({
init: function (config) {
config.code = config.code || 0;
return config;
},
success: function (response, config, client) {
var request;
if (isRedirect(response, config)) {
request = response.request || {};
client = (config.client || request.originator || client.skip());
if (isRedirect(response, config)) {
request = response.request || {};
client = (config.client || request.originator || client.skip());
return client({
method: 'GET',
path: response.headers.Location
});
}
return client({
method: 'GET',
path: response.headers.Location
});
}
return response;
}
});
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
return response;
}
});
/*
* Copyright 2012-2014 the original author or authors
* Copyright 2012-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,104 +8,103 @@ *

(function (define) {
'use strict';
'use strict';
define(function (require) {
var interceptor, mime, registry, noopConverter, missingConverter, attempt;
var interceptor, mime, registry, noopConverter, when;
interceptor = require('../interceptor');
mime = require('../mime');
registry = require('../mime/registry');
attempt = require('../util/attempt');
interceptor = require('../interceptor');
mime = require('../mime');
registry = require('../mime/registry');
when = require('when');
noopConverter = {
read: function (obj) { return obj; },
write: function (obj) { return obj; }
};
noopConverter = {
read: function (obj) { return obj; },
write: function (obj) { return obj; }
};
missingConverter = {
read: function () { throw 'No read method found on converter'; },
write: function () { throw 'No write method found on converter'; }
};
/**
* MIME type support for request and response entities. Entities are
* (de)serialized using the converter for the MIME type.
*
* Request entities are converted using the desired converter and the
* 'Accept' request header prefers this MIME.
*
* Response entities are converted based on the Content-Type response header.
*
* @param {Client} [client] client to wrap
* @param {string} [config.mime='text/plain'] MIME type to encode the request
* entity
* @param {string} [config.accept] Accept header for the request
* @param {Client} [config.client=<request.originator>] client passed to the
* converter, defaults to the client originating the request
* @param {Registry} [config.registry] MIME registry, defaults to the root
* registry
* @param {boolean} [config.permissive] Allow an unkown request MIME type
*
* @returns {Client}
*/
return interceptor({
init: function (config) {
config.registry = config.registry || registry;
return config;
},
request: function (request, config) {
var type, headers;
/**
* MIME type support for request and response entities. Entities are
* (de)serialized using the converter for the MIME type.
*
* Request entities are converted using the desired converter and the
* 'Accept' request header prefers this MIME.
*
* Response entities are converted based on the Content-Type response header.
*
* @param {Client} [client] client to wrap
* @param {string} [config.mime='text/plain'] MIME type to encode the request
* entity
* @param {string} [config.accept] Accept header for the request
* @param {Client} [config.client=<request.originator>] client passed to the
* converter, defaults to the client originating the request
* @param {Registry} [config.registry] MIME registry, defaults to the root
* registry
* @param {boolean} [config.permissive] Allow an unkown request MIME type
*
* @returns {Client}
*/
module.exports = interceptor({
init: function (config) {
config.registry = config.registry || registry;
return config;
},
request: function (request, config) {
var type, headers;
headers = request.headers || (request.headers = {});
type = mime.parse(headers['Content-Type'] = headers['Content-Type'] || config.mime || 'text/plain');
headers.Accept = headers.Accept || config.accept || type.raw + ', application/json;q=0.8, text/plain;q=0.5, */*;q=0.2';
headers = request.headers || (request.headers = {});
type = mime.parse(headers['Content-Type'] || config.mime || 'text/plain');
headers.Accept = headers.Accept || config.accept || type.raw + ', application/json;q=0.8, text/plain;q=0.5, */*;q=0.2';
if (!('entity' in request)) {
return request;
}
if (!('entity' in request)) {
return request;
}
return config.registry.lookup(type).otherwise(function () {
// failed to resolve converter
if (config.permissive) {
return noopConverter;
}
throw 'mime-unknown';
}).then(function (converter) {
var client = config.client || request.originator;
headers['Content-Type'] = type.raw;
return when.attempt(converter.write, request.entity, { client: client, request: request, mime: type, registry: config.registry })
.otherwise(function() {
throw 'mime-serialization';
})
.then(function(entity) {
request.entity = entity;
return request;
});
return config.registry.lookup(type)['catch'](function () {
// failed to resolve converter
if (config.permissive) {
return noopConverter;
}
throw 'mime-unknown';
}).then(function (converter) {
var client = config.client || request.originator,
write = converter.write || missingConverter.write;
return attempt(write.bind(void 0, request.entity, { client: client, request: request, mime: type, registry: config.registry }))
['catch'](function() {
throw 'mime-serialization';
})
.then(function(entity) {
request.entity = entity;
return request;
});
},
response: function (response, config) {
if (!(response.headers && response.headers['Content-Type'] && response.entity)) {
return response;
}
});
},
response: function (response, config) {
if (!(response.headers && response.headers['Content-Type'] && response.entity)) {
return response;
}
var type = mime.parse(response.headers['Content-Type']);
var type = mime.parse(response.headers['Content-Type']);
return config.registry.lookup(type).otherwise(function () { return noopConverter; }).then(function (converter) {
var client = config.client || response.request && response.request.originator;
return config.registry.lookup(type)['catch'](function () { return noopConverter; }).then(function (converter) {
var client = config.client || response.request && response.request.originator,
read = converter.read || missingConverter.read;
return when.attempt(converter.read, response.entity, { client: client, response: response, mime: type, registry: config.registry })
.otherwise(function (e) {
response.error = 'mime-deserialization';
response.cause = e;
throw response;
})
.then(function (entity) {
response.entity = entity;
return response;
});
return attempt(read.bind(void 0, response.entity, { client: client, response: response, mime: type, registry: config.registry }))
['catch'](function (e) {
response.error = 'mime-deserialization';
response.cause = e;
throw response;
})
.then(function (entity) {
response.entity = entity;
return response;
});
}
});
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
}
});
/*
* Copyright 2012-2013 the original author or authors
* Copyright 2012-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,141 +8,129 @@ *

(function (define, global) {
'use strict';
'use strict';
define(function (require) {
var interceptor, UrlBuilder, pubsub;
var interceptor, UrlBuilder, pubsub, when;
interceptor = require('../interceptor');
UrlBuilder = require('../UrlBuilder');
pubsub = require('../util/pubsub');
interceptor = require('../interceptor');
UrlBuilder = require('../UrlBuilder');
pubsub = require('../util/pubsub');
when = require('when');
function defaultOAuthCallback(hash) {
var params, queryString, regex, m;
function defaultOAuthCallback(hash) {
var params, queryString, regex, m;
queryString = hash.indexOf('#') === 0 ? hash.substring(1) : hash;
params = {};
regex = /([^&=]+)=([^&]*)/g;
queryString = hash.indexOf('#') === 0 ? hash.substring(1) : hash;
params = {};
regex = /([^&=]+)=([^&]*)/g;
m = regex.exec(queryString);
do {
params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
m = regex.exec(queryString);
} while (m);
m = regex.exec(queryString);
do {
params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
m = regex.exec(queryString);
} while (m);
/*jshint camelcase:false */
pubsub.publish(params.state, params.token_type + ' ' + params.access_token);
}
/*jshint camelcase:false */
pubsub.publish(params.state, params.token_type + ' ' + params.access_token);
}
function defaultWindowStrategy(url) {
var w = window.open(url, '_blank', 'width=500,height=400');
return function () {
w.close();
};
}
function defaultWindowStrategy(url) {
var w = window.open(url, '_blank', 'width=500,height=400');
return function () {
w.close();
};
}
function authorize(config) {
var state, url, dismissWindow;
function authorize(config) {
var state, url, dismissWindow;
return new Promise(function (resolve) {
return when.promise(function (resolve) {
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
});
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);
dismissWindow = config.windowStrategy(url);
pubsub.subscribe(state, function (authorization) {
dismissWindow();
resolve(authorization);
});
pubsub.subscribe(state, function (authorization) {
dismissWindow();
resolve(authorization);
});
});
}
});
}
/**
* OAuth implicit flow support
*
* Authorizes request with the OAuth authorization token. Tokens are
* requested from the authorization server as needed if there isn't a
* token, or the token is expired.
*
* A custom window strategy can be provided to replace the default popup
* window. The window strategy is a function that must accept a URL as an
* argument and returns a function to close and cleanup the window. A
* common custom strategy would be to use an iframe in a dialog.
*
* The callback function must be invoked when the authorization server
* redirects the browser back to the application.
*
* NOTE: Registering a handler to receive the redirect is required and
* outside the scope of this interceptor. The implementer must collect the
* URL fragment and pass it to the callback function on the 'opener', or
* 'parent' window.
*
* @param {Client} [target] client to wrap
* @param {string} [config.token] pre-configured authentication token
* @param {string} config.clientId OAuth clientId
* @param {string} config.scope OAuth scope
* @param {string} config.authorizationUrlBase URL of the authorization server
* @param {string} [config.redirectUrl] callback URL from the authorization server. Will be converted to a fully qualified, absolute URL, if needed. Default's to the window's location or base href.
* @param {Function} [config.windowStrategy] strategy for opening the authorization window, defaults to window.open
* @param {string} [config.oAuthCallbackName='oAuthCallback'] name to register the callback as in global scope
* @param {Function} [config.oAuthCallback] callback function to receive OAuth URL fragment
*
* @returns {Client}
*/
module.exports = 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';
/**
* OAuth implicit flow support
*
* Authorizes request with the OAuth authorization token. Tokens are
* requested from the authorization server as needed if there isn't a
* token, or the token is expired.
*
* A custom window strategy can be provided to replace the default popup
* window. The window strategy is a function that must accept a URL as an
* argument and returns a function to close and cleanup the window. A
* common custom strategy would be to use an iframe in a dialog.
*
* The callback function must be invoked when the authorization server
* redirects the browser back to the application.
*
* NOTE: Registering a handler to receive the redirect is required and
* outside the scope of this interceptor. The implementer must collect the
* URL fragment and pass it to the callback function on the 'opener', or
* 'parent' window.
*
* @param {Client} [target] client to wrap
* @param {string} [config.token] pre-configured authentication token
* @param {string} config.clientId OAuth clientId
* @param {string} config.scope OAuth scope
* @param {string} config.authorizationUrlBase URL of the authorization server
* @param {string} [config.redirectUrl] callback URL from the authorization server. Will be converted to a fully qualified, absolute URL, if needed. Default's to the window's location or base href.
* @param {Function} [config.windowStrategy] strategy for opening the authorization window, defaults to window.open
* @param {string} [config.oAuthCallbackName='oAuthCallback'] name to register the callback as in global scope
* @param {Function} [config.oAuthCallback] callback function to receive OAuth URL fragment
*
* @returns {Client}
*/
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';
window[config.oAuthCallbackName] = config.oAuthCallback;
global[config.oAuthCallbackName] = config.oAuthCallback;
return config;
},
request: function (request, config) {
request.headers = request.headers || {};
return config;
},
request: function (request, config) {
request.headers = request.headers || {};
if (config.token) {
request.headers.Authorization = config.token;
return request;
}
else {
return authorize(config).then(function (authorization) {
request.headers.Authorization = config.token = authorization;
return request;
});
}
},
response: function (response, config, meta) {
if (response.status.code === 401) {
// token probably expired, reauthorize
return authorize(config).then(function (authorization) {
config.token = authorization;
return meta.client(response.request);
});
}
else if (response.status.code === 403) {
return Promise.reject(response);
}
if (config.token) {
request.headers.Authorization = config.token;
return request;
}
else {
return authorize(config).then(function (authorization) {
request.headers.Authorization = config.token = authorization;
return request;
});
}
},
response: function (response, config, meta) {
if (response.status.code === 401) {
// token probably expired, reauthorize
return authorize(config).then(function (authorization) {
config.token = authorization;
return meta.client(response.request);
});
}
else if (response.status.code === 403) {
return when.reject(response);
}
return response;
}
});
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); },
typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : void 0
// Boilerplate for AMD and Node
));
return response;
}
});
/*
* Copyright 2012-2013 the original author or authors
* Copyright 2012-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,53 +8,43 @@ *

(function (define) {
'use strict';
'use strict';
define(function (require) {
var interceptor, UrlBuilder;
var interceptor, UrlBuilder;
interceptor = require('../interceptor');
UrlBuilder = require('../UrlBuilder');
interceptor = require('../interceptor');
UrlBuilder = require('../UrlBuilder');
function startsWith(str, prefix) {
return str.indexOf(prefix) === 0;
}
function startsWith(str, prefix) {
return str.indexOf(prefix) === 0;
}
function endsWith(str, suffix) {
return str.lastIndexOf(suffix) + suffix.length === str.length;
}
function endsWith(str, suffix) {
return str.lastIndexOf(suffix) + suffix.length === str.length;
}
/**
* Prefixes the request path with a common value.
*
* @param {Client} [client] client to wrap
* @param {number} [config.prefix] path prefix
*
* @returns {Client}
*/
module.exports = interceptor({
request: function (request, config) {
var path;
/**
* Prefixes the request path with a common value.
*
* @param {Client} [client] client to wrap
* @param {number} [config.prefix] path prefix
*
* @returns {Client}
*/
return interceptor({
request: function (request, config) {
var path;
if (config.prefix && !(new UrlBuilder(request.path).isFullyQualified())) {
path = config.prefix;
if (request.path) {
if (!endsWith(path, '/') && !startsWith(request.path, '/')) {
// add missing '/' between path sections
path += '/';
}
path += request.path;
}
request.path = path;
if (config.prefix && !(new UrlBuilder(request.path).isFullyQualified())) {
path = config.prefix;
if (request.path) {
if (!endsWith(path, '/') && !startsWith(request.path, '/')) {
// add missing '/' between path sections
path += '/';
}
return request;
path += request.path;
}
});
request.path = path;
}
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
return request;
}
});
/*
* Copyright 2012-2014 the original author or authors
* Copyright 2012-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -9,52 +9,43 @@ *

(function (define) {
'use strict';
'use strict';
define(function (require) {
var interceptor, delay;
var interceptor, when;
interceptor = require('../interceptor');
delay = require('../util/delay');
interceptor = require('../interceptor');
when = require('when');
/**
* Retries a rejected request using an exponential backoff.
*
* Defaults to an initial interval of 100ms, a multiplier of 2, and no max interval.
*
* @param {Client} [client] client to wrap
* @param {number} [config.intial=100] initial interval in ms
* @param {number} [config.multiplier=2] interval multiplier
* @param {number} [config.max] max interval in ms
*
* @returns {Client}
*/
module.exports = interceptor({
init: function (config) {
config.initial = config.initial || 100;
config.multiplier = config.multiplier || 2;
config.max = config.max || Infinity;
return config;
},
error: function (response, config, meta) {
var request;
/**
* Retries a rejected request using an exponential backoff.
*
* Defaults to an initial interval of 100ms, a multiplier of 2, and no max interval.
*
* @param {Client} [client] client to wrap
* @param {number} [config.intial=100] initial interval in ms
* @param {number} [config.multiplier=2] interval multiplier
* @param {number} [config.max] max interval in ms
*
* @returns {Client}
*/
return interceptor({
init: function (config) {
config.initial = config.initial || 100;
config.multiplier = config.multiplier || 2;
config.max = config.max || Infinity;
return config;
},
error: function (response, config, meta) {
var request;
request = response.request;
request.retry = request.retry || config.initial;
request = response.request;
request.retry = request.retry || config.initial;
return when(request).delay(request.retry).then(function (request) {
if (request.canceled) {
// cancel here in case client doesn't check canceled flag
return when.reject({ request: request, error: 'precanceled' });
}
request.retry = Math.min(request.retry * config.multiplier, config.max);
return meta.client(request);
});
return delay(request.retry, request).then(function (request) {
if (request.canceled) {
// cancel here in case client doesn't check canceled flag
return Promise.reject({ request: request, error: 'precanceled' });
}
request.retry = Math.min(request.retry * config.multiplier, config.max);
return meta.client(request);
});
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
}
});
/*
* Copyright 2015 the original author or authors
* Copyright 2015-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,50 +8,40 @@ *

(function (define) {
'use strict';
'use strict';
define(function (require) {
var interceptor, uriTemplate, mixin;
var interceptor, uriTemplate, mixin;
interceptor = require('../interceptor');
uriTemplate = require('../util/uriTemplate');
mixin = require('../util/mixin');
interceptor = require('../interceptor');
uriTemplate = require('../util/uriTemplate');
mixin = require('../util/mixin');
/**
* Applies request params to the path as a URI Template
*
* Params are removed from the request object, as they have been consumed.
*
* @see https://tools.ietf.org/html/rfc6570
*
* @param {Client} [client] client to wrap
* @param {Object} [config.params] default param values
* @param {string} [config.template] default template
*
* @returns {Client}
*/
module.exports = interceptor({
init: function (config) {
config.params = config.params || {};
config.template = config.template || '';
return config;
},
request: function (request, config) {
var template, params;
/**
* Applies request params to the path as a URI Template
*
* Params are removed from the request object, as they have been consumed.
*
* @see https://tools.ietf.org/html/rfc6570
*
* @param {Client} [client] client to wrap
* @param {Object} [config.params] default param values
* @param {string} [config.template] default template
*
* @returns {Client}
*/
return interceptor({
init: function (config) {
config.params = config.params || {};
config.template = config.template || '';
return config;
},
request: function (request, config) {
var template, params;
template = request.path || config.template;
params = mixin({}, request.params, config.params);
template = request.path || config.template;
params = mixin({}, request.params, config.params);
request.path = uriTemplate.expand(template, params);
delete request.params;
request.path = uriTemplate.expand(template, params);
delete request.params;
return request;
}
});
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
return request;
}
});
/*
* Copyright 2012-2015 the original author or authors
* Copyright 2012-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -9,64 +9,55 @@ *

(function (define) {
'use strict';
'use strict';
define(function (require) {
var interceptor;
var interceptor, when;
interceptor = require('../interceptor');
interceptor = require('../interceptor');
when = require('when');
/**
* Cancels a request if it takes longer then the timeout value.
*
* @param {Client} [client] client to wrap
* @param {number} [config.timeout=0] duration in milliseconds before canceling the request. Non-positive values disable the timeout
* @param {boolean} [config.transient=false] if true, timed out requests will not be marked as canceled so that it may be retried
*
* @returns {Client}
*/
return interceptor({
init: function (config) {
config.timeout = config.timeout || 0;
config.transient = !!config.transient;
return config;
},
request: function (request, config) {
var timeout, abortTrigger, transient;
timeout = 'timeout' in request ? request.timeout : config.timeout;
transient = 'transient' in request ? request.transient : config.transient;
if (timeout <= 0) {
return request;
/**
* Cancels a request if it takes longer then the timeout value.
*
* @param {Client} [client] client to wrap
* @param {number} [config.timeout=0] duration in milliseconds before canceling the request. Non-positive values disable the timeout
* @param {boolean} [config.transient=false] if true, timed out requests will not be marked as canceled so that it may be retried
*
* @returns {Client}
*/
module.exports = interceptor({
init: function (config) {
config.timeout = config.timeout || 0;
config.transient = !!config.transient;
return config;
},
request: function (request, config) {
var timeout, abort, triggerAbort, transient;
timeout = 'timeout' in request ? request.timeout : config.timeout;
transient = 'transient' in request ? request.transient : config.transient;
if (timeout <= 0) {
return request;
}
abort = new Promise(function (resolve, reject) {
triggerAbort = reject;
});
this.timeout = setTimeout(function () {
triggerAbort({ request: request, error: 'timeout' });
if (request.cancel) {
request.cancel();
if (transient) {
// unmark request as canceled for future requests
request.canceled = false;
}
abortTrigger = when.defer();
this.timeout = setTimeout(function () {
abortTrigger.reject({ request: request, error: 'timeout' });
if (request.cancel) {
request.cancel();
if (transient) {
// unmark request as canceled for future requests
request.canceled = false;
}
}
else if (!transient) {
request.canceled = true;
}
}, timeout);
return new interceptor.ComplexRequest({ request: request, abort: abortTrigger.promise });
},
response: function (response) {
if (this.timeout) {
clearTimeout(this.timeout);
delete this.timeout;
}
return response;
}
});
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
else if (!transient) {
request.canceled = true;
}
}, timeout);
return new interceptor.ComplexRequest({ request: request, abort: abort });
},
response: function (response) {
if (this.timeout) {
clearTimeout(this.timeout);
delete this.timeout;
}
return response;
}
});
/*
* Copyright 2014 the original author or authors
* Copyright 2014-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,47 +8,35 @@ *

(function (define) {
'use strict';
'use strict';
var undef;
/**
* Parse a MIME type into it's constituent parts
*
* @param {string} mime MIME type to parse
* @return {{
* {string} raw the original MIME type
* {string} type the type and subtype
* {string} [suffix] mime suffix, including the plus, if any
* {Object} params key/value pair of attributes
* }}
*/
function parse(mime) {
var params, type;
define(function (/* require */) {
params = mime.split(';');
type = params[0].trim().split('+');
/**
* Parse a MIME type into it's constituent parts
*
* @param {string} mime MIME type to parse
* @return {{
* {string} raw the original MIME type
* {string} type the type and subtype
* {string} [suffix] mime suffix, including the plus, if any
* {Object} params key/value pair of attributes
* }}
*/
function parse(mime) {
var params, type;
return {
raw: mime,
type: type[0],
suffix: type[1] ? '+' + type[1] : '',
params: params.slice(1).reduce(function (params, pair) {
pair = pair.split('=');
params[pair[0].trim()] = pair[1] ? pair[1].trim() : void 0;
return params;
}, {})
};
}
params = mime.split(';');
type = params[0].trim().split('+');
return {
raw: mime,
type: type[0],
suffix: type[1] ? '+' + type[1] : '',
params: params.slice(1).reduce(function (params, pair) {
pair = pair.split('=');
params[pair[0].trim()] = pair[1] ? pair[1].trim() : undef;
return params;
}, {})
};
}
return {
parse: parse
};
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
module.exports = {
parse: parse
};
/*
* Copyright 2012-2014 the original author or authors
* Copyright 2012-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,109 +8,98 @@ *

(function (define) {
'use strict';
'use strict';
define(function (require) {
var mime, registry;
var mime, when, registry;
mime = require('../mime');
mime = require('../mime');
when = require('when');
function Registry(mimes) {
function Registry(mimes) {
/**
* Lookup the converter for a MIME type
*
* @param {string} type the MIME type
* @return a promise for the converter
*/
this.lookup = function lookup(type) {
var parsed;
/**
* Lookup the converter for a MIME type
*
* @param {string} type the MIME type
* @return a promise for the converter
*/
this.lookup = function lookup(type) {
var parsed;
parsed = typeof type === 'string' ? mime.parse(type) : type;
parsed = typeof type === 'string' ? mime.parse(type) : type;
if (mimes[parsed.raw]) {
return mimes[parsed.raw];
}
if (mimes[parsed.type + parsed.suffix]) {
return mimes[parsed.type + parsed.suffix];
}
if (mimes[parsed.type]) {
return mimes[parsed.type];
}
if (mimes[parsed.suffix]) {
return mimes[parsed.suffix];
}
if (mimes[parsed.raw]) {
return mimes[parsed.raw];
}
if (mimes[parsed.type + parsed.suffix]) {
return mimes[parsed.type + parsed.suffix];
}
if (mimes[parsed.type]) {
return mimes[parsed.type];
}
if (mimes[parsed.suffix]) {
return mimes[parsed.suffix];
}
return Promise.reject(new Error('Unable to locate converter for mime "' + parsed.raw + '"'));
};
return when.reject(new Error('Unable to locate converter for mime "' + parsed.raw + '"'));
};
/**
* Create a late dispatched proxy to the target converter.
*
* Common when a converter is registered under multiple names and
* should be kept in sync if updated.
*
* @param {string} type mime converter to dispatch to
* @returns converter whose read/write methods target the desired mime converter
*/
this.delegate = function delegate(type) {
return {
read: function () {
var args = arguments;
return this.lookup(type).then(function (converter) {
return converter.read.apply(this, args);
}.bind(this));
}.bind(this),
write: function () {
var args = arguments;
return this.lookup(type).then(function (converter) {
return converter.write.apply(this, args);
}.bind(this));
}.bind(this)
};
};
/**
* Create a late dispatched proxy to the target converter.
*
* Common when a converter is registered under multiple names and
* should be kept in sync if updated.
*
* @param {string} type mime converter to dispatch to
* @returns converter whose read/write methods target the desired mime converter
*/
this.delegate = function delegate(type) {
return {
read: function () {
var args = arguments;
return this.lookup(type).then(function (converter) {
return converter.read.apply(this, args);
}.bind(this));
}.bind(this),
write: function () {
var args = arguments;
return this.lookup(type).then(function (converter) {
return converter.write.apply(this, args);
}.bind(this));
}.bind(this)
};
};
/**
* Register a custom converter for a MIME type
*
* @param {string} type the MIME type
* @param converter the converter for the MIME type
* @return a promise for the converter
*/
this.register = function register(type, converter) {
mimes[type] = Promise.resolve(converter);
return mimes[type];
};
/**
* Register a custom converter for a MIME type
*
* @param {string} type the MIME type
* @param converter the converter for the MIME type
* @return a promise for the converter
*/
this.register = function register(type, converter) {
mimes[type] = when(converter);
return mimes[type];
};
/**
* Create a child registry whoes registered converters remain local, while
* able to lookup converters from its parent.
*
* @returns child MIME registry
*/
this.child = function child() {
return new Registry(Object.create(mimes));
};
/**
* Create a child registry whoes registered converters remain local, while
* able to lookup converters from its parent.
*
* @returns child MIME registry
*/
this.child = function child() {
return new Registry(Object.create(mimes));
};
}
}
registry = new Registry({});
registry = new Registry({});
// include provided serializers
registry.register('application/hal', require('./type/application/hal'));
registry.register('application/json', require('./type/application/json'));
registry.register('application/x-www-form-urlencoded', require('./type/application/x-www-form-urlencoded'));
registry.register('multipart/form-data', require('./type/multipart/form-data'));
registry.register('text/plain', require('./type/text/plain'));
// include provided serializers
registry.register('application/hal', require('./type/application/hal'));
registry.register('application/json', require('./type/application/json'));
registry.register('application/x-www-form-urlencoded', require('./type/application/x-www-form-urlencoded'));
registry.register('multipart/form-data', require('./type/multipart/form-data'));
registry.register('text/plain', require('./type/text/plain'));
registry.register('+json', registry.delegate('application/json'));
registry.register('+json', registry.delegate('application/json'));
return registry;
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
module.exports = registry;
/*
* Copyright 2013-2015 the original author or authors
* Copyright 2013-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,133 +8,122 @@ *

(function (define) {
'use strict';
'use strict';
define(function (require) {
var pathPrefix, template, find, lazyPromise, responsePromise;
var pathPrefix, template, find, lazyPromise, responsePromise, when;
pathPrefix = require('../../../interceptor/pathPrefix');
template = require('../../../interceptor/template');
find = require('../../../util/find');
lazyPromise = require('../../../util/lazyPromise');
responsePromise = require('../../../util/responsePromise');
pathPrefix = require('../../../interceptor/pathPrefix');
template = require('../../../interceptor/template');
find = require('../../../util/find');
lazyPromise = require('../../../util/lazyPromise');
responsePromise = require('../../../util/responsePromise');
when = require('when');
function defineProperty(obj, name, value) {
Object.defineProperty(obj, name, {
value: value,
configurable: true,
enumerable: false,
writeable: true
});
}
function defineProperty(obj, name, value) {
Object.defineProperty(obj, name, {
value: value,
configurable: true,
enumerable: false,
writeable: true
});
}
/**
* Hypertext Application Language serializer
*
* Implemented to https://tools.ietf.org/html/draft-kelly-json-hal-06
*
* As the spec is still a draft, this implementation will be updated as the
* spec evolves
*
* Objects are read as HAL indexing links and embedded objects on to the
* resource. Objects are written as plain JSON.
*
* Embedded relationships are indexed onto the resource by the relationship
* as a promise for the related resource.
*
* Links are indexed onto the resource as a lazy promise that will GET the
* resource when a handler is first registered on the promise.
*
* A `requestFor` method is added to the entity to make a request for the
* relationship.
*
* A `clientFor` method is added to the entity to get a full Client for a
* relationship.
*
* The `_links` and `_embedded` properties on the resource are made
* non-enumerable.
*/
module.exports = {
/**
* Hypertext Application Language serializer
*
* Implemented to https://tools.ietf.org/html/draft-kelly-json-hal-06
*
* As the spec is still a draft, this implementation will be updated as the
* spec evolves
*
* Objects are read as HAL indexing links and embedded objects on to the
* resource. Objects are written as plain JSON.
*
* Embedded relationships are indexed onto the resource by the relationship
* as a promise for the related resource.
*
* Links are indexed onto the resource as a lazy promise that will GET the
* resource when a handler is first registered on the promise.
*
* A `requestFor` method is added to the entity to make a request for the
* relationship.
*
* A `clientFor` method is added to the entity to get a full Client for a
* relationship.
*
* The `_links` and `_embedded` properties on the resource are made
* non-enumerable.
*/
return {
read: function (str, opts) {
var client, console;
read: function (str, opts) {
var client, console;
opts = opts || {};
client = opts.client;
console = opts.console || console;
opts = opts || {};
client = opts.client;
console = opts.console || console;
function deprecationWarning(relationship, deprecation) {
if (deprecation && console && console.warn || console.log) {
(console.warn || console.log).call(console, 'Relationship \'' + relationship + '\' is deprecated, see ' + deprecation);
}
}
function deprecationWarning(relationship, deprecation) {
if (deprecation && console && console.warn || console.log) {
(console.warn || console.log).call(console, 'Relationship \'' + relationship + '\' is deprecated, see ' + deprecation);
}
}
return opts.registry.lookup(opts.mime.suffix).then(function (converter) {
return when(converter.read(str, opts)).then(function (root) {
find.findProperties(root, '_embedded', function (embedded, resource, name) {
Object.keys(embedded).forEach(function (relationship) {
if (relationship in resource) { return; }
var related = responsePromise({
entity: embedded[relationship]
});
defineProperty(resource, relationship, related);
});
defineProperty(resource, name, embedded);
});
find.findProperties(root, '_links', function (links, resource, name) {
Object.keys(links).forEach(function (relationship) {
var link = links[relationship];
if (relationship in resource) { return; }
defineProperty(resource, relationship, responsePromise.make(lazyPromise(function () {
if (link.deprecation) { deprecationWarning(relationship, link.deprecation); }
if (link.templated === true) {
return template(client)({ path: link.href });
}
return client({ path: link.href });
})));
});
defineProperty(resource, name, links);
defineProperty(resource, 'clientFor', function (relationship, clientOverride) {
var link = links[relationship];
if (!link) {
throw new Error('Unknown relationship: ' + relationship);
}
if (link.deprecation) { deprecationWarning(relationship, link.deprecation); }
if (link.templated === true) {
return template(
clientOverride || client,
{ template: link.href }
);
}
return pathPrefix(
clientOverride || client,
{ prefix: link.href }
);
});
defineProperty(resource, 'requestFor', function (relationship, request, clientOverride) {
var client = this.clientFor(relationship, clientOverride);
return client(request);
});
});
return root;
return opts.registry.lookup(opts.mime.suffix).then(function (converter) {
return converter.read(str, opts);
}).then(function (root) {
find.findProperties(root, '_embedded', function (embedded, resource, name) {
Object.keys(embedded).forEach(function (relationship) {
if (relationship in resource) { return; }
var related = responsePromise({
entity: embedded[relationship]
});
defineProperty(resource, relationship, related);
});
defineProperty(resource, name, embedded);
});
find.findProperties(root, '_links', function (links, resource, name) {
Object.keys(links).forEach(function (relationship) {
var link = links[relationship];
if (relationship in resource) { return; }
defineProperty(resource, relationship, responsePromise.make(lazyPromise(function () {
if (link.deprecation) { deprecationWarning(relationship, link.deprecation); }
if (link.templated === true) {
return template(client)({ path: link.href });
}
return client({ path: link.href });
})));
});
defineProperty(resource, name, links);
defineProperty(resource, 'clientFor', function (relationship, clientOverride) {
var link = links[relationship];
if (!link) {
throw new Error('Unknown relationship: ' + relationship);
}
if (link.deprecation) { deprecationWarning(relationship, link.deprecation); }
if (link.templated === true) {
return template(
clientOverride || client,
{ template: link.href }
);
}
return pathPrefix(
clientOverride || client,
{ prefix: link.href }
);
});
defineProperty(resource, 'requestFor', function (relationship, request, clientOverride) {
var client = this.clientFor(relationship, clientOverride);
return client(request);
});
});
},
return root;
});
write: function (obj, opts) {
return opts.registry.lookup(opts.mime.suffix).then(function (converter) {
return converter.write(obj, opts);
});
}
},
};
});
write: function (obj, opts) {
return opts.registry.lookup(opts.mime.suffix).then(function (converter) {
return converter.write(obj, opts);
});
}
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
};
/*
* Copyright 2012-2015 the original author or authors
* Copyright 2012-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,41 +8,31 @@ *

(function (define) {
'use strict';
'use strict';
define(function (/* require */) {
/**
* Create a new JSON converter with custom reviver/replacer.
*
* The extended converter must be published to a MIME registry in order
* to be used. The existing converter will not be modified.
*
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON
*
* @param {function} [reviver=undefined] custom JSON.parse reviver
* @param {function|Array} [replacer=undefined] custom JSON.stringify replacer
*/
function createConverter(reviver, replacer) {
return {
/**
* Create a new JSON converter with custom reviver/replacer.
*
* The extended converter must be published to a MIME registry in order
* to be used. The existing converter will not be modified.
*
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON
*
* @param {function} [reviver=undefined] custom JSON.parse reviver
* @param {function|Array} [replacer=undefined] custom JSON.stringify replacer
*/
function createConverter(reviver, replacer) {
return {
read: function (str) {
return JSON.parse(str, reviver);
},
read: function (str) {
return JSON.parse(str, reviver);
},
write: function (obj) {
return JSON.stringify(obj, replacer);
},
write: function (obj) {
return JSON.stringify(obj, replacer);
},
extend: createConverter
extend: createConverter
};
}
};
}
return createConverter();
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
module.exports = createConverter();
/*
* Copyright 2012 the original author or authors
* Copyright 2012-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,84 +8,75 @@ *

(function (define) {
'use strict';
'use strict';
define(function (/* require */) {
var encodedSpaceRE, urlEncodedSpaceRE;
var encodedSpaceRE, urlEncodedSpaceRE;
encodedSpaceRE = /%20/g;
urlEncodedSpaceRE = /\+/g;
encodedSpaceRE = /%20/g;
urlEncodedSpaceRE = /\+/g;
function urlEncode(str) {
str = encodeURIComponent(str);
// spec says space should be encoded as '+'
return str.replace(encodedSpaceRE, '+');
}
function urlEncode(str) {
str = encodeURIComponent(str);
// spec says space should be encoded as '+'
return str.replace(encodedSpaceRE, '+');
}
function urlDecode(str) {
// spec says space should be encoded as '+'
str = str.replace(urlEncodedSpaceRE, ' ');
return decodeURIComponent(str);
}
function urlDecode(str) {
// spec says space should be encoded as '+'
str = str.replace(urlEncodedSpaceRE, ' ');
return decodeURIComponent(str);
function append(str, name, value) {
if (Array.isArray(value)) {
value.forEach(function (value) {
str = append(str, name, value);
});
}
else {
if (str.length > 0) {
str += '&';
}
str += urlEncode(name);
if (value !== undefined && value !== null) {
str += '=' + urlEncode(value);
}
}
return str;
}
function append(str, name, value) {
if (Array.isArray(value)) {
value.forEach(function (value) {
str = append(str, name, value);
});
module.exports = {
read: function (str) {
var obj = {};
str.split('&').forEach(function (entry) {
var pair, name, value;
pair = entry.split('=');
name = urlDecode(pair[0]);
if (pair.length === 2) {
value = urlDecode(pair[1]);
}
else {
if (str.length > 0) {
str += '&';
value = null;
}
if (name in obj) {
if (!Array.isArray(obj[name])) {
// convert to an array, perserving currnent value
obj[name] = [obj[name]];
}
str += urlEncode(name);
if (value !== undefined && value !== null) {
str += '=' + urlEncode(value);
}
obj[name].push(value);
}
return str;
}
return {
read: function (str) {
var obj = {};
str.split('&').forEach(function (entry) {
var pair, name, value;
pair = entry.split('=');
name = urlDecode(pair[0]);
if (pair.length === 2) {
value = urlDecode(pair[1]);
}
else {
value = null;
}
if (name in obj) {
if (!Array.isArray(obj[name])) {
// convert to an array, perserving currnent value
obj[name] = [obj[name]];
}
obj[name].push(value);
}
else {
obj[name] = value;
}
});
return obj;
},
write: function (obj) {
var str = '';
Object.keys(obj).forEach(function (name) {
str = append(str, name, obj[name]);
});
return str;
else {
obj[name] = value;
}
});
return obj;
},
};
});
write: function (obj) {
var str = '';
Object.keys(obj).forEach(function (name) {
str = append(str, name, obj[name]);
});
return str;
}
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
};
/*
* Copyright 2014 the original author or authors
* Copyright 2014-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -10,65 +10,56 @@ *

(function (define) {
'use strict';
'use strict';
define(function (/* require */) {
function isFormElement(object) {
return object &&
object.nodeType === 1 && // Node.ELEMENT_NODE
object.tagName === 'FORM';
}
function isFormElement(object) {
return object &&
object.nodeType === 1 && // Node.ELEMENT_NODE
object.tagName === 'FORM';
}
function createFormDataFromObject(object) {
var formData = new FormData();
function createFormDataFromObject(object) {
var formData = new FormData();
var value;
for (var property in object) {
if (object.hasOwnProperty(property)) {
value = object[property];
var value;
for (var property in object) {
if (object.hasOwnProperty(property)) {
value = object[property];
if (value instanceof File) {
formData.append(property, value, value.name);
} else if (value instanceof Blob) {
formData.append(property, value);
} else {
formData.append(property, String(value));
}
}
if (value instanceof File) {
formData.append(property, value, value.name);
} else if (value instanceof Blob) {
formData.append(property, value);
} else {
formData.append(property, String(value));
}
return formData;
}
}
return {
return formData;
}
write: function (object) {
if (typeof FormData === 'undefined') {
throw new Error('The multipart/form-data mime serializer requires FormData support');
}
module.exports = {
// Support FormData directly.
if (object instanceof FormData) {
return object;
}
write: function (object) {
if (typeof FormData === 'undefined') {
throw new Error('The multipart/form-data mime serializer requires FormData support');
}
// Support <form> elements.
if (isFormElement(object)) {
return new FormData(object);
}
// Support FormData directly.
if (object instanceof FormData) {
return object;
}
// Support plain objects, may contain File/Blob as value.
if (typeof object === 'object' && object !== null) {
return createFormDataFromObject(object);
}
// Support <form> elements.
if (isFormElement(object)) {
return new FormData(object);
}
throw new Error('Unable to create FormData from object ' + object);
}
// Support plain objects, may contain File/Blob as value.
if (typeof object === 'object' && object !== null) {
return createFormDataFromObject(object);
}
};
});
throw new Error('Unable to create FormData from object ' + object);
}
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
};
/*
* Copyright 2012 the original author or authors
* Copyright 2012-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,23 +8,14 @@ *

(function (define) {
'use strict';
'use strict';
define(function (/* require */) {
module.exports = {
return {
read: function (str) {
return str;
},
read: function (str) {
return str;
},
write: function (obj) {
return obj.toString();
}
write: function (obj) {
return obj.toString();
}
};
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
};
/*
* Copyright 2014 the original author or authors
* Copyright 2014-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,19 +8,9 @@ *

(function (define) {
'use strict';
'use strict';
define(function (require) {
var rest = require('./client/default'),
node = require('./client/node');
var rest = require('./client/default'),
node = require('./client/node');
rest.setPlatformDefaultClient(node);
rest.setPlatformDefaultClient(node);
return rest;
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
module.exports = rest;
{
"name": "rest",
"version": "1.3.2",
"version": "2.0.0",
"description": "RESTful HTTP client library",

@@ -33,6 +33,5 @@ "keywords": ["rest", "http", "client", "rest-template", "spring", "cujojs"],

],
"dependencies": {
"when": "~3"
},
"dependencies": {},
"devDependencies": {
"when": "~3",
"wire": "~0.9",

@@ -39,0 +38,0 @@ "test-support": "~0.4",

@@ -1,4 +0,1 @@

(function (define) {
define(function (require, exports, module) {
module.exports = (function(){

@@ -10,3 +7,3 @@ /*

*/
function quote(s) {

@@ -34,3 +31,3 @@ /*

}
var result = {

@@ -67,3 +64,3 @@ /*

};
if (startRule !== undefined) {

@@ -76,3 +73,3 @@ if (parseFunctions[startRule] === undefined) {

}
var pos = 0;

@@ -82,6 +79,6 @@ var reportFailures = 0;

var rightmostFailuresExpected = [];
function padLeft(input, padding, length) {
var result = input;
var padLength = length - input.length;

@@ -91,6 +88,6 @@ for (var i = 0; i < padLength; i++) {

}
return result;
}
function escape(ch) {

@@ -100,3 +97,3 @@ var charCode = ch.charCodeAt(0);

var length;
if (charCode <= 0xFF) {

@@ -109,6 +106,6 @@ escapeChar = 'x';

}
return '\\' + escapeChar + padLeft(charCode.toString(16).toUpperCase(), '0', length);
}
function matchFailed(failure) {

@@ -118,3 +115,3 @@ if (pos < rightmostFailuresPos) {

}
if (pos > rightmostFailuresPos) {

@@ -124,10 +121,10 @@ rightmostFailuresPos = pos;

}
rightmostFailuresExpected.push(failure);
}
function parse_start() {
var result0, result1, result2, result3, result4;
var pos0, pos1, pos2, pos3;
pos0 = pos;

@@ -241,7 +238,7 @@ pos1 = pos;

}
function parse_LinkValue() {
var result0, result1, result2, result3, result4, result5;
var pos0, pos1;
pos0 = pos;

@@ -316,7 +313,7 @@ pos1 = pos;

}
function parse_LinkParams() {
var result0, result1, result2, result3;
var pos0, pos1;
pos0 = pos;

@@ -365,7 +362,7 @@ pos1 = pos;

}
function parse_URIReference() {
var result0, result1;
var pos0;
pos0 = pos;

@@ -406,7 +403,7 @@ if (/^[^>]/.test(input.charAt(pos))) {

}
function parse_LinkParam() {
var result0, result1;
var pos0, pos1;
pos0 = pos;

@@ -436,7 +433,7 @@ pos1 = pos;

}
function parse_LinkParamName() {
var result0, result1;
var pos0;
pos0 = pos;

@@ -477,7 +474,7 @@ if (/^[a-z]/.test(input.charAt(pos))) {

}
function parse_LinkParamValue() {
var result0, result1;
var pos0, pos1;
pos0 = pos;

@@ -517,7 +514,7 @@ pos1 = pos;

}
function parse_PToken() {
var result0, result1;
var pos0;
pos0 = pos;

@@ -542,6 +539,6 @@ result1 = parse_PTokenChar();

}
function parse_PTokenChar() {
var result0;
if (input.charCodeAt(pos) === 33) {

@@ -861,6 +858,6 @@ result0 = "!";

}
function parse_OptionalSP() {
var result0, result1;
result0 = [];

@@ -874,7 +871,7 @@ result1 = parse_SP();

}
function parse_QuotedString() {
var result0, result1, result2;
var pos0, pos1;
pos0 = pos;

@@ -909,7 +906,7 @@ pos1 = pos;

}
function parse_QuotedStringInternal() {
var result0, result1;
var pos0;
pos0 = pos;

@@ -936,6 +933,6 @@ result0 = [];

}
function parse_Char() {
var result0;
if (/^[\0-]/.test(input.charAt(pos))) {

@@ -952,6 +949,6 @@ result0 = input.charAt(pos);

}
function parse_UpAlpha() {
var result0;
if (/^[A-Z]/.test(input.charAt(pos))) {

@@ -968,6 +965,6 @@ result0 = input.charAt(pos);

}
function parse_LoAlpha() {
var result0;
if (/^[a-z]/.test(input.charAt(pos))) {

@@ -984,6 +981,6 @@ result0 = input.charAt(pos);

}
function parse_Alpha() {
var result0;
result0 = parse_UpAlpha();

@@ -995,6 +992,6 @@ if (result0 === null) {

}
function parse_Digit() {
var result0;
if (/^[0-9]/.test(input.charAt(pos))) {

@@ -1011,6 +1008,6 @@ result0 = input.charAt(pos);

}
function parse_SP() {
var result0;
if (/^[ ]/.test(input.charAt(pos))) {

@@ -1027,6 +1024,6 @@ result0 = input.charAt(pos);

}
function parse_DQ() {
var result0;
if (/^["]/.test(input.charAt(pos))) {

@@ -1043,6 +1040,6 @@ result0 = input.charAt(pos);

}
function parse_QDText() {
var result0;
if (/^[^"]/.test(input.charAt(pos))) {

@@ -1059,7 +1056,7 @@ result0 = input.charAt(pos);

}
function parse_QuotedPair() {
var result0, result1;
var pos0;
pos0 = pos;

@@ -1089,7 +1086,7 @@ if (/^[\\]/.test(input.charAt(pos))) {

}
function cleanupExpected(expected) {
expected.sort();
var lastExpected = null;

@@ -1105,3 +1102,3 @@ var cleanExpected = [];

}
function computeErrorPosition() {

@@ -1114,7 +1111,7 @@ /*

*/
var line = 1;
var column = 1;
var seenCR = false;
for (var i = 0; i < Math.max(pos, rightmostFailuresPos); i++) {

@@ -1135,9 +1132,9 @@ var ch = input.charAt(i);

}
return { line: line, column: column };
}
var result = parseFunctions[startRule]();
/*

@@ -1171,3 +1168,3 @@ * The parser is now in one of the following three states:

var errorPosition = computeErrorPosition();
throw new this.SyntaxError(

@@ -1181,16 +1178,16 @@ cleanupExpected(rightmostFailuresExpected),

}
return result;
},
/* Returns the parser source code. */
toSource: function() { return this._source; }
};
/* Thrown when a parser encounters a syntax error. */
result.SyntaxError = function(expected, found, offset, line, column) {
function buildMessage(expected, found) {
var expectedHumanized, foundHumanized;
switch (expected.length) {

@@ -1208,8 +1205,8 @@ case 0:

}
foundHumanized = found ? quote(found) : "end of input";
return "Expected " + expectedHumanized + " but " + foundHumanized + " found.";
}
this.name = "SyntaxError";

@@ -1223,11 +1220,6 @@ this.expected = expected;

};
result.SyntaxError.prototype = Error.prototype;
return result;
})();
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { factory(require, module.exports, module); }
));

@@ -144,10 +144,8 @@ rest.js

Tested environments:
- Node.js (0.6, 0.8. 0.10, 4, 5)
- Node.js (0.10, 4, 6)
- Chrome (stable)
- Firefox (stable, ESR, should work in earlier versions)
- Edge
- IE (6-11)
- Safari (5-9, iOS 4-9.2, should work in earlier versions)
- Android (4.0-5.1, should work in earlier versions)
- Opera (11, 12, should work in earlier versions)
- IE (11, should work in earlier versions)
- Safari (8-9, iOS 8-9, should work in earlier versions)
- Android (4.3-5, should work in earlier versions)

@@ -178,3 +176,3 @@ 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.

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/) as CommonJS modules. Any module loader capable of loading either AMD or CommonJS modules should be able to load rest.js. cujoJS [curl.js](https://github.com/cujojs/curl) is actively tested.
rest.js is designed to run in a browser environment, utilizing a CommonJS Module loader, a transformer such as Browserify or WebPack, or within [Node.js](http://nodejs.org/). Any module loader capable of loading either CommonJS modules should be able to load rest.js. cujoJS [curl.js](https://github.com/cujojs/curl) is actively tested with the cjsm11 loader.

@@ -233,3 +231,3 @@ 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 test with cujoJS [poly.js](https://github.com/cujojs/poly)

Copyright 2012-2015 the original author or authors
Copyright 2012-2016 the original author or authors

@@ -242,2 +240,19 @@ rest.js is made available under the MIT license. See LICENSE.txt for details.

2.0.0
- MAJOR: Drop hard when.js dependency in favor of ES6 Promise API. See https://github.com/cujojs/when/blob/master/docs/es6-promise-shim.md to use when.js as an ES6 Promise polyfill.
- MAJOR: AMD modules are no longer supported. curl.js users can use the cjsm11 loader, see https://github.com/cujojs/curl#api-at-a-glance
- Moved path token param replacement from the clients into the `rest/interceptor/params` interceptor, which is also deprecated. The behavior will no longer be applied automatically in the client. Using the `rest/interceptor/template` interceptor is far more powerful and preferred.
- Fixed an issue preventing uri template exploded values from expanding correctly.
- Update tested environments:
- Android 5.1, 4.4 and 4.3
- Chrome latest
- Edge latest
- Firefox latest, 45 ESR, 38 ESR
- Node 0.10, 4, 6
- IE 11
- iOS 8 and 9
- Safari 8 and 9
- Removed old IE XDomainRequest client and xhr and xdr interceptors
- mime interceptor no longer sets Content-Type on requests without an entity
1.3.2

@@ -244,0 +259,0 @@ - fix to correctly url encode character codes 0-15, such as \n

/*
* Copyright 2012-2014 the original author or authors
* Copyright 2012-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,18 +8,8 @@ *

(function (define) {
'use strict';
'use strict';
define(function (require) {
if (console) {
(console.warn || console.log).call(console, 'rest.js: The main module has moved, please switch your configuration to use \'rest/browser\' as the main module for browser applications.');
}
if (console) {
(console.warn || console.log).call(console, 'rest.js: The main module has moved, please switch your configuration to use \'rest/browser\' as the main module for browser applications.');
}
return require('./browser');
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
module.exports = require('./browser');

@@ -18,3 +18,3 @@ /*

define('rest/browser-test', function (require) {
define('rest-test/browser-test', function (require) {

@@ -21,0 +21,0 @@ var rest, defaultClient, xhr;

[
// we don't really care about the platform, but without it the browser may fail to resolve
{ browserName: 'MicrosoftEdge', platform: 'Windows 10' }
{ browserName: 'MicrosoftEdge', platform: 'Windows 10' }
]
[
// we don't really care about the platform, but without it the browser may fail to resolve
{ browserName: 'firefox', platform: 'Windows 2008' }
{ browserName: 'firefox', platform: 'Windows 10' }
]
[
// we don't really care about the platform, but without it the browser may fail to resolve
{ browserName: 'ipad', version: '9.2', platform: 'OS X 10.10' }
{ browserName: 'ipad', version: '9.2', platform: 'Mac 10.10' }
]
[
// we don't really care about the platform, but without it the browser may fail to resolve
{ browserName: 'safari', version: '9.0', platform: 'OS X 10.11' }
{ browserName: 'safari', version: '9', platform: 'Mac 10.11' }
]
/*
* Copyright 2012-2014 the original author or authors
* Copyright 2012-2015 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -10,2 +10,6 @@ *

if (typeof Promise === 'undefined') {
require('when/es6-shim/Promise');
}
config['rest:node'] = {

@@ -41,2 +45,3 @@ environment: 'node',

libs: [
'node_modules/when/es6-shim/Promise.js',
'test/curl-config.js',

@@ -43,0 +48,0 @@ 'node_modules/curl/src/curl.js'

@@ -18,3 +18,3 @@ /*

define('rest/client-test', function (require) {
define('rest-test/client-test', function (require) {

@@ -21,0 +21,0 @@ var client, rest, interceptor, defaultClient, skippableClient, defaultInterceptor;

/*
* Copyright 2012-2014 the original author or authors
* Copyright 2012-2015 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -18,3 +18,3 @@ *

define('rest/client/jsonp-test', function (require) {
define('rest-test/client/jsonp-test', function (require) {

@@ -29,10 +29,10 @@ var client, jsonpInterceptor, rest;

'should make a cross origin request': function () {
var request = { path: 'https://api.github.com/' };
var request = { path: 'http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=jsonp' };
return client(request).then(function (response) {
assert.match(response.url, 'https://api.github.com/?callback=');
assert(response.entity.data);
assert.match(response.url, 'http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=jsonp&callback=');
assert(Object.keys(response.entity).length);
assert.same(request, response.request);
refute(request.canceled);
refute(response.raw.parentNode);
}).otherwise(fail);
})['catch'](fail);
},

@@ -47,7 +47,7 @@ 'should use the jsonp client from the jsonp interceptor by default': function () {

refute(response.raw.parentNode);
}).otherwise(fail);
})['catch'](fail);
},
'should abort the request if canceled': function () {
var request, response;
request = { path: 'http://ajax.googleapis.com/ajax/services/search/web?v=1.0', params: { q: 'jsonp' } };
request = { path: 'http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=jsonp' };
response = client(request).then(

@@ -77,3 +77,3 @@ fail,

'should not make a request that has already been canceled': function () {
var request = { canceled: true, path: 'http://ajax.googleapis.com/ajax/services/search/web?v=1.0', params: { q: 'html5' } };
var request = { canceled: true, path: 'http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=html5' };
return client(request).then(

@@ -109,7 +109,7 @@ fail,

'should normalize a string to a request object': function () {
var request = 'https://api.github.com/';
var request = 'http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=jsonp';
return client(request).then(function (response) {
assert.match(response.url, 'https://api.github.com/?callback=');
assert.match(response.url, 'http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=jsonp&callback=');
assert.same(request, response.request.path);
}).otherwise(fail);
})['catch'](fail);
},

@@ -125,3 +125,3 @@ 'should not be the default client': function () {

var response = client();
response.otherwise(function () {});
response['catch'](function () {});
assert.isFunction(response.entity);

@@ -128,0 +128,0 @@ }

/*
* Copyright 2012-2014 the original author or authors
* Copyright 2012-2015 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -19,3 +19,3 @@ *

define('rest/client/node-test', function (require) {
define('rest-test/client/node-test', function (require) {

@@ -81,3 +81,3 @@ var rest, client, http, https, fs, serverHttp, serverHttps;

refute(request.canceled);
}).otherwise(fail);
})['catch'](fail);
},

@@ -93,3 +93,3 @@ 'should make an explicit GET': function () {

refute(request.canceled);
}).otherwise(fail);
})['catch'](fail);
},

@@ -107,3 +107,3 @@ 'should make a POST with an entity': function () {

refute(request.canceled);
}).otherwise(fail);
})['catch'](fail);
},

@@ -118,3 +118,3 @@ 'should make an explicit POST with an entity': function () {

refute(request.canceled);
}).otherwise(fail);
})['catch'](fail);
},

@@ -138,3 +138,3 @@ 'should make an https request': function () {

refute(request.canceled);
}).otherwise(fail);
})['catch'](fail);
},

@@ -180,3 +180,3 @@ 'should abort the request if canceled': function () {

assert.same('http://localhost:8080/', response.request.path);
}).otherwise(fail);
})['catch'](fail);
},

@@ -192,3 +192,3 @@ 'should be the default client': function () {

var response = client();
response.otherwise(function () {});
response['catch'](function () {});
assert.isFunction(response.entity);

@@ -195,0 +195,0 @@ }

/*
* Copyright 2012-2014 the original author or authors
* Copyright 2012-2015 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -18,14 +18,10 @@ *

define('rest/client/xhr-test', function (require) {
define('rest-test/client/xhr-test', function (require) {
var xhr, rest, xhrFallback, when, client;
var client, rest, when;
xhr = require('rest/client/xhr');
client = 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.wrap(xhrFallback) : xhr;
buster.testCase('rest/client/xhr', {

@@ -50,3 +46,3 @@ 'should make a GET by default': function () {

refute(request.canceled);
}).otherwise(fail);
})['catch'](fail);
},

@@ -71,3 +67,3 @@ 'should make an explicit GET': function () {

refute(request.canceled);
}).otherwise(fail);
})['catch'](fail);
},

@@ -92,3 +88,3 @@ 'should make a POST with an entity': function () {

refute(request.canceled);
}).otherwise(fail);
})['catch'](fail);
},

@@ -113,3 +109,3 @@ 'should make an explicit POST with an entity': function () {

refute(request.canceled);
}).otherwise(fail);
})['catch'](fail);
},

@@ -124,3 +120,3 @@ 'should mixin additional properties': {

refute.equals(xhr.foo, 'bar');
}).otherwise(function (err) {
})['catch'](function (err) {
fail(JSON.stringify(err));

@@ -186,7 +182,6 @@ });

var request = { path: '/' };
return xhr(request).then(
return client(request).then(
fail,
failOnThrow(function (response) {
assert.same(request, response.request);
assert.equals(response.url, '/');
assert.same('xhr-not-available', response.error);

@@ -201,10 +196,10 @@ })

assert.same('/', response.request.path);
}).otherwise(fail);
})['catch'](fail);
},
'should be the default client': function () {
rest.resetDefaultClient();
assert.same(xhr, rest.getDefaultClient());
assert.same(client, rest.getDefaultClient());
},
'should support interceptor wrapping': function () {
assert(typeof xhr.wrap === 'function');
assert(typeof client.wrap === 'function');
},

@@ -211,0 +206,0 @@ 'should return a ResponsePromise': function () {

/*
* Copyright 2012-2014 the original author or authors
* Copyright 2012-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,17 +8,14 @@ *

(function (global) {
'use strict';
'use strict';
global.curl = {
packages: [
{ name: 'rest', location: './', main: 'browser' },
{ name: 'curl', location: 'node_modules/curl/src/curl', main: 'curl' },
{ name: 'poly', location: 'node_modules/poly', main: 'poly' },
{ name: 'when', location: 'node_modules/when', main: 'when' },
{ name: 'wire', location: 'node_modules/wire', main: 'wire' }
],
// 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));
window.curl = {
packages: [
{ name: 'rest', location: './', main: 'browser', config: { moduleLoader: 'curl/loader/cjsm11' } },
{ name: 'curl', location: 'node_modules/curl/src/curl', main: 'curl' },
{ name: 'poly', location: 'node_modules/poly', main: 'poly' },
{ name: 'when', location: 'node_modules/when', main: 'when' },
{ name: 'wire', location: 'node_modules/wire', main: 'wire' }
],
// 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']
};

@@ -18,3 +18,3 @@ /*

define('rest/interceptor-test', function (require) {
define('rest-test/interceptor-test', function (require) {

@@ -52,3 +52,3 @@ var interceptor, rest, when;

assert.same(client, response.request.originator);
}).otherwise(fail);
})['catch'](fail);
},

@@ -64,3 +64,3 @@ 'should use the client configured into the interceptor by default': function () {

assert.same(client, response.request.originator);
}).otherwise(fail);
})['catch'](fail);
},

@@ -76,3 +76,3 @@ 'should override the client configured into the interceptor by default': function () {

assert.same(client, response.request.originator);
}).otherwise(fail);
})['catch'](fail);
},

@@ -90,3 +90,3 @@ 'should intercept the request phase': function () {

assert.same('request', response.request.phase);
}).otherwise(fail);
})['catch'](fail);
},

@@ -107,3 +107,3 @@ 'should intercept the request phase and handle a promise': function () {

assert.same('request', response.request.phase);
}).otherwise(fail);
})['catch'](fail);
},

@@ -140,3 +140,3 @@ 'should intercept the request phase and handle a rejected promise': function () {

assert.same('response', response.phase);
}).otherwise(fail);
})['catch'](fail);
},

@@ -156,3 +156,3 @@ 'should intercept the response phase and handle a promise': function () {

assert.same('response', response.phase);
}).otherwise(fail);
})['catch'](fail);
},

@@ -235,3 +235,3 @@ 'should intercept the response phase and handle a rejceted promise': function () {

assert.same('success', response.phase);
}).otherwise(fail);
})['catch'](fail);
},

@@ -252,3 +252,3 @@ 'should intercept the success phase and handle a promise': function () {

assert.same('success', response.phase);
}).otherwise(fail);
})['catch'](fail);
},

@@ -284,3 +284,3 @@ 'should intercept the success phase and handle a rejceted promise': function () {

assert.same('error', response.phase);
}).otherwise(fail);
})['catch'](fail);
},

@@ -299,3 +299,3 @@ 'should intercept the error phase and handle a promise': function () {

assert.same('error', response.phase);
}).otherwise(fail);
})['catch'](fail);
},

@@ -338,3 +338,3 @@ 'should intercept the error phase and handle a rejceted promise': function () {

assert.same('response', response.phase);
}).otherwise(fail);
})['catch'](fail);
},

@@ -366,3 +366,3 @@ 'should share context between handlers that is unique per request': function () {

assert(counted.indexOf(3) >= 0);
}).otherwise(fail);
})['catch'](fail);
},

@@ -383,3 +383,3 @@ 'should use the client provided by a ComplexRequest': function () {

assert.same(client, response.request.originator);
}).otherwise(fail);
})['catch'](fail);
},

@@ -399,3 +399,3 @@ 'should use the repsponse provided by a ComplexRequest': function () {

assert.same(client, response.request.originator);
}).otherwise(fail);
})['catch'](fail);
},

@@ -439,3 +439,3 @@ 'should cancel requests with the abort trigger provided by a ComplexRequest': function () {

assert.same('default', response.id);
}).otherwise(fail);
})['catch'](fail);
},

@@ -460,3 +460,3 @@ 'should have access to the invocation args': function () {

assert.same('default', response.id);
}).otherwise(fail);
})['catch'](fail);
},

@@ -490,3 +490,3 @@ 'should initialize the config object, modifying the provided object': function () {

assert.same('default', response.id);
}).otherwise(fail);
})['catch'](fail);
},

@@ -499,3 +499,3 @@ 'should normalize a string to a request object': function () {

assert.same('/', response.request.path);
}).otherwise(fail);
})['catch'](fail);
},

@@ -502,0 +502,0 @@ 'should have the default client as the parent by default': function () {

@@ -17,3 +17,3 @@ /*

define('rest/interceptor/basicAuth-test', function (require) {
define('rest-test/interceptor/basicAuth-test', function (require) {

@@ -33,3 +33,3 @@ var basicAuth, rest;

assert.equals('Basic dXNlcjpwYXNz', response.request.headers.Authorization);
}).otherwise(fail);
})['catch'](fail);
},

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

assert.equals('Basic dXNlcjpwYXNz', response.request.headers.Authorization);
}).otherwise(fail);
})['catch'](fail);
},

@@ -51,3 +51,3 @@ 'should not authenticate without a username': function () {

refute.defined(response.request.headers.Authorization);
}).otherwise(fail);
})['catch'](fail);
},

@@ -54,0 +54,0 @@ 'should have the default client as the parent by default': function () {

/*
* Copyright 2013-2014 the original author or authors
* Copyright 2013-2015 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -17,3 +17,3 @@ *

define('rest/interceptor/csrf-test', function (require) {
define('rest-test/interceptor/csrf-test', function (require) {

@@ -33,3 +33,3 @@ var csrf, rest;

assert.equals('abc123xyz789', response.request.headers['X-Csrf-Token']);
}).otherwise(fail);
})['catch'](fail);
},

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

assert.equals('abc123xyz789', response.request.headers['X-Csrf-Token']);
}).otherwise(fail);
})['catch'](fail);
},

@@ -52,3 +52,3 @@ 'should protect the requst from the config using a custom header': function () {

assert.equals('abc123xyz789', response.request.headers['Csrf-Token']);
}).otherwise(fail);
})['catch'](fail);
},

@@ -61,3 +61,3 @@ 'should protect the requst from the request using a custom header': function () {

assert.equals('abc123xyz789', response.request.headers['Csrf-Token']);
}).otherwise(fail);
})['catch'](fail);
},

@@ -70,3 +70,3 @@ 'should not protect without a token': function () {

refute.defined(response.request.headers['X-Csrf-Token']);
}).otherwise(fail);
})['catch'](fail);
},

@@ -73,0 +73,0 @@ 'should have the default client as the parent by default': function () {

/*
* Copyright 2013-2014 the original author or authors
* Copyright 2013-2015 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -17,3 +17,3 @@ *

define('rest/interceptor/defaultRequest-test', function (require) {
define('rest-test/interceptor/defaultRequest-test', function (require) {

@@ -36,3 +36,3 @@ var defaultRequest, rest;

assert.equals({}, response.request);
}).otherwise(fail);
})['catch'](fail);
},

@@ -43,3 +43,3 @@ 'should default the method': function () {

assert.equals('PUT', response.request.method);
}).otherwise(fail);
})['catch'](fail);
},

@@ -50,3 +50,3 @@ 'should not overwrite the method': function () {

assert.equals('GET', response.request.method);
}).otherwise(fail);
})['catch'](fail);
},

@@ -57,3 +57,3 @@ 'should default the path': function () {

assert.equals('/foo', response.request.path);
}).otherwise(fail);
})['catch'](fail);
},

@@ -64,3 +64,3 @@ 'should not overwrite the path': function () {

assert.equals('/bar', response.request.path);
}).otherwise(fail);
})['catch'](fail);
},

@@ -72,3 +72,3 @@ 'should default params': function () {

assert.equals('false', response.request.params.bool);
}).otherwise(fail);
})['catch'](fail);
},

@@ -81,3 +81,3 @@ 'should merge params': function () {

assert.equals('bloop', response.request.params.bleep);
}).otherwise(fail);
})['catch'](fail);
},

@@ -89,3 +89,3 @@ 'should default headers': function () {

assert.equals('false', response.request.headers.bool);
}).otherwise(fail);
})['catch'](fail);
},

@@ -98,3 +98,3 @@ 'should merge headers': function () {

assert.equals('bloop', response.request.headers.bleep);
}).otherwise(fail);
})['catch'](fail);
},

@@ -105,3 +105,3 @@ 'should default the entity': function () {

assert.same(Math, response.request.entity);
}).otherwise(fail);
})['catch'](fail);
},

@@ -112,3 +112,3 @@ 'should not overwrite the entity': function () {

assert.same(Date, response.request.entity);
}).otherwise(fail);
})['catch'](fail);
},

@@ -115,0 +115,0 @@ 'should have the default client as the parent by default': function () {

/*
* Copyright 2012-2014 the original author or authors
* Copyright 2012-2015 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -17,3 +17,3 @@ *

define('rest/interceptor/entity-test', function (require) {
define('rest-test/interceptor/entity-test', function (require) {

@@ -34,3 +34,3 @@ var entity, rest;

assert.same(body, response);
}).otherwise(fail);
})['catch'](fail);
},

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

assert.same(response, r);
}).otherwise(fail);
})['catch'](fail);
},

@@ -48,0 +48,0 @@ 'should have the default client as the parent by default': function () {

/*
* Copyright 2012-2014 the original author or authors
* Copyright 2012-2015 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -18,3 +18,3 @@ *

define('rest/interceptor/errorCode-test', function (require) {
define('rest-test/interceptor/errorCode-test', function (require) {

@@ -33,3 +33,3 @@ var errorCode, rest;

assert.equals(399, response.status.code);
}).otherwise(fail);
})['catch'](fail);
},

@@ -36,0 +36,0 @@ 'should reject for 400 or greater by default': function () {

/*
* Copyright 2012-2014 the original author or authors
* Copyright 2012-2015 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -17,3 +17,3 @@ *

define('rest/interceptor/hateoas-test', function (require) {
define('rest-test/interceptor/hateoas-test', function (require) {

@@ -69,3 +69,3 @@ var hateoas, rest, when, supports;

assert.same(response.links.nextLink.title, 'next chapter');
}).otherwise(fail);
})['catch'](fail);
},

@@ -86,3 +86,3 @@ 'should parse compound header links': function () {

assert.same(response.links.nextLink.title, 'next chapter');
}).otherwise(fail);
})['catch'](fail);
},

@@ -98,3 +98,3 @@ 'should gracefully recover from maleformed header links': function () {

assert.same(entity, response.entity);
}).otherwise(fail);
})['catch'](fail);
},

@@ -116,3 +116,3 @@ '': {

assert.same(self, response.entity._links.selfLink);
}).otherwise(fail);
})['catch'](fail);
},

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

assert.same(self, response.entity.selfLink);
}).otherwise(fail);
})['catch'](fail);
},

@@ -148,3 +148,3 @@ 'should create a client for the related resource': function () {

});
}).otherwise(fail);
})['catch'](fail);
},

@@ -161,3 +161,3 @@ 'should return the same value for multiple property accesses': function () {

assert.same(response.entity.self, response.entity.self);
}).otherwise(fail);
})['catch'](fail);
}

@@ -184,3 +184,3 @@ },

});
}).otherwise(fail);
})['catch'](fail);
}

@@ -187,0 +187,0 @@ },

/*
* Copyright 2012-2014 the original author or authors
* Copyright 2012-2015 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -17,3 +17,3 @@ *

define('rest/interceptor/jsonp-test', function (require) {
define('rest-test/interceptor/jsonp-test', function (require) {

@@ -37,3 +37,3 @@ var jsonp, rest, jsonpClient, when;

assert.equals('jsonp123456', response.request.callback.name);
}).otherwise(fail);
})['catch'](fail);
},

@@ -49,3 +49,3 @@ 'should include callback info from request overridding config values': function () {

assert.equals('customName', response.request.callback.name);
}).otherwise(fail);
})['catch'](fail);
},

@@ -52,0 +52,0 @@ 'should have the jsonp client as the parent by default': function () {

/*
* Copyright 2012-2014 the original author or authors
* Copyright 2012-2015 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -17,3 +17,3 @@ *

define('rest/interceptor/location-test', function (require) {
define('rest-test/interceptor/location-test', function (require) {

@@ -46,3 +46,3 @@ var location, rest;

refute(spy.returnValues[2].headers.Location);
}).otherwise(fail);
})['catch'](fail);
},

@@ -68,3 +68,3 @@ 'should follow the location header when status code is greater or equal to configured status code': function () {

assert.same(spy.args[1][0].path, '/foo');
}).otherwise(fail);
})['catch'](fail);
},

@@ -78,3 +78,3 @@ 'should return the response if there is no location header': function () {

assert.same(1, spy.callCount);
}).otherwise(fail);
})['catch'](fail);
},

@@ -81,0 +81,0 @@ 'should have the default client as the parent by default': function () {

/*
* Copyright 2012-2014 the original author or authors
* Copyright 2012-2015 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -18,3 +18,3 @@ *

define('rest/interceptor/mime-test', function (require) {
define('rest-test/interceptor/mime-test', function (require) {

@@ -38,3 +38,3 @@ var mime, registry, rest, when;

assert.equals({}, response.entity);
}).otherwise(fail);
})['catch'](fail);
},

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

assert.equals('{}', response.request.entity);
}).otherwise(fail);
})['catch'](fail);
},

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

assert.equals(0, response.request.headers.Accept.indexOf('application/json'));
}).otherwise(fail);
})['catch'](fail);
},

@@ -87,4 +87,19 @@ 'should not overwrite the requests Accept header': function () {

assert.equals('foo', response.request.headers.Accept);
}).otherwise(fail);
})['catch'](fail);
},
'should not set the requests Content-Type header if there is no entity': function () {
var client;
client = mime(
function (request) {
return { request: request, headers: {} };
},
{ mime: 'application/json' }
);
return client({}).then(function (response) {
assert.equals(undefined, response.request.entity);
assert.equals(undefined, response.request.headers['Content-Type']);
})['catch'](fail);
},
'should error the request if unable to find a converter for the desired mime': function () {

@@ -119,3 +134,3 @@ var client, request;

assert.equals('application/vnd.com.example', response.request.headers['Content-Type']);
}).otherwise(fail);
})['catch'](fail);
},

@@ -131,3 +146,3 @@ 'should use text/plain converter for a response if unable to find a converter for the desired mime': function () {

assert.same('{}', response.entity);
}).otherwise(fail);
})['catch'](fail);
},

@@ -174,3 +189,3 @@ 'should use the configured mime registry': function () {

});
}).otherwise(fail);
})['catch'](fail);
},

@@ -276,3 +291,3 @@ 'should reject the response if the serializer fails to write the request': function () {

assert.equals('response entity', response.entity);
}).otherwise(fail);
})['catch'](fail);
},

@@ -301,3 +316,3 @@ 'should wait for entity to resolve before returning when serializer returns a promise while writing request entity': function () {

assert.equals('request entity', response.request.entity);
}).otherwise(fail);
})['catch'](fail);
},

@@ -304,0 +319,0 @@ 'should reject the response if serializer rejects promise while writing request entity': function () {

/*
* Copyright 2012-2014 the original author or authors
* Copyright 2012-2015 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -17,3 +17,3 @@ *

define('rest/interceptor/pathPrefix-test', function (require) {
define('rest-test/interceptor/pathPrefix-test', function (require) {

@@ -33,3 +33,3 @@ var pathPrefix, rest;

assert.equals('/foo/bar', response.request.path);
}).otherwise(fail);
})['catch'](fail);
},

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

assert.equals('/foo/bar', response.request.path);
}).otherwise(fail);
})['catch'](fail);
},

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

assert.equals('/foo/bar', response.request.path);
}).otherwise(fail);
})['catch'](fail);
},

@@ -63,3 +63,3 @@ 'should not prepend prefix before a fully qualified path': function () {

assert.equals('http://www.example.com/', response.request.path);
}).otherwise(fail);
})['catch'](fail);
},

@@ -66,0 +66,0 @@ 'should have the default client as the parent by default': function () {

/*
* Copyright 2012-2014 the original author or authors
* Copyright 2012-2015 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -9,3 +9,3 @@ *

(function (buster, define, nextTick) {
(function (buster, define) {
'use strict';

@@ -19,5 +19,5 @@

define('rest/interceptor/retry-test', function (require) {
define('rest-test/interceptor/retry-test', function (require) {
var interceptor, retry, rest, when, clock;
var interceptor, retry, rest, when;

@@ -43,38 +43,27 @@ interceptor = require('rest/interceptor');

assert.equals(200, response.status.code);
}).otherwise(fail);
})['catch'](fail);
},
'should accept custom config': {
setUp: function () {
clock = this.useFakeTimers();
},
tearDown: function () {
clock.restore();
},
'': function () {
var count = 0, client, start, config;
'should accept custom config': function () {
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 {
nextTick(function () {
clock.tick(tick);
}, 0);
return when.reject({ request: request, error: 'Thrown by fake client' });
}
},
config
);
start = new Date().getTime();
config = { initial: 10, multiplier: 3, max: 20 };
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' });
}
},
config
);
return client({}).then(function (response) {
assert.equals(200, response.status.code);
assert.equals(count, 4);
assert.equals(50, new Date().getTime() - start);
}).otherwise(fail);
}
return client({}).then(function (response) {
var durration = Date.now() - start;
assert.equals(200, response.status.code);
assert.equals(count, 4);
assert(40 <= durration);
})['catch'](fail);
},

@@ -120,14 +109,4 @@ 'should not make propagate request if marked as canceled': function () {

});
},
// retain access to the native setTimeout function
(function (setTimeout) {
return typeof process !== 'undefined' && process.nextTick ?
function (work) {
process.nextTick(work);
} :
function (work) {
setTimeout(work, 0);
};
}(setTimeout))
}
// Boilerplate for AMD and Node
));

@@ -17,3 +17,3 @@ /*

define('rest/interceptor/template-test', function (require) {
define('rest-test/interceptor/template-test', function (require) {

@@ -39,3 +39,3 @@ var template, rest;

refute('params' in response.request);
}).otherwise(fail);
})['catch'](fail);
},

@@ -51,3 +51,3 @@ 'should apply the template and params from the config if not defined on the request': function () {

refute('params' in response.request);
}).otherwise(fail);
})['catch'](fail);
},

@@ -63,3 +63,3 @@ 'should individually mix config params into the request': function () {

refute('params' in response.request);
}).otherwise(fail);
})['catch'](fail);
},

@@ -75,3 +75,3 @@ 'should ignore missing and overdefined params': function () {

refute('params' in response.request);
}).otherwise(fail);
})['catch'](fail);
},

@@ -78,0 +78,0 @@ 'should have the default client as the parent by default': function () {

@@ -19,3 +19,3 @@ /*

define('rest/interceptor/timeout-test', function (require) {
define('rest-test/interceptor/timeout-test', function (require) {

@@ -63,7 +63,7 @@ var timeout, rest, when;

});
}).otherwise(fail);
})['catch'](fail);
},
'should resolve if client responds before timeout': function () {
var client, request;
client = timeout(delayedClient, { timeout: 100 });
client = timeout(delayedClient, { timeout: 200 });
request = {};

@@ -74,3 +74,3 @@ return client(request).then(function (response) {

refute(request.canceled);
}).otherwise(fail);
})['catch'](fail);
},

@@ -111,3 +111,3 @@ 'should reject even if client responds after timeout': function () {

refute(request.canceled);
}).otherwise(fail);
})['catch'](fail);
},

@@ -122,3 +122,3 @@ 'should not reject without a configured timeout value': function () {

refute(request.canceled);
}).otherwise(fail);
})['catch'](fail);
},

@@ -125,0 +125,0 @@ 'should cancel request if client support cancelation': function () {

@@ -17,3 +17,3 @@ /*

define('rest/mime-test', function (require) {
define('rest-test/mime-test', function (require) {

@@ -20,0 +20,0 @@ var mime;

/*
* Copyright 2012-2014 the original author or authors
* Copyright 2012-2015 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -17,3 +17,3 @@ *

define('rest/mime/registry-test', function (require) {
define('rest-test/mime/registry-test', function (require) {

@@ -33,3 +33,3 @@ var mimeRegistry, when, registry;

assert.isFunction(converter.write);
}).otherwise(fail);
})['catch'](fail);
},

@@ -41,3 +41,3 @@ 'should return registed converter': function () {

assert.same(converter, c);
}).otherwise(fail);
})['catch'](fail);
},

@@ -59,3 +59,3 @@ 'should reject for non-existant converter': function () {

assert.same(converter, c);
}).otherwise(fail);
})['catch'](fail);
},

@@ -71,3 +71,3 @@ 'should override parent registries when registering in a child': function () {

assert.same(converterChild, c);
}).otherwise(fail);
})['catch'](fail);
},

@@ -83,3 +83,3 @@ 'should not have any side effects in a parent registry from a child': function () {

assert.same(converterParent, c);
}).otherwise(fail);
})['catch'](fail);
},

@@ -91,3 +91,3 @@ 'should ignore charset in mime resolution': function () {

assert.same(converter, c);
}).otherwise(fail);
})['catch'](fail);
},

@@ -99,3 +99,3 @@ 'should ignore suffix in mime resolution': function () {

assert.same(converter, c);
}).otherwise(fail);
})['catch'](fail);
},

@@ -107,3 +107,3 @@ 'should fallback to suffix if mime type is not resolved': function () {

assert.same(converter, c);
}).otherwise(fail);
})['catch'](fail);
},

@@ -110,0 +110,0 @@ 'should invoke the delegate mime converter': function () {

@@ -17,3 +17,3 @@ /*

define('rest/mime/type/application/hal-test', function (require) {
define('rest-test/mime/type/application/hal-test', function (require) {

@@ -50,3 +50,3 @@ var hal, mime, registry, halMime, supports;

assert.equals('{"foo":"bar"}', resource);
}).otherwise(fail);
})['catch'](fail);
},

@@ -56,3 +56,3 @@ 'should read json': function () {

assert.equals({ foo: 'bar' }, resource);
}).otherwise(fail);
})['catch'](fail);
},

@@ -64,3 +64,3 @@ 'should place embedded relationships on the host object': function () {

});
}).otherwise(fail);
})['catch'](fail);
},

@@ -70,3 +70,3 @@ 'should not overwrite a property on the host oject with an embedded relationship': function () {

assert.same(resource.prop, 'host');
}).otherwise(fail);
})['catch'](fail);
},

@@ -76,3 +76,3 @@ 'should place linked relationships on the host object': function () {

assert.isFunction(resource.prop.entity);
}).otherwise(fail);
})['catch'](fail);
},

@@ -82,3 +82,3 @@ 'should not overwrite a property on the host oject with a linked relationship': function () {

assert.same(resource.prop, 'host');
}).otherwise(fail);
})['catch'](fail);
},

@@ -97,3 +97,3 @@ 'should fetch a linked resource': function () {

});
}).otherwise(fail);
})['catch'](fail);
},

@@ -112,3 +112,3 @@ 'should fetch a templated linked resource': function () {

});
}).otherwise(fail);
})['catch'](fail);
},

@@ -121,3 +121,3 @@ 'should make a request for a relationship': function () {

});
}).otherwise(fail);
})['catch'](fail);
},

@@ -129,3 +129,3 @@ 'should get a client for a relationship': function () {

});
}).otherwise(fail);
})['catch'](fail);
},

@@ -138,3 +138,3 @@ 'should get a client for a templated relationship': function () {

});
}).otherwise(fail);
})['catch'](fail);
},

@@ -156,3 +156,3 @@ 'should safely warn when accessing a deprecated relationship': {

});
}).otherwise(fail);
})['catch'](fail);

@@ -172,3 +172,3 @@ },

});
}).otherwise(fail);
})['catch'](fail);
},

@@ -184,3 +184,3 @@ 'doing nothing if the console is unavailable': function () {

});
}).otherwise(fail);
})['catch'](fail);
}

@@ -187,0 +187,0 @@ },

@@ -16,3 +16,3 @@ /*

define('rest/mime/type/application/json-test', function (require) {
define('rest-test/mime/type/application/json-test', function (require) {

@@ -19,0 +19,0 @@ var json = require('rest/mime/type/application/json');

@@ -16,3 +16,3 @@ /*

define('rest/mime/type/application/x-www-form-urlencoded-test', function (require) {
define('rest-test/mime/type/application/x-www-form-urlencoded-test', function (require) {

@@ -19,0 +19,0 @@ var encodeder = require('rest/mime/type/application/x-www-form-urlencoded');

@@ -16,3 +16,3 @@ /*

define('rest/mime/type/multipart/form-data-test', function (require) {
define('rest-test/mime/type/multipart/form-data-test', function (require) {

@@ -22,3 +22,3 @@ var encoder = require('rest/mime/type/multipart/form-data');

buster.testCase('rest/mime/type/multipart/form-data', {
requiresSupportFor: { FormData: 'FormData' in window },
requiresSupportFor: { FormData: typeof FormData !== 'undefined' },
'should pass a FormData object through unmodified': function () {

@@ -25,0 +25,0 @@ var data = new FormData();

@@ -16,3 +16,3 @@ /*

define('rest/mime/type/text/plain-test', function (require) {
define('rest-test/mime/type/text/plain-test', function (require) {

@@ -19,0 +19,0 @@ var plain = require('rest/mime/type/text/plain');

@@ -18,3 +18,3 @@ /*

define('rest/node-test', function (require) {
define('rest-test/node-test', function (require) {

@@ -21,0 +21,0 @@ var rest, defaultClient, node;

@@ -11,10 +11,10 @@ /*

define('rest/test/run', ['curl/_privileged', 'domReady!'], function (curl) {
define('rest-test/test/run', ['curl/_privileged', 'domReady!'], function (curl) {
var modules = Object.keys(curl.cache).filter(function (moduleId) {
return moduleId.indexOf('-test') > 0;
return moduleId.match(/-test(-browser)?$/);
});
buster.testRunner.timeout = 5000;
define('rest/test/run-faux', modules, function () {
define('rest-test/test/run-faux', modules, function () {
buster.run();

@@ -21,0 +21,0 @@ });

@@ -16,3 +16,3 @@ /*

define('rest/UrlBuilder-test', function (require) {
define('rest-test/UrlBuilder-test', function (require) {

@@ -37,2 +37,5 @@ var UrlBuilder = require('rest/UrlBuilder');

},
'should add named param multiple times to query string if value is an array': function () {
assert.equals('/foo/bar?foo=bar&foo=baz', new UrlBuilder('/foo/bar', { foo: ['bar', 'baz'] }).build());
},
'should add unused params to an exsisting query string': function () {

@@ -42,3 +45,3 @@ assert.equals('/foo/bar?bleep=bloop', new UrlBuilder('/foo/{foo}', { foo: 'bar', bleep: 'bloop' }).build());

'should url encode all param names and values added to the url': function () {
assert.equals('/foo/bar?bl%25eep=bl%20oop', new UrlBuilder('/foo/bar', { 'bl%eep': 'bl oop' }).build());
assert.equals('/foo/bar?bl%25eep=bl+oop', new UrlBuilder('/foo/bar', { 'bl%eep': 'bl oop' }).build());
},

@@ -45,0 +48,0 @@ 'should return a built url for string concatination': function () {

@@ -16,3 +16,3 @@ /*

define('rest/util/base64-test', function (require) {
define('rest-test/util/base64-test', function (require) {

@@ -19,0 +19,0 @@ var base64 = require('rest/util/base64');

@@ -16,3 +16,3 @@ /*

define('rest/util/find-test', function (require) {
define('rest-test/util/find-test', function (require) {

@@ -19,0 +19,0 @@ var find = require('rest/util/find');

@@ -17,3 +17,3 @@ /*

define('rest/util/lazyPromise-test', function (require) {
define('rest-test/util/lazyPromise-test', function (require) {

@@ -20,0 +20,0 @@ var lazyPromise = require('rest/util/lazyPromise');

@@ -16,3 +16,3 @@ /*

define('rest/util/mixin-test', function (require) {
define('rest-test/util/mixin-test', function (require) {

@@ -19,0 +19,0 @@ var mixin = require('rest/util/mixin');

@@ -16,3 +16,3 @@ /*

define('rest/util/normalizeHeaderName-test', function (require) {
define('rest-test/util/normalizeHeaderName-test', function (require) {

@@ -19,0 +19,0 @@ var normalizeHeaderName = require('rest/util/normalizeHeaderName');

@@ -16,3 +16,3 @@ /*

define('rest/util/pubsub-test', function (require) {
define('rest-test/util/pubsub-test', function (require) {

@@ -19,0 +19,0 @@ var pubsub = require('rest/util/pubsub');

@@ -18,3 +18,3 @@ /*

define('rest/util/responsePromise-test', function (require) {
define('rest-test/util/responsePromise-test', function (require) {

@@ -47,3 +47,3 @@ var responsePromise, mime, when, client;

'should be an instance of Promise': function () {
assert(responsePromise() instanceof when.Promise);
assert(responsePromise() instanceof Promise);
},

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

@@ -16,3 +16,3 @@ /*

define('rest/util/uriTemplate-test', function (require) {
define('rest-test/util/uriTemplate-test', function (require) {

@@ -57,2 +57,7 @@ var uriTemplate, params;

assert.same(uriTemplate.expand('{&count*}', params), '&count=one&count=two&count=three');
assert.same(uriTemplate.expand('{?count*,who}', params), '?count=one&count=two&count=three&who=fred');
assert.same(uriTemplate.expand('{?who,count*}', params), '?who=fred&count=one&count=two&count=three');
assert.same(uriTemplate.expand('{?keys*,who}', params), '?semi=%3B&dot=.&comma=%2C&who=fred');
assert.same(uriTemplate.expand('{?who,keys*}', params), '?who=fred&semi=%3B&dot=.&comma=%2C');
},

@@ -59,0 +64,0 @@ '3.2.2. Simple String Expansion: {var}': function () {

@@ -16,3 +16,3 @@ /*

define('rest/version-test', function (require) {
define('rest-test/version-test', function (require) {

@@ -19,0 +19,0 @@ var bowerJson, packageJson;

@@ -18,3 +18,3 @@ /*

define('rest/wire-test', function (require) {
define('rest-test/wire-test', function (require) {

@@ -56,3 +56,3 @@ var rest, pathPrefixInterceptor, wire;

});
}).otherwise(fail);
})['catch'](fail);
},

@@ -89,3 +89,3 @@ 'with interceptor references': function () {

});
}).otherwise(fail);
})['catch'](fail);
},

@@ -110,3 +110,3 @@ 'with interceptor string shortcuts': function () {

assert.same(client, spec.client.skip().skip().skip());
}).otherwise(fail);
})['catch'](fail);
},

@@ -134,3 +134,3 @@ 'with concrete interceptors': function () {

});
}).otherwise(fail);
})['catch'](fail);
},

@@ -149,3 +149,3 @@ 'using the default client': function () {

assert.same(rest, spec.client.skip());
}).otherwise(fail);
})['catch'](fail);
},

@@ -171,3 +171,3 @@ 'using a referenced parent client': function () {

assert.same(client, spec.client.skip());
}).otherwise(fail);
})['catch'](fail);
},

@@ -198,3 +198,3 @@ 'wiring interceptor configurations': function () {

});
}).otherwise(fail);
})['catch'](fail);
}

@@ -201,0 +201,0 @@ }

/*
* Copyright 2012-2013 the original author or authors
* Copyright 2012-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,223 +8,210 @@ *

(function (define, location) {
'use strict';
'use strict';
var undef;
var mixin, xWWWFormURLEncoder, origin, urlRE, absoluteUrlRE, fullyQualifiedUrlRE;
define(function (require) {
mixin = require('./util/mixin');
xWWWFormURLEncoder = require('./mime/type/application/x-www-form-urlencoded');
var mixin, origin, urlRE, absoluteUrlRE, fullyQualifiedUrlRE;
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;
mixin = require('./util/mixin');
/**
* Apply params to the template to create a URL.
*
* Parameters that are not applied directly to the template, are appended
* to the URL as query string parameters.
*
* @param {string} template the URI template
* @param {Object} params parameters to apply to the template
* @return {string} the resulting URL
*/
function buildUrl(template, params) {
// internal builder to convert template with params.
var url, name, queryStringParams, queryString, re;
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;
url = template;
queryStringParams = {};
/**
* Apply params to the template to create a URL.
*
* Parameters that are not applied directly to the template, are appended
* to the URL as query string parameters.
*
* @param {string} template the URI template
* @param {Object} params parameters to apply to the template
* @return {string} the resulting URL
*/
function buildUrl(template, params) {
// internal builder to convert template with params.
var url, name, queryStringParams, re;
url = template;
queryStringParams = {};
if (params) {
for (name in params) {
/*jshint forin:false */
re = new RegExp('\\{' + name + '\\}');
if (re.test(url)) {
url = url.replace(re, encodeURIComponent(params[name]), 'g');
}
else {
queryStringParams[name] = params[name];
}
}
for (name in queryStringParams) {
url += url.indexOf('?') === -1 ? '?' : '&';
url += encodeURIComponent(name);
if (queryStringParams[name] !== null && queryStringParams[name] !== undefined) {
url += '=';
url += encodeURIComponent(queryStringParams[name]);
}
}
if (params) {
for (name in params) {
/*jshint forin:false */
re = new RegExp('\\{' + name + '\\}');
if (re.test(url)) {
url = url.replace(re, encodeURIComponent(params[name]), 'g');
}
return url;
else {
queryStringParams[name] = params[name];
}
}
function startsWith(str, test) {
return str.indexOf(test) === 0;
queryString = xWWWFormURLEncoder.write(queryStringParams);
if (queryString) {
url += url.indexOf('?') === -1 ? '?' : '&';
url += queryString;
}
}
return url;
}
/**
* Create a new URL Builder
*
* @param {string|UrlBuilder} template the base template to build from, may be another UrlBuilder
* @param {Object} [params] base parameters
* @constructor
*/
function UrlBuilder(template, params) {
if (!(this instanceof UrlBuilder)) {
// invoke as a constructor
return new UrlBuilder(template, params);
}
function startsWith(str, test) {
return str.indexOf(test) === 0;
}
if (template instanceof UrlBuilder) {
this._template = template.template;
this._params = mixin({}, this._params, params);
}
else {
this._template = (template || '').toString();
this._params = params || {};
}
}
/**
* Create a new URL Builder
*
* @param {string|UrlBuilder} template the base template to build from, may be another UrlBuilder
* @param {Object} [params] base parameters
* @constructor
*/
function UrlBuilder(template, params) {
if (!(this instanceof UrlBuilder)) {
// invoke as a constructor
return new UrlBuilder(template, params);
}
UrlBuilder.prototype = {
if (template instanceof UrlBuilder) {
this._template = template.template;
this._params = mixin({}, this._params, params);
}
else {
this._template = (template || '').toString();
this._params = params || {};
}
}
/**
* Create a new UrlBuilder instance that extends the current builder.
* The current builder is unmodified.
*
* @param {string} [template] URL template to append to the current template
* @param {Object} [params] params to combine with current params. New params override existing params
* @return {UrlBuilder} the new builder
*/
append: function (template, params) {
// TODO consider query strings and fragments
return new UrlBuilder(this._template + template, mixin({}, this._params, params));
},
UrlBuilder.prototype = {
/**
* Create a new UrlBuilder with a fully qualified URL based on the
* window's location or base href and the current templates relative URL.
*
* Path variables are preserved.
*
* *Browser only*
*
* @return {UrlBuilder} the fully qualified URL template
*/
fullyQualify: function () {
if (!location) { return this; }
if (this.isFullyQualified()) { return this; }
/**
* Create a new UrlBuilder instance that extends the current builder.
* The current builder is unmodified.
*
* @param {string} [template] URL template to append to the current template
* @param {Object} [params] params to combine with current params. New params override existing params
* @return {UrlBuilder} the new builder
*/
append: function (template, params) {
// TODO consider query strings and fragments
return new UrlBuilder(this._template + template, mixin({}, this._params, params));
},
var template = this._template;
/**
* Create a new UrlBuilder with a fully qualified URL based on the
* window's location or base href and the current templates relative URL.
*
* Path variables are preserved.
*
* *Browser only*
*
* @return {UrlBuilder} the fully qualified URL template
*/
fullyQualify: function () {
if (typeof location === 'undefined') { return this; }
if (this.isFullyQualified()) { return this; }
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);
}
var template = this._template;
if (template.indexOf('/', 8) === -1) {
// default the pathname to '/'
template = template + '/';
}
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);
}
return new UrlBuilder(template, this._params);
},
if (template.indexOf('/', 8) === -1) {
// default the pathname to '/'
template = template + '/';
}
/**
* True if the URL is absolute
*
* @return {boolean}
*/
isAbsolute: function () {
return absoluteUrlRE.test(this.build());
},
return new UrlBuilder(template, this._params);
},
/**
* True if the URL is fully qualified
*
* @return {boolean}
*/
isFullyQualified: function () {
return fullyQualifiedUrlRE.test(this.build());
},
/**
* True if the URL is absolute
*
* @return {boolean}
*/
isAbsolute: function () {
return absoluteUrlRE.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;
},
/**
* True if the URL is fully qualified
*
* @return {boolean}
*/
isFullyQualified: function () {
return fullyQualifiedUrlRE.test(this.build());
},
/**
* 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 () {
/*jshint maxcomplexity:20 */
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;
},
/**
* 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;
},
/**
* Expand the template replacing path variables with parameters
*
* @param {Object} [params] params to combine with current params. New params override existing params
* @return {string} the expanded URL
*/
build: function (params) {
return buildUrl(this._template, mixin({}, this._params, params));
},
/**
* 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 () {
/*jshint maxcomplexity:20 */
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;
},
/**
* @see build
*/
toString: function () {
return this.build();
}
/**
* Expand the template replacing path variables with parameters
*
* @param {Object} [params] params to combine with current params. New params override existing params
* @return {string} the expanded URL
*/
build: function (params) {
return buildUrl(this._template, mixin({}, this._params, params));
},
};
/**
* @see build
*/
toString: function () {
return this.build();
}
origin = location ? new UrlBuilder(location.href).parts() : undef;
};
return UrlBuilder;
});
origin = typeof location !== 'undefined' ? new UrlBuilder(location.href).parts() : void 0;
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); },
typeof window !== 'undefined' ? window.location : void 0
// Boilerplate for AMD and Node
));
module.exports = UrlBuilder;

@@ -27,130 +27,121 @@ /*

*
* Converted to AMD and linter refinement by Scott Andrews
* Linter refinement by Scott Andrews
*/
(function (define) {
'use strict';
'use strict';
/*jshint bitwise: false */
define(function (/* require */) {
/*jshint bitwise: false */
var digits = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
var digits = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
/**
* Base64-encodes a string of text.
*
* @param {string} text The text to encode.
* @return {string} The base64-encoded string.
*/
function base64Encode(text) {
/**
* Base64-encodes a string of text.
*
* @param {string} text The text to encode.
* @return {string} The base64-encoded string.
*/
function base64Encode(text) {
if (/([^\u0000-\u00ff])/.test(text)) {
throw new Error('Can\'t base64 encode non-ASCII characters.');
}
if (/([^\u0000-\u00ff])/.test(text)) {
throw new Error('Can\'t base64 encode non-ASCII characters.');
}
var i = 0,
cur, prev, byteNum,
result = [];
var i = 0,
cur, prev, byteNum,
result = [];
while (i < text.length) {
while (i < text.length) {
cur = text.charCodeAt(i);
byteNum = i % 3;
cur = text.charCodeAt(i);
byteNum = i % 3;
switch (byteNum) {
case 0: //first byte
result.push(digits.charAt(cur >> 2));
break;
switch (byteNum) {
case 0: //first byte
result.push(digits.charAt(cur >> 2));
break;
case 1: //second byte
result.push(digits.charAt((prev & 3) << 4 | (cur >> 4)));
break;
case 1: //second byte
result.push(digits.charAt((prev & 3) << 4 | (cur >> 4)));
break;
case 2: //third byte
result.push(digits.charAt((prev & 0x0f) << 2 | (cur >> 6)));
result.push(digits.charAt(cur & 0x3f));
break;
}
prev = cur;
i += 1;
}
if (byteNum === 0) {
result.push(digits.charAt((prev & 3) << 4));
result.push('==');
} else if (byteNum === 1) {
result.push(digits.charAt((prev & 0x0f) << 2));
result.push('=');
}
return result.join('');
case 2: //third byte
result.push(digits.charAt((prev & 0x0f) << 2 | (cur >> 6)));
result.push(digits.charAt(cur & 0x3f));
break;
}
/**
* Base64-decodes a string of text.
*
* @param {string} text The text to decode.
* @return {string} The base64-decoded string.
*/
function base64Decode(text) {
prev = cur;
i += 1;
}
//ignore white space
text = text.replace(/\s/g, '');
if (byteNum === 0) {
result.push(digits.charAt((prev & 3) << 4));
result.push('==');
} else if (byteNum === 1) {
result.push(digits.charAt((prev & 0x0f) << 2));
result.push('=');
}
//first check for any unexpected input
if (!(/^[a-z0-9\+\/\s]+\={0,2}$/i.test(text)) || text.length % 4 > 0) {
throw new Error('Not a base64-encoded string.');
}
return result.join('');
}
//local variables
var cur, prev, digitNum,
i = 0,
result = [];
/**
* Base64-decodes a string of text.
*
* @param {string} text The text to decode.
* @return {string} The base64-decoded string.
*/
function base64Decode(text) {
//remove any equals signs
text = text.replace(/\=/g, '');
//ignore white space
text = text.replace(/\s/g, '');
//loop over each character
while (i < text.length) {
//first check for any unexpected input
if (!(/^[a-z0-9\+\/\s]+\={0,2}$/i.test(text)) || text.length % 4 > 0) {
throw new Error('Not a base64-encoded string.');
}
cur = digits.indexOf(text.charAt(i));
digitNum = i % 4;
//local variables
var cur, prev, digitNum,
i = 0,
result = [];
switch (digitNum) {
//remove any equals signs
text = text.replace(/\=/g, '');
//case 0: first digit - do nothing, not enough info to work with
//loop over each character
while (i < text.length) {
case 1: //second digit
result.push(String.fromCharCode(prev << 2 | cur >> 4));
break;
cur = digits.indexOf(text.charAt(i));
digitNum = i % 4;
case 2: //third digit
result.push(String.fromCharCode((prev & 0x0f) << 4 | cur >> 2));
break;
switch (digitNum) {
case 3: //fourth digit
result.push(String.fromCharCode((prev & 3) << 6 | cur));
break;
}
//case 0: first digit - do nothing, not enough info to work with
prev = cur;
i += 1;
}
case 1: //second digit
result.push(String.fromCharCode(prev << 2 | cur >> 4));
break;
//return a string
return result.join('');
case 2: //third digit
result.push(String.fromCharCode((prev & 0x0f) << 4 | cur >> 2));
break;
case 3: //fourth digit
result.push(String.fromCharCode((prev & 3) << 6 | cur));
break;
}
return {
encode: base64Encode,
decode: base64Decode
};
prev = cur;
i += 1;
}
});
//return a string
return result.join('');
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
}
module.exports = {
encode: base64Encode,
decode: base64Decode
};
/*
* Copyright 2013 the original author or authors
* Copyright 2013-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,35 +8,25 @@ *

(function (define) {
'use strict';
'use strict';
define(function (/* require */) {
module.exports = {
return {
/**
* Find objects within a graph the contain a property of a certain name.
*
* NOTE: this method will not discover object graph cycles.
*
* @param {*} obj object to search on
* @param {string} prop name of the property to search for
* @param {Function} callback function to receive the found properties and their parent
*/
findProperties: function findProperties(obj, prop, callback) {
if (typeof obj !== 'object' || obj === null) { return; }
if (prop in obj) {
callback(obj[prop], obj, prop);
}
Object.keys(obj).forEach(function (key) {
findProperties(obj[key], prop, callback);
});
}
/**
* Find objects within a graph the contain a property of a certain name.
*
* NOTE: this method will not discover object graph cycles.
*
* @param {*} obj object to search on
* @param {string} prop name of the property to search for
* @param {Function} callback function to receive the found properties and their parent
*/
findProperties: function findProperties(obj, prop, callback) {
if (typeof obj !== 'object' || obj === null) { return; }
if (prop in obj) {
callback(obj[prop], obj, prop);
}
Object.keys(obj).forEach(function (key) {
findProperties(obj[key], prop, callback);
});
}
};
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
};
/*
* Copyright 2013 the original author or authors
* Copyright 2013-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,49 +8,40 @@ *

(function (define) {
'use strict';
'use strict';
define(function (require) {
var attempt = require('./attempt');
var when;
/**
* Create a promise whose work is started only when a handler is registered.
*
* The work function will be invoked at most once. Thrown values will result
* in promise rejection.
*
* @param {Function} work function whose ouput is used to resolve the
* returned promise.
* @returns {Promise} a lazy promise
*/
function lazyPromise(work) {
var started, resolver, promise, then;
when = require('when');
started = false;
/**
* Create a promise whose work is started only when a handler is registered.
*
* The work function will be invoked at most once. Thrown values will result
* in promise rejection.
*
* @param {Function} work function whose ouput is used to resolve the
* returned promise.
* @returns {Promise} a lazy promise
*/
function lazyPromise(work) {
var defer, started, resolver, promise, then;
promise = new Promise(function (resolve, reject) {
resolver = {
resolve: resolve,
reject: reject
};
});
then = promise.then;
defer = when.defer();
started = false;
resolver = defer.resolver;
promise = defer.promise;
then = promise.then;
promise.then = function () {
if (!started) {
started = true;
when.attempt(work).then(resolver.resolve, resolver.reject);
}
return then.apply(promise, arguments);
};
return promise;
promise.then = function () {
if (!started) {
started = true;
attempt(work).then(resolver.resolve, resolver.reject);
}
return then.apply(promise, arguments);
};
return lazyPromise;
return promise;
}
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
module.exports = lazyPromise;
/*
* Copyright 2012-2013 the original author or authors
* Copyright 2012-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,42 +8,31 @@ *

(function (define) {
'use strict';
'use strict';
// derived from dojo.mixin
define(function (/* require */) {
var empty = {};
var empty = {};
/**
* 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.
*
* @param {Object} dest the object to copy properties to
* @param {Object} sources the objects to copy properties from. May be 1 to N arguments, but not an Array.
* @return {Object} the destination object
*/
function mixin(dest /*, sources... */) {
var i, l, source, name;
/**
* 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.
*
* @param {Object} dest the object to copy properties to
* @param {Object} sources the objects to copy properties from. May be 1 to N arguments, but not an Array.
* @return {Object} the destination object
*/
function mixin(dest /*, sources... */) {
var i, l, source, name;
if (!dest) { dest = {}; }
for (i = 1, l = arguments.length; i < l; i += 1) {
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];
}
}
if (!dest) { dest = {}; }
for (i = 1, l = arguments.length; i < l; i += 1) {
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];
}
return dest; // Object
}
}
return mixin;
return dest; // Object
}
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
module.exports = mixin;
/*
* Copyright 2012 the original author or authors
* Copyright 2012-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,32 +8,22 @@ *

(function (define) {
'use strict';
'use strict';
define(function (/* require */) {
/**
* Normalize HTTP header names using the pseudo camel case.
*
* For example:
* content-type -> Content-Type
* accepts -> Accepts
* x-custom-header-name -> X-Custom-Header-Name
*
* @param {string} name the raw header name
* @return {string} the normalized header name
*/
function normalizeHeaderName(name) {
return name.toLowerCase()
.split('-')
.map(function (chunk) { return chunk.charAt(0).toUpperCase() + chunk.slice(1); })
.join('-');
}
/**
* Normalize HTTP header names using the pseudo camel case.
*
* For example:
* content-type -> Content-Type
* accepts -> Accepts
* x-custom-header-name -> X-Custom-Header-Name
*
* @param {string} name the raw header name
* @return {string} the normalized header name
*/
function normalizeHeaderName(name) {
return name.toLowerCase()
.split('-')
.map(function (chunk) { return chunk.charAt(0).toUpperCase() + chunk.slice(1); })
.join('-');
}
return normalizeHeaderName;
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
module.exports = normalizeHeaderName;
/*
* Copyright 2012 the original author or authors
* Copyright 2012-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,49 +8,39 @@ *

(function (define) {
'use strict';
'use strict';
define(function (/* require */) {
// A poor man's pub-sub. A single listener is supported per topic. When
// the topic is published, the listener is unsubscribed.
// A poor man's pub-sub. A single listener is supported per topic. When
// the topic is published, the listener is unsubscribed.
var topics = {};
var topics = {};
/**
* Publishes the message to the topic, invoking the listener.
*
* The listener is unsubscribed from the topic after receiving a message.
*
* @param {string} topic the topic to publish to
* @param {Object} message message to publish
*/
function publish(topic /* , message... */) {
if (!topics[topic]) { return; }
topics[topic].apply({}, Array.prototype.slice.call(arguments, 1));
// auto cleanup
delete topics[topic];
}
/**
* Publishes the message to the topic, invoking the listener.
*
* The listener is unsubscribed from the topic after receiving a message.
*
* @param {string} topic the topic to publish to
* @param {Object} message message to publish
*/
function publish(topic /* , message... */) {
if (!topics[topic]) { return; }
topics[topic].apply({}, Array.prototype.slice.call(arguments, 1));
// auto cleanup
delete topics[topic];
}
/**
* Register a callback function to receive notification of a message published to the topic.
*
* Any existing callback for the topic will be unsubscribed.
*
* @param {string} topic the topic to listen on
* @param {Function} callback the callback to receive the message published to the topic
*/
function subscribe(topic, callback) {
topics[topic] = callback;
}
/**
* Register a callback function to receive notification of a message published to the topic.
*
* Any existing callback for the topic will be unsubscribed.
*
* @param {string} topic the topic to listen on
* @param {Function} callback the callback to receive the message published to the topic
*/
function subscribe(topic, callback) {
topics[topic] = callback;
}
return {
publish: publish,
subscribe: subscribe
};
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
module.exports = {
publish: publish,
subscribe: subscribe
};
/*
* Copyright 2014-2015 the original author or authors
* Copyright 2014-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,134 +8,128 @@ *

(function (define) {
'use strict';
'use strict';
define(function (require) {
/*jshint latedef: nofunc */
var when = require('when'),
normalizeHeaderName = require('./normalizeHeaderName');
var normalizeHeaderName = require('./normalizeHeaderName');
function property(promise, name) {
return promise.then(
function (value) {
return value && value[name];
},
function (value) {
return when.reject(value && value[name]);
}
);
function property(promise, name) {
return promise.then(
function (value) {
return value && value[name];
},
function (value) {
return Promise.reject(value && value[name]);
}
);
}
/**
* Obtain the response entity
*
* @returns {Promise} for the response entity
*/
function entity() {
/*jshint validthis:true */
return property(this, 'entity');
}
/**
* Obtain the response entity
*
* @returns {Promise} for the response entity
*/
function entity() {
/*jshint validthis:true */
return property(this, 'entity');
}
/**
* Obtain the response status
*
* @returns {Promise} for the response status
*/
function status() {
/*jshint validthis:true */
return property(property(this, 'status'), 'code');
}
/**
* Obtain the response status
*
* @returns {Promise} for the response status
*/
function status() {
/*jshint validthis:true */
return property(property(this, 'status'), 'code');
}
/**
* Obtain the response headers map
*
* @returns {Promise} for the response headers map
*/
function headers() {
/*jshint validthis:true */
return property(this, 'headers');
}
/**
* Obtain the response headers map
*
* @returns {Promise} for the response headers map
*/
function headers() {
/*jshint validthis:true */
return property(this, 'headers');
}
/**
* Obtain a specific response header
*
* @param {String} headerName the header to retrieve
* @returns {Promise} for the response header's value
*/
function header(headerName) {
/*jshint validthis:true */
headerName = normalizeHeaderName(headerName);
return property(this.headers(), headerName);
}
/**
* Obtain a specific response header
*
* @param {String} headerName the header to retrieve
* @returns {Promise} for the response header's value
*/
function header(headerName) {
/*jshint validthis:true */
headerName = normalizeHeaderName(headerName);
return property(this.headers(), headerName);
}
/**
* Follow a related resource
*
* The relationship to follow may be define as a plain string, an object
* with the rel and params, or an array containing one or more entries
* with the previous forms.
*
* Examples:
* response.follow('next')
*
* response.follow({ rel: 'next', params: { pageSize: 100 } })
*
* response.follow([
* { rel: 'items', params: { projection: 'noImages' } },
* 'search',
* { rel: 'findByGalleryIsNull', params: { projection: 'noImages' } },
* 'items'
* ])
*
* @param {String|Object|Array} rels one, or more, relationships to follow
* @returns ResponsePromise<Response> related resource
*/
function follow(rels) {
/*jshint validthis:true */
rels = [].concat(rels);
return make(when.reduce(rels, function (response, rel) {
if (typeof rel === 'string') {
rel = { rel: rel };
}
if (typeof response.entity.clientFor !== 'function') {
throw new Error('Hypermedia response expected');
}
var client = response.entity.clientFor(rel.rel);
return client({ params: rel.params });
}, this));
}
/**
* Follow a related resource
*
* The relationship to follow may be define as a plain string, an object
* with the rel and params, or an array containing one or more entries
* with the previous forms.
*
* Examples:
* response.follow('next')
*
* response.follow({ rel: 'next', params: { pageSize: 100 } })
*
* response.follow([
* { rel: 'items', params: { projection: 'noImages' } },
* 'search',
* { rel: 'findByGalleryIsNull', params: { projection: 'noImages' } },
* 'items'
* ])
*
* @param {String|Object|Array} rels one, or more, relationships to follow
* @returns ResponsePromise<Response> related resource
*/
function follow(rels) {
/*jshint validthis:true */
rels = [].concat(rels);
/**
* Wrap a Promise as an ResponsePromise
*
* @param {Promise<Response>} promise the promise for an HTTP Response
* @returns {ResponsePromise<Response>} wrapped promise for Response with additional helper methods
*/
function make(promise) {
promise.status = status;
promise.headers = headers;
promise.header = header;
promise.entity = entity;
promise.follow = follow;
return promise;
}
return make(rels.reduce(function (response, rel) {
return response.then(function (response) {
if (typeof rel === 'string') {
rel = { rel: rel };
}
if (typeof response.entity.clientFor !== 'function') {
throw new Error('Hypermedia response expected');
}
var client = response.entity.clientFor(rel.rel);
return client({ params: rel.params });
});
}, this));
}
function responsePromise() {
return make(when.apply(when, arguments));
}
/**
* Wrap a Promise as an ResponsePromise
*
* @param {Promise<Response>} promise the promise for an HTTP Response
* @returns {ResponsePromise<Response>} wrapped promise for Response with additional helper methods
*/
function make(promise) {
promise.status = status;
promise.headers = headers;
promise.header = header;
promise.entity = entity;
promise.follow = follow;
return promise;
}
responsePromise.make = make;
responsePromise.reject = function (val) {
return make(when.reject(val));
};
responsePromise.promise = function (func) {
return make(when.promise(func));
};
function responsePromise(obj, callback, errback) {
return make(Promise.resolve(obj).then(callback, errback));
}
return responsePromise;
responsePromise.make = make;
responsePromise.reject = function (val) {
return make(Promise.reject(val));
};
responsePromise.promise = function (func) {
return make(new Promise(func));
};
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
module.exports = responsePromise;
/*
* Copyright 2015 the original author or authors
* Copyright 2015-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,174 +8,164 @@ *

(function (define) {
'use strict';
'use strict';
define(function (/* require */) {
var charMap;
var charMap;
charMap = (function () {
var strings = {
alpha: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
digit: '0123456789'
};
charMap = (function () {
var strings = {
alpha: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
digit: '0123456789'
};
strings.genDelims = ':/?#[]@';
strings.subDelims = '!$&\'()*+,;=';
strings.reserved = strings.genDelims + strings.subDelims;
strings.unreserved = strings.alpha + strings.digit + '-._~';
strings.url = strings.reserved + strings.unreserved;
strings.scheme = strings.alpha + strings.digit + '+-.';
strings.userinfo = strings.unreserved + strings.subDelims + ':';
strings.host = strings.unreserved + strings.subDelims;
strings.port = strings.digit;
strings.pchar = strings.unreserved + strings.subDelims + ':@';
strings.segment = strings.pchar;
strings.path = strings.segment + '/';
strings.query = strings.pchar + '/?';
strings.fragment = strings.pchar + '/?';
strings.genDelims = ':/?#[]@';
strings.subDelims = '!$&\'()*+,;=';
strings.reserved = strings.genDelims + strings.subDelims;
strings.unreserved = strings.alpha + strings.digit + '-._~';
strings.url = strings.reserved + strings.unreserved;
strings.scheme = strings.alpha + strings.digit + '+-.';
strings.userinfo = strings.unreserved + strings.subDelims + ':';
strings.host = strings.unreserved + strings.subDelims;
strings.port = strings.digit;
strings.pchar = strings.unreserved + strings.subDelims + ':@';
strings.segment = strings.pchar;
strings.path = strings.segment + '/';
strings.query = strings.pchar + '/?';
strings.fragment = strings.pchar + '/?';
return Object.keys(strings).reduce(function (charMap, set) {
charMap[set] = strings[set].split('').reduce(function (chars, myChar) {
chars[myChar] = true;
return chars;
}, {});
return charMap;
}, {});
}());
return Object.keys(strings).reduce(function (charMap, set) {
charMap[set] = strings[set].split('').reduce(function (chars, myChar) {
chars[myChar] = true;
return chars;
}, {});
return charMap;
}, {});
}());
function encode(str, allowed) {
if (typeof str !== 'string') {
throw new Error('String required for URL encoding');
}
return str.split('').map(function (myChar) {
if (allowed.hasOwnProperty(myChar)) {
return myChar;
}
var code = myChar.charCodeAt(0);
if (code <= 127) {
var encoded = code.toString(16).toUpperCase();
return '%' + (encoded.length % 2 === 1 ? '0' : '') + encoded;
}
else {
return encodeURIComponent(myChar).toUpperCase();
}
}).join('');
function encode(str, allowed) {
if (typeof str !== 'string') {
throw new Error('String required for URL encoding');
}
return str.split('').map(function (myChar) {
if (allowed.hasOwnProperty(myChar)) {
return myChar;
}
function makeEncoder(allowed) {
allowed = allowed || charMap.unreserved;
return function (str) {
return encode(str, allowed);
};
var code = myChar.charCodeAt(0);
if (code <= 127) {
var encoded = code.toString(16).toUpperCase();
return '%' + (encoded.length % 2 === 1 ? '0' : '') + encoded;
}
function decode(str) {
return decodeURIComponent(str);
else {
return encodeURIComponent(myChar).toUpperCase();
}
}).join('');
}
return {
function makeEncoder(allowed) {
allowed = allowed || charMap.unreserved;
return function (str) {
return encode(str, allowed);
};
}
/*
* Decode URL encoded strings
*
* @param {string} URL encoded string
* @returns {string} URL decoded string
*/
decode: decode,
function decode(str) {
return decodeURIComponent(str);
}
/*
* URL encode a string
*
* All but alpha-numerics and a very limited set of punctuation - . _ ~ are
* encoded.
*
* @param {string} string to encode
* @returns {string} URL encoded string
*/
encode: makeEncoder(),
module.exports = {
/*
* URL encode a URL
*
* All character permitted anywhere in a URL are left unencoded even
* if that character is not permitted in that portion of a URL.
*
* Note: This method is typically not what you want.
*
* @param {string} string to encode
* @returns {string} URL encoded string
*/
encodeURL: makeEncoder(charMap.url),
/*
* Decode URL encoded strings
*
* @param {string} URL encoded string
* @returns {string} URL decoded string
*/
decode: decode,
/*
* URL encode the scheme portion of a URL
*
* @param {string} string to encode
* @returns {string} URL encoded string
*/
encodeScheme: makeEncoder(charMap.scheme),
/*
* URL encode a string
*
* All but alpha-numerics and a very limited set of punctuation - . _ ~ are
* encoded.
*
* @param {string} string to encode
* @returns {string} URL encoded string
*/
encode: makeEncoder(),
/*
* URL encode the user info portion of a URL
*
* @param {string} string to encode
* @returns {string} URL encoded string
*/
encodeUserInfo: makeEncoder(charMap.userinfo),
/*
* URL encode a URL
*
* All character permitted anywhere in a URL are left unencoded even
* if that character is not permitted in that portion of a URL.
*
* Note: This method is typically not what you want.
*
* @param {string} string to encode
* @returns {string} URL encoded string
*/
encodeURL: makeEncoder(charMap.url),
/*
* URL encode the host portion of a URL
*
* @param {string} string to encode
* @returns {string} URL encoded string
*/
encodeHost: makeEncoder(charMap.host),
/*
* URL encode the scheme portion of a URL
*
* @param {string} string to encode
* @returns {string} URL encoded string
*/
encodeScheme: makeEncoder(charMap.scheme),
/*
* URL encode the port portion of a URL
*
* @param {string} string to encode
* @returns {string} URL encoded string
*/
encodePort: makeEncoder(charMap.port),
/*
* URL encode the user info portion of a URL
*
* @param {string} string to encode
* @returns {string} URL encoded string
*/
encodeUserInfo: makeEncoder(charMap.userinfo),
/*
* URL encode a path segment portion of a URL
*
* @param {string} string to encode
* @returns {string} URL encoded string
*/
encodePathSegment: makeEncoder(charMap.segment),
/*
* URL encode the host portion of a URL
*
* @param {string} string to encode
* @returns {string} URL encoded string
*/
encodeHost: makeEncoder(charMap.host),
/*
* URL encode the path portion of a URL
*
* @param {string} string to encode
* @returns {string} URL encoded string
*/
encodePath: makeEncoder(charMap.path),
/*
* URL encode the port portion of a URL
*
* @param {string} string to encode
* @returns {string} URL encoded string
*/
encodePort: makeEncoder(charMap.port),
/*
* URL encode the query portion of a URL
*
* @param {string} string to encode
* @returns {string} URL encoded string
*/
encodeQuery: makeEncoder(charMap.query),
/*
* URL encode a path segment portion of a URL
*
* @param {string} string to encode
* @returns {string} URL encoded string
*/
encodePathSegment: makeEncoder(charMap.segment),
/*
* URL encode the fragment portion of a URL
*
* @param {string} string to encode
* @returns {string} URL encoded string
*/
encodeFragment: makeEncoder(charMap.fragment)
/*
* URL encode the path portion of a URL
*
* @param {string} string to encode
* @returns {string} URL encoded string
*/
encodePath: makeEncoder(charMap.path),
};
/*
* URL encode the query portion of a URL
*
* @param {string} string to encode
* @returns {string} URL encoded string
*/
encodeQuery: makeEncoder(charMap.query),
});
/*
* URL encode the fragment portion of a URL
*
* @param {string} string to encode
* @returns {string} URL encoded string
*/
encodeFragment: makeEncoder(charMap.fragment)
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
};
/*
* Copyright 2015 the original author or authors
* Copyright 2015-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,96 +8,58 @@ *

(function (define) {
'use strict';
'use strict';
var undef;
var uriEncoder, operations, prefixRE;
define(function (require) {
uriEncoder = require('./uriEncoder');
var uriEncoder, operations, prefixRE;
prefixRE = /^([^:]*):([0-9]+)$/;
operations = {
'': { first: '', separator: ',', named: false, empty: '', encoder: uriEncoder.encode },
'+': { first: '', separator: ',', named: false, empty: '', encoder: uriEncoder.encodeURL },
'#': { first: '#', separator: ',', named: false, empty: '', encoder: uriEncoder.encodeURL },
'.': { first: '.', separator: '.', named: false, empty: '', encoder: uriEncoder.encode },
'/': { first: '/', separator: '/', named: false, empty: '', encoder: uriEncoder.encode },
';': { first: ';', separator: ';', named: true, empty: '', encoder: uriEncoder.encode },
'?': { first: '?', separator: '&', named: true, empty: '=', encoder: uriEncoder.encode },
'&': { first: '&', separator: '&', named: true, empty: '=', encoder: uriEncoder.encode },
'=': { reserved: true },
',': { reserved: true },
'!': { reserved: true },
'@': { reserved: true },
'|': { reserved: true }
};
uriEncoder = require('./uriEncoder');
function apply(operation, expression, params) {
/*jshint maxcomplexity:11 */
return expression.split(',').reduce(function (result, variable) {
var opts, value;
prefixRE = /^([^:]*):([0-9]+)$/;
operations = {
'': { first: '', separator: ',', named: false, empty: '', encoder: uriEncoder.encode },
'+': { first: '', separator: ',', named: false, empty: '', encoder: uriEncoder.encodeURL },
'#': { first: '#', separator: ',', named: false, empty: '', encoder: uriEncoder.encodeURL },
'.': { first: '.', separator: '.', named: false, empty: '', encoder: uriEncoder.encode },
'/': { first: '/', separator: '/', named: false, empty: '', encoder: uriEncoder.encode },
';': { first: ';', separator: ';', named: true, empty: '', encoder: uriEncoder.encode },
'?': { first: '?', separator: '&', named: true, empty: '=', encoder: uriEncoder.encode },
'&': { first: '&', separator: '&', named: true, empty: '=', encoder: uriEncoder.encode },
'=': { reserved: true },
',': { reserved: true },
'!': { reserved: true },
'@': { reserved: true },
'|': { reserved: true }
};
opts = {};
if (variable.slice(-1) === '*') {
variable = variable.slice(0, -1);
opts.explode = true;
}
if (prefixRE.test(variable)) {
var prefix = prefixRE.exec(variable);
variable = prefix[1];
opts.maxLength = parseInt(prefix[2]);
}
function apply(operation, expression, params) {
/*jshint maxcomplexity:11 */
return expression.split(',').reduce(function (result, variable) {
var opts, value;
variable = uriEncoder.decode(variable);
value = params[variable];
opts = {};
if (variable.slice(-1) === '*') {
variable = variable.slice(0, -1);
opts.explode = true;
if (value === void 0 || value === null) {
return result;
}
if (Array.isArray(value)) {
result = value.reduce(function (result, value) {
if (result.length) {
result += opts.explode ? operation.separator : ',';
if (operation.named && opts.explode) {
result += operation.encoder(variable);
result += value.length ? '=' : operation.empty;
}
}
if (prefixRE.test(variable)) {
var prefix = prefixRE.exec(variable);
variable = prefix[1];
opts.maxLength = parseInt(prefix[2]);
}
variable = uriEncoder.decode(variable);
value = params[variable];
if (value === undef || value === null) {
return result;
}
if (Array.isArray(value)) {
result += value.reduce(function (result, value) {
if (result.length) {
result += opts.explode ? operation.separator : ',';
if (operation.named && opts.explode) {
result += operation.encoder(variable);
result += value.length ? '=' : operation.empty;
}
}
else {
result += operation.first;
if (operation.named) {
result += operation.encoder(variable);
result += value.length ? '=' : operation.empty;
}
}
result += operation.encoder(value);
return result;
}, '');
}
else if (typeof value === 'object') {
result += Object.keys(value).reduce(function (result, name) {
if (result.length) {
result += opts.explode ? operation.separator : ',';
}
else {
result += operation.first;
if (operation.named && !opts.explode) {
result += operation.encoder(variable);
result += value[name].length ? '=' : operation.empty;
}
}
result += operation.encoder(name);
result += opts.explode ? '=' : ',';
result += operation.encoder(value[name]);
return result;
}, '');
}
else {
value = String(value);
if (opts.maxLength) {
value = value.slice(0, opts.maxLength);
}
result += result.length ? operation.separator : operation.first;
result += operation.first;
if (operation.named) {

@@ -107,68 +69,94 @@ result += operation.encoder(variable);

}
result += operation.encoder(value);
}
result += operation.encoder(value);
return result;
}, '');
}, result);
}
function expandExpression(expression, params) {
var operation;
operation = operations[expression.slice(0,1)];
if (operation) {
expression = expression.slice(1);
else if (typeof value === 'object') {
result = Object.keys(value).reduce(function (result, name) {
if (result.length) {
result += opts.explode ? operation.separator : ',';
}
else {
result += operation.first;
if (operation.named && !opts.explode) {
result += operation.encoder(variable);
result += value[name].length ? '=' : operation.empty;
}
}
result += operation.encoder(name);
result += opts.explode ? '=' : ',';
result += operation.encoder(value[name]);
return result;
}, result);
}
else {
value = String(value);
if (opts.maxLength) {
value = value.slice(0, opts.maxLength);
}
else {
operation = operations[''];
result += result.length ? operation.separator : operation.first;
if (operation.named) {
result += operation.encoder(variable);
result += value.length ? '=' : operation.empty;
}
result += operation.encoder(value);
}
if (operation.reserved) {
throw new Error('Reserved expression operations are not supported');
}
return result;
}, '');
}
return apply(operation, expression, params);
}
function expandExpression(expression, params) {
var operation;
function expandTemplate(template, params) {
var start, end, uri;
operation = operations[expression.slice(0,1)];
if (operation) {
expression = expression.slice(1);
}
else {
operation = operations[''];
}
uri = '';
end = 0;
while (true) {
start = template.indexOf('{', end);
if (start === -1) {
// no more expressions
uri += template.slice(end);
break;
}
uri += template.slice(end, start);
end = template.indexOf('}', start) + 1;
uri += expandExpression(template.slice(start + 1, end - 1), params);
}
if (operation.reserved) {
throw new Error('Reserved expression operations are not supported');
}
return uri;
return apply(operation, expression, params);
}
function expandTemplate(template, params) {
var start, end, uri;
uri = '';
end = 0;
while (true) {
start = template.indexOf('{', end);
if (start === -1) {
// no more expressions
uri += template.slice(end);
break;
}
uri += template.slice(end, start);
end = template.indexOf('}', start) + 1;
uri += expandExpression(template.slice(start + 1, end - 1), params);
}
return {
return uri;
}
/**
* Expand a URI Template with parameters to form a URI.
*
* Full implementation (level 4) of rfc6570.
* @see https://tools.ietf.org/html/rfc6570
*
* @param {string} template URI template
* @param {Object} [params] params to apply to the template durring expantion
* @returns {string} expanded URI
*/
expand: expandTemplate
module.exports = {
};
/**
* Expand a URI Template with parameters to form a URI.
*
* Full implementation (level 4) of rfc6570.
* @see https://tools.ietf.org/html/rfc6570
*
* @param {string} template URI template
* @param {Object} [params] params to apply to the template durring expantion
* @returns {string} expanded URI
*/
expand: expandTemplate
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
};
/*
* Copyright 2012-2015 the original author or authors
* Copyright 2012-2016 the original author or authors
* @license MIT, see LICENSE.txt for details

@@ -8,75 +8,65 @@ *

(function (define) {
'use strict';
'use strict';
define(function (require) {
var client, when, pipeline, plugin;
var client, when, pipeline, plugin;
client = require('./client/default');
when = require('when');
pipeline = require('when/pipeline');
client = require('./client/default');
when = require('when');
pipeline = require('when/pipeline');
function normalizeRestFactoryConfig(spec, wire) {
var config = {};
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 when.all([
wire(typeof interceptorDef === 'string' ? { module: interceptorDef } : interceptorDef),
wire(interceptorConfig)
]).spread(function (interceptor, config) {
return { interceptor: interceptor, config: 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 when.all([
wire(typeof interceptorDef === 'string' ? { module: interceptorDef } : interceptorDef),
wire(interceptorConfig)
]).spread(function (interceptor, config) {
return { interceptor: interceptor, config: config };
});
}));
return config;
}
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);
});
});
}
/**
* 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
*/
plugin = {
resolvers: {
client: function () {
throw new Error('rest.js: client! wire reference resolved is deprecated, use \'rest\' facotry instead');
}
},
factories: {
rest: restFactory
}
};
/**
* The plugin instance. Can be the same for all wiring runs
*/
plugin = {
resolvers: {
client: function () {
throw new Error('rest.js: client! wire reference resolved is deprecated, use \'rest\' facotry instead');
}
},
factories: {
rest: restFactory
}
};
return {
wire$plugin: function restPlugin(/* ready, destroyed, options */) {
return plugin;
}
};
});
}(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
));
module.exports = {
wire$plugin: function restPlugin(/* ready, destroyed, options */) {
return plugin;
}
};

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