├── .gitignore ├── Gruntfile.js ├── README.md ├── bower.json ├── dist ├── ng-couchbase-lite.js └── ng-couchbase-lite.min.js ├── package.json └── src └── ng-couchbase-lite.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store* 2 | ~* 3 | node_modules 4 | *.log 5 | .idea 6 | bower_components 7 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | 3 | grunt.initConfig({ 4 | pkg: grunt.file.readJSON('package.json'), 5 | concat: { 6 | options: { 7 | }, 8 | dist: { 9 | src: ['src/*.js'], 10 | dest: 'dist/<%= pkg.name %>.js', 11 | }, 12 | }, 13 | 14 | uglify: { 15 | options: { 16 | banner: '// <%= pkg.name %> - v<%= pkg.version %> (<%= grunt.template.today("yyyy-mm-dd") %>)\n' + '// http://www.couchbase.com\n' 17 | }, 18 | build: { 19 | src: ['src/*.js'], 20 | dest: 'dist/<%= pkg.name %>.min.js' 21 | } 22 | }, 23 | jshint: { 24 | all: ['src/*.js'] 25 | }, 26 | clean: { 27 | js: ['dist/*.min.js'] 28 | } 29 | }); 30 | 31 | grunt.loadNpmTasks('grunt-contrib-uglify'); 32 | grunt.loadNpmTasks('grunt-contrib-jshint'); 33 | grunt.loadNpmTasks('grunt-contrib-clean'); 34 | grunt.loadNpmTasks('grunt-contrib-concat'); 35 | 36 | grunt.registerTask('test', ['clean', 'jshint']); 37 | grunt.registerTask('default', ['clean', 'jshint', 'concat', 'uglify']); 38 | 39 | }; 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ng-couchbase-lite 2 | 3 | This is an AngularJS wrapper to be used with the Couchbase Lite RESTful APIs. It makes it so you don't have to do all the requests manually, but instead can call simple commands. 4 | 5 | ## Installation 6 | 7 | Include the repositories **dist/ng-couchbase-lite.min.js** file into your mobile hybrid application's project directory. With the file in place, include the script in your HTML file, typically **index.html**. Finally inject the library into your AngularJS `angular.module` in a similar fashion to the following: 8 | 9 | ``` 10 | angular.module("modulename", ["ngCouchbaseLite"]) 11 | ``` 12 | 13 | ## Usage 14 | 15 | To use, inject `$couchbase` into your controller dependencies and call the constructor method: 16 | 17 | ``` 18 | var database = new $couchbase(databaseUrl, databaseName); 19 | ``` 20 | 21 | Note that the databaseUrl is the URL that is returned when using the `cblite.getURL` method that ships with the Apache Cordova Couchbase plugin. 22 | 23 | ### Available Commands 24 | 25 | ``` 26 | promise database.createDatabase(); 27 | promise database.getDatabase(); 28 | promise database.createDesignDocument(string designDocumentName, object designDocumentViews); 29 | promise database.createDocument(object json); 30 | promise database.getDesignDocument(string designDocumentName); 31 | promise database.queryView(string designDocumentName, string viewName); 32 | promise database.updateDocument(string documentId, string documentRevision, object jsonObject); 33 | promise database.deleteDocument(string documentId, string documentRevision); 34 | promise database.getAllDocuments(); 35 | promise database.getDocument(string documentId); 36 | promise database.replicate(string source, string target, boolean continuous); 37 | void database.listen(); 38 | ``` 39 | 40 | ## Need Help? 41 | 42 | Visit the [Couchbase Forums](https://forums.couchbase.com/) and open a ticket under the mobile section. 43 | 44 | ## Resources 45 | 46 | Couchbase Lite REST API - [http://developer.couchbase.com/mobile/develop/references/couchbase-lite/rest-api/index.html](http://developer.couchbase.com/mobile/develop/references/couchbase-lite/rest-api/index.html) 47 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ng-couchbase-lite", 3 | "main": [ 4 | "./dist/ng-couchbase-lite.js", 5 | "./dist/ng-couchbase-lite.min.js" 6 | ], 7 | "version": "0.0.1", 8 | "homepage": "https://github.com/couchbaselabs/ng-couchbase-lite", 9 | "authors": [ 10 | "Nic Raboy ", 11 | "Couchbase " 12 | ], 13 | "description": "AngularJS wrapper for Couchbase Lite RESTful API endpoints", 14 | "moduleType": [ 15 | "node" 16 | ], 17 | "keywords": [ 18 | "ng-couchbase-lite", 19 | "api", 20 | "angularjs", 21 | "couchbase", 22 | "mobile", 23 | "apache cordova", 24 | "phonegap", 25 | "ionic framework" 26 | ], 27 | "license": "MIT", 28 | "ignore": [ 29 | "**/.*", 30 | "node_modules", 31 | "bower_components", 32 | "test", 33 | "tests" 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /dist/ng-couchbase-lite.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This AngularJS factory is just a wrapper for all the RESTful API requests that 3 | * come packaged with the Couchbase Lite SDK. 4 | * 5 | * URL: http://developer.couchbase.com/mobile/develop/references/couchbase-lite/rest-api/index.html 6 | */ 7 | angular.module("ngCouchbaseLite", []).factory("$couchbase", ["$q", "$http", "$rootScope", function($q, $http, $rootScope) { 8 | 9 | this.databaseUrl = null; 10 | this.databaseName = null; 11 | 12 | /* 13 | * Construct a new Couchbase object given a database URL and database name 14 | * 15 | * @param string databaseUrl 16 | * @param string databaseName 17 | * @return promise 18 | */ 19 | var couchbase = function(databaseUrl, databaseName) { 20 | this.databaseUrl = databaseUrl; 21 | this.databaseName = databaseName; 22 | }; 23 | 24 | couchbase.prototype = { 25 | 26 | /* 27 | * Create a new database with a name that was passed in from the constructor method 28 | * 29 | * @param 30 | * @return promise 31 | */ 32 | createDatabase: function() { 33 | return this.makeRequest("PUT", this.databaseUrl + this.databaseName); 34 | }, 35 | 36 | /* 37 | * Get a database from the name that was passed in from the constructor method 38 | * 39 | * @param 40 | * @return promise 41 | */ 42 | getDatabase: function() { 43 | return this.makeRequest("GET", this.databaseUrl + this.databaseName); 44 | }, 45 | 46 | /* 47 | * Create a new design document with views 48 | * 49 | * @param string designDocumentName 50 | * @param object designDocumentViews 51 | * @return promise 52 | */ 53 | createDesignDocument: function(designDocumentName, designDocumentViews) { 54 | var data = { 55 | views: designDocumentViews 56 | }; 57 | return this.makeRequest("PUT", this.databaseUrl + this.databaseName + "/" + designDocumentName, {}, data); 58 | }, 59 | 60 | /* 61 | * Get a design document and all views associated to insert 62 | * 63 | * @param string designDocumentName 64 | * @return promise 65 | */ 66 | getDesignDocument: function(designDocumentName) { 67 | return this.makeRequest("GET", this.databaseUrl + this.databaseName + "/" + designDocumentName); 68 | }, 69 | 70 | /* 71 | * Query a particular database view 72 | * 73 | * @param string designDocumentName 74 | * @param string viewName 75 | * @param object options 76 | * @return promise 77 | */ 78 | queryView: function(designDocumentName, viewName, options) { 79 | return this.makeRequest("GET", this.databaseUrl + this.databaseName + "/" + designDocumentName + "/_view/" + viewName, options); 80 | }, 81 | 82 | /* 83 | * Create a new database document 84 | * 85 | * @param object jsonDocument 86 | * @return promise 87 | */ 88 | createDocument: function(jsonDocument) { 89 | return this.makeRequest("POST", this.databaseUrl + this.databaseName, {}, jsonDocument); 90 | }, 91 | 92 | /* 93 | * Update a particular document based on its id and revision 94 | * 95 | * @param string documentId 96 | * @param string documentRevision 97 | * @param object jsonDocument 98 | * @return promise 99 | */ 100 | updateDocument: function(documentId, documentRevision, jsonDocument) { 101 | return this.makeRequest("PUT", this.databaseUrl + this.databaseName + "/" + documentId, {rev: documentRevision}, jsonDocument); 102 | }, 103 | 104 | /* 105 | * Delete a particular document based on its id and revision 106 | * 107 | * @param string documentId 108 | * @param string documentRevision 109 | * @return promise 110 | */ 111 | deleteDocument: function(documentId, documentRevision) { 112 | return this.makeRequest("DELETE", this.databaseUrl + this.databaseName + "/" + documentId, {rev: documentRevision}); 113 | }, 114 | 115 | /* 116 | * Get all documents from the database 117 | * 118 | * @param 119 | * @return promise 120 | */ 121 | getAllDocuments: function() { 122 | return this.makeRequest("GET", this.databaseUrl + this.databaseName + "/_all_docs"); 123 | }, 124 | 125 | /* 126 | * Get a document from the database 127 | * 128 | * @param string documentId 129 | * @return promise 130 | */ 131 | getDocument: function(documentId) { 132 | return this.makeRequest("GET", this.databaseUrl + this.databaseName + "/" + documentId); 133 | }, 134 | 135 | /* 136 | * Replicate in a single direction whether that be local to remote or remote to local 137 | * 138 | * @param string source 139 | * @param string target 140 | * @param boolean continuous 141 | * @return promise 142 | */ 143 | replicate: function(source, target, continuous) { 144 | return this.makeRequest("POST", this.databaseUrl + "_replicate", {}, {source: source, target: target, continuous: continuous}); 145 | }, 146 | 147 | /* 148 | * Continually poll the database for changes that include replications from a remote source 149 | * 150 | * @param 151 | * @return 152 | */ 153 | listen: function() { 154 | var poller = function(databaseUrl, databaseName, cseq) { 155 | $http({method: "GET", url: databaseUrl + databaseName + "/_changes", params: {feed: "longpoll", since: cseq}, withCredentials: true}).then(function(result) { 156 | $rootScope.$broadcast("couchbase:change", result.data); 157 | setTimeout(function() { 158 | poller(databaseUrl, databaseName, result.data.last_seq); 159 | }, 10); 160 | }, function(error) { 161 | console.log("POLLING ERROR -> " + JSON.stringify(error)); 162 | }); 163 | }; 164 | poller(this.databaseUrl, this.databaseName, 0); 165 | }, 166 | 167 | /* 168 | * Make a RESTful request to an endpoint while providing parameters or data or both 169 | * 170 | * @param string method 171 | * @param string url 172 | * @param object params 173 | * @param object data 174 | * @return promise 175 | */ 176 | makeRequest: function(method, url, params, data) { 177 | var deferred = $q.defer(); 178 | var settings = { 179 | method: method, 180 | url: url, 181 | withCredentials: true 182 | }; 183 | if(params) { 184 | settings.params = params; 185 | } 186 | if(data) { 187 | settings.data = data; 188 | } 189 | $http(settings) 190 | .success(function(result) { 191 | deferred.resolve(result); 192 | }) 193 | .error(function(error) { 194 | deferred.reject(error); 195 | }); 196 | return deferred.promise; 197 | } 198 | 199 | }; 200 | 201 | return couchbase; 202 | 203 | }]); 204 | -------------------------------------------------------------------------------- /dist/ng-couchbase-lite.min.js: -------------------------------------------------------------------------------- 1 | // ng-couchbase-lite - v0.0.1 (2016-02-05) 2 | // http://www.couchbase.com 3 | angular.module("ngCouchbaseLite",[]).factory("$couchbase",["$q","$http","$rootScope",function(a,b,c){this.databaseUrl=null,this.databaseName=null;var d=function(a,b){this.databaseUrl=a,this.databaseName=b};return d.prototype={createDatabase:function(){return this.makeRequest("PUT",this.databaseUrl+this.databaseName)},getDatabase:function(){return this.makeRequest("GET",this.databaseUrl+this.databaseName)},createDesignDocument:function(a,b){var c={views:b};return this.makeRequest("PUT",this.databaseUrl+this.databaseName+"/"+a,{},c)},getDesignDocument:function(a){return this.makeRequest("GET",this.databaseUrl+this.databaseName+"/"+a)},queryView:function(a,b,c){return this.makeRequest("GET",this.databaseUrl+this.databaseName+"/"+a+"/_view/"+b,c)},createDocument:function(a){return this.makeRequest("POST",this.databaseUrl+this.databaseName,{},a)},updateDocument:function(a,b,c){return this.makeRequest("PUT",this.databaseUrl+this.databaseName+"/"+a,{rev:b},c)},deleteDocument:function(a,b){return this.makeRequest("DELETE",this.databaseUrl+this.databaseName+"/"+a,{rev:b})},getAllDocuments:function(){return this.makeRequest("GET",this.databaseUrl+this.databaseName+"/_all_docs")},getDocument:function(a){return this.makeRequest("GET",this.databaseUrl+this.databaseName+"/"+a)},replicate:function(a,b,c){return this.makeRequest("POST",this.databaseUrl+"_replicate",{},{source:a,target:b,continuous:c})},listen:function(){var a=function(d,e,f){b({method:"GET",url:d+e+"/_changes",params:{feed:"longpoll",since:f},withCredentials:!0}).then(function(b){c.$broadcast("couchbase:change",b.data),setTimeout(function(){a(d,e,b.data.last_seq)},10)},function(a){console.log("POLLING ERROR -> "+JSON.stringify(a))})};a(this.databaseUrl,this.databaseName,0)},makeRequest:function(c,d,e,f){var g=a.defer(),h={method:c,url:d,withCredentials:!0};return e&&(h.params=e),f&&(h.data=f),b(h).success(function(a){g.resolve(a)}).error(function(a){g.reject(a)}),g.promise}},d}]); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ng-couchbase-lite", 3 | "version": "0.0.1", 4 | "description": "AngularJS wrapper for Couchbase Lite RESTful API endpoints", 5 | "author": { 6 | "name": "Couchbase, Inc.", 7 | "url": "http://www.couchbase.com" 8 | }, 9 | "homepage": "https://www.couchbase.com", 10 | "devDependencies": { 11 | "grunt": "~0.4.5", 12 | "grunt-contrib-jshint": "~0.10.0", 13 | "grunt-contrib-clean": "~0.6.0", 14 | "grunt-contrib-uglify": "~0.5.0", 15 | "grunt-contrib-concat": "^0.5.1" 16 | }, 17 | "keywords": [ 18 | "angularjs", 19 | "restful", 20 | "api", 21 | "couchbase", 22 | "mobile", 23 | "android", 24 | "ios" 25 | ], 26 | "license": "MIT", 27 | "scripts": { 28 | "test": "grunt test" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/ng-couchbase-lite.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This AngularJS factory is just a wrapper for all the RESTful API requests that 3 | * come packaged with the Couchbase Lite SDK. 4 | * 5 | * URL: http://developer.couchbase.com/mobile/develop/references/couchbase-lite/rest-api/index.html 6 | */ 7 | angular.module("ngCouchbaseLite", []).factory("$couchbase", ["$q", "$http", "$rootScope", function($q, $http, $rootScope) { 8 | 9 | this.databaseUrl = null; 10 | this.databaseName = null; 11 | 12 | /* 13 | * Construct a new Couchbase object given a database URL and database name 14 | * 15 | * @param string databaseUrl 16 | * @param string databaseName 17 | * @return promise 18 | */ 19 | var couchbase = function(databaseUrl, databaseName) { 20 | this.databaseUrl = databaseUrl; 21 | this.databaseName = databaseName; 22 | }; 23 | 24 | couchbase.prototype = { 25 | 26 | /* 27 | * returns the database url 28 | * 29 | * @param 30 | * @return string 31 | */ 32 | getUrl: function() { 33 | return this.databaseUrl; 34 | }, 35 | 36 | /* 37 | * Create a new database with a name that was passed in from the constructor method 38 | * 39 | * @param 40 | * @return promise 41 | */ 42 | createDatabase: function() { 43 | return this.makeRequest("PUT", this.databaseUrl + this.databaseName); 44 | }, 45 | 46 | /* 47 | * Get a database from the name that was passed in from the constructor method 48 | * 49 | * @param 50 | * @return promise 51 | */ 52 | getDatabase: function() { 53 | return this.makeRequest("GET", this.databaseUrl + this.databaseName); 54 | }, 55 | 56 | /* 57 | * Create a new design document with views 58 | * 59 | * @param string designDocumentName 60 | * @param object designDocumentViews 61 | * @return promise 62 | */ 63 | createDesignDocument: function(designDocumentName, designDocumentViews) { 64 | var data = { 65 | views: designDocumentViews 66 | }; 67 | var designPrefix = ""; 68 | if(designDocumentName.indexOf("_design/") === -1){ 69 | designPrefix = "_design/"; 70 | } 71 | return this.makeRequest("PUT", this.databaseUrl + this.databaseName + "/" + designPrefix + designDocumentName, {}, data); 72 | }, 73 | 74 | /* 75 | * Get a design document and all views associated to insert 76 | * 77 | * @param string designDocumentName 78 | * @return promise 79 | */ 80 | getDesignDocument: function(designDocumentName) { 81 | var designPrefix = ""; 82 | if(designDocumentName.indexOf("_design/") === -1){ 83 | designPrefix = "_design/"; 84 | } 85 | return this.makeRequest("GET", this.databaseUrl + this.databaseName + "/" + designPrefix + designDocumentName); 86 | }, 87 | 88 | /* 89 | * Query a particular database view 90 | * 91 | * @param string designDocumentName 92 | * @param string viewName 93 | * @param object options 94 | * @return promise 95 | */ 96 | queryView: function(designDocumentName, viewName, options) { 97 | return this.makeRequest("GET", this.databaseUrl + this.databaseName + "/" + designDocumentName + "/_view/" + viewName, options); 98 | }, 99 | 100 | /* 101 | * Create a new database document 102 | * 103 | * @param object jsonDocument 104 | * @return promise 105 | */ 106 | createDocument: function(jsonDocument) { 107 | return this.makeRequest("POST", this.databaseUrl + this.databaseName, {}, jsonDocument); 108 | }, 109 | 110 | /* 111 | * Create a new database local document 112 | * 113 | * @param string id or empty string for auto generated id, object jsonDocument 114 | * @return promise 115 | */ 116 | createLocalDocument: function(id,jsonDocument) { 117 | return this.makeRequest("PUT", this.databaseUrl + this.databaseName + "/_local/" + id, {}, jsonDocument); 118 | }, 119 | 120 | /* 121 | * Update a particular document based on its id and revision 122 | * 123 | * @param string documentId 124 | * @param string documentRevision 125 | * @param object jsonDocument 126 | * @return promise 127 | */ 128 | updateDocument: function(documentId, documentRevision, jsonDocument) { 129 | return this.makeRequest("PUT", this.databaseUrl + this.databaseName + "/" + documentId, {rev: documentRevision}, jsonDocument); 130 | }, 131 | 132 | /* 133 | * Delete a particular document based on its id and revision 134 | * 135 | * @param string documentId 136 | * @param string documentRevision 137 | * @return promise 138 | */ 139 | deleteDocument: function(documentId, documentRevision) { 140 | return this.makeRequest("DELETE", this.databaseUrl + this.databaseName + "/" + documentId, {rev: documentRevision}); 141 | }, 142 | 143 | /* 144 | * Get all documents from the database 145 | * 146 | * @param 147 | * @return promise 148 | */ 149 | getAllDocuments: function() { 150 | return this.makeRequest("GET", this.databaseUrl + this.databaseName + "/_all_docs"); 151 | }, 152 | 153 | /* 154 | * Get a document from the database 155 | * 156 | * @param string documentId 157 | * @return promise 158 | */ 159 | getDocument: function(documentId) { 160 | return this.makeRequest("GET", this.databaseUrl + this.databaseName + "/" + documentId); 161 | }, 162 | 163 | /* 164 | * Get a local document from the database 165 | * 166 | * @param string documentId 167 | * @return promise 168 | */ 169 | getLocalDocument: function(documentId) { 170 | return this.makeRequest("GET", this.databaseUrl + this.databaseName + "/_local/" + documentId); 171 | }, 172 | 173 | /* 174 | * Replicate in a single direction whether that be local to remote or remote to local 175 | * 176 | * @param string source 177 | * @param string target 178 | * @param boolean continuous 179 | * @return promise 180 | */ 181 | replicate: function(source, target, continuous) { 182 | return this.makeRequest("POST", this.databaseUrl + "_replicate", {}, {source: source, target: target, continuous: continuous}); 183 | }, 184 | 185 | /* 186 | * Continually poll the database for changes that include replications from a remote source 187 | * 188 | * @param 189 | * @return 190 | */ 191 | listen: function() { 192 | var poller = function(databaseUrl, databaseName, cseq) { 193 | $http({method: "GET", url: databaseUrl + databaseName + "/_changes", params: {feed: "longpoll", since: cseq}, withCredentials: true}).then(function(result) { 194 | $rootScope.$broadcast("couchbase:change", result.data); 195 | setTimeout(function() { 196 | poller(databaseUrl, databaseName, result.data.last_seq); 197 | }, 10); 198 | }, function(error) { 199 | console.log("POLLING ERROR -> " + JSON.stringify(error)); 200 | }); 201 | }; 202 | poller(this.databaseUrl, this.databaseName, 0); 203 | }, 204 | 205 | /* 206 | * retrieve a list of all tasks running on the server 207 | * 208 | * @param 209 | * @return promise 210 | */ 211 | getActiveTasks: function () { 212 | return this.makeRequest("GET", this.databaseUrl + "_active_tasks"); 213 | }, 214 | 215 | /* 216 | * Make a RESTful request to an endpoint while providing parameters or data or both 217 | * 218 | * @param string method 219 | * @param string url 220 | * @param object params 221 | * @param object data 222 | * @param boolean complete 223 | * @return promise 224 | */ 225 | makeRequest: function(method, url, params, data,complete) { 226 | var deferred = $q.defer(); 227 | var settings = { 228 | method: method, 229 | url: url, 230 | withCredentials: true 231 | }; 232 | if(params) { 233 | settings.params = params; 234 | } 235 | if(data) { 236 | settings.data = data; 237 | } 238 | if(complete){ 239 | return $http(settings); 240 | } 241 | $http(settings) 242 | .success(function(result) { 243 | deferred.resolve(result); 244 | }) 245 | .error(function(error) { 246 | deferred.reject(error); 247 | }); 248 | 249 | return deferred.promise; 250 | } 251 | 252 | }; 253 | 254 | return couchbase; 255 | 256 | }]); 257 | --------------------------------------------------------------------------------