├── .DS_Store ├── .gitignore ├── Gruntfile.js ├── README.md ├── bower.json ├── dist ├── angular-api.js └── angular-api.min.js ├── karma.conf.js ├── package.json ├── src ├── angular-api.js └── api.js └── test └── apiTest.js /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rodrigobranas/angular-api/04cce9ce7ba51c96563148b1c3dde03916f04519/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function (grunt) { 2 | 3 | grunt.initConfig({ 4 | clean: { 5 | dist: ['dist/'] 6 | }, 7 | jshint: { 8 | options: { 9 | curly: false, 10 | eqeqeq: false, 11 | immed: true, 12 | latedef: true, 13 | newcap: true, 14 | noarg: true, 15 | sub: true, 16 | undef: false, 17 | unused: false, 18 | boss: true, 19 | eqnull: false, 20 | browser: true, 21 | noempty: true, 22 | trailing: true, 23 | globals: { 24 | jQuery: true 25 | } 26 | }, 27 | dist: ['js/*.js'] 28 | }, 29 | concat: { 30 | dist: { 31 | src: ['src/api.js', 'src/angular-api.js'], 32 | dest: 'dist/angular-api.js' 33 | } 34 | }, 35 | uglify: { 36 | dist: { 37 | src: ['dist/angular-api.js'], 38 | dest: 'dist/angular-api.min.js' 39 | } 40 | }, 41 | karma: { 42 | dist: { 43 | configFile: 'karma.conf.js', 44 | } 45 | } 46 | }); 47 | 48 | grunt.loadNpmTasks('grunt-contrib-clean'); 49 | grunt.loadNpmTasks('grunt-contrib-jshint'); 50 | grunt.loadNpmTasks('grunt-contrib-concat'); 51 | grunt.loadNpmTasks('grunt-contrib-uglify'); 52 | grunt.loadNpmTasks('grunt-karma'); 53 | 54 | grunt.registerTask('dist', ['clean', 'jshint', 'concat', 'uglify', 'karma']); 55 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # angular-api 2 | Angular API mapper 3 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-api", 3 | "main": "angular-api.js", 4 | "version": "1.0.0", 5 | "homepage": "https://github.com/rodrigobranas/angular-api", 6 | "authors": [ 7 | "Rodrigo Branas " 8 | ], 9 | "description": "Angular API mapper", 10 | "keywords": [ 11 | "angular" 12 | ], 13 | "license": "MIT", 14 | "ignore": [ 15 | "**/.*", 16 | "node_modules", 17 | "bower_components", 18 | "test", 19 | "tests" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /dist/angular-api.js: -------------------------------------------------------------------------------- 1 | var buildApi = function (config, http) { 2 | 3 | var createQueryString = function (queryString) { 4 | var parameters = []; 5 | for(parameter in queryString) { 6 | parameters.push(parameter + "=" + queryString[parameter]); 7 | } 8 | return "?" + parameters.join("&"); 9 | }; 10 | 11 | var addTimestamp = function (url, queryString) { 12 | if (!config.nocache) return url; 13 | return url + ((queryString) ? "&" : "?") + "nocache=" + new Date().getTime(); 14 | }; 15 | 16 | var createUrl = function (parent, resource, id, queryString) { 17 | return parent + resource + ((id) ? "/" + id : "") + ((queryString) ? createQueryString(queryString) : ""); 18 | }; 19 | 20 | var createResource = function (resourceName, parent, options) { 21 | var resource = {}; 22 | if (options.resources) resource.resource = function (id) { 23 | return createUrl(parent, resourceName, id) + "/"; 24 | }; 25 | resource.get = function (id, queryString, config) { 26 | return http.get(addTimestamp(createUrl(parent, resourceName, id, queryString), queryString), config); 27 | }; 28 | resource.list = function (queryString, config) { 29 | return http.get(addTimestamp(createUrl(parent, resourceName, undefined, queryString), queryString), config); 30 | }; 31 | resource.save = function (data, queryString, config) { 32 | if (options.beforeSave) data = options.beforeSave(data); 33 | return http.post(createUrl(parent, resourceName, undefined, queryString), data, config); 34 | }; 35 | resource.update = function (id, data, queryString, config) { 36 | return http.put(createUrl(parent, resourceName, id, queryString), data, config); 37 | }; 38 | resource.patch = function (id, data, queryString, config) { 39 | return http.patch(createUrl(parent, resourceName, id, queryString), data, config); 40 | }; 41 | resource.delete = function (id, queryString, config) { 42 | return http.delete(createUrl(parent, resourceName, id, queryString), config); 43 | }; 44 | 45 | resource.getOperations = function (id) { 46 | var url = createUrl(parent, resourceName, id); 47 | var operations = {}; 48 | for(operation in options.operations) { 49 | (function (operation) { 50 | operations[operation] = function (data, queryString, config) { 51 | var method = options.operations[operation].method; 52 | return http[method](addTimestamp(url + "/" + operation + ((queryString) ? createQueryString(queryString) : ""), ((queryString) ? createQueryString(queryString) : "")), data, config); 53 | } 54 | })(operation); 55 | } 56 | 57 | return operations; 58 | }; 59 | 60 | return resource; 61 | }; 62 | 63 | var createStructure = function (resources, parent) { 64 | var structure = {}; 65 | for(resourceChild in resources) { 66 | structure[resourceChild] = createResource(resourceChild, parent, resources[resourceChild]); 67 | if (!resources[resourceChild].resources) continue; 68 | (function (resourceChild) { 69 | structure[resourceChild].getResources = function (id) { 70 | return createStructure(resources[resourceChild].resources, structure[resourceChild].resource(id)); 71 | }; 72 | })(resourceChild); 73 | } 74 | return structure; 75 | }; 76 | 77 | return createStructure(config.resources, config.baseUrl); 78 | }; 79 | angular.module("ngApi", []); 80 | angular.module("ngApi").provider("api", function () { 81 | var _config; 82 | 83 | this.setConfig = function (config) { 84 | _config = config; 85 | }; 86 | 87 | this.$get = ["$http", function ($http) { 88 | return buildApi(_config, $http); 89 | }]; 90 | }); -------------------------------------------------------------------------------- /dist/angular-api.min.js: -------------------------------------------------------------------------------- 1 | var buildApi=function(a,b){var c=function(a){var b=[];for(parameter in a)b.push(parameter+"="+a[parameter]);return"?"+b.join("&")},d=function(b,c){return a.nocache?b+(c?"&":"?")+"nocache="+(new Date).getTime():b},e=function(a,b,d,e){return a+b+(d?"/"+d:"")+(e?c(e):"")},f=function(a,f,g){var h={};return g.resources&&(h.resource=function(b){return e(f,a,b)+"/"}),h.get=function(c,g,h){return b.get(d(e(f,a,c,g),g),h)},h.list=function(c,g){return b.get(d(e(f,a,void 0,c),c),g)},h.save=function(c,d,h){return g.beforeSave&&(c=g.beforeSave(c)),b.post(e(f,a,void 0,d),c,h)},h.update=function(c,d,g,h){return b.put(e(f,a,c,g),d,h)},h.patch=function(c,d,g,h){return b.patch(e(f,a,c,g),d,h)},h["delete"]=function(c,d,g){return b["delete"](e(f,a,c,d),g)},h.getOperations=function(h){var i=e(f,a,h),j={};for(operation in g.operations)!function(a){j[a]=function(e,f,h){var j=g.operations[a].method;return b[j](d(i+"/"+a+(f?c(f):""),f?c(f):""),e,h)}}(operation);return j},h},g=function(a,b){var c={};for(resourceChild in a)c[resourceChild]=f(resourceChild,b,a[resourceChild]),a[resourceChild].resources&&!function(b){c[b].getResources=function(d){return g(a[b].resources,c[b].resource(d))}}(resourceChild);return c};return g(a.resources,a.baseUrl)};angular.module("ngApi",[]),angular.module("ngApi").provider("api",function(){var a;this.setConfig=function(b){a=b},this.$get=["$http",function(b){return buildApi(a,b)}]}); -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration 2 | // Generated on Mon Aug 03 2015 16:30:06 GMT-0300 (BRT) 3 | 4 | module.exports = function(config) { 5 | config.set({ 6 | 7 | // base path that will be used to resolve all patterns (eg. files, exclude) 8 | basePath: '', 9 | 10 | 11 | // frameworks to use 12 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter 13 | frameworks: ['jasmine'], 14 | 15 | 16 | // list of files / patterns to load in the browser 17 | files: [ 18 | 'src/api.js', 19 | 'test/apiTest.js' 20 | ], 21 | 22 | 23 | // list of files to exclude 24 | exclude: [ 25 | ], 26 | 27 | 28 | // preprocess matching files before serving them to the browser 29 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor 30 | preprocessors: { 31 | }, 32 | 33 | 34 | // test results reporter to use 35 | // possible values: 'dots', 'progress' 36 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter 37 | reporters: ['progress'], 38 | 39 | 40 | // web server port 41 | port: 9876, 42 | 43 | 44 | // enable / disable colors in the output (reporters and logs) 45 | colors: true, 46 | 47 | 48 | // level of logging 49 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 50 | logLevel: config.LOG_INFO, 51 | 52 | 53 | // enable / disable watching file and executing tests whenever any file changes 54 | autoWatch: true, 55 | 56 | 57 | // start these browsers 58 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher 59 | browsers: ['Chrome'], 60 | 61 | 62 | // Continuous Integration mode 63 | // if true, Karma captures browsers, runs the tests and exits 64 | singleRun: false 65 | }) 66 | } 67 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "branas-angular-api", 3 | "version": "1.1.3", 4 | "description": "Angular API mapper", 5 | "main": "Gruntfile.js", 6 | "directories": { 7 | "test": "test" 8 | }, 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/rodrigobranas/angular-api.git" 15 | }, 16 | "keywords": [ 17 | "angular" 18 | ], 19 | "author": "Rodrigo Branas", 20 | "license": "ISC", 21 | "bugs": { 22 | "url": "https://github.com/rodrigobranas/angular-api/issues" 23 | }, 24 | "homepage": "https://github.com/rodrigobranas/angular-api#readme", 25 | "dependencies": { 26 | "grunt": "^0.4.5", 27 | "grunt-contrib-clean": "^0.6.0", 28 | "grunt-contrib-concat": "^0.5.1", 29 | "grunt-contrib-copy": "^0.8.0", 30 | "grunt-contrib-jshint": "^0.11.2", 31 | "grunt-contrib-uglify": "^0.9.1", 32 | "grunt-karma": "^0.12.0", 33 | "jasmine-core": "^2.3.4", 34 | "karma": "^0.13.3", 35 | "karma-chrome-launcher": "^0.2.0", 36 | "karma-jasmine": "^0.3.6" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/angular-api.js: -------------------------------------------------------------------------------- 1 | angular.module("ngApi", []); 2 | angular.module("ngApi").provider("api", function () { 3 | var _config; 4 | 5 | this.setConfig = function (config) { 6 | _config = config; 7 | }; 8 | 9 | this.$get = ["$http", function ($http) { 10 | return buildApi(_config, $http); 11 | }]; 12 | }); -------------------------------------------------------------------------------- /src/api.js: -------------------------------------------------------------------------------- 1 | var buildApi = function (config, http) { 2 | 3 | var createQueryString = function (queryString) { 4 | var parameters = []; 5 | for(var parameter in queryString) { 6 | parameters.push(parameter + "=" + queryString[parameter]); 7 | } 8 | return "?" + parameters.join("&"); 9 | }; 10 | 11 | var addTimestamp = function (url, queryString) { 12 | if (!config.nocache) return url; 13 | return url + ((queryString) ? "&" : "?") + "nocache=" + new Date().getTime(); 14 | }; 15 | 16 | var createUrl = function (parent, resource, id, queryString) { 17 | return parent + resource + ((id) ? "/" + id : "") + ((queryString) ? createQueryString(queryString) : ""); 18 | }; 19 | 20 | var createResource = function (resourceName, parent, options) { 21 | var resource = {}; 22 | if (options.resources) resource.resource = function (id) { 23 | return createUrl(parent, resourceName, id) + "/"; 24 | }; 25 | resource.get = function (id, queryString, config) { 26 | return http.get(addTimestamp(createUrl(parent, resourceName, id, queryString), queryString), config); 27 | }; 28 | resource.list = function (queryString, config) { 29 | return http.get(addTimestamp(createUrl(parent, resourceName, undefined, queryString), queryString), config); 30 | }; 31 | resource.save = function (data, queryString, config) { 32 | if (options.beforeSave) data = options.beforeSave(data); 33 | return http.post(createUrl(parent, resourceName, undefined, queryString), data, config); 34 | }; 35 | resource.update = function (id, data, queryString, config) { 36 | return http.put(createUrl(parent, resourceName, id, queryString), data, config); 37 | }; 38 | resource.patch = function (id, data, queryString, config) { 39 | return http.patch(createUrl(parent, resourceName, id, queryString), data, config); 40 | }; 41 | resource.delete = function (id, queryString, config) { 42 | return http.delete(createUrl(parent, resourceName, id, queryString), config); 43 | }; 44 | 45 | resource.getOperations = function (id) { 46 | var url = createUrl(parent, resourceName, id); 47 | var operations = {}; 48 | for(var operation in options.operations) { 49 | (function (operation) { 50 | operations[operation] = function (data, queryString, config) { 51 | var method = options.operations[operation].method; 52 | return http[method](addTimestamp(url + "/" + operation + ((queryString) ? createQueryString(queryString) : ""), ((queryString) ? createQueryString(queryString) : "")), data, config); 53 | } 54 | })(operation); 55 | } 56 | 57 | return operations; 58 | }; 59 | 60 | return resource; 61 | }; 62 | 63 | var createStructure = function (resources, parent) { 64 | var structure = {}; 65 | for(var resourceChild in resources) { 66 | structure[resourceChild] = createResource(resourceChild, parent, resources[resourceChild]); 67 | if (!resources[resourceChild].resources) continue; 68 | (function (resourceChild) { 69 | structure[resourceChild].getResources = function (id) { 70 | return createStructure(resources[resourceChild].resources, structure[resourceChild].resource(id)); 71 | }; 72 | })(resourceChild); 73 | } 74 | return structure; 75 | }; 76 | 77 | return createStructure(config.resources, config.baseUrl); 78 | }; -------------------------------------------------------------------------------- /test/apiTest.js: -------------------------------------------------------------------------------- 1 | describe("API Test", function () { 2 | it("Should be configured", function () { 3 | 4 | var config = { 5 | baseUrl: "http://kapta.gennera.com.br/", 6 | nocache: true, 7 | resources: { 8 | app: {}, 9 | formulario: { 10 | resources: { 11 | resposta: { 12 | resources: { 13 | lancamento: {} 14 | }, 15 | }, 16 | relatorio: {}, 17 | comunicado: {} 18 | }, 19 | beforeSave: function (data) { 20 | data.metadata = JSON.stringify(data.metadata); 21 | return data; 22 | } 23 | }, 24 | smtp: { 25 | operations: { 26 | testar: { 27 | method: "put" 28 | }, 29 | homologar: { 30 | method: "post" 31 | }, 32 | confirmar: { 33 | method: "get" 34 | } 35 | } 36 | }, 37 | portador: {}, 38 | pergunta: {} 39 | } 40 | }; 41 | 42 | var http = { 43 | get: function (url, config) { 44 | return "GET(" + url + ")" + ((config) ? " with config (" + Object.keys(config) + ")" : ""); 45 | }, 46 | post: function (url, data, config) { 47 | return "POST(" + url + ")" + ((config) ? " with config (" + Object.keys(config) + ")" : ""); 48 | }, 49 | put: function (url, data, config) { 50 | return "PUT(" + url + ")" + ((config) ? " with config (" + Object.keys(config) + ")" : ""); 51 | }, 52 | patch: function (url, data, config) { 53 | return "PATCH(" + url + ")" + ((config) ? " with config (" + Object.keys(config) + ")" : ""); 54 | }, 55 | delete: function (url, config) { 56 | return "DELETE(" + url + ")" + ((config) ? " with config (" + Object.keys(config) + ")" : ""); 57 | } 58 | }; 59 | 60 | var api = buildApi(config, http); 61 | 62 | Date.prototype.getTime = function () { 63 | return "xyz"; 64 | }; 65 | 66 | expect(api.app.get(1, undefined, {a: 1, b: 2, c: 3})).toBe("GET(http://kapta.gennera.com.br/app/1?nocache=xyz) with config (a,b,c)"); 67 | expect(api.app.get(2, {customer: 1}, {a: 1, b: 2, c: 3})).toBe("GET(http://kapta.gennera.com.br/app/2?customer=1&nocache=xyz) with config (a,b,c)"); 68 | expect(api.formulario.list({fields: "id,hash,titulo,tags,seguranca"}, {a: 1, b: 2, c: 3})).toBe("GET(http://kapta.gennera.com.br/formulario?fields=id,hash,titulo,tags,seguranca&nocache=xyz) with config (a,b,c)"); 69 | expect(api.smtp.save()).toBe("POST(http://kapta.gennera.com.br/smtp)"); 70 | expect(api.smtp.getOperations(2).testar({})).toBe("PUT(http://kapta.gennera.com.br/smtp/2/testar?nocache=xyz)"); 71 | expect(api.smtp.getOperations(10).testar(undefined, {customer: 1, user: 2, product: 100})).toBe("PUT(http://kapta.gennera.com.br/smtp/10/testar?customer=1&user=2&product=100&nocache=xyz)"); 72 | expect(api.smtp.getOperations().homologar(undefined, undefined, {a: 1, b: 2, c: 3})).toBe("POST(http://kapta.gennera.com.br/smtp/homologar?nocache=xyz) with config (a,b,c)"); 73 | expect(api.smtp.getOperations(2).confirmar(undefined, {customer: 1})).toBe("GET(http://kapta.gennera.com.br/smtp/2/confirmar?customer=1&nocache=xyz)"); 74 | expect(api.portador.get(3)).toBe("GET(http://kapta.gennera.com.br/portador/3?nocache=xyz)"); 75 | expect(api.pergunta.update(4)).toBe("PUT(http://kapta.gennera.com.br/pergunta/4)"); 76 | expect(api.pergunta.update(5, undefined, {customer: 1})).toBe("PUT(http://kapta.gennera.com.br/pergunta/5?customer=1)"); 77 | expect(api.formulario.getResources(5).resposta.delete(9, undefined, {a: 1, b: 2, c: 3})).toBe("DELETE(http://kapta.gennera.com.br/formulario/5/resposta/9) with config (a,b,c)"); 78 | expect(api.formulario.getResources(6).relatorio.get(10)).toBe("GET(http://kapta.gennera.com.br/formulario/6/relatorio/10?nocache=xyz)"); 79 | expect(api.formulario.getResources(7).comunicado.get(11)).toBe("GET(http://kapta.gennera.com.br/formulario/7/comunicado/11?nocache=xyz)"); 80 | expect(api.formulario.getResources(8).resposta.getResources(12).lancamento.get(13)).toBe("GET(http://kapta.gennera.com.br/formulario/8/resposta/12/lancamento/13?nocache=xyz)"); 81 | expect(api.formulario.getResources(8).resposta.getResources(12).lancamento.get(14, {customer: 1})).toBe("GET(http://kapta.gennera.com.br/formulario/8/resposta/12/lancamento/14?customer=1&nocache=xyz)"); 82 | expect(api.formulario.save({})).toBe("POST(http://kapta.gennera.com.br/formulario)"); 83 | expect(api.formulario.save({}, {customer: 1})).toBe("POST(http://kapta.gennera.com.br/formulario?customer=1)"); 84 | expect(api.pergunta.patch(4)).toBe("PATCH(http://kapta.gennera.com.br/pergunta/4)"); 85 | expect(api.pergunta.patch(5, undefined, {customer: 1})).toBe("PATCH(http://kapta.gennera.com.br/pergunta/5?customer=1)"); 86 | }); 87 | }); --------------------------------------------------------------------------------