2
0
mirror of https://github.com/tenrok/axios.git synced 2026-06-23 20:40:40 +03:00

Adding ESLint

This commit is contained in:
mzabriskie
2015-03-17 14:14:26 -06:00
parent 7387829d33
commit a98c61f458
17 changed files with 128 additions and 77 deletions
+13
View File
@@ -0,0 +1,13 @@
{
"globals": {
"console": true,
"module": true,
"require": true
},
"env": {
"browser": true
},
"rules": {
"quotes": "single"
}
}
+5 -1
View File
@@ -48,6 +48,10 @@ module.exports = function(grunt) {
} }
}, },
eslint: {
target: ['lib/**/*.js']
},
karma: { karma: {
options: { options: {
configFile: 'karma.conf.js' configFile: 'karma.conf.js'
@@ -78,7 +82,7 @@ module.exports = function(grunt) {
} }
}); });
grunt.registerTask('test', 'Run the jasmine and nodeunit tests', ['webpack:global', 'nodeunit', 'karma:single', 'ts']); grunt.registerTask('test', 'Run the jasmine and nodeunit tests', ['eslint', 'webpack:global', 'nodeunit', 'karma:single', 'ts']);
grunt.registerTask('build', 'Run webpack and bundle the source', ['webpack']); grunt.registerTask('build', 'Run webpack and bundle the source', ['webpack']);
grunt.registerTask('publish', 'Prepare the code for release', ['clean', 'test', 'build', 'usebanner', 'update_json']); grunt.registerTask('publish', 'Prepare the code for release', ['clean', 'test', 'build', 'usebanner', 'update_json']);
}; };
+5 -3
View File
@@ -9,6 +9,8 @@ var pkg = require('./../../package.json');
var Buffer = require('buffer').Buffer; var Buffer = require('buffer').Buffer;
module.exports = function httpAdapter(resolve, reject, config) { module.exports = function httpAdapter(resolve, reject, config) {
'use strict';
// Transform request data // Transform request data
var data = transformData( var data = transformData(
config.data, config.data,
@@ -71,9 +73,9 @@ module.exports = function httpAdapter(resolve, reject, config) {
}; };
// Resolve or reject the Promise based on the status // Resolve or reject the Promise based on the status
(res.statusCode >= 200 && res.statusCode < 300 (res.statusCode >= 200 && res.statusCode < 300 ?
? resolve resolve :
: reject)(response); reject)(response);
}); });
}); });
+19 -15
View File
@@ -1,3 +1,5 @@
/*global ActiveXObject:true*/
var defaults = require('./../defaults'); var defaults = require('./../defaults');
var utils = require('./../utils'); var utils = require('./../utils');
var buildUrl = require('./../helpers/buildUrl'); var buildUrl = require('./../helpers/buildUrl');
@@ -7,6 +9,8 @@ var transformData = require('./../helpers/transformData');
var urlIsSameOrigin = require('./../helpers/urlIsSameOrigin'); var urlIsSameOrigin = require('./../helpers/urlIsSameOrigin');
module.exports = function xhrAdapter(resolve, reject, config) { module.exports = function xhrAdapter(resolve, reject, config) {
'use strict';
// Transform request data // Transform request data
var data = transformData( var data = transformData(
config.data, config.data,
@@ -15,42 +19,42 @@ module.exports = function xhrAdapter(resolve, reject, config) {
); );
// Merge headers // Merge headers
var headers = utils.merge( var requestHeaders = utils.merge(
defaults.headers.common, defaults.headers.common,
defaults.headers[config.method] || {}, defaults.headers[config.method] || {},
config.headers || {} config.headers || {}
); );
if (utils.isFormData(data)) { if (utils.isFormData(data)) {
delete headers['Content-Type']; // Let the browser set it delete requestHeaders['Content-Type']; // Let the browser set it
} }
// Create the request // Create the request
var request = new(XMLHttpRequest || ActiveXObject)('Microsoft.XMLHTTP'); var request = new (XMLHttpRequest || ActiveXObject)('Microsoft.XMLHTTP');
request.open(config.method.toUpperCase(), buildUrl(config.url, config.params), true); request.open(config.method.toUpperCase(), buildUrl(config.url, config.params), true);
// Listen for ready state // Listen for ready state
request.onreadystatechange = function () { request.onreadystatechange = function () {
if (request && request.readyState === 4) { if (request && request.readyState === 4) {
// Prepare the response // Prepare the response
var headers = parseHeaders(request.getAllResponseHeaders()); var responseHeaders = parseHeaders(request.getAllResponseHeaders());
var responseData = ['text', ''].indexOf(config.responseType || '') !== -1 ? request.responseText : request.response; var responseData = ['text', ''].indexOf(config.responseType || '') !== -1 ? request.responseText : request.response;
var response = { var response = {
data: transformData( data: transformData(
responseData, responseData,
headers, responseHeaders,
config.transformResponse config.transformResponse
), ),
status: request.status, status: request.status,
statusText: request.statusText, statusText: request.statusText,
headers: headers, headers: responseHeaders,
config: config config: config
}; };
// Resolve or reject the Promise based on the status // Resolve or reject the Promise based on the status
(request.status >= 200 && request.status < 300 (request.status >= 200 && request.status < 300 ?
? resolve resolve :
: reject)(response); reject)(response);
// Clean up request // Clean up request
request = null; request = null;
@@ -58,18 +62,18 @@ module.exports = function xhrAdapter(resolve, reject, config) {
}; };
// Add xsrf header // Add xsrf header
var xsrfValue = urlIsSameOrigin(config.url) var xsrfValue = urlIsSameOrigin(config.url) ?
? cookies.read(config.xsrfCookieName || defaults.xsrfCookieName) cookies.read(config.xsrfCookieName || defaults.xsrfCookieName) :
: undefined; undefined;
if (xsrfValue) { if (xsrfValue) {
headers[config.xsrfHeaderName || defaults.xsrfHeaderName] = xsrfValue; requestHeaders[config.xsrfHeaderName || defaults.xsrfHeaderName] = xsrfValue;
} }
// Add headers to the request // Add headers to the request
utils.forEach(headers, function (val, key) { utils.forEach(requestHeaders, function (val, key) {
// Remove Content-Type if data is undefined // Remove Content-Type if data is undefined
if (!data && key.toLowerCase() === 'content-type') { if (!data && key.toLowerCase() === 'content-type') {
delete headers[key]; delete requestHeaders[key];
} }
// Otherwise add header to the request // Otherwise add header to the request
else { else {
+31 -23
View File
@@ -6,6 +6,8 @@ var InterceptorManager = require('./core/InterceptorManager');
// Polyfill ES6 Promise if needed // Polyfill ES6 Promise if needed
(function () { (function () {
'use strict';
// webpack is being used to set es6-promise to the native Promise // webpack is being used to set es6-promise to the native Promise
// for the standalone build. It's necessary to make sure polyfill exists. // for the standalone build. It's necessary to make sure polyfill exists.
var P = require('es6-promise'); var P = require('es6-promise');
@@ -15,6 +17,8 @@ var InterceptorManager = require('./core/InterceptorManager');
})(); })();
var axios = module.exports = function axios(config) { var axios = module.exports = function axios(config) {
'use strict';
config = utils.merge({ config = utils.merge({
method: 'get', method: 'get',
headers: {}, headers: {},
@@ -69,6 +73,7 @@ axios.defaults = defaults;
// Expose all/spread // Expose all/spread
axios.all = function (promises) { axios.all = function (promises) {
'use strict';
return Promise.all(promises); return Promise.all(promises);
}; };
axios.spread = require('./helpers/spread'); axios.spread = require('./helpers/spread');
@@ -80,29 +85,32 @@ axios.interceptors = {
}; };
// Provide aliases for supported request methods // Provide aliases for supported request methods
createShortMethods('delete', 'get', 'head'); (function () {
createShortMethodsWithData('post', 'put', 'patch'); 'use strict';
function createShortMethods() { function createShortMethods() {
utils.forEach(arguments, function (method) { utils.forEach(arguments, function (method) {
axios[method] = function (url, config) { axios[method] = function (url, config) {
return axios(utils.merge(config || {}, { return axios(utils.merge(config || {}, {
method: method, method: method,
url: url url: url
})); }));
}; };
}); });
} }
function createShortMethodsWithData() { function createShortMethodsWithData() {
utils.forEach(arguments, function (method) { utils.forEach(arguments, function (method) {
axios[method] = function (url, data, config) { axios[method] = function (url, data, config) {
return axios(utils.merge(config || {}, { return axios(utils.merge(config || {}, {
method: method, method: method,
url: url, url: url,
data: data data: data
})); }));
}; };
}); });
} }
createShortMethods('delete', 'get', 'head');
createShortMethodsWithData('post', 'put', 'patch');
})();
+6 -5
View File
@@ -1,10 +1,9 @@
'use strict';
var utils = require('./../utils'); var utils = require('./../utils');
function InterceptorManager() { function InterceptorManager() {
'use strict';
this.handlers = []; this.handlers = [];
}; }
/** /**
* Add a new interceptor to the stack * Add a new interceptor to the stack
@@ -15,6 +14,7 @@ function InterceptorManager() {
* @return {Number} An ID used to remove interceptor later * @return {Number} An ID used to remove interceptor later
*/ */
InterceptorManager.prototype.use = function (fulfilled, rejected) { InterceptorManager.prototype.use = function (fulfilled, rejected) {
'use strict';
this.handlers.push({ this.handlers.push({
fulfilled: fulfilled, fulfilled: fulfilled,
rejected: rejected rejected: rejected
@@ -28,6 +28,7 @@ InterceptorManager.prototype.use = function (fulfilled, rejected) {
* @param {Number} id The ID that was returned by `use` * @param {Number} id The ID that was returned by `use`
*/ */
InterceptorManager.prototype.eject = function (id) { InterceptorManager.prototype.eject = function (id) {
'use strict';
if (this.handlers[id]) { if (this.handlers[id]) {
this.handlers[id] = null; this.handlers[id] = null;
} }
@@ -42,12 +43,12 @@ InterceptorManager.prototype.eject = function (id) {
* @param {Function} fn The function to call for each interceptor * @param {Function} fn The function to call for each interceptor
*/ */
InterceptorManager.prototype.forEach = function (fn) { InterceptorManager.prototype.forEach = function (fn) {
'use strict';
utils.forEach(this.handlers, function (h) { utils.forEach(this.handlers, function (h) {
if (h !== null) { if (h !== null) {
fn(h); fn(h);
} }
}); });
}; };
module.exports = InterceptorManager; module.exports = InterceptorManager;
+2 -2
View File
@@ -1,5 +1,3 @@
'use strict';
/** /**
* Dispatch a request to the server using whichever adapter * Dispatch a request to the server using whichever adapter
* is supported by the current environment. * is supported by the current environment.
@@ -8,6 +6,8 @@
* @returns {Promise} The Promise to be fulfilled * @returns {Promise} The Promise to be fulfilled
*/ */
module.exports = function dispatchRequest(config) { module.exports = function dispatchRequest(config) {
'use strict';
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
try { try {
// For browsers use XHR adapter // For browsers use XHR adapter
+3 -3
View File
@@ -1,5 +1,3 @@
'use strict';
var utils = require('./utils'); var utils = require('./utils');
var JSON_START = /^\s*(\[|\{[^\{])/; var JSON_START = /^\s*(\[|\{[^\{])/;
@@ -11,6 +9,7 @@ var DEFAULT_CONTENT_TYPE = {
module.exports = { module.exports = {
transformRequest: [function (data, headers) { transformRequest: [function (data, headers) {
'use strict';
if (utils.isArrayBuffer(data)) { if (utils.isArrayBuffer(data)) {
return data; return data;
} }
@@ -28,6 +27,7 @@ module.exports = {
}], }],
transformResponse: [function (data) { transformResponse: [function (data) {
'use strict';
if (typeof data === 'string') { if (typeof data === 'string') {
data = data.replace(PROTECTION_PREFIX, ''); data = data.replace(PROTECTION_PREFIX, '');
if (JSON_START.test(data) && JSON_END.test(data)) { if (JSON_START.test(data) && JSON_END.test(data)) {
@@ -48,4 +48,4 @@ module.exports = {
xsrfCookieName: 'XSRF-TOKEN', xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN' xsrfHeaderName: 'X-XSRF-TOKEN'
}; };
+2 -2
View File
@@ -1,8 +1,7 @@
'use strict';
var utils = require('./../utils'); var utils = require('./../utils');
function encode(val) { function encode(val) {
'use strict';
return encodeURIComponent(val). return encodeURIComponent(val).
replace(/%40/gi, '@'). replace(/%40/gi, '@').
replace(/%3A/gi, ':'). replace(/%3A/gi, ':').
@@ -19,6 +18,7 @@ function encode(val) {
* @returns {string} The formatted url * @returns {string} The formatted url
*/ */
module.exports = function buildUrl(url, params) { module.exports = function buildUrl(url, params) {
'use strict';
if (!params) { if (!params) {
return url; return url;
} }
+4 -3
View File
@@ -1,9 +1,8 @@
'use strict';
var utils = require('./../utils'); var utils = require('./../utils');
module.exports = { module.exports = {
write: function write(name, value, expires, path, domain, secure) { write: function write(name, value, expires, path, domain, secure) {
'use strict';
var cookie = []; var cookie = [];
cookie.push(name + '=' + encodeURIComponent(value)); cookie.push(name + '=' + encodeURIComponent(value));
@@ -27,11 +26,13 @@ module.exports = {
}, },
read: function read(name) { read: function read(name) {
'use strict';
var match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)')); var match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)'));
return (match ? decodeURIComponent(match[3]) : null); return (match ? decodeURIComponent(match[3]) : null);
}, },
remove: function remove(name) { remove: function remove(name) {
'use strict';
this.write(name, '', Date.now() - 86400000); this.write(name, '', Date.now() - 86400000);
} }
}; };
+3 -2
View File
@@ -1,5 +1,3 @@
'use strict';
/** /**
* Supply a warning to the developer that a method they are using * Supply a warning to the developer that a method they are using
* has been deprecated. * has been deprecated.
@@ -9,6 +7,9 @@
* @param {string} [docs] The documentation URL to get further details * @param {string} [docs] The documentation URL to get further details
*/ */
module.exports = function deprecatedMethod(method, instead, docs) { module.exports = function deprecatedMethod(method, instead, docs) {
/*eslint-env node*/
'use strict';
try { try {
console.warn( console.warn(
'DEPRECATED method `' + method + '`.' + 'DEPRECATED method `' + method + '`.' +
+3 -4
View File
@@ -1,5 +1,3 @@
'use strict';
var utils = require('./../utils'); var utils = require('./../utils');
/** /**
@@ -16,9 +14,10 @@ var utils = require('./../utils');
* @returns {Object} Headers parsed into an object * @returns {Object} Headers parsed into an object
*/ */
module.exports = function parseHeaders(headers) { module.exports = function parseHeaders(headers) {
'use strict';
var parsed = {}, key, val, i; var parsed = {}, key, val, i;
if (!headers) return parsed; if (!headers) { return parsed; }
utils.forEach(headers.split('\n'), function(line) { utils.forEach(headers.split('\n'), function(line) {
i = line.indexOf(':'); i = line.indexOf(':');
@@ -31,4 +30,4 @@ module.exports = function parseHeaders(headers) {
}); });
return parsed; return parsed;
}; };
+2 -1
View File
@@ -19,7 +19,8 @@
* @returns {Function} * @returns {Function}
*/ */
module.exports = function spread(callback) { module.exports = function spread(callback) {
'use strict';
return function (arr) { return function (arr) {
callback.apply(null, arr); callback.apply(null, arr);
}; };
}; };
+2 -3
View File
@@ -1,5 +1,3 @@
'use strict';
var utils = require('./../utils'); var utils = require('./../utils');
/** /**
@@ -11,9 +9,10 @@ var utils = require('./../utils');
* @returns {*} The resulting transformed data * @returns {*} The resulting transformed data
*/ */
module.exports = function transformData(data, headers, fns) { module.exports = function transformData(data, headers, fns) {
'use strict';
utils.forEach(fns, function (fn) { utils.forEach(fns, function (fn) {
data = fn(data, headers); data = fn(data, headers);
}); });
return data; return data;
}; };
+10 -8
View File
@@ -1,9 +1,7 @@
'use strict';
var msie = /(msie|trident)/i.test(navigator.userAgent);
var utils = require('./../utils'); var utils = require('./../utils');
var msie = /(msie|trident)/i.test(navigator.userAgent);
var urlParsingNode = document.createElement('a'); var urlParsingNode = document.createElement('a');
var originUrl = urlResolve(window.location.href); var originUrl;
/** /**
* Parse a URL to discover it's components * Parse a URL to discover it's components
@@ -12,6 +10,7 @@ var originUrl = urlResolve(window.location.href);
* @returns {Object} * @returns {Object}
*/ */
function urlResolve(url) { function urlResolve(url) {
'use strict';
var href = url; var href = url;
if (msie) { if (msie) {
@@ -31,12 +30,14 @@ function urlResolve(url) {
hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '', hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',
hostname: urlParsingNode.hostname, hostname: urlParsingNode.hostname,
port: urlParsingNode.port, port: urlParsingNode.port,
pathname: (urlParsingNode.pathname.charAt(0) === '/') pathname: (urlParsingNode.pathname.charAt(0) === '/') ?
? urlParsingNode.pathname urlParsingNode.pathname :
: '/' + urlParsingNode.pathname '/' + urlParsingNode.pathname
}; };
} }
originUrl = urlResolve(window.location.href);
/** /**
* Determine if a URL shares the same origin as the current location * Determine if a URL shares the same origin as the current location
* *
@@ -44,7 +45,8 @@ function urlResolve(url) {
* @returns {boolean} True if URL shares the same origin, otherwise false * @returns {boolean} True if URL shares the same origin, otherwise false
*/ */
module.exports = function urlIsSameOrigin(requestUrl) { module.exports = function urlIsSameOrigin(requestUrl) {
'use strict';
var parsed = (utils.isString(requestUrl)) ? urlResolve(requestUrl) : requestUrl; var parsed = (utils.isString(requestUrl)) ? urlResolve(requestUrl) : requestUrl;
return (parsed.protocol === originUrl.protocol && return (parsed.protocol === originUrl.protocol &&
parsed.host === originUrl.host); parsed.host === originUrl.host);
}; };
+17 -2
View File
@@ -1,3 +1,4 @@
/*global toString:true*/
// utils is a library of generic helper functions non-specific to axios // utils is a library of generic helper functions non-specific to axios
var toString = Object.prototype.toString; var toString = Object.prototype.toString;
@@ -9,6 +10,7 @@ var toString = Object.prototype.toString;
* @returns {boolean} True if value is an Array, otherwise false * @returns {boolean} True if value is an Array, otherwise false
*/ */
function isArray(val) { function isArray(val) {
'use strict';
return toString.call(val) === '[object Array]'; return toString.call(val) === '[object Array]';
} }
@@ -19,6 +21,7 @@ function isArray(val) {
* @returns {boolean} True if value is an ArrayBuffer, otherwise false * @returns {boolean} True if value is an ArrayBuffer, otherwise false
*/ */
function isArrayBuffer(val) { function isArrayBuffer(val) {
'use strict';
return toString.call(val) === '[object ArrayBuffer]'; return toString.call(val) === '[object ArrayBuffer]';
} }
@@ -29,6 +32,7 @@ function isArrayBuffer(val) {
* @returns {boolean} True if value is an FormData, otherwise false * @returns {boolean} True if value is an FormData, otherwise false
*/ */
function isFormData(val) { function isFormData(val) {
'use strict';
return toString.call(val) === '[object FormData]'; return toString.call(val) === '[object FormData]';
} }
@@ -39,6 +43,7 @@ function isFormData(val) {
* @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false
*/ */
function isArrayBufferView(val) { function isArrayBufferView(val) {
'use strict';
if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) { if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) {
return ArrayBuffer.isView(val); return ArrayBuffer.isView(val);
} else { } else {
@@ -53,6 +58,7 @@ function isArrayBufferView(val) {
* @returns {boolean} True if value is a String, otherwise false * @returns {boolean} True if value is a String, otherwise false
*/ */
function isString(val) { function isString(val) {
'use strict';
return typeof val === 'string'; return typeof val === 'string';
} }
@@ -63,6 +69,7 @@ function isString(val) {
* @returns {boolean} True if value is a Number, otherwise false * @returns {boolean} True if value is a Number, otherwise false
*/ */
function isNumber(val) { function isNumber(val) {
'use strict';
return typeof val === 'number'; return typeof val === 'number';
} }
@@ -73,6 +80,7 @@ function isNumber(val) {
* @returns {boolean} True if the value is undefined, otherwise false * @returns {boolean} True if the value is undefined, otherwise false
*/ */
function isUndefined(val) { function isUndefined(val) {
'use strict';
return typeof val === 'undefined'; return typeof val === 'undefined';
} }
@@ -83,6 +91,7 @@ function isUndefined(val) {
* @returns {boolean} True if value is an Object, otherwise false * @returns {boolean} True if value is an Object, otherwise false
*/ */
function isObject(val) { function isObject(val) {
'use strict';
return val !== null && typeof val === 'object'; return val !== null && typeof val === 'object';
} }
@@ -93,6 +102,7 @@ function isObject(val) {
* @returns {boolean} True if value is a Date, otherwise false * @returns {boolean} True if value is a Date, otherwise false
*/ */
function isDate(val) { function isDate(val) {
'use strict';
return toString.call(val) === '[object Date]'; return toString.call(val) === '[object Date]';
} }
@@ -103,6 +113,7 @@ function isDate(val) {
* @returns {boolean} True if value is a File, otherwise false * @returns {boolean} True if value is a File, otherwise false
*/ */
function isFile(val) { function isFile(val) {
'use strict';
return toString.call(val) === '[object File]'; return toString.call(val) === '[object File]';
} }
@@ -113,6 +124,7 @@ function isFile(val) {
* @returns {boolean} True if value is a Blob, otherwise false * @returns {boolean} True if value is a Blob, otherwise false
*/ */
function isBlob(val) { function isBlob(val) {
'use strict';
return toString.call(val) === '[object Blob]'; return toString.call(val) === '[object Blob]';
} }
@@ -123,6 +135,7 @@ function isBlob(val) {
* @returns {String} The String freed of excess whitespace * @returns {String} The String freed of excess whitespace
*/ */
function trim(str) { function trim(str) {
'use strict';
return str.replace(/^\s*/, '').replace(/\s*$/, ''); return str.replace(/^\s*/, '').replace(/\s*$/, '');
} }
@@ -139,6 +152,7 @@ function trim(str) {
* @param {Function} fn The callback to invoke for each item * @param {Function} fn The callback to invoke for each item
*/ */
function forEach(obj, fn) { function forEach(obj, fn) {
'use strict';
// Don't bother if no value provided // Don't bother if no value provided
if (obj === null || typeof obj === 'undefined') { if (obj === null || typeof obj === 'undefined') {
return; return;
@@ -154,7 +168,7 @@ function forEach(obj, fn) {
// Iterate over array values // Iterate over array values
if (isArrayLike) { if (isArrayLike) {
for (var i=0, l=obj.length; i<l; i++) { for (var i = 0, l = obj.length; i < l; i++) {
fn.call(null, obj[i], i, obj); fn.call(null, obj[i], i, obj);
} }
} }
@@ -185,7 +199,8 @@ function forEach(obj, fn) {
* @param {Object} obj1 Object to merge * @param {Object} obj1 Object to merge
* @returns {Object} Result of all merge properties * @returns {Object} Result of all merge properties
*/ */
function merge(obj1/*, obj2, obj3, ...*/) { function merge(/*obj1, obj2, obj3, ...*/) {
'use strict';
var result = {}; var result = {};
forEach(arguments, function (obj) { forEach(arguments, function (obj) {
forEach(obj, function (val, key) { forEach(obj, function (val, key) {
+1
View File
@@ -33,6 +33,7 @@
"grunt-contrib-clean": "^0.6.0", "grunt-contrib-clean": "^0.6.0",
"grunt-contrib-nodeunit": "^0.4.1", "grunt-contrib-nodeunit": "^0.4.1",
"grunt-contrib-watch": "^0.6.1", "grunt-contrib-watch": "^0.6.1",
"grunt-eslint": "^9.0.0",
"grunt-karma": "^0.10.1", "grunt-karma": "^0.10.1",
"grunt-ts": "^3.0.0", "grunt-ts": "^3.0.0",
"grunt-update-json": "^0.2.1", "grunt-update-json": "^0.2.1",