├── .gitignore ├── grunt ├── coffeelint.coffee ├── jsonlint.coffee ├── jshint.coffee ├── jsdoc.coffee ├── yuidoc.coffee ├── gh-pages.coffee ├── release.coffee ├── aliases.yaml └── swagger-js-codegen.coffee ├── CHANGELOG.md ├── .editorconfig ├── Gruntfile.js ├── README.md ├── coffeelint.json ├── templates ├── request.mustache ├── class.mustache └── method.mustache ├── .jshintrc ├── package.json └── .travis.yml /.gitignore: -------------------------------------------------------------------------------- 1 | doc 2 | node_modules 3 | -------------------------------------------------------------------------------- /grunt/coffeelint.coffee: -------------------------------------------------------------------------------- 1 | module.exports = 2 | 3 | grunt: ['grunt/**/*.coffee'] 4 | -------------------------------------------------------------------------------- /grunt/jsonlint.coffee: -------------------------------------------------------------------------------- 1 | module.exports = 2 | 3 | package: 4 | src: ['package.json'] 5 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ### 0.0.8 - 2015-12-11 2 | ### 0.0.7 - 2015-12-09 3 | ### 0.0.6 - 2015-12-09 4 | ### 0.0.5 - 2015-12-09 5 | ### 0.0.4 - 2015-12-09 6 | -------------------------------------------------------------------------------- /grunt/jshint.coffee: -------------------------------------------------------------------------------- 1 | module.exports = 2 | all: ['Gruntfile.js', 'lib/**/*.js', 'test/**/*.js'] 3 | options: 4 | jshintrc: '.jshintrc' 5 | 6 | -------------------------------------------------------------------------------- /grunt/jsdoc.coffee: -------------------------------------------------------------------------------- 1 | module.exports = 2 | 3 | doc: 4 | src: ['lib/**/*.js'] 5 | options: 6 | destination: 'doc' 7 | theme: 'simplex' 8 | -------------------------------------------------------------------------------- /grunt/yuidoc.coffee: -------------------------------------------------------------------------------- 1 | module.exports = 2 | compile: 3 | name: '<%= package.name %>' 4 | version: '<%= package.version %>' 5 | options: 6 | paths: 'lib/' 7 | outdir: 'doc/' 8 | -------------------------------------------------------------------------------- /grunt/gh-pages.coffee: -------------------------------------------------------------------------------- 1 | module.exports = 2 | 3 | dist: 4 | options: 5 | base: 'doc' 6 | branch: 'gh-pages' 7 | message: 'Auto-generated commit' 8 | 9 | src: ['**'] 10 | -------------------------------------------------------------------------------- /grunt/release.coffee: -------------------------------------------------------------------------------- 1 | module.exports = 2 | 3 | options: 4 | changelog: true 5 | commit: true 6 | file: 'package.json' 7 | push: true 8 | pushTags: true 9 | beforeBump: ['prepublish'] 10 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | charset = utf-8 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | 10 | [*.md] 11 | trim_trailing_whitespace = false 12 | -------------------------------------------------------------------------------- /grunt/aliases.yaml: -------------------------------------------------------------------------------- 1 | prepublish: 2 | - codegen 3 | - lint 4 | - document 5 | 6 | codegen: 7 | - swagger-js-codegen 8 | 9 | document: 10 | - yuidoc 11 | 12 | lint: 13 | - jsonlint 14 | - jshint 15 | - coffeelint 16 | 17 | test: 18 | - codegen 19 | - lint 20 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | 3 | module.exports = function(grunt) { 4 | 5 | // measures the time each task takes 6 | require('time-grunt')(grunt); 7 | 8 | // load grunt config 9 | require('load-grunt-config')(grunt, { 10 | configPath: path.join(process.cwd(), './grunt'), 11 | init: true, 12 | jitGrunt: true 13 | }); 14 | 15 | }; 16 | -------------------------------------------------------------------------------- /grunt/swagger-js-codegen.coffee: -------------------------------------------------------------------------------- 1 | module.exports = 2 | 3 | magento: 4 | options: 5 | apis: [ 6 | swagger: '<%= package.config.swagger %>' 7 | className: 'Magento' 8 | mustache: 9 | className: 'Magento' 10 | # customParam: 'foo' 11 | template: 12 | class: './templates/class.mustache', 13 | method: './templates/method.mustache', 14 | request: './templates/request.mustache' 15 | custom: true 16 | ] 17 | dest: 'lib' 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Magento 2 REST API client automatically generated from Swagger specification 2 | 3 | Magento 2 implements [Swagger](http://swagger.io/) providing a JSON Schema of the REST endpoints, this package compiles the JSON into classes and methods using templates (see inside the `templates/` directory) for consuming the API in a NodeJS applicaton. 4 | 5 | ## Installation 6 | 7 | ```sh 8 | npm install magento2-swagger --save 9 | ``` 10 | 11 | ## Example usage 12 | 13 | A full specification of all the endpoints in this packages can be found in the [Magento 2 Dev Docs](http://devdocs.magento.com/swagger/index.html) 14 | 15 | ```js 16 | var magentoSwagger = require('magento2-swagger').Magento; 17 | 18 | var magento = new magentoSwagger('http://www.example.com/rest'); 19 | 20 | magento.catalogCategoryManagementV1GetTreeGet().done(function (response) { 21 | console.log(response.body); 22 | }); 23 | ``` 24 | -------------------------------------------------------------------------------- /coffeelint.json: -------------------------------------------------------------------------------- 1 | { 2 | "arrow_spacing": { 3 | "level": "error" 4 | }, 5 | "line_endings": { 6 | "level": "error" 7 | }, 8 | "indentation": { 9 | "value": 4 10 | }, 11 | "colon_assignment_spacing": { 12 | "level": "error", 13 | "spacing": { 14 | "left": 0, 15 | "right": 1 16 | } 17 | }, 18 | "space_operators": { 19 | "level": "error" 20 | }, 21 | "cyclomatic_complexity": { 22 | "value": 11, 23 | "level": "warn" 24 | }, 25 | "no_debugger": { 26 | "level": "error", 27 | "console": true 28 | }, 29 | "spacing_after_comma": { 30 | "level": "error" 31 | }, 32 | "no_unnecessary_double_quotes": { 33 | "level": "error" 34 | }, 35 | "braces_spacing": { 36 | "level": "error", 37 | "spaces": 1 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /templates/request.mustache: -------------------------------------------------------------------------------- 1 | var req = { 2 | method: '{{method}}', 3 | uri: domain + path, 4 | qs: queryParameters, 5 | headers: headers, 6 | body: body 7 | }; 8 | if(Object.keys(form).length > 0) { 9 | req.form = form; 10 | } 11 | if(typeof(body) === 'object' && !(body instanceof Buffer)) { 12 | req.json = true; 13 | } 14 | request(req, function(error, response, body){ 15 | if(error) { 16 | deferred.reject(error); 17 | } else { 18 | if(/^application\/(.*\\+)?json/.test(response.headers['content-type'])) { 19 | try { 20 | body = JSON.parse(body); 21 | } catch(e) { 22 | 23 | } 24 | } 25 | if(response.statusCode === 204) { 26 | deferred.resolve({ response: response }); 27 | } else if(response.statusCode >= 200 && response.statusCode <= 299) { 28 | deferred.resolve({ response: response, body: body }); 29 | } else { 30 | deferred.reject({ response: response, body: body }); 31 | } 32 | } 33 | }); 34 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "boss": true, // true: Tolerate assignments where comparisons would be expected 3 | "curly": true, // true: Require {} for every new block or scope 4 | "eqeqeq": true, // true: Require triple equals (===) for comparison 5 | "eqnull": true, // true: Tolerate use of `== null` 6 | "immed": true, // true: Require immediate invocations to be wrapped in parens e.g. `(function () { } ());` 7 | "latedef": true, // true: Require variables/functions to be defined before being used 8 | "newcap": true, // true: Require capitalization of all constructor functions e.g. `new F()` 9 | "noarg": true, // true: Prohibit use of `arguments.caller` and `arguments.callee` 10 | "sub": true, // true: Tolerate using `[]` notation when it can still be expressed in dot notation 11 | "undef": true, // true: Require all non-global variables to be declared (prevents global leaks) 12 | "unused": true, 13 | "node": true, // Node.js 14 | "-W117": true // true: Ignore `not defined` errors as an example of using a rule (W117) by code. 15 | } 16 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "magento2-swagger", 3 | "version": "0.0.8", 4 | "author": "Adam Johnson", 5 | "description": "Magento 2 REST API - code generated from official Swagger spec", 6 | "homepage": "https://github.com/adamj88/node-magento2-swagger#readme", 7 | "keywords": [ 8 | "magento 2", 9 | "rest" 10 | ], 11 | "main": "lib/magento.js", 12 | "config": { 13 | "swagger": "http://devdocs.magento.com/swagger/schemas/latest.json" 14 | }, 15 | "scripts": { 16 | "prepublish": "grunt prepublish", 17 | "test": "grunt test" 18 | }, 19 | "repository": { 20 | "type": "git", 21 | "url": "git+https://github.com/adamj88/node-magento2-swagger.git" 22 | }, 23 | "license": "MIT", 24 | "bugs": { 25 | "url": "https://github.com/adamj88/node-magento2-swagger/issues" 26 | }, 27 | "dependencies": {}, 28 | "devDependencies": { 29 | "coffeelint": "^1.14.2", 30 | "grunt": "^0.4.5", 31 | "grunt-coffeelint": "0.0.13", 32 | "grunt-contrib-jshint": "^0.11.3", 33 | "grunt-contrib-yuidoc": "^0.10.0", 34 | "grunt-gh-pages": "^1.0.0", 35 | "grunt-jsonlint": "^1.0.6", 36 | "grunt-release": "^0.13.0", 37 | "grunt-swagger-js-codegen": "^0.4.4", 38 | "load-grunt-config": "^0.19.1", 39 | "time-grunt": "^1.2.2" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /templates/class.mustache: -------------------------------------------------------------------------------- 1 | /*jshint -W069 */ 2 | /** 3 | * {{&description}} 4 | * @class {{&className}} 5 | * @param {(string|object)} [domainOrOptions] - The project domain or options object. If object, see the object's optional properties. 6 | * @param {string} [domainOrOptions.domain] - The project domain 7 | * @param {object} [domainOrOptions.token] - auth token - object with value property and optional headerOrQueryName and isQuery properties 8 | */ 9 | var {{&className}} = (function(){ 10 | 'use strict'; 11 | 12 | var request = require('request'); 13 | var Q = require('q'); 14 | 15 | function {{&className}}(options){ 16 | var domain = (typeof options === 'object') ? options.domain : options; 17 | this.domain = domain ? domain : '{{&domain}}'; 18 | if(this.domain.length === 0) { 19 | throw new Error('Domain parameter must be specified as a string.'); 20 | } 21 | {{#isSecure}} 22 | this.token = (typeof options === 'object') ? (options.token ? options.token : {}) : {}; 23 | {{/isSecure}} 24 | } 25 | 26 | {{#isSecure}} 27 | /** 28 | * Set Token 29 | * @method 30 | * @name {{&className}}#setToken 31 | * @param {string} value - token's value 32 | * @param {string} headerOrQueryName - the header or query name to send the token at 33 | * @param {boolean} isQuery - true if send the token as query param, otherwise, send as header param 34 | * 35 | */ 36 | {{&className}}.prototype.setToken = function (value, headerOrQueryName, isQuery) { 37 | this.token.value = value; 38 | this.token.headerOrQueryName = headerOrQueryName; 39 | this.token.isQuery = isQuery; 40 | }; 41 | {{/isSecure}} 42 | 43 | {{#methods}} 44 | {{> method}} 45 | {{/methods}} 46 | 47 | return {{&className}}; 48 | })(); 49 | 50 | exports.{{&className}} = {{&className}}; 51 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - v5 4 | - v4 5 | - '0.12' 6 | - '0.10' 7 | before_install: 8 | - npm install -g grunt grunt-cli 9 | after_success: 10 | - grunt gh-pages 11 | env: 12 | global: 13 | - secure: mYk/xZP0O3HeNLT7bJUHZOWYksB/wvogCasKvFNi6+GT/DtKrbH5sPcS4kReGMu4RAJwnZ1Zsj1DDzme5I3ZWijST0MPxB+giMzgr2McBWDLWFmsCJWPUj0mwdug5dqGGNkBjkjisY12an/RIx8SBsL0oN9IoeZrFCZB9Ra9sY4qYYPvBhWPfl4Uw2KDm4icTgTHW8e5pSTZyxzuerjWIYLNZ4yhL33SewNdL26Aab7pyJkjGHTlWo6TZafHOczH64y4hC5GkCJk+2hXZ1fH6UILNVqeCuR3/Y1P5XcUoft26IOdcnwuYAoNyl6KF1TNKe1lXZwZn/1S75pX38X0zxfkgdE3ONRc7dx1klVfNNF63Ipw3YM6WGsxBs1tIscC93NYpKikcQ+Wo1jEeCPscCpLF9AZ1QbxqaJ0Dvrzsc44Sdhad9nnP+R0InEB9kIVa7ISo49mhPms+5HYenyHCmYlcFIVwWDhrOIENOPiwf382lEEx4hXcRusKhB+H8jf8ZrrDUohYk4qxCiQhEDCcZ9CVCco2Z5QfkKkk6qcDkpKSPEoQPbi8h0rzZettoRvB5/ucalK4KntNkbZHcJqKbjJh5teLLHnIHuOVrdCnqOJ8eaJghzpUN+6pxRRIeIkY07nhi24KV8DPcAQAAzrDd+VJIl2iQfATa3GJ0YQ8E0= 14 | - secure: ZnOy7uh4Ova0VkwqBPOmPuy5RZMENC1Qlhv6QI7EeaThN4/Z3l/AbBRluEJius8Ud1axI73xxOOEuB0JEk8qyQ8JnXv1DPj3XNcm++YAeEWkWnhQpXNsj43ET2HMmKme7uz+WeAS7XTxAu5ddLO8G3i2zNewzG4njKIk8LLUUl86v/B/8aJr3Ue+O7MCXwcs4MchfeF/GQ+FKhalwX5Z/B0kWfAKeJeKKigHtIqkmx8ZaGILJozXiB944rABpQ6Jxb7UmSenqQkur6YRcUvpQLUgWEIL9cNo/H0zzOKlOY2Ym46argovSkG43kXPfscXX24ewjSMYypd7vza+vKxw46REa7ae2+WdhNwJFB4TTRuxGOMu3YcZScypdXDhyXRQmcA0xbGyRBqk+gpHSQnPVVGA/hDs7eSGPdEe4RSpAB8gIa/CgwHxVLM6kxhRE/6KYujfXtUFdzkzIMp3NHE5dAlNer4zcPoqAm21VZUIIjQV83vf5koYWrpinKPZlQNabd0n4oqorqfFlMfuL2oa+bosYBPSSljgKsAsAoFd8bnr6KQ26+sNvTG9hBhTYptcz/PYAFFmpEpbFCWhux5v9XNNacXoms0+6x7xOus59JUlRY8hMZDuDhL0ezwFIgGt3UaKcCbvyn/IqV0qEWTjcY3d6LCZCyG+xiRFcH652c= 15 | - secure: uZloZ5iHgQqPQam9ewsPRoMfqu9vAIzzzDimAZFDyMFhVgRN5XsaSWn0re9/rRASysUGurtvaXX99tLnr44xlNYUMPkC1hUzw3Hu5/7G46cAE/aOtUgieepzn7RePwm43KpVykLxGTmzAZp9bJbXI+EGlmOEIHuqngLniEE27igN55jjlyK4K79oyK70YSVQPe8ETJ5lcvsvsWOBH0OdhB9yH61fNNWpctbVmkFd70TTgjLFoEZtiTuloJ1GYXd4kvciP+eAMIdhKKvaw1uYR7VgoHSgyxe+I6WyEnTzuBVjhwAG2qeh63DONnFJ5gZbSn65pnHrcVQxNeH2GvOajS7FYuDPcEJMO73tG9gBFHnubgrKBOP2QKWWpnESX82RUZaKah4ln5Sjd52l7QQ7ovEAWzsUvYr4Lmmy+xonevdmL6Je6EQrVEBqWzkQQj30AmaeL6QfkmFbsVaUO2ptuMHpoeVNznuX8mFB+r4oQdMteHZCIoNBYqFDssQi9xAoGyzJkekv6De16KUrQig+rvwlRe0F5Q9quUI3k7iKKAcwTc5WA1P8LUgHJM+8DWeZnJ0nJf7fCNjIO3s3P8oMMZAtKA6KN9y8kp9HoelbY4JunfIlWE6IpOZqKxPPAtO1FUNyIejv264hYq4f7mcAJZFNCPv1UBfAJORXmzXOuec= 16 | -------------------------------------------------------------------------------- /templates/method.mustache: -------------------------------------------------------------------------------- 1 | /** 2 | * {{&summary}} 3 | * @method {{&methodName}} 4 | * @name {{&className}}#{{&methodName}} 5 | {{#parameters}} 6 | {{^isSingleton}} * @param {{=<% %>=}}{<%&type%>}<%={{ }}=%> {{&camelCaseName}} - {{&description}}{{/isSingleton}} 7 | {{/parameters}} 8 | * 9 | */ 10 | {{&className}}.prototype.{{&methodName}} = function(parameters){ 11 | if(parameters === undefined) { 12 | parameters = {}; 13 | } 14 | var deferred = Q.defer(); 15 | 16 | var domain = this.domain; 17 | var path = '{{&path}}'; 18 | 19 | var body; 20 | var queryParameters = {}; 21 | var headers = {}; 22 | var form = {}; 23 | 24 | {{#isSecure}} 25 | if (this.token.isQuery) { 26 | queryParameters[this.token.headerOrQueryName] = this.token.value; 27 | } else if (this.token.headerOrQueryName) { 28 | headers[this.token.headerOrQueryName] = this.token.value; 29 | } else { 30 | headers['Authorization'] = 'Bearer ' + this.token.value; 31 | } 32 | {{/isSecure}} 33 | 34 | {{#parameters}} 35 | 36 | {{#isQueryParameter}} 37 | {{#isSingleton}} 38 | queryParameters['{{&name}}'] = '{{&singleton}}'; 39 | {{/isSingleton}} 40 | {{^isSingleton}} 41 | {{#isPatternType}} 42 | Object.keys(parameters).forEach(function(parameterName) { 43 | if(new RegExp('{{&pattern}}').test(parameterName)){ 44 | queryParameters[parameterName] = parameters[parameterName]; 45 | } 46 | }); 47 | {{/isPatternType}} 48 | {{^isPatternType}} 49 | if(parameters['{{&camelCaseName}}'] !== undefined){ 50 | queryParameters['{{&name}}'] = parameters['{{&camelCaseName}}']; 51 | } 52 | {{/isPatternType}} 53 | {{/isSingleton}} 54 | {{/isQueryParameter}} 55 | 56 | {{#isPathParameter}} 57 | path = path.replace('{{=<% %>=}}{<%&name%>}<%={{ }}=%>', parameters['{{&camelCaseName}}']); 58 | {{/isPathParameter}} 59 | 60 | {{#isHeaderParameter}} 61 | {{#isSingleton}} 62 | headers['{{&name}}'] = '{{&singleton}}'; 63 | {{/isSingleton}} 64 | {{^isSingleton}} 65 | if(parameters['{{&camelCaseName}}'] !== undefined){ 66 | headers['{{&name}}'] = parameters['{{&camelCaseName}}']; 67 | } 68 | {{/isSingleton}} 69 | {{/isHeaderParameter}} 70 | 71 | {{#isBodyParameter}} 72 | if(parameters['{{&camelCaseName}}'] !== undefined){ 73 | body = parameters['{{&camelCaseName}}']; 74 | } 75 | {{/isBodyParameter}} 76 | 77 | {{#isFormParameter}} 78 | {{#isSingleton}} 79 | form['{{&name}}'] = '{{&singleton}}'; 80 | {{/isSingleton}} 81 | {{^isSingleton}} 82 | if(parameters['{{&camelCaseName}}'] !== undefined){ 83 | form['{{&name}}'] = parameters['{{&camelCaseName}}']; 84 | } 85 | {{/isSingleton}} 86 | {{/isFormParameter}} 87 | 88 | {{#required}} 89 | if(parameters['{{&camelCaseName}}'] === undefined){ 90 | deferred.reject(new Error('Missing required {{¶mType}} parameter: {{&camelCaseName}}')); 91 | return deferred.promise; 92 | } 93 | {{/required}} 94 | 95 | {{/parameters}} 96 | 97 | if(parameters.$queryParameters) { 98 | Object.keys(parameters.$queryParameters) 99 | .forEach(function(parameterName){ 100 | var parameter = parameters.$queryParameters[parameterName]; 101 | queryParameters[parameterName] = parameter; 102 | }); 103 | } 104 | 105 | {{> request}} 106 | 107 | return deferred.promise; 108 | }; 109 | --------------------------------------------------------------------------------