diff --git a/Gruntfile.js b/Gruntfile.js index e6bb130..64bb94f 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -7,11 +7,11 @@ module.exports = function(grunt) { // NPM tasks, alphabetical grunt.loadNpmTasks('grunt-contrib-clean'); - grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-docco'); grunt.loadNpmTasks('grunt-mocha-test'); + grunt.loadNpmTasks('grunt-webpack'); grunt.initConfig({ // Clean @@ -20,17 +20,6 @@ module.exports = function(grunt) { coverage: ['test/coverage.html'] }, - // Concat - concat: { - angular: { - src: ['lib/index.js', 'lib/http_adapter/angular.js', 'lib/wrappers/angular.js'], - dest: 'monocle-client-angular.js', - options: { - footer: 'Monocle.angularWrapper(angular, Monocle);' - } - } - }, - // Documentation docco: { main: { @@ -116,6 +105,21 @@ module.exports = function(grunt) { ], tasks: ['mochaTest:unit'] } + }, + + webpack: { + angular: { + entry: './lib/angular.js', + output: { + path: './', + filename: 'monocle-client-angular.js' + }, + stats: { + colors: false, + modules: true, + reasons: true + } + } } }); @@ -138,5 +142,5 @@ module.exports = function(grunt) { grunt.registerTask('dev', 'Enables watchers for developing', ['watch:unit']); // Build concatenated/minified version for browsers - grunt.registerTask('build', 'Builds concatenated/minified versions for browsers', ['concat', 'uglify']); + grunt.registerTask('build', 'Builds concatenated/minified versions for browsers', ['webpack', 'uglify']); }; diff --git a/demo/public/monocle-client-angular.js b/demo/public/monocle-client-angular.js index 077cb23..04e4e83 100644 --- a/demo/public/monocle-client-angular.js +++ b/demo/public/monocle-client-angular.js @@ -1,185 +1,216 @@ -// This file may run in a browser, so wrap it in an IIFE. -(function() { - 'use strict'; - - var context = typeof exports !== 'undefined' ? exports : window; - if (typeof(require) === 'function') { - var Promise = context.Promise || require('bluebird'); - } - - var Monocle = function(http) { - this._http = http; - this._base = '/'; - }; - - Monocle.prototype.setBase = function(base) { - this._base = base; - return this; - }; - - ['get', 'post', 'put', 'patch', 'delete', 'options'].forEach(function(method) { - Monocle.prototype[method] = function(path, options) { - var fullPath = (this._base + path).replace(/\/{2,}/g, '/'); - var query = {}; - - if (options && options.props) { - query.props = options.props.join(','); - } - - var queryStringParts = []; - for (var i in query) { - queryStringParts.push(encodeURIComponent(i) + '=' + encodeURIComponent(query[i])); - } - if (queryStringParts.length) { - fullPath += '?' + queryStringParts.join('&'); - } - - return this._http.request(method.toUpperCase(), fullPath, options); - }; - }); - - if (typeof exports !== 'undefined') { - // We're in a nodejs environment, export this module - module.exports = Monocle; - } else { - // We're in a browser environment, expose this module globally - context.Monocle = Monocle; - } -})(); - -// This file is generally run in a browser, so wrap it in an IIFE -(function() { - 'use strict'; - - var context = typeof exports !== 'undefined' ? exports : window; - - function AngularAdapter($http, $q, $window) { - this._$http = $http; - this._$q = $q; - this._$window = $window; - this._timeout = 30000; - this._headers = { - 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', - 'X-Requested-With': 'XMLHttpRequest' - }; - } - - AngularAdapter.prototype.setTimeout = function(timeout) { - this._timeout = parseInt(timeout, 10) || 30000; - return this; - }; - - AngularAdapter.prototype.setHeader = function(key, value) { - this._headers[key] = value; - }; - - AngularAdapter.prototype.setHeaders = function(headers) { - for (var i in headers) { - if (!headers.hasOwnProperty(i)) continue; - this.setHeader(i, headers[i]); - } - }; - - AngularAdapter.prototype.request = function(method, path, options) { - var headerPromises = []; - var headerKeys = []; - - for (var i in this._headers) { - if (!this._headers.hasOwnProperty(i)) continue; - - if (typeof this._headers[i] === 'function') { - headerPromises.push(this._headers[i]()); - headerKeys.push(i); - continue; - } - - headerPromises.push(this._headers[i]); - headerKeys.push(i); - } - - return this._$q.all(headerPromises) - .then(function(results) { - var headers = {}; - for (var i = 0, len = results.length; i < len; i++) { - headers[headerKeys[i]] = results[i]; - } - - return this._$http({ - method: method.toUpperCase(), - url: path, - timeout: this._timeout, - headers: headers - }) - .catch(function(response) { - return this._$q.reject(response.data); - }.bind(this)) - .then(function(response) { - return response.data; - }); - }.bind(this)); - }; - - if (typeof exports !== 'undefined') { - // We're in a nodejs environment, export this module (useful for unit testing) - module.exports = AngularAdapter; - } else { - // We're in a browser environment, export this module globally, - // attached to the TaggedApi module - var Monocle = context.Monocle || {}; - Monocle.AngularAdapter = AngularAdapter; - } -})(); - -// This file is generally run in a browser, so wrap it in an IIFE -(function() { - 'use strict'; - - var wrapper = function(angular, Monocle) { - // ## Module: monocle - // Registers the module `monocle` with Angular, - // allowing Angular apps to declare this module as a dependency. - // This module has no dependencies of its own. - var module = angular.module('monocle', []); - - // Register the `monocle` provider. - module.provider('monocle', function monocleProvider() { - this._base = '/'; - this._timeout = 30000; - this._headers = {}; - - this.setBase = function(base) { - this._base = base; - }; - - this.setTimeout = function(timeout) { - this._timeout = parseInt(timeout, 10) || 30000; - }; - - this.setHeader = function(key, value) { - this._headers[key] = value; - }; - - this.$get = function($http, $q, $window) { - var angularAdapter = new Monocle.AngularAdapter($http, $q, $window); - angularAdapter.setTimeout(this._timeout); - angularAdapter.setHeaders(this._headers); - - var monocle = new Monocle(angularAdapter); - monocle.setBase(this._base); - - return monocle; - }; - - this.$get.$provide = ['$http', '$q', '$window']; - }); - }; - - if (typeof exports !== 'undefined') { - // We're in a nodejs environment, export this module - module.exports = wrapper; - } else { - // We're in a browser environment, expose this module globally - Monocle.angularWrapper = wrapper; - } -})(); -Monocle.angularWrapper(angular, Monocle); \ No newline at end of file +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; + +/******/ // The require function +/******/ function __webpack_require__(moduleId) { + +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; + +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; + +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + +/******/ // Flag the module as loaded +/******/ module.loaded = true; + +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } + + +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; + +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; + +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; + +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + + var monocle = __webpack_require__(1); + var wrapper = __webpack_require__(2); + wrapper(angular, monocle); + + +/***/ }, +/* 1 */ +/***/ function(module, exports) { + + 'use strict'; + + var Monocle = function(http) { + this._http = http; + this._base = '/'; + }; + + Monocle.prototype.setBase = function(base) { + this._base = base; + return this; + }; + + ['get', 'post', 'put', 'patch', 'delete', 'options'].forEach(function(method) { + Monocle.prototype[method] = function(path, options) { + var fullPath = (this._base + path).replace(/\/{2,}/g, '/'); + var query = {}; + + if (options && options.props) { + query.props = options.props.join(','); + } + + var queryStringParts = []; + for (var i in query) { + queryStringParts.push(encodeURIComponent(i) + '=' + encodeURIComponent(query[i])); + } + if (queryStringParts.length) { + fullPath += '?' + queryStringParts.join('&'); + } + + return this._http.request(method.toUpperCase(), fullPath, options); + }; + }); + + module.exports = Monocle; + + +/***/ }, +/* 2 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + module.exports = function(angular, Monocle) { + var AngularAdapter = __webpack_require__(3); + // ## Module: monocle + // Registers the module `monocle` with Angular, + // allowing Angular apps to declare this module as a dependency. + // This module has no dependencies of its own. + var module = angular.module('monocle', []); + + // Register the `monocle` provider. + module.provider('monocle', function monocleProvider() { + this._base = '/'; + this._timeout = 30000; + this._headers = {}; + + this.setBase = function(base) { + this._base = base; + }; + + this.setTimeout = function(timeout) { + this._timeout = parseInt(timeout, 10) || 30000; + }; + + this.setHeader = function(key, value) { + this._headers[key] = value; + }; + + this.$get = function($http, $q, $window) { + var angularAdapter = new AngularAdapter($http, $q, $window); + angularAdapter.setTimeout(this._timeout); + angularAdapter.setHeaders(this._headers); + + var monocle = new Monocle(angularAdapter); + monocle.setBase(this._base); + + return monocle; + }; + + this.$get.$provide = ['$http', '$q', '$window']; + }); + }; + + +/***/ }, +/* 3 */ +/***/ function(module, exports) { + + 'use strict'; + + function AngularAdapter($http, $q, $window) { + this._$http = $http; + this._$q = $q; + this._$window = $window; + this._timeout = 30000; + this._headers = { + 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', + 'X-Requested-With': 'XMLHttpRequest' + }; + } + + AngularAdapter.prototype.setTimeout = function(timeout) { + this._timeout = parseInt(timeout, 10) || 30000; + return this; + }; + + AngularAdapter.prototype.setHeader = function(key, value) { + this._headers[key] = value; + }; + + AngularAdapter.prototype.setHeaders = function(headers) { + for (var i in headers) { + if (!headers.hasOwnProperty(i)) continue; + this.setHeader(i, headers[i]); + } + }; + + AngularAdapter.prototype.request = function(method, path, options) { + var headerPromises = []; + var headerKeys = []; + + for (var i in this._headers) { + if (!this._headers.hasOwnProperty(i)) continue; + + if (typeof this._headers[i] === 'function') { + headerPromises.push(this._headers[i]()); + headerKeys.push(i); + continue; + } + + headerPromises.push(this._headers[i]); + headerKeys.push(i); + } + + return this._$q.all(headerPromises) + .then(function(results) { + var headers = {}; + for (var i = 0, len = results.length; i < len; i++) { + headers[headerKeys[i]] = results[i]; + } + + return this._$http({ + method: method.toUpperCase(), + url: path, + timeout: this._timeout, + headers: headers + }) + .catch(function(response) { + return this._$q.reject(response.data); + }.bind(this)) + .then(function(response) { + return response.data; + }); + }.bind(this)); + }; + + module.exports = AngularAdapter; + + +/***/ } +/******/ ]); \ No newline at end of file diff --git a/lib/angular.js b/lib/angular.js new file mode 100644 index 0000000..b95b1f4 --- /dev/null +++ b/lib/angular.js @@ -0,0 +1,3 @@ +var monocle = require('./monocle'); +var wrapper = require('./wrappers/angular'); +wrapper(angular, monocle); diff --git a/lib/cache/memory.js b/lib/cache/memory.js index 5be8c46..0a4cafd 100644 --- a/lib/cache/memory.js +++ b/lib/cache/memory.js @@ -1,157 +1,149 @@ -(function() { - var context = typeof exports !== 'undefined' ? exports : window; - - var MemoryCache = function(cacheId, options) { - this._cacheId = cacheId; - this._cache = {}; - this._head = null; - this._tail = null; - this._options = options || {}; - if (!this._options.hasOwnProperty('capacity')) { - this._options.capacity = false; - } - }; +'use strict'; + +var MemoryCache = function(cacheId, options) { + this._cacheId = cacheId; + this._cache = {}; + this._head = null; + this._tail = null; + this._options = options || {}; + if (!this._options.hasOwnProperty('capacity')) { + this._options.capacity = false; + } +}; - MemoryCache.prototype.get = function(cacheKey) { - if (!this._cache.hasOwnProperty(cacheKey)) { - return undefined; - } +MemoryCache.prototype.get = function(cacheKey) { + if (!this._cache.hasOwnProperty(cacheKey)) { + return undefined; + } - var entry = this._cache[cacheKey]; + var entry = this._cache[cacheKey]; - if (entry.expiration) { - var now = new Date(); - if (now.getTime() > entry.expiration.getTime()) { - this.remove(cacheKey); - return undefined; - } + if (entry.expiration) { + var now = new Date(); + if (now.getTime() > entry.expiration.getTime()) { + this.remove(cacheKey); + return undefined; } + } - moveToHead.call(this, entry); + moveToHead.call(this, entry); - return entry.value; - }; + return entry.value; +}; - MemoryCache.prototype.put = function(cacheKey, value, ttl, tags) { - if (!Array.isArray(tags)) { - tags = toString.call(tags) == '[object String]' ? [tags] : []; - } +MemoryCache.prototype.put = function(cacheKey, value, ttl, tags) { + if (!Array.isArray(tags)) { + tags = toString.call(tags) == '[object String]' ? [tags] : []; + } - var entry = { - key: cacheKey, - value: value, - expiration: false, - tags: tags - }; + var entry = { + key: cacheKey, + value: value, + expiration: false, + tags: tags + }; - ttl = parseInt(ttl, 10); + ttl = parseInt(ttl, 10); - if (isFinite(ttl) && ttl > 0) { - entry.expiration = new Date(new Date().getTime() + ttl); - } + if (isFinite(ttl) && ttl > 0) { + entry.expiration = new Date(new Date().getTime() + ttl); + } - moveToHead.call(this, entry); + moveToHead.call(this, entry); - this._cache[cacheKey] = entry; + this._cache[cacheKey] = entry; - var size = Object.keys(this._cache).length; - if (this._options.capacity > 0 && size > this._options.capacity) { - clearExpired.call(this); + var size = Object.keys(this._cache).length; + if (this._options.capacity > 0 && size > this._options.capacity) { + clearExpired.call(this); - if (Object.keys(this._cache).length > this._options.capacity) { - purgeTail.call(this); - } + if (Object.keys(this._cache).length > this._options.capacity) { + purgeTail.call(this); } - }; + } +}; - var moveToHead = function(entry) { - if (this._head) { - entry.next = this._head; - this._head.previous = entry; - } else { - entry.next = null; - } +var moveToHead = function(entry) { + if (this._head) { + entry.next = this._head; + this._head.previous = entry; + } else { + entry.next = null; + } - // Head has no previous - entry.previous = null; + // Head has no previous + entry.previous = null; - this._head = entry; + this._head = entry; - if (!this._tail) { - this._tail = entry; - } - }; + if (!this._tail) { + this._tail = entry; + } +}; - var purgeTail = function() { - if (this._head === this._tail) { - // Do not purge - return; - } +var purgeTail = function() { + if (this._head === this._tail) { + // Do not purge + return; + } - var tail = this._tail; - var previous = tail.previous; - previous.next = null; - this._tail = previous; - delete this._cache[tail.key]; - }; + var tail = this._tail; + var previous = tail.previous; + previous.next = null; + this._tail = previous; + delete this._cache[tail.key]; +}; - var clearExpired = function() { - var now = new Date(); - Object.keys(this._cache).forEach(function(cacheKey) { - var entry = this._cache[cacheKey]; - if (entry.expiration) { - if (now.getTime() > entry.expiration.getTime()) { - this.remove(cacheKey); - } +var clearExpired = function() { + var now = new Date(); + Object.keys(this._cache).forEach(function(cacheKey) { + var entry = this._cache[cacheKey]; + if (entry.expiration) { + if (now.getTime() > entry.expiration.getTime()) { + this.remove(cacheKey); } - }.bind(this)); - }; - - MemoryCache.prototype.remove = function(cacheKey) { - if (this._cache.hasOwnProperty(cacheKey)) { - var entry = this._cache[cacheKey]; + } + }.bind(this)); +}; - // Update the doubly-linked list pointers - var previous = entry.previous; - var next = entry.next; +MemoryCache.prototype.remove = function(cacheKey) { + if (this._cache.hasOwnProperty(cacheKey)) { + var entry = this._cache[cacheKey]; - if (previous) { - previous.next = next; - } + // Update the doubly-linked list pointers + var previous = entry.previous; + var next = entry.next; - if (next) { - next.previous = previous; - } + if (previous) { + previous.next = next; + } - if (this._tail === entry) { - this._tail = previous; - } + if (next) { + next.previous = previous; + } - delete this._cache[cacheKey]; + if (this._tail === entry) { + this._tail = previous; } - }; - MemoryCache.prototype.removeAll = function() { - this._cache = {}; - this._head = null; - this._tail = null; - }; + delete this._cache[cacheKey]; + } +}; - MemoryCache.prototype.removeMatchingTag = function(tag) { - // TODO: Use a faster lookup, perhaps a map? - Object.keys(this._cache).forEach(function(cacheKey) { - var entry = this._cache[cacheKey]; - if (-1 !== entry.tags.indexOf(tag)) { - this.remove(cacheKey); - } - }.bind(this)); - }; +MemoryCache.prototype.removeAll = function() { + this._cache = {}; + this._head = null; + this._tail = null; +}; - if (typeof exports !== 'undefined') { - // We're in a nodejs environment, export this module - module.exports = MemoryCache; - } else { - // We're in a browser environment, expose this module globally - context.MemoryCache = MemoryCache; - } -})(); +MemoryCache.prototype.removeMatchingTag = function(tag) { + // TODO: Use a faster lookup, perhaps a map? + Object.keys(this._cache).forEach(function(cacheKey) { + var entry = this._cache[cacheKey]; + if (-1 !== entry.tags.indexOf(tag)) { + this.remove(cacheKey); + } + }.bind(this)); +}; + +module.exports = MemoryCache; diff --git a/lib/http_adapter/angular.js b/lib/http_adapter/angular.js index 485fbfb..04f9457 100644 --- a/lib/http_adapter/angular.js +++ b/lib/http_adapter/angular.js @@ -1,82 +1,69 @@ -// This file is generally run in a browser, so wrap it in an IIFE -(function() { - 'use strict'; +'use strict'; - var context = typeof exports !== 'undefined' ? exports : window; - - function AngularAdapter($http, $q, $window) { - this._$http = $http; - this._$q = $q; - this._$window = $window; - this._timeout = 30000; - this._headers = { - 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', - 'X-Requested-With': 'XMLHttpRequest' - }; - } - - AngularAdapter.prototype.setTimeout = function(timeout) { - this._timeout = parseInt(timeout, 10) || 30000; - return this; +function AngularAdapter($http, $q, $window) { + this._$http = $http; + this._$q = $q; + this._$window = $window; + this._timeout = 30000; + this._headers = { + 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', + 'X-Requested-With': 'XMLHttpRequest' }; +} - AngularAdapter.prototype.setHeader = function(key, value) { - this._headers[key] = value; - }; +AngularAdapter.prototype.setTimeout = function(timeout) { + this._timeout = parseInt(timeout, 10) || 30000; + return this; +}; - AngularAdapter.prototype.setHeaders = function(headers) { - for (var i in headers) { - if (!headers.hasOwnProperty(i)) continue; - this.setHeader(i, headers[i]); - } - }; +AngularAdapter.prototype.setHeader = function(key, value) { + this._headers[key] = value; +}; - AngularAdapter.prototype.request = function(method, path, options) { - var headerPromises = []; - var headerKeys = []; +AngularAdapter.prototype.setHeaders = function(headers) { + for (var i in headers) { + if (!headers.hasOwnProperty(i)) continue; + this.setHeader(i, headers[i]); + } +}; - for (var i in this._headers) { - if (!this._headers.hasOwnProperty(i)) continue; +AngularAdapter.prototype.request = function(method, path, options) { + var headerPromises = []; + var headerKeys = []; - if (typeof this._headers[i] === 'function') { - headerPromises.push(this._headers[i]()); - headerKeys.push(i); - continue; - } + for (var i in this._headers) { + if (!this._headers.hasOwnProperty(i)) continue; - headerPromises.push(this._headers[i]); + if (typeof this._headers[i] === 'function') { + headerPromises.push(this._headers[i]()); headerKeys.push(i); + continue; } - return this._$q.all(headerPromises) - .then(function(results) { - var headers = {}; - for (var i = 0, len = results.length; i < len; i++) { - headers[headerKeys[i]] = results[i]; - } + headerPromises.push(this._headers[i]); + headerKeys.push(i); + } - return this._$http({ - method: method.toUpperCase(), - url: path, - timeout: this._timeout, - headers: headers - }) - .catch(function(response) { - return this._$q.reject(response.data); - }.bind(this)) - .then(function(response) { - return response.data; - }); - }.bind(this)); - }; + return this._$q.all(headerPromises) + .then(function(results) { + var headers = {}; + for (var i = 0, len = results.length; i < len; i++) { + headers[headerKeys[i]] = results[i]; + } - if (typeof exports !== 'undefined') { - // We're in a nodejs environment, export this module (useful for unit testing) - module.exports = AngularAdapter; - } else { - // We're in a browser environment, export this module globally, - // attached to the TaggedApi module - var Monocle = context.Monocle || {}; - Monocle.AngularAdapter = AngularAdapter; - } -})(); + return this._$http({ + method: method.toUpperCase(), + url: path, + timeout: this._timeout, + headers: headers + }) + .catch(function(response) { + return this._$q.reject(response.data); + }.bind(this)) + .then(function(response) { + return response.data; + }); + }.bind(this)); +}; + +module.exports = AngularAdapter; diff --git a/lib/http_adapter/node.js b/lib/http_adapter/node.js index 1db19e4..2d4d0d1 100644 --- a/lib/http_adapter/node.js +++ b/lib/http_adapter/node.js @@ -1,5 +1,6 @@ -var Promise = require('bluebird'); +'use strict'; +var Promise = require('bluebird'); var DEFAULT_TIMEOUT = 30000; var NodeAdapter = function(request) { diff --git a/lib/index.js b/lib/index.js deleted file mode 100644 index 2048811..0000000 --- a/lib/index.js +++ /dev/null @@ -1,48 +0,0 @@ -// This file may run in a browser, so wrap it in an IIFE. -(function() { - 'use strict'; - - var context = typeof exports !== 'undefined' ? exports : window; - if (typeof(require) === 'function') { - var Promise = context.Promise || require('bluebird'); - } - - var Monocle = function(http) { - this._http = http; - this._base = '/'; - }; - - Monocle.prototype.setBase = function(base) { - this._base = base; - return this; - }; - - ['get', 'post', 'put', 'patch', 'delete', 'options'].forEach(function(method) { - Monocle.prototype[method] = function(path, options) { - var fullPath = (this._base + path).replace(/\/{2,}/g, '/'); - var query = {}; - - if (options && options.props) { - query.props = options.props.join(','); - } - - var queryStringParts = []; - for (var i in query) { - queryStringParts.push(encodeURIComponent(i) + '=' + encodeURIComponent(query[i])); - } - if (queryStringParts.length) { - fullPath += '?' + queryStringParts.join('&'); - } - - return this._http.request(method.toUpperCase(), fullPath, options); - }; - }); - - if (typeof exports !== 'undefined') { - // We're in a nodejs environment, export this module - module.exports = Monocle; - } else { - // We're in a browser environment, expose this module globally - context.Monocle = Monocle; - } -})(); diff --git a/lib/monocle.js b/lib/monocle.js new file mode 100644 index 0000000..d515eb3 --- /dev/null +++ b/lib/monocle.js @@ -0,0 +1,34 @@ +'use strict'; + +var Monocle = function(http) { + this._http = http; + this._base = '/'; +}; + +Monocle.prototype.setBase = function(base) { + this._base = base; + return this; +}; + +['get', 'post', 'put', 'patch', 'delete', 'options'].forEach(function(method) { + Monocle.prototype[method] = function(path, options) { + var fullPath = (this._base + path).replace(/\/{2,}/g, '/'); + var query = {}; + + if (options && options.props) { + query.props = options.props.join(','); + } + + var queryStringParts = []; + for (var i in query) { + queryStringParts.push(encodeURIComponent(i) + '=' + encodeURIComponent(query[i])); + } + if (queryStringParts.length) { + fullPath += '?' + queryStringParts.join('&'); + } + + return this._http.request(method.toUpperCase(), fullPath, options); + }; +}); + +module.exports = Monocle; diff --git a/lib/wrappers/angular.js b/lib/wrappers/angular.js index 796e51c..be64ccb 100644 --- a/lib/wrappers/angular.js +++ b/lib/wrappers/angular.js @@ -1,52 +1,42 @@ -// This file is generally run in a browser, so wrap it in an IIFE -(function() { - 'use strict'; - - var wrapper = function(angular, Monocle) { - // ## Module: monocle - // Registers the module `monocle` with Angular, - // allowing Angular apps to declare this module as a dependency. - // This module has no dependencies of its own. - var module = angular.module('monocle', []); - - // Register the `monocle` provider. - module.provider('monocle', function monocleProvider() { - this._base = '/'; - this._timeout = 30000; - this._headers = {}; - - this.setBase = function(base) { - this._base = base; - }; - - this.setTimeout = function(timeout) { - this._timeout = parseInt(timeout, 10) || 30000; - }; - - this.setHeader = function(key, value) { - this._headers[key] = value; - }; - - this.$get = function($http, $q, $window) { - var angularAdapter = new Monocle.AngularAdapter($http, $q, $window); - angularAdapter.setTimeout(this._timeout); - angularAdapter.setHeaders(this._headers); - - var monocle = new Monocle(angularAdapter); - monocle.setBase(this._base); - - return monocle; - }; - - this.$get.$provide = ['$http', '$q', '$window']; - }); - }; - - if (typeof exports !== 'undefined') { - // We're in a nodejs environment, export this module - module.exports = wrapper; - } else { - // We're in a browser environment, expose this module globally - Monocle.angularWrapper = wrapper; - } -})(); +'use strict'; + +module.exports = function(angular, Monocle) { + var AngularAdapter = require('../http_adapter/angular'); + // ## Module: monocle + // Registers the module `monocle` with Angular, + // allowing Angular apps to declare this module as a dependency. + // This module has no dependencies of its own. + var module = angular.module('monocle', []); + + // Register the `monocle` provider. + module.provider('monocle', function monocleProvider() { + this._base = '/'; + this._timeout = 30000; + this._headers = {}; + + this.setBase = function(base) { + this._base = base; + }; + + this.setTimeout = function(timeout) { + this._timeout = parseInt(timeout, 10) || 30000; + }; + + this.setHeader = function(key, value) { + this._headers[key] = value; + }; + + this.$get = function($http, $q, $window) { + var angularAdapter = new AngularAdapter($http, $q, $window); + angularAdapter.setTimeout(this._timeout); + angularAdapter.setHeaders(this._headers); + + var monocle = new Monocle(angularAdapter); + monocle.setBase(this._base); + + return monocle; + }; + + this.$get.$provide = ['$http', '$q', '$window']; + }); +}; diff --git a/monocle-client-angular-min.js b/monocle-client-angular-min.js index 5d6059c..401cc20 100644 --- a/monocle-client-angular-min.js +++ b/monocle-client-angular-min.js @@ -1 +1 @@ -!function(){"use strict";var a="undefined"!=typeof exports?exports:window;if("function"==typeof require){a.Promise||require("bluebird")}var b=function(a){this._http=a,this._base="/"};b.prototype.setBase=function(a){return this._base=a,this},["get","post","put","patch","delete","options"].forEach(function(a){b.prototype[a]=function(b,c){var d=(this._base+b).replace(/\/{2,}/g,"/"),e={};c&&c.props&&(e.props=c.props.join(","));var f=[];for(var g in e)f.push(encodeURIComponent(g)+"="+encodeURIComponent(e[g]));return f.length&&(d+="?"+f.join("&")),this._http.request(a.toUpperCase(),d,c)}}),"undefined"!=typeof exports?module.exports=b:a.Monocle=b}(),function(){"use strict";function a(a,b,c){this._$http=a,this._$q=b,this._$window=c,this._timeout=3e4,this._headers={"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8","X-Requested-With":"XMLHttpRequest"}}var b="undefined"!=typeof exports?exports:window;if(a.prototype.setTimeout=function(a){return this._timeout=parseInt(a,10)||3e4,this},a.prototype.setHeader=function(a,b){this._headers[a]=b},a.prototype.setHeaders=function(a){for(var b in a)a.hasOwnProperty(b)&&this.setHeader(b,a[b])},a.prototype.request=function(a,b,c){var d=[],e=[];for(var f in this._headers)this._headers.hasOwnProperty(f)&&("function"!=typeof this._headers[f]?(d.push(this._headers[f]),e.push(f)):(d.push(this._headers[f]()),e.push(f)));return this._$q.all(d).then(function(c){for(var d={},f=0,g=c.length;g>f;f++)d[e[f]]=c[f];return this._$http({method:a.toUpperCase(),url:b,timeout:this._timeout,headers:d})["catch"](function(a){return this._$q.reject(a.data)}.bind(this)).then(function(a){return a.data})}.bind(this))},"undefined"!=typeof exports)module.exports=a;else{var c=b.Monocle||{};c.AngularAdapter=a}}(),function(){"use strict";var a=function(a,b){var c=a.module("monocle",[]);c.provider("monocle",function(){this._base="/",this._timeout=3e4,this._headers={},this.setBase=function(a){this._base=a},this.setTimeout=function(a){this._timeout=parseInt(a,10)||3e4},this.setHeader=function(a,b){this._headers[a]=b},this.$get=function(a,c,d){var e=new b.AngularAdapter(a,c,d);e.setTimeout(this._timeout),e.setHeaders(this._headers);var f=new b(e);return f.setBase(this._base),f},this.$get.$provide=["$http","$q","$window"]})};"undefined"!=typeof exports?module.exports=a:Monocle.angularWrapper=a}(),Monocle.angularWrapper(angular,Monocle); \ No newline at end of file +!function(a){function b(d){if(c[d])return c[d].exports;var e=c[d]={exports:{},id:d,loaded:!1};return a[d].call(e.exports,e,e.exports,b),e.loaded=!0,e.exports}var c={};return b.m=a,b.c=c,b.p="",b(0)}([function(a,b,c){var d=c(1),e=c(2);e(angular,d)},function(a,b){"use strict";var c=function(a){this._http=a,this._base="/"};c.prototype.setBase=function(a){return this._base=a,this},["get","post","put","patch","delete","options"].forEach(function(a){c.prototype[a]=function(b,c){var d=(this._base+b).replace(/\/{2,}/g,"/"),e={};c&&c.props&&(e.props=c.props.join(","));var f=[];for(var g in e)f.push(encodeURIComponent(g)+"="+encodeURIComponent(e[g]));return f.length&&(d+="?"+f.join("&")),this._http.request(a.toUpperCase(),d,c)}}),a.exports=c},function(a,b,c){"use strict";a.exports=function(a,b){var d=c(3),e=a.module("monocle",[]);e.provider("monocle",function(){this._base="/",this._timeout=3e4,this._headers={},this.setBase=function(a){this._base=a},this.setTimeout=function(a){this._timeout=parseInt(a,10)||3e4},this.setHeader=function(a,b){this._headers[a]=b},this.$get=function(a,c,e){var f=new d(a,c,e);f.setTimeout(this._timeout),f.setHeaders(this._headers);var g=new b(f);return g.setBase(this._base),g},this.$get.$provide=["$http","$q","$window"]})}},function(a,b){"use strict";function c(a,b,c){this._$http=a,this._$q=b,this._$window=c,this._timeout=3e4,this._headers={"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8","X-Requested-With":"XMLHttpRequest"}}c.prototype.setTimeout=function(a){return this._timeout=parseInt(a,10)||3e4,this},c.prototype.setHeader=function(a,b){this._headers[a]=b},c.prototype.setHeaders=function(a){for(var b in a)a.hasOwnProperty(b)&&this.setHeader(b,a[b])},c.prototype.request=function(a,b,c){var d=[],e=[];for(var f in this._headers)this._headers.hasOwnProperty(f)&&("function"!=typeof this._headers[f]?(d.push(this._headers[f]),e.push(f)):(d.push(this._headers[f]()),e.push(f)));return this._$q.all(d).then(function(c){for(var d={},f=0,g=c.length;g>f;f++)d[e[f]]=c[f];return this._$http({method:a.toUpperCase(),url:b,timeout:this._timeout,headers:d})["catch"](function(a){return this._$q.reject(a.data)}.bind(this)).then(function(a){return a.data})}.bind(this))},a.exports=c}]); \ No newline at end of file diff --git a/monocle-client-angular.js b/monocle-client-angular.js index 077cb23..04e4e83 100644 --- a/monocle-client-angular.js +++ b/monocle-client-angular.js @@ -1,185 +1,216 @@ -// This file may run in a browser, so wrap it in an IIFE. -(function() { - 'use strict'; - - var context = typeof exports !== 'undefined' ? exports : window; - if (typeof(require) === 'function') { - var Promise = context.Promise || require('bluebird'); - } - - var Monocle = function(http) { - this._http = http; - this._base = '/'; - }; - - Monocle.prototype.setBase = function(base) { - this._base = base; - return this; - }; - - ['get', 'post', 'put', 'patch', 'delete', 'options'].forEach(function(method) { - Monocle.prototype[method] = function(path, options) { - var fullPath = (this._base + path).replace(/\/{2,}/g, '/'); - var query = {}; - - if (options && options.props) { - query.props = options.props.join(','); - } - - var queryStringParts = []; - for (var i in query) { - queryStringParts.push(encodeURIComponent(i) + '=' + encodeURIComponent(query[i])); - } - if (queryStringParts.length) { - fullPath += '?' + queryStringParts.join('&'); - } - - return this._http.request(method.toUpperCase(), fullPath, options); - }; - }); - - if (typeof exports !== 'undefined') { - // We're in a nodejs environment, export this module - module.exports = Monocle; - } else { - // We're in a browser environment, expose this module globally - context.Monocle = Monocle; - } -})(); - -// This file is generally run in a browser, so wrap it in an IIFE -(function() { - 'use strict'; - - var context = typeof exports !== 'undefined' ? exports : window; - - function AngularAdapter($http, $q, $window) { - this._$http = $http; - this._$q = $q; - this._$window = $window; - this._timeout = 30000; - this._headers = { - 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', - 'X-Requested-With': 'XMLHttpRequest' - }; - } - - AngularAdapter.prototype.setTimeout = function(timeout) { - this._timeout = parseInt(timeout, 10) || 30000; - return this; - }; - - AngularAdapter.prototype.setHeader = function(key, value) { - this._headers[key] = value; - }; - - AngularAdapter.prototype.setHeaders = function(headers) { - for (var i in headers) { - if (!headers.hasOwnProperty(i)) continue; - this.setHeader(i, headers[i]); - } - }; - - AngularAdapter.prototype.request = function(method, path, options) { - var headerPromises = []; - var headerKeys = []; - - for (var i in this._headers) { - if (!this._headers.hasOwnProperty(i)) continue; - - if (typeof this._headers[i] === 'function') { - headerPromises.push(this._headers[i]()); - headerKeys.push(i); - continue; - } - - headerPromises.push(this._headers[i]); - headerKeys.push(i); - } - - return this._$q.all(headerPromises) - .then(function(results) { - var headers = {}; - for (var i = 0, len = results.length; i < len; i++) { - headers[headerKeys[i]] = results[i]; - } - - return this._$http({ - method: method.toUpperCase(), - url: path, - timeout: this._timeout, - headers: headers - }) - .catch(function(response) { - return this._$q.reject(response.data); - }.bind(this)) - .then(function(response) { - return response.data; - }); - }.bind(this)); - }; - - if (typeof exports !== 'undefined') { - // We're in a nodejs environment, export this module (useful for unit testing) - module.exports = AngularAdapter; - } else { - // We're in a browser environment, export this module globally, - // attached to the TaggedApi module - var Monocle = context.Monocle || {}; - Monocle.AngularAdapter = AngularAdapter; - } -})(); - -// This file is generally run in a browser, so wrap it in an IIFE -(function() { - 'use strict'; - - var wrapper = function(angular, Monocle) { - // ## Module: monocle - // Registers the module `monocle` with Angular, - // allowing Angular apps to declare this module as a dependency. - // This module has no dependencies of its own. - var module = angular.module('monocle', []); - - // Register the `monocle` provider. - module.provider('monocle', function monocleProvider() { - this._base = '/'; - this._timeout = 30000; - this._headers = {}; - - this.setBase = function(base) { - this._base = base; - }; - - this.setTimeout = function(timeout) { - this._timeout = parseInt(timeout, 10) || 30000; - }; - - this.setHeader = function(key, value) { - this._headers[key] = value; - }; - - this.$get = function($http, $q, $window) { - var angularAdapter = new Monocle.AngularAdapter($http, $q, $window); - angularAdapter.setTimeout(this._timeout); - angularAdapter.setHeaders(this._headers); - - var monocle = new Monocle(angularAdapter); - monocle.setBase(this._base); - - return monocle; - }; - - this.$get.$provide = ['$http', '$q', '$window']; - }); - }; - - if (typeof exports !== 'undefined') { - // We're in a nodejs environment, export this module - module.exports = wrapper; - } else { - // We're in a browser environment, expose this module globally - Monocle.angularWrapper = wrapper; - } -})(); -Monocle.angularWrapper(angular, Monocle); \ No newline at end of file +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; + +/******/ // The require function +/******/ function __webpack_require__(moduleId) { + +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; + +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; + +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + +/******/ // Flag the module as loaded +/******/ module.loaded = true; + +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } + + +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; + +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; + +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; + +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + + var monocle = __webpack_require__(1); + var wrapper = __webpack_require__(2); + wrapper(angular, monocle); + + +/***/ }, +/* 1 */ +/***/ function(module, exports) { + + 'use strict'; + + var Monocle = function(http) { + this._http = http; + this._base = '/'; + }; + + Monocle.prototype.setBase = function(base) { + this._base = base; + return this; + }; + + ['get', 'post', 'put', 'patch', 'delete', 'options'].forEach(function(method) { + Monocle.prototype[method] = function(path, options) { + var fullPath = (this._base + path).replace(/\/{2,}/g, '/'); + var query = {}; + + if (options && options.props) { + query.props = options.props.join(','); + } + + var queryStringParts = []; + for (var i in query) { + queryStringParts.push(encodeURIComponent(i) + '=' + encodeURIComponent(query[i])); + } + if (queryStringParts.length) { + fullPath += '?' + queryStringParts.join('&'); + } + + return this._http.request(method.toUpperCase(), fullPath, options); + }; + }); + + module.exports = Monocle; + + +/***/ }, +/* 2 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + module.exports = function(angular, Monocle) { + var AngularAdapter = __webpack_require__(3); + // ## Module: monocle + // Registers the module `monocle` with Angular, + // allowing Angular apps to declare this module as a dependency. + // This module has no dependencies of its own. + var module = angular.module('monocle', []); + + // Register the `monocle` provider. + module.provider('monocle', function monocleProvider() { + this._base = '/'; + this._timeout = 30000; + this._headers = {}; + + this.setBase = function(base) { + this._base = base; + }; + + this.setTimeout = function(timeout) { + this._timeout = parseInt(timeout, 10) || 30000; + }; + + this.setHeader = function(key, value) { + this._headers[key] = value; + }; + + this.$get = function($http, $q, $window) { + var angularAdapter = new AngularAdapter($http, $q, $window); + angularAdapter.setTimeout(this._timeout); + angularAdapter.setHeaders(this._headers); + + var monocle = new Monocle(angularAdapter); + monocle.setBase(this._base); + + return monocle; + }; + + this.$get.$provide = ['$http', '$q', '$window']; + }); + }; + + +/***/ }, +/* 3 */ +/***/ function(module, exports) { + + 'use strict'; + + function AngularAdapter($http, $q, $window) { + this._$http = $http; + this._$q = $q; + this._$window = $window; + this._timeout = 30000; + this._headers = { + 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', + 'X-Requested-With': 'XMLHttpRequest' + }; + } + + AngularAdapter.prototype.setTimeout = function(timeout) { + this._timeout = parseInt(timeout, 10) || 30000; + return this; + }; + + AngularAdapter.prototype.setHeader = function(key, value) { + this._headers[key] = value; + }; + + AngularAdapter.prototype.setHeaders = function(headers) { + for (var i in headers) { + if (!headers.hasOwnProperty(i)) continue; + this.setHeader(i, headers[i]); + } + }; + + AngularAdapter.prototype.request = function(method, path, options) { + var headerPromises = []; + var headerKeys = []; + + for (var i in this._headers) { + if (!this._headers.hasOwnProperty(i)) continue; + + if (typeof this._headers[i] === 'function') { + headerPromises.push(this._headers[i]()); + headerKeys.push(i); + continue; + } + + headerPromises.push(this._headers[i]); + headerKeys.push(i); + } + + return this._$q.all(headerPromises) + .then(function(results) { + var headers = {}; + for (var i = 0, len = results.length; i < len; i++) { + headers[headerKeys[i]] = results[i]; + } + + return this._$http({ + method: method.toUpperCase(), + url: path, + timeout: this._timeout, + headers: headers + }) + .catch(function(response) { + return this._$q.reject(response.data); + }.bind(this)) + .then(function(response) { + return response.data; + }); + }.bind(this)); + }; + + module.exports = AngularAdapter; + + +/***/ } +/******/ ]); \ No newline at end of file diff --git a/package.json b/package.json index f640614..5178d04 100644 --- a/package.json +++ b/package.json @@ -34,13 +34,15 @@ "chai-as-promised": "4.1.1", "grunt": "0.4.5", "grunt-contrib-clean": "0.5.0", - "grunt-contrib-concat": "0.5.0", "grunt-contrib-uglify": "0.5.0", "grunt-contrib-watch": "0.6.1", "grunt-docco": "0.3.3", "grunt-mocha-test": "0.11.0", + "grunt-webpack": "1.0.11", "memwatch": "0.2.2", "mocha": "1.20.1", - "sinon": "1.10.3" + "sinon": "1.10.3", + "webpack": "1.12.2", + "webpack-dev-server": "1.12.0" } } diff --git a/test/unit/lib/index_test.js b/test/unit/lib/monocle_test.js similarity index 98% rename from test/unit/lib/index_test.js rename to test/unit/lib/monocle_test.js index 9f2c2a4..91dcfce 100644 --- a/test/unit/lib/index_test.js +++ b/test/unit/lib/monocle_test.js @@ -1,5 +1,5 @@ /*jshint expr: true*/ -var Monocle = require(LIB_DIR); +var Monocle = require(LIB_DIR + '/monocle'); var HttpMock = require('./mocks/http.js'); describe('Monocle API Client', function() { diff --git a/test/unit/lib/wrappers/angular_test.js b/test/unit/lib/wrappers/angular_test.js index a8cf225..87f6f7a 100644 --- a/test/unit/lib/wrappers/angular_test.js +++ b/test/unit/lib/wrappers/angular_test.js @@ -1,5 +1,6 @@ /*jshint expr: true*/ var wrapper = require(LIB_DIR + '/wrappers/angular'); +var AngularAdapter = require(LIB_DIR + '/http_adapter/angular'); describe('Angular Wrapper', function() { beforeEach(function() { @@ -18,9 +19,6 @@ describe('Angular Wrapper', function() { this.Monocle = sinon.spy(); this.Monocle.prototype.setBase = sinon.spy(); - this.Monocle.AngularAdapter = sinon.spy(); - this.Monocle.AngularAdapter.prototype.setTimeout = sinon.spy(); - this.Monocle.AngularAdapter.prototype.setHeaders = sinon.spy(); wrapper(this.angular, this.Monocle); }); @@ -50,7 +48,7 @@ describe('Angular Wrapper', function() { var $window = {}; var provider = new (this.providers.monocle)(); var api = provider.$get($http, $q, $window); - this.Monocle.lastCall.args[0].should.be.instanceOf(this.Monocle.AngularAdapter); + this.Monocle.lastCall.args[0].should.be.instanceOf(AngularAdapter); }); it('sets base path', function() {